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 <stdio.h>
17 #include <unistd.h>
18 #include <sys/time.h>
19 #include <hdf_sbuf.h>
20 #include "securec.h"
21 #include "osal_atomic.h"
22 #include "hdf_base.h"
23 #include "hdf_log.h"
24 #include "hdf_device_desc.h"
25 #include "hdf_usb_pnp_manage.h"
26 
27 #define HDF_LOG_TAG   USB_HOST_PNP_TEST
28 
29 #if USB_PNP_NOTIFY_TEST_MODE == true
30 #define USB_HOST_PNP_TEST_SERVICE_NAME "hdf_usb_pnp_notify_service"
31 #define STR_LEN     1024
32 #ifndef INT32_MAX
33 #define INT32_MAX 0x7fffffff
34 #endif
35 #define USB_TEST_INTERFACE_NUM  2
36 
37 struct HdfSBuf *g_data;
38 struct HdfSBuf *g_reply;
39 
TestPnpWriteLog(char * strTmp)40 static void TestPnpWriteLog(char *strTmp)
41 {
42     char str[STR_LEN] = {0};
43     FILE *fp = NULL;
44     struct timeval time;
45 
46     gettimeofday(&time, NULL);
47 
48     fp = fopen("/data/usbhost_pnp_xts", "a+");
49 
50     int32_t ret = snprintf_s(str, STR_LEN, STR_LEN - 1, "[XTSCHECK] %d.%06d, %s\n",
51         time.tv_sec, time.tv_usec, strTmp);
52     if (ret < 0) {
53         HDF_LOGE("%{public}s: sbuf write failed", __func__);
54         (void)fclose(fp);
55         return;
56     }
57 
58     (void)fwrite(str, strlen(str), 1, fp);
59     (void)fclose(fp);
60 }
61 
TestInitPnpInfo(enum UsbPnpNotifyServiceCmd cmdType)62 static void TestInitPnpInfo(enum UsbPnpNotifyServiceCmd cmdType)
63 {
64     struct UsbPnpNotifyMatchInfoTable infoTable;
65     infoTable.usbDevAddr = 0;
66     infoTable.devNum = 0;
67     if (cmdType == USB_PNP_NOTIFY_REMOVE_TEST) {
68         infoTable.busNum = -1;
69     } else {
70         infoTable.busNum = 0;
71     }
72 
73     infoTable.deviceInfo.vendorId = 0xFFF0;
74     infoTable.deviceInfo.productId = 0xFFF0;
75     infoTable.deviceInfo.bcdDeviceLow = 0x0000;
76     infoTable.deviceInfo.bcdDeviceHigh = 0x0000;
77     infoTable.deviceInfo.deviceClass = 0;
78     infoTable.deviceInfo.deviceSubClass = 0;
79     infoTable.deviceInfo.deviceProtocol = 0;
80 
81     infoTable.removeType = USB_PNP_NOTIFY_REMOVE_BUS_DEV_NUM;
82 
83     if (cmdType != USB_PNP_NOTIFY_REMOVE_TEST) {
84         infoTable.numInfos = USB_TEST_INTERFACE_NUM;
85         for (uint8_t i = 0; i < infoTable.numInfos; i++) {
86             infoTable.interfaceInfo[i].interfaceClass = 0;
87             infoTable.interfaceInfo[i].interfaceSubClass = 0;
88             infoTable.interfaceInfo[i].interfaceProtocol = 0;
89             infoTable.interfaceInfo[i].interfaceNumber = i;
90         }
91     }
92 
93     if (!HdfSbufWriteBuffer(g_data, (const void *)(&infoTable), sizeof(struct UsbPnpNotifyMatchInfoTable))) {
94         HDF_LOGE("%{public}s: sbuf write infoTable failed", __func__);
95     }
96 }
97 
TestPnpAdd(struct HdfIoService * serv)98 static void TestPnpAdd(struct HdfIoService *serv)
99 {
100     int32_t replyData = 0;
101     TestPnpWriteLog("usb pnp sample device driver test add start");
102     TestInitPnpInfo(USB_PNP_NOTIFY_ADD_TEST);
103 
104     int32_t status = serv->dispatcher->Dispatch(&serv->object, USB_PNP_NOTIFY_ADD_TEST, g_data, g_reply);
105     if (status) {
106         HDF_LOGE("%{public}s: Dispatch USB_PNP_NOTIFY_ADD_TEST failed status = %{public}d", __func__, status);
107         return;
108     }
109 
110     if (!HdfSbufReadInt32(g_reply, &replyData)) {
111         HDF_LOGE("%{public}s: HdfSbufReadInt32 failed %{public}d", __func__, __LINE__);
112         return;
113     }
114 
115     if (replyData != INT32_MAX) {
116         TestPnpWriteLog("usb pnp sample device driver test add reply failed.");
117     } else {
118         TestPnpWriteLog("usb pnp sample device driver test add reply ok.");
119     }
120 }
121 
TestPnpRemove(struct HdfIoService * serv)122 static void TestPnpRemove(struct HdfIoService *serv)
123 {
124     int32_t replyData = 0;
125     TestPnpWriteLog("usb pnp sample device driver test remove start");
126     TestInitPnpInfo(USB_PNP_NOTIFY_REMOVE_TEST);
127 
128     int32_t status = serv->dispatcher->Dispatch(&serv->object, USB_PNP_NOTIFY_REMOVE_TEST, g_data, g_reply);
129     if (status != HDF_SUCCESS) {
130         HDF_LOGE("%{public}s: Dispatch USB_PNP_NOTIFY_REMOVE_TEST failed status = %{public}d", __func__, status);
131         return;
132     }
133 
134     if (!HdfSbufReadInt32(g_reply, &replyData)) {
135         HDF_LOGE("%{public}s: HdfSbufReadInt32 failed %{public}d", __func__, __LINE__);
136         return;
137     }
138 
139     if (replyData != INT32_MAX) {
140         TestPnpWriteLog("usb pnp sample device driver test remove reply failed.");
141     } else {
142         TestPnpWriteLog("usb pnp sample device driver test remove reply ok.");
143     }
144 }
145 #endif
main(int32_t argc,char * argv[])146 int32_t main(int32_t argc, char *argv[])
147 {
148 #if USB_PNP_NOTIFY_TEST_MODE == true
149     HDF_LOGI("%{public}s:%{public}d usbhost pnp test start", __func__, __LINE__);
150     char cmd;
151     int32_t argNum = 2;
152     if (argc != argNum) {
153         HDF_LOGE("%{public}s:%{public}d invalid param", __func__, __LINE__);
154         return HDF_FAILURE;
155     }
156     if (!strcmp(argv[1], "-add")) {
157         cmd = 'a';
158     } else if (!strcmp(argv[1], "-remove")) {
159         cmd = 'r';
160     } else {
161         HDF_LOGE("%{public}s:%{public}d invalid param", __func__, __LINE__);
162         return HDF_FAILURE;
163     }
164 
165     struct HdfIoService *serv = HdfIoServiceBind(USB_HOST_PNP_TEST_SERVICE_NAME);
166     if (serv == NULL) {
167         HDF_LOGE("%{public}s:%{public}d fail to get service %{public}s", \
168             __func__, __LINE__, USB_HOST_PNP_TEST_SERVICE_NAME);
169         return HDF_FAILURE;
170     }
171 
172     g_data = HdfSbufObtainDefaultSize();
173     g_reply = HdfSbufObtainDefaultSize();
174     if (g_data == NULL || g_reply == NULL) {
175         HDF_LOGE("%{public}s:%{public}d GetService err", __func__, __LINE__);
176         return HDF_FAILURE;
177     }
178 
179     switch (cmd) {
180         case 'a':
181             TestPnpAdd(serv);
182             break;
183         case 'r':
184             TestPnpRemove(serv);
185             break;
186         default:
187             break;
188     }
189 
190     HdfSbufRecycle(g_data);
191     HdfSbufRecycle(g_reply);
192 
193     HdfIoServiceRecycle(serv);
194 
195     HDF_LOGI("%{public}s:%{public}d usbhost pnp test end", __func__, __LINE__);
196 #else
197     HDF_LOGE("%{public}s:%{public}d USB_PNP_NOTIFY_TEST_MODE is not support!!!", __func__, __LINE__);
198 #endif
199     return HDF_SUCCESS;
200 }
201 
202