1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "usb_pnp_manager.h"
17 #include <pthread.h>
18 #include <unistd.h>
19
20 #include "ddk_device_manager.h"
21 #include "ddk_pnp_listener_mgr.h"
22 #include "ddk_uevent_handle.h"
23 #include "device_resource_if.h"
24 #include "hdf_base.h"
25 #include "hdf_device_desc.h"
26 #include "hdf_device_object.h"
27 #include "hdf_io_service_if.h"
28 #include "hdf_log.h"
29 #include "osal_mem.h"
30 #include "securec.h"
31 #include "usb_ddk_pnp_loader.h"
32
33 #define HDF_LOG_TAG usb_pnp_manager
34 #define MODULENAMESIZE 128
35
UsbPnpManagerWriteModuleName(struct HdfSBuf * sbuf,const char * moduleName)36 bool UsbPnpManagerWriteModuleName(struct HdfSBuf *sbuf, const char *moduleName)
37 {
38 char modName[MODULENAMESIZE] = {0};
39 if (sprintf_s(modName, MODULENAMESIZE, "lib%s.z.so", moduleName) < 0) {
40 HDF_LOGE("%{public}s: sprintf_s modName failed", __func__);
41 return false;
42 }
43
44 return HdfSbufWriteString(sbuf, modName);
45 }
46
UsbPnpManagerDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)47 static int32_t UsbPnpManagerDispatch(
48 struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
49 {
50 (void)client;
51 (void)cmd;
52 (void)data;
53 (void)reply;
54
55 HDF_LOGI("received cmd = %d", cmd);
56 return HDF_SUCCESS;
57 }
58
UsbPnpManagerBind(struct HdfDeviceObject * device)59 static int32_t UsbPnpManagerBind(struct HdfDeviceObject *device)
60 {
61 static struct IDeviceIoService pnpLoaderService = {
62 .Dispatch = UsbPnpManagerDispatch,
63 };
64
65 if (device == NULL) {
66 return HDF_ERR_INVALID_OBJECT;
67 }
68
69 device->service = &pnpLoaderService;
70 HDF_LOGI("usb pnp manager bind success\n");
71
72 return HDF_SUCCESS;
73 }
74
75 #ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE
UsbPnpManagerStartUeventThread(void)76 int32_t UsbPnpManagerStartUeventThread(void)
77 {
78 pthread_t tid;
79 int32_t ret = pthread_create(&tid, NULL, DdkUeventMain, NULL);
80 if (ret != 0) {
81 HDF_LOGE("%{public}s: create thread failed:%{public}d", __func__, ret);
82 return ret;
83 }
84
85 ret = pthread_setname_np(tid, "usbpnpUeventThd");
86 if (ret != 0) {
87 HDF_LOGE("%{public}s: set thread name failed:%{public}d", __func__, ret);
88 }
89 return ret;
90 }
91 #endif
92
UsbPnpMgrGetGadgetPath(struct HdfDeviceObject * device,const char * attrName)93 static const char *UsbPnpMgrGetGadgetPath(struct HdfDeviceObject *device, const char *attrName)
94 {
95 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
96 if (iface == NULL) {
97 HDF_LOGE("%{public}s: DeviceResourceGetIfaceInstance failed\n", __func__);
98 return NULL;
99 }
100
101 const char *path = NULL;
102 const char *pathDef = NULL;
103 if (device == NULL) {
104 HDF_LOGE("%{public}s: device is empty\n", __func__);
105 return NULL;
106 }
107 if (iface->GetString(device->property, attrName, &path, pathDef) != HDF_SUCCESS) {
108 HDF_LOGE("%{public}s: read %{public}s failed", __func__, attrName);
109 return NULL;
110 }
111 return path;
112 }
113
UsbPnpManagerInit(struct HdfDeviceObject * device)114 static int32_t UsbPnpManagerInit(struct HdfDeviceObject *device)
115 {
116 static struct HdfDevEventlistener usbPnpListener = {
117 .callBack = UsbDdkPnpLoaderEventReceived,
118 };
119 usbPnpListener.priv = (void *)(device);
120
121 int32_t ret = DdkDevMgrInit(UsbPnpMgrGetGadgetPath(device, "gadget_state_path"));
122 if (ret != HDF_SUCCESS) {
123 HDF_LOGE("%{public}s: DdkDevMgrInit error", __func__);
124 return HDF_FAILURE;
125 }
126
127 ret = DdkListenerMgrInit();
128 if (ret != HDF_SUCCESS) {
129 HDF_LOGE("%{public}s: DdkListenerMgrInit error", __func__);
130 return HDF_FAILURE;
131 }
132
133 ret = DdkUeventInit(UsbPnpMgrGetGadgetPath(device, "gadget_uevent_path"));
134 if (ret != HDF_SUCCESS) {
135 HDF_LOGE("%{public}s: DdkUeventInit error", __func__);
136 return ret;
137 }
138 #ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE
139 if (UsbPnpManagerStartUeventThread() != HDF_SUCCESS) {
140 HDF_LOGE("%{public}s: start uevent thread failed", __func__);
141 return HDF_FAILURE;
142 }
143 #endif
144 ret = UsbDdkPnpLoaderEventHandle();
145 if (ret != HDF_SUCCESS) {
146 HDF_LOGE("%{public}s: UsbDdkPnpLoaderEventHandle failed", __func__);
147 return ret;
148 }
149 if (DdkListenerMgrAdd(&usbPnpListener) != HDF_SUCCESS) {
150 HDF_LOGE("%{public}s: add listener failed", __func__);
151 return HDF_FAILURE;
152 }
153 HDF_LOGI("UsbPnpManagerInit done");
154 return HDF_SUCCESS;
155 }
156
UsbPnpManagerRelease(struct HdfDeviceObject * device)157 static void UsbPnpManagerRelease(struct HdfDeviceObject *device)
158 {
159 (void)device;
160 return;
161 }
162
163 struct HdfDriverEntry g_usbPnpManagerEntry = {
164 .moduleVersion = 1,
165 .Bind = UsbPnpManagerBind,
166 .Init = UsbPnpManagerInit,
167 .Release = UsbPnpManagerRelease,
168 .moduleName = "HDF_USB_PNP_MANAGER",
169 };
170
171 HDF_INIT(g_usbPnpManagerEntry);
172