1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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_accessory_uevent_handle.h"
17 #include "hdf_base.h"
18 #include "hdf_log.h"
19 #include "usbd_wrapper.h"
20 #include "ddk_pnp_listener_mgr.h"
21
22 #define HDF_LOG_TAG usb_accessory_uevent
23
24 char *g_usbAccessoryUeventPath = "invalid_path";
25
26 struct UsbAccessoryUeventInfo {
27 const char *devPath;
28 const char *subSystem;
29 const char *accessory;
30 const char *devName;
31 };
32
UsbAccessoryDispatchUevent(const struct UsbAccessoryUeventInfo * info)33 static void UsbAccessoryDispatchUevent(const struct UsbAccessoryUeventInfo *info)
34 {
35 HDF_LOGD("%{public}s: devPath: %{public}s, accessory: %{public}s", __func__, info->devPath, info->accessory);
36 if (strcmp(info->devPath, g_usbAccessoryUeventPath) != 0) {
37 return;
38 }
39 if (strcmp(info->accessory, "START") == 0) {
40 DdkListenerMgrNotifyAll(NULL, USB_ACCESSORY_START);
41 } else if (strcmp(info->accessory, "SEND") == 0) {
42 DdkListenerMgrNotifyAll(NULL, USB_ACCESSORY_SEND);
43 }
44 }
45
UsbAccessoryUeventHandle(const char msg[],ssize_t rcvLen)46 void UsbAccessoryUeventHandle(const char msg[], ssize_t rcvLen)
47 {
48 HDF_LOGD("%{public}s: msg: %{public}s, len: %{public}zd", __func__, msg, rcvLen);
49 char fullMsg[rcvLen + 1];
50 for (int i = 0; i < rcvLen; i++) {
51 if (msg[i] == '\0') {
52 fullMsg[i] = ' ';
53 } else {
54 fullMsg[i] = msg[i];
55 }
56 }
57 fullMsg[rcvLen] = '\0';
58 HDF_LOGD("%{public}s:Full message: %{public}s", __func__, fullMsg);
59
60 struct UsbAccessoryUeventInfo info = {
61 .devPath = "",
62 .subSystem = "",
63 .accessory = "",
64 .devName = ""
65 };
66 const char *msgTmp = msg;
67 while (*msgTmp && (msgTmp - msg < rcvLen)) {
68 if (strncmp(msgTmp, "DEVPATH=", strlen("DEVPATH=")) == 0) {
69 msgTmp += strlen("DEVPATH=");
70 info.devPath = msgTmp;
71 } else if (strncmp(msgTmp, "SUBSYSTEM=", strlen("SUBSYSTEM=")) == 0 &&
72 strlen(info.subSystem) == 0) { // some uevent has more than one SUBSYSTEM property
73 msgTmp += strlen("SUBSYSTEM=");
74 info.subSystem = msgTmp;
75 } else if (strncmp(msgTmp, "ACCESSORY=", strlen("ACCESSORY=")) == 0) {
76 msgTmp += strlen("ACCESSORY=");
77 info.accessory = msgTmp;
78 } else if (strncmp(msgTmp, "DEVNAME=", strlen("DEVNAME=")) == 0) {
79 msgTmp += strlen("DEVNAME=");
80 info.devName = msgTmp;
81 }
82 msgTmp += strlen(msgTmp) + 1; // 1 is a skip character '\0'
83 }
84
85 UsbAccessoryDispatchUevent(&info);
86 }
87
UsbAccessoryUeventInit(const char * ueventPath)88 int32_t UsbAccessoryUeventInit(const char *ueventPath)
89 {
90 if (ueventPath == NULL) {
91 HDF_LOGE("%{public}s invalid param", __func__);
92 return HDF_ERR_INVALID_PARAM;
93 }
94 HDF_LOGD("%{public}s: enter, ueventPath: %{public}s", __func__, ueventPath);
95
96 g_usbAccessoryUeventPath = (char *)ueventPath;
97 return HDF_SUCCESS;
98 }
99