• 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/c_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 {
CServiceDriverCodeEmitter()16 CServiceDriverCodeEmitter::CServiceDriverCodeEmitter() : CCodeEmitter()
17 {
18     hostName_ = StringHelper::StrToLower(baseName_) + "Host";
19 }
20 
ResolveDirectory(const std::string & targetDirectory)21 bool CServiceDriverCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
22 {
23     if (ast_->GetASTFileType() != ASTFileType::AST_IFACE) {
24         return false;
25     }
26 
27     directory_ = GetFileParentPath(targetDirectory);
28     if (!File::CreateParentDir(directory_)) {
29         Logger::E("CServiceDriverCodeEmitter", "Create '%s' failed!", directory_.c_str());
30         return false;
31     }
32 
33     return true;
34 }
35 
EmitCode()36 void CServiceDriverCodeEmitter::EmitCode()
37 {
38     if (Options::GetInstance().DoPassthrough()) {
39         return;
40     }
41 
42     // the callback interface or interface as method parameter have no driver file.
43     if (isKernelCode_ || !interface_->IsSerializable()) {
44         EmitDriverSourceFile();
45     }
46 }
47 
EmitDriverSourceFile()48 void CServiceDriverCodeEmitter::EmitDriverSourceFile()
49 {
50     std::string filePath =
51         File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_ + "Driver").c_str()));
52     File file(filePath, File::WRITE);
53     StringBuilder sb;
54 
55     EmitLicense(sb);
56     EmitDriverInclusions(sb);
57     sb.Append("\n");
58     EmitLogTagMacro(sb, FileName(baseName_ + "Driver"));
59     sb.Append("\n");
60     EmitDriverServiceDecl(sb);
61     sb.Append("\n");
62     if (isKernelCode_) {
63         EmitKernelDriverDispatch(sb);
64         sb.Append("\n");
65         EmitDriverInit(sb);
66         sb.Append("\n");
67         EmitKernelDriverBind(sb);
68         sb.Append("\n");
69         EmitKernelDriverRelease(sb);
70     } else {
71         EmitDriverDispatch(sb);
72         sb.Append("\n");
73         EmitDriverInit(sb);
74         sb.Append("\n");
75         EmitDriverBind(sb);
76         sb.Append("\n");
77         EmitDriverRelease(sb);
78     }
79     sb.Append("\n");
80     EmitDriverEntryDefinition(sb);
81 
82     std::string data = sb.ToString();
83     file.WriteData(data.c_str(), data.size());
84     file.Flush();
85     file.Close();
86 }
87 
EmitDriverInclusions(StringBuilder & sb)88 void CServiceDriverCodeEmitter::EmitDriverInclusions(StringBuilder &sb)
89 {
90     HeaderFile::HeaderFileSet headerFiles;
91 
92     if (isKernelCode_) {
93         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(implName_));
94     } else {
95         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
96     }
97 
98     GetDriverSourceOtherLibInclusions(headerFiles);
99 
100     for (const auto &file : headerFiles) {
101         sb.AppendFormat("%s\n", file.ToString().c_str());
102     }
103 }
104 
GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)105 void CServiceDriverCodeEmitter::GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
106 {
107     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
108     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
109     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
110     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc");
111     if (!isKernelCode_) {
112         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_object");
113         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service");
114         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
115     }
116 }
117 
EmitDriverServiceDecl(StringBuilder & sb)118 void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder &sb)
119 {
120     sb.AppendFormat("struct Hdf%sHost {\n", baseName_.c_str());
121     sb.Append(TAB).AppendFormat("struct IDeviceIoService ioService;\n");
122     if (isKernelCode_) {
123         sb.Append(TAB).AppendFormat("struct %s *service;\n", implName_.c_str());
124     } else {
125         sb.Append(TAB).AppendFormat("struct %s *service;\n", interfaceName_.c_str());
126         sb.Append(TAB).Append("struct HdfRemoteService **stubObject;\n");
127     }
128     sb.Append("};\n");
129 }
130 
EmitKernelDriverDispatch(StringBuilder & sb)131 void CServiceDriverCodeEmitter::EmitKernelDriverDispatch(StringBuilder &sb)
132 {
133     sb.AppendFormat(
134         "static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", baseName_.c_str());
135     sb.Append(TAB).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
136     sb.Append("{\n");
137     sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(\n", baseName_.c_str(), hostName_.c_str());
138     sb.Append(TAB).Append(TAB).AppendFormat(
139         "client->device->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
140     sb.Append(TAB).AppendFormat("if (%s->service == NULL || %s->service->stub.OnRemoteRequest == NULL) {\n",
141         hostName_.c_str(), hostName_.c_str());
142     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
143     sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
144     sb.Append(TAB).Append("}\n\n");
145     sb.Append(TAB).AppendFormat("return %s->service->stub.OnRemoteRequest(", hostName_.c_str());
146     sb.AppendFormat("&%s->service->stub.interface, cmdId, data, reply);\n", hostName_.c_str());
147     sb.Append("}\n");
148 }
149 
EmitDriverDispatch(StringBuilder & sb)150 void CServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder &sb)
151 {
152     sb.AppendFormat(
153         "static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", baseName_.c_str());
154     sb.Append(TAB).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
155     sb.Append("{\n");
156     sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
157     sb.AppendFormat("client->device->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
158     sb.Append(TAB).AppendFormat("if (%s->service == NULL || %s->stubObject == NULL) {\n",
159         hostName_.c_str(), hostName_.c_str());
160     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
161     sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
162     sb.Append(TAB).Append("}\n\n");
163     sb.Append(TAB).AppendFormat("struct HdfRemoteService *stubObj = *%s->stubObject;\n", hostName_.c_str());
164     sb.Append(TAB).AppendFormat("if (stubObj == NULL || stubObj->dispatcher == NULL || ");
165     sb.Append("stubObj->dispatcher->Dispatch == NULL) {\n");
166     sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
167     sb.Append(TAB).Append("}\n\n");
168     sb.Append(TAB).Append("return stubObj->dispatcher->Dispatch(");
169     sb.Append("(struct HdfRemoteService *)stubObj->target, cmdId, data, reply);\n");
170     sb.Append("}\n");
171 }
172 
EmitDriverInit(StringBuilder & sb)173 void CServiceDriverCodeEmitter::EmitDriverInit(StringBuilder &sb)
174 {
175     sb.AppendFormat("static int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
176     sb.Append("{\n");
177     sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver init start\", __func__);\n");
178     sb.Append(TAB).Append("return HDF_SUCCESS;\n");
179     sb.Append("}\n");
180 }
181 
EmitKernelDriverBind(StringBuilder & sb)182 void CServiceDriverCodeEmitter::EmitKernelDriverBind(StringBuilder &sb)
183 {
184     sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
185     sb.Append("{\n");
186     sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
187     sb.Append("\n");
188 
189     sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(", baseName_.c_str(),
190         hostName_.c_str(), baseName_.c_str());
191     sb.AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.c_str());
192     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", hostName_.c_str());
193     sb.Append(TAB).Append(TAB).AppendFormat(
194         "HDF_LOGE(\"Hdf%sDriverBind create Hdf%sHost object failed!\");\n", baseName_.c_str(), baseName_.c_str());
195     sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
196     sb.Append(TAB).Append("}\n");
197     sb.Append("\n");
198     sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", hostName_.c_str(), baseName_.c_str());
199     sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", hostName_.c_str());
200     sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n", hostName_.c_str());
201     sb.Append(TAB).AppendFormat("%s->service = %sServiceGet();\n", hostName_.c_str(), baseName_.c_str());
202     sb.Append(TAB).AppendFormat("if (%s->service == NULL) {\n", hostName_.c_str());
203     sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
204     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get service object\", __func__);\n");
205     sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
206     sb.Append(TAB).Append("}\n");
207     sb.Append("\n");
208     sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", hostName_.c_str());
209     sb.Append(TAB).Append("return HDF_SUCCESS;\n");
210     sb.Append("}\n");
211 }
212 
EmitDriverBind(StringBuilder & sb)213 void CServiceDriverCodeEmitter::EmitDriverBind(StringBuilder &sb)
214 {
215     sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
216     sb.Append("{\n");
217     sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
218     sb.Append(TAB).AppendFormat("int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, %s);\n",
219         interface_->EmitDescMacroName().c_str());
220     sb.Append(TAB).Append("if (ret != HDF_SUCCESS) {\n");
221     sb.Append(TAB).Append(TAB).Append(
222         "HDF_LOGE(\"%{public}s: failed to set interface descriptor of device object\", __func__);\n");
223     sb.Append(TAB).Append(TAB).Append("return ret;\n");
224     sb.Append(TAB).Append("}\n\n");
225 
226     sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(", baseName_.c_str(),
227         hostName_.c_str(), baseName_.c_str());
228     sb.AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.c_str());
229     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", hostName_.c_str());
230     sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: create Hdf%sHost object failed!\", __func__);\n",
231         baseName_.c_str());
232     sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
233     sb.Append(TAB).Append("}\n\n");
234     sb.Append(TAB).AppendFormat("struct %s *serviceImpl = %sGet(true);\n", interfaceName_.c_str(),
235         interfaceName_.c_str());
236     sb.Append(TAB).Append("if (serviceImpl == NULL) {\n");
237     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: create serviceImpl failed!\", __func__);\n");
238     sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
239     sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
240     sb.Append(TAB).Append("}\n\n");
241     sb.Append(TAB).AppendFormat("struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(");
242     sb.AppendFormat("%s, serviceImpl);\n", interface_->EmitDescMacroName().c_str());
243     sb.Append(TAB).Append("if (stubObj == NULL) {\n");
244     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get stub object\", __func__);\n");
245     sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
246     sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(serviceImpl, true);\n", interfaceName_.c_str());
247     sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
248     sb.Append(TAB).Append("}\n\n");
249 
250     sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", hostName_.c_str(), baseName_.c_str());
251     sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", hostName_.c_str());
252     sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n", hostName_.c_str());
253     sb.Append(TAB).AppendFormat("%s->service = serviceImpl;\n", hostName_.c_str());
254     sb.Append(TAB).AppendFormat("%s->stubObject = stubObj;\n", hostName_.c_str());
255     sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", hostName_.c_str());
256     sb.Append(TAB).Append("return HDF_SUCCESS;\n");
257     sb.Append("}\n");
258 }
259 
EmitKernelDriverRelease(StringBuilder & sb)260 void CServiceDriverCodeEmitter::EmitKernelDriverRelease(StringBuilder &sb)
261 {
262     sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
263     sb.Append("{\n");
264     sb.Append(TAB).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter.\");\n", baseName_.c_str());
265     sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
266     sb.Append(TAB).Append(TAB).Append("return;\n");
267     sb.Append(TAB).Append("}\n\n");
268     sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
269     sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
270     sb.Append(TAB).AppendFormat("if (%s != NULL) {\n", hostName_.c_str());
271     sb.Append(TAB).Append(TAB).AppendFormat("%sServiceRelease(%s->service);\n", baseName_.c_str(), hostName_.c_str());
272     sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
273     sb.Append(TAB).Append("}\n");
274     sb.Append("}\n");
275 }
276 
EmitDriverRelease(StringBuilder & sb)277 void CServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder &sb)
278 {
279     sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
280     sb.Append("{\n");
281     sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
282 
283     sb.Append(TAB).Append("if (deviceObject->service == NULL) {\n");
284     sb.Append(TAB).Append(TAB).Append("return;\n");
285     sb.Append(TAB).Append("}\n\n");
286 
287     sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
288     sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
289     sb.Append(TAB).AppendFormat("if (%s != NULL) {\n", hostName_.c_str());
290     sb.Append(TAB).Append(TAB).AppendFormat("StubCollectorRemoveObject(%s, %s->service);\n",
291         interface_->EmitDescMacroName().c_str(), hostName_.c_str());
292     sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(%s->service, true);\n", interfaceName_.c_str(),
293         hostName_.c_str());
294     sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
295     sb.Append(TAB).Append("}\n");
296     sb.Append("}\n");
297 }
298 
EmitDriverEntryDefinition(StringBuilder & sb)299 void CServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder &sb)
300 {
301     sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", StringHelper::StrToLower(baseName_).c_str());
302     sb.Append(TAB).Append(".moduleVersion = 1,\n");
303     sb.Append(TAB).AppendFormat(".moduleName = \"%s\",\n", Options::GetInstance().GetModuleName().c_str());
304     sb.Append(TAB).AppendFormat(".Bind = Hdf%sDriverBind,\n", baseName_.c_str());
305     sb.Append(TAB).AppendFormat(".Init = Hdf%sDriverInit,\n", baseName_.c_str());
306     sb.Append(TAB).AppendFormat(".Release = Hdf%sDriverRelease,\n", baseName_.c_str());
307     sb.Append("};\n\n");
308     sb.AppendFormat("HDF_INIT(g_%sDriverEntry);\n", StringHelper::StrToLower(baseName_).c_str());
309 }
310 } // namespace HDI
311 } // namespace OHOS