• 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 {
ResolveDirectory(const String & targetDirectory)16 bool CServiceDriverCodeEmitter::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("CServiceDriverCodeEmitter", "Create '%s' failed!", directory_.string());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CServiceDriverCodeEmitter::EmitCode()
32 {
33     // the callback interface or interface as method parameter have no driver file.
34     if (!interface_->IsSerializable()) {
35         EmitDriverSourceFile();
36     }
37 }
38 
EmitDriverSourceFile()39 void CServiceDriverCodeEmitter::EmitDriverSourceFile()
40 {
41     String filePath = String::Format("%s/%s.c", 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     EmitDriverServiceDecl(sb);
49     sb.Append("\n");
50     EmitDriverDispatch(sb);
51     sb.Append("\n");
52     EmitDriverInit(sb);
53     sb.Append("\n");
54     EmitDriverBind(sb);
55     sb.Append("\n");
56     EmitDriverRelease(sb);
57     sb.Append("\n");
58     EmitDriverEntryDefinition(sb);
59 
60     String data = sb.ToString();
61     file.WriteData(data.string(), data.GetLength());
62     file.Flush();
63     file.Close();
64 }
65 
EmitDriverIncluions(StringBuilder & sb)66 void CServiceDriverCodeEmitter::EmitDriverIncluions(StringBuilder& sb)
67 {
68     HeaderFile::HeaderFileSet headerFiles;
69 
70     headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(implName_)));
71     GetDriverSourceOtherLibInclusions(headerFiles);
72 
73     for (const auto& file : headerFiles) {
74         sb.AppendFormat("%s\n", file.ToString().string());
75     }
76 }
77 
GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)78 void CServiceDriverCodeEmitter::GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles)
79 {
80     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base"));
81     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log"));
82     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem"));
83     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc"));
84     if (!isKernelCode_) {
85         headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_object"));
86     }
87 }
88 
EmitDriverServiceDecl(StringBuilder & sb)89 void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb)
90 {
91     sb.AppendFormat("struct Hdf%sHost {\n", baseName_.string());
92     sb.Append(g_tab).AppendFormat("struct IDeviceIoService ioservice;\n");
93     sb.Append(g_tab).AppendFormat("struct %s *service;\n", implName_.string());
94     sb.Append("};\n");
95 }
96 
EmitDriverDispatch(StringBuilder & sb)97 void CServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder& sb)
98 {
99     String hostName = baseName_.ToLowerCase() + "Host";
100     sb.AppendFormat("static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n",
101         baseName_.string());
102     sb.Append(g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
103     sb.Append("{\n");
104     sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(\n",
105         baseName_.string(), hostName.string());
106     sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n",
107         baseName_.string());
108 
109     sb.Append(g_tab).AppendFormat("if (%s->service == NULL || %s->service->stub.OnRemoteRequest == NULL) {\n",
110         hostName.string(), hostName.string());
111     sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
112     sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_OBJECT;\n");
113     sb.Append(g_tab).Append("}\n\n");
114 
115     if (!isKernelCode_) {
116         sb.Append(g_tab).AppendFormat("if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {\n");
117         sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: check interface desc failed!\", __func__);\n");
118         sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
119         sb.Append(g_tab).Append("}\n\n");
120     }
121 
122     sb.Append(g_tab).AppendFormat("return %s->service->stub.OnRemoteRequest(", hostName.string());
123     sb.AppendFormat("&%s->service->stub.interface, cmdId, data, reply);\n", hostName.string());
124     sb.Append("}\n");
125 }
126 
EmitDriverInit(StringBuilder & sb)127 void CServiceDriverCodeEmitter::EmitDriverInit(StringBuilder& sb)
128 {
129     sb.AppendFormat("int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", baseName_.string());
130     sb.Append("{\n");
131     sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverInit enter.\");\n", baseName_.string());
132     sb.Append(g_tab).Append("return HDF_SUCCESS;\n");
133     sb.Append("}\n");
134 }
135 
EmitDriverBind(StringBuilder & sb)136 void CServiceDriverCodeEmitter::EmitDriverBind(StringBuilder& sb)
137 {
138     String hostName = baseName_.ToLowerCase() + "Host";
139     sb.AppendFormat("int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.string());
140     sb.Append("{\n");
141     sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter.\");\n", baseName_.string());
142     sb.Append("\n");
143 
144     if (!isKernelCode_) {
145         sb.Append(g_tab).AppendFormat("int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, %s);\n",
146             EmitDescMacroName().string());
147         sb.Append(g_tab).Append("if (ret != HDF_SUCCESS) {\n");
148         sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"failed to set interface descriptor of device object\");\n");
149         sb.Append(g_tab).Append(g_tab).Append("return ret;\n");
150         sb.Append(g_tab).Append("}\n\n");
151     }
152 
153     sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(\n",
154         baseName_.string(), hostName.string(), baseName_.string());
155     sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.string());
156     sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", hostName.string());
157     sb.Append(g_tab).Append(g_tab).AppendFormat(
158         "HDF_LOGE(\"Hdf%sDriverBind OsalMemCalloc Hdf%sHost failed!\");\n", baseName_.string(), baseName_.string());
159     sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n");
160     sb.Append(g_tab).Append("}\n");
161     sb.Append("\n");
162     sb.Append(g_tab).AppendFormat("%s->ioservice.Dispatch = %sDriverDispatch;\n",
163         hostName.string(), baseName_.string());
164     sb.Append(g_tab).AppendFormat("%s->ioservice.Open = NULL;\n", hostName.string());
165     sb.Append(g_tab).AppendFormat("%s->ioservice.Release = NULL;\n", hostName.string());
166     sb.Append(g_tab).AppendFormat("%s->service = %sServiceGet();\n", hostName.string(), baseName_.string());
167     sb.Append(g_tab).AppendFormat("if (%s->service == NULL) {\n", hostName.string());
168     sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", hostName.string());
169     sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n");
170     sb.Append(g_tab).Append("}\n");
171     sb.Append("\n");
172     sb.Append(g_tab).AppendFormat("deviceObject->service = &%s->ioservice;\n", hostName.string());
173     sb.Append(g_tab).Append("return HDF_SUCCESS;\n");
174     sb.Append("}\n");
175 }
176 
EmitDriverRelease(StringBuilder & sb)177 void CServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder& sb)
178 {
179     String hostName = baseName_.ToLowerCase() + "Host";
180     sb.AppendFormat("void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.string());
181     sb.Append("{\n");
182     sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter.\");\n", baseName_.string());
183     sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.string(), hostName.string());
184     sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioservice);\n",
185         baseName_.string());
186     sb.Append(g_tab).AppendFormat("%sServiceRelease(%s->service);\n", baseName_.string(), hostName.string());
187     sb.Append(g_tab).AppendFormat("OsalMemFree(%s);\n", hostName.string());
188     sb.Append("}\n");
189 }
190 
EmitDriverEntryDefinition(StringBuilder & sb)191 void CServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder& sb)
192 {
193     sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", baseName_.ToLowerCase().string());
194     sb.Append(g_tab).Append(".moduleVersion = 1,\n");
195     sb.Append(g_tab).AppendFormat(".moduleName = \"%s\",\n",
196         Options::GetInstance().GetModuleName().string());
197     sb.Append(g_tab).AppendFormat(".Bind = Hdf%sDriverBind,\n", baseName_.string());
198     sb.Append(g_tab).AppendFormat(".Init = Hdf%sDriverInit,\n", baseName_.string());
199     sb.Append(g_tab).AppendFormat(".Release = Hdf%sDriverRelease,\n", baseName_.string());
200     sb.Append("};\n\n");
201     sb.AppendFormat("HDF_INIT(g_%sDriverEntry);", baseName_.ToLowerCase().string());
202 }
203 } // namespace HDI
204 } // namespace OHOS