• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "codegen/cpp_service_driver_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12 #include "util/options.h"
13 
14 namespace OHOS {
15 namespace HDI {
ResolveDirectory(const String & targetDirectory)16 bool CppServiceDriverCodeEmitter::ResolveDirectory(const String& targetDirectory)
17 {
18     if (ast_->GetASTFileType() != ASTFileType::AST_IFACE) {
19         return false;
20     }
21 
22     directory_ = GetFilePath(targetDirectory);
23     if (!File::CreateParentDir(directory_)) {
24         Logger::E("CppServiceDriverCodeEmitter", "Create '%s' failed!", directory_.string());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CppServiceDriverCodeEmitter::EmitCode()
32 {
33     // the callback interface have no driver file.
34     if (!interface_->IsSerializable()) {
35         EmitDriverSourceFile();
36     }
37 }
38 
EmitDriverSourceFile()39 void CppServiceDriverCodeEmitter::EmitDriverSourceFile()
40 {
41     String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(baseName_ + "Driver").string());
42     File file(filePath, File::WRITE);
43     StringBuilder sb;
44 
45     EmitLicense(sb);
46     EmitDriverIncluions(sb);
47     sb.Append("\n");
48     EmitDriverUsings(sb);
49     sb.Append("\n");
50     EmitDriverServiceDecl(sb);
51     sb.Append("\n");
52     EmitDriverDispatch(sb);
53     sb.Append("\n");
54     EmitDriverInit(sb);
55     sb.Append("\n");
56     EmitDriverBind(sb);
57     sb.Append("\n");
58     EmitDriverRelease(sb);
59     sb.Append("\n");
60     EmitDriverEntryDefinition(sb);
61 
62     String data = sb.ToString();
63     file.WriteData(data.string(), data.GetLength());
64     file.Flush();
65     file.Close();
66 }
67 
EmitDriverIncluions(StringBuilder & sb)68 void CppServiceDriverCodeEmitter::EmitDriverIncluions(StringBuilder& sb)
69 {
70     HeaderFile::HeaderFileSet headerFiles;
71 
72     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base"));
73     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log"));
74     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem"));
75     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc"));
76     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf_ipc"));
77     headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(implName_)));
78 
79     for (const auto& file : headerFiles) {
80         sb.AppendFormat("%s\n", file.ToString().string());
81     }
82 }
83 
EmitDriverUsings(StringBuilder & sb)84 void CppServiceDriverCodeEmitter::EmitDriverUsings(StringBuilder& sb)
85 {
86     String nspace = EmitPackageToNameSpace(interface_->GetNamespace()->ToString());
87     sb.AppendFormat("using namespace %s;\n", nspace.string());
88 }
89 
EmitDriverServiceDecl(StringBuilder & sb)90 void CppServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb)
91 {
92     sb.AppendFormat("struct Hdf%sHost {\n", baseName_.string());
93     sb.Append(g_tab).Append("struct IDeviceIoService ioservice;\n");
94     sb.Append(g_tab).AppendFormat("%s *service;\n", implName_.string());
95     sb.Append("};\n");
96 }
97 
EmitDriverDispatch(StringBuilder & sb)98 void CppServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder& sb)
99 {
100     String objName = String::Format("hdf%sHost", baseName_.string());
101     sb.AppendFormat("static int32_t %sDriverDispatch(", baseName_.string());
102     sb.Append("struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,\n");
103     sb.Append(g_tab).Append("struct HdfSBuf *reply)\n");
104     sb.Append("{\n");
105     sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.string(), objName.string());
106     sb.AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n\n", baseName_.string());
107 
108     sb.Append(g_tab).Append("OHOS::MessageParcel *dataParcel = nullptr;\n");
109     sb.Append(g_tab).Append("OHOS::MessageParcel *replyParcel = nullptr;\n");
110     sb.Append(g_tab).Append("OHOS::MessageOption option;\n\n");
111 
112     sb.Append(g_tab).Append("(void)SbufToParcel(reply, &replyParcel);\n");
113     sb.Append(g_tab).Append("if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {\n");
114     sb.Append(g_tab).Append(g_tab).Append(
115         "HDF_LOGE(\"%{public}s:invalid data sbuf object to dispatch\", __func__);\n");
116     sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
117     sb.Append(g_tab).Append("}\n\n");
118 
119     sb.Append(g_tab).AppendFormat("return %s->service->OnRemoteRequest(cmdId, *dataParcel, *replyParcel, option);\n",
120         objName.string());
121     sb.Append("}\n");
122 }
123 
EmitDriverInit(StringBuilder & sb)124 void CppServiceDriverCodeEmitter::EmitDriverInit(StringBuilder& sb)
125 {
126     sb.AppendFormat("int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", baseName_.string());
127     sb.Append("{\n");
128     sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverInit enter\");\n", baseName_.string());
129     sb.Append(g_tab).Append("return HDF_SUCCESS;\n");
130     sb.Append("}\n");
131 }
132 
EmitDriverBind(StringBuilder & sb)133 void CppServiceDriverCodeEmitter::EmitDriverBind(StringBuilder& sb)
134 {
135     String objName = String::Format("hdf%sHost", baseName_.string());
136     sb.AppendFormat("int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.string());
137     sb.Append("{\n");
138     sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter\");\n\n", baseName_.string());
139 
140     sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(\n",
141         baseName_.string(), objName.string(), baseName_.string());
142     sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.string());
143     sb.Append(g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string());
144     sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"Hdf%sDriverBind OsalMemCalloc Hdf%sHost failed!\");\n",
145         baseName_.string(), baseName_.string());
146     sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n");
147     sb.Append(g_tab).Append("}\n\n");
148 
149     sb.Append(g_tab).AppendFormat("%s->ioservice.Dispatch = %sDriverDispatch;\n",
150         objName.string(), baseName_.string());
151     sb.Append(g_tab).AppendFormat("%s->ioservice.Open = NULL;\n", objName.string());
152     sb.Append(g_tab).AppendFormat("%s->ioservice.Release = NULL;\n", objName.string());
153     sb.Append(g_tab).AppendFormat("%s->service = new %s();\n\n", objName.string(), implName_.string());
154 
155     sb.Append(g_tab).AppendFormat("deviceObject->service = &%s->ioservice;\n", objName.string());
156     sb.Append(g_tab).Append("return HDF_SUCCESS;\n");
157     sb.Append("}\n");
158 }
159 
EmitDriverRelease(StringBuilder & sb)160 void CppServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder& sb)
161 {
162     String objName = String::Format("hdf%sHost", baseName_.string());
163     sb.AppendFormat("void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)", baseName_.string());
164     sb.Append("{\n");
165     sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter\");\n\n", baseName_.string());
166     sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.string(), objName.string());
167     sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioservice);\n", baseName_.string());
168     sb.Append(g_tab).AppendFormat("delete %s->service;\n", objName.string());
169     sb.Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string());
170     sb.Append("}\n");
171 }
172 
EmitDriverEntryDefinition(StringBuilder & sb)173 void CppServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder& sb)
174 {
175     sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", baseName_.ToLowerCase().string());
176     sb.Append(g_tab).Append(".moduleVersion = 1,\n");
177     sb.Append(g_tab).AppendFormat(".moduleName = \"%s\",\n",
178         Options::GetInstance().GetModuleName().string());
179     sb.Append(g_tab).AppendFormat(".Bind = Hdf%sDriverBind,\n", baseName_.string());
180     sb.Append(g_tab).AppendFormat(".Init = Hdf%sDriverInit,\n", baseName_.string());
181     sb.Append(g_tab).AppendFormat(".Release = Hdf%sDriverRelease,\n", baseName_.string());
182     sb.Append("};\n");
183     sb.Append("\n");
184     sb.Append("#ifndef __cplusplus\n");
185     sb.Append("extern \"C\" {\n");
186     sb.Append("#endif\n");
187     sb.AppendFormat("HDF_INIT(g_%sDriverEntry);\n", baseName_.ToLowerCase().string());
188     sb.Append("#ifndef __cplusplus\n");
189     sb.Append("}\n");
190     sb.Append("#endif\n");
191 }
192 } // namespace HDI
193 } // namespace OHOS