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
37struct HdfSBuf *g_data;
38struct HdfSBuf *g_reply;
39
40static 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
62static 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
98static 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
122static 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
146int32_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