142103316Sopenharmony_ci/*
242103316Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
342103316Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
442103316Sopenharmony_ci * you may not use this file except in compliance with the License.
542103316Sopenharmony_ci * You may obtain a copy of the License at
642103316Sopenharmony_ci *
742103316Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
842103316Sopenharmony_ci *
942103316Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1042103316Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1142103316Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1242103316Sopenharmony_ci * See the License for the specific language governing permissions and
1342103316Sopenharmony_ci * limitations under the License.
1442103316Sopenharmony_ci */
1542103316Sopenharmony_ci
1642103316Sopenharmony_ci#include "cstdio"
1742103316Sopenharmony_ci#include "usb_common_test.h"
1842103316Sopenharmony_ci#include "usb_srv_client.h"
1942103316Sopenharmony_ci#include "cJSON.h"
2042103316Sopenharmony_ci#include "common_event_manager.h"
2142103316Sopenharmony_ci#include "common_event_support.h"
2242103316Sopenharmony_ci
2342103316Sopenharmony_ciusing namespace std;
2442103316Sopenharmony_ciusing namespace OHOS;
2542103316Sopenharmony_ciusing namespace OHOS::USB;
2642103316Sopenharmony_ciusing namespace OHOS::USB::Common;
2742103316Sopenharmony_ciusing namespace OHOS::EventFwk;
2842103316Sopenharmony_cistatic constexpr int32_t DEFAULT_PORT_ID = 1;
2942103316Sopenharmony_cistatic constexpr int32_t DEFAULT_ROLE_HOST = 1;
3042103316Sopenharmony_cistatic constexpr int32_t DEFAULT_ROLE_DEVICE = 2;
3142103316Sopenharmony_cistatic constexpr int32_t MIN_ARG_NUM = 3;
3242103316Sopenharmony_cistatic constexpr uint32_t CMD_INDEX = 1;
3342103316Sopenharmony_cistatic constexpr uint32_t PARAM_INDEX = 2;
3442103316Sopenharmony_ci
3542103316Sopenharmony_cistatic constexpr int32_t HOST_MODE = 2;
3642103316Sopenharmony_ci
3742103316Sopenharmony_cistatic UsbSrvClient &g_usbClient = UsbSrvClient::GetInstance();
3842103316Sopenharmony_ci
3942103316Sopenharmony_cistatic void PrintHelp()
4042103316Sopenharmony_ci{
4142103316Sopenharmony_ci    printf("2 args\n");
4242103316Sopenharmony_ci    printf("-p 0: Query Port\n");
4342103316Sopenharmony_ci    printf("-p 1: Switch to host\n");
4442103316Sopenharmony_ci    printf("-p 2: Switch to device:\n");
4542103316Sopenharmony_ci    printf("-f 0: Query function\n");
4642103316Sopenharmony_ci    printf("-f 1: Switch to function:acm\n");
4742103316Sopenharmony_ci    printf("-f 2: Switch to function:ecm\n");
4842103316Sopenharmony_ci    printf("-f 3: Switch to function:acm&ecm\n");
4942103316Sopenharmony_ci    printf("-f 4: Switch to function:hdc\n");
5042103316Sopenharmony_ci    printf("-f 5: Switch to function:acm&hdc\n");
5142103316Sopenharmony_ci    printf("-f 6: Switch to function:ecm&hdc\n");
5242103316Sopenharmony_ci    printf("-f 8: Switch to function:mtp\n");
5342103316Sopenharmony_ci    printf("-f 16: Switch to function:ptp\n");
5442103316Sopenharmony_ci    printf("-f 32: Switch to function:rndis\n");
5542103316Sopenharmony_ci    printf("-f 512: Switch to function:storage\n");
5642103316Sopenharmony_ci    printf("-f 36: Switch to function:rndis&hdc\n");
5742103316Sopenharmony_ci    printf("-f 516: Switch to function:storage&hdc\n");
5842103316Sopenharmony_ci    printf("-c 1: Switch to recv braodcast\n");
5942103316Sopenharmony_ci    printf("-s 0: Get devicespeed\n");
6042103316Sopenharmony_ci    printf("-s 1: Get interface actived\n");
6142103316Sopenharmony_ci    printf("-r 0: Reset proxy\n");
6242103316Sopenharmony_ci}
6342103316Sopenharmony_ci
6442103316Sopenharmony_ciclass UsbSubscriberTest : public CommonEventSubscriber {
6542103316Sopenharmony_cipublic:
6642103316Sopenharmony_ci    explicit UsbSubscriberTest(const CommonEventSubscribeInfo &sp) : CommonEventSubscriber(sp) {}
6742103316Sopenharmony_ci
6842103316Sopenharmony_ci    void OnReceiveEvent(const CommonEventData &data) override
6942103316Sopenharmony_ci    {
7042103316Sopenharmony_ci        USB_HILOGI(MODULE_USB_SERVICE, "recv event ok");
7142103316Sopenharmony_ci        eventData_ = data;
7242103316Sopenharmony_ci        std::string deviceStr = eventData_.GetData();
7342103316Sopenharmony_ci        USB_HILOGI(MODULE_USB_SERVICE, "recv broadcast: %{public}s", deviceStr.c_str());
7442103316Sopenharmony_ci
7542103316Sopenharmony_ci        cJSON* pDevice =  cJSON_Parse(deviceStr.c_str());
7642103316Sopenharmony_ci        UsbDevice device(pDevice);
7742103316Sopenharmony_ci        std::string strConfig = "null";
7842103316Sopenharmony_ci        if (device.GetConfigCount() > 0) {
7942103316Sopenharmony_ci            USBConfig config;
8042103316Sopenharmony_ci            device.GetConfig(0, config);
8142103316Sopenharmony_ci            strConfig = config.ToString();
8242103316Sopenharmony_ci        }
8342103316Sopenharmony_ci        USB_HILOGI(MODULE_USB_SERVICE, "recv broadcast:Name: %{public}s, config size: %{public}d, config0: %{public}s",
8442103316Sopenharmony_ci            device.GetName().c_str(), device.GetConfigCount(), strConfig.c_str());
8542103316Sopenharmony_ci    }
8642103316Sopenharmony_ci
8742103316Sopenharmony_ci    static CommonEventData eventData_;
8842103316Sopenharmony_ci};
8942103316Sopenharmony_ci
9042103316Sopenharmony_ciCommonEventData UsbSubscriberTest::eventData_ {};
9142103316Sopenharmony_cistd::shared_ptr<UsbSubscriberTest> subscriber = nullptr;
9242103316Sopenharmony_cistatic void AddCommonEvent()
9342103316Sopenharmony_ci{
9442103316Sopenharmony_ci    MatchingSkills matchingSkills;
9542103316Sopenharmony_ci    matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED);
9642103316Sopenharmony_ci    matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED);
9742103316Sopenharmony_ci    matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USB_STATE);
9842103316Sopenharmony_ci    CommonEventSubscribeInfo subscriberInfo(matchingSkills);
9942103316Sopenharmony_ci    subscriber = std::make_shared<UsbSubscriberTest>(subscriberInfo);
10042103316Sopenharmony_ci    bool ret = CommonEventManager::SubscribeCommonEvent(subscriber);
10142103316Sopenharmony_ci    if (!ret) {
10242103316Sopenharmony_ci        USB_HILOGW(MODULE_USB_SERVICE, "subscriber event for failed: %{public}d", ret);
10342103316Sopenharmony_ci    }
10442103316Sopenharmony_ci}
10542103316Sopenharmony_ci
10642103316Sopenharmony_cistatic void StopSubscriberCommonEvent(int32_t signo)
10742103316Sopenharmony_ci{
10842103316Sopenharmony_ci    (void) signo;
10942103316Sopenharmony_ci    if (subscriber != nullptr) {
11042103316Sopenharmony_ci        CommonEventManager::UnSubscribeCommonEvent(subscriber);
11142103316Sopenharmony_ci    }
11242103316Sopenharmony_ci    std::cout << "stop recv broadcast."<< std::endl;
11342103316Sopenharmony_ci    USB_HILOGI(MODULE_USB_SERVICE, "stop recv broadcast.");
11442103316Sopenharmony_ci}
11542103316Sopenharmony_ci
11642103316Sopenharmony_cistatic void GetCurrentFunctionInfo()
11742103316Sopenharmony_ci{
11842103316Sopenharmony_ci    int32_t funcs = 0;
11942103316Sopenharmony_ci    string strFun = "";
12042103316Sopenharmony_ci    int32_t ret = g_usbClient.GetCurrentFunctions(funcs);
12142103316Sopenharmony_ci    if (ret) {
12242103316Sopenharmony_ci        printf("%s:%d error exit\n", __func__, __LINE__);
12342103316Sopenharmony_ci        return;
12442103316Sopenharmony_ci    }
12542103316Sopenharmony_ci    strFun = g_usbClient.UsbFunctionsToString(funcs);
12642103316Sopenharmony_ci    printf("%s:%d get current function: %s\n", __func__, __LINE__, strFun.c_str());
12742103316Sopenharmony_ci}
12842103316Sopenharmony_ci
12942103316Sopenharmony_cistatic void FunctionSwitch(UsbSrvClient &g_usbClient, int32_t mode)
13042103316Sopenharmony_ci{
13142103316Sopenharmony_ci    switch (mode) {
13242103316Sopenharmony_ci        case 0:
13342103316Sopenharmony_ci            GetCurrentFunctionInfo();
13442103316Sopenharmony_ci            break;
13542103316Sopenharmony_ci        default:
13642103316Sopenharmony_ci            int32_t ret = g_usbClient.SetCurrentFunctions(mode);
13742103316Sopenharmony_ci            if (ret) {
13842103316Sopenharmony_ci                printf("%s:%d error exit\n", __func__, __LINE__);
13942103316Sopenharmony_ci                break;
14042103316Sopenharmony_ci            }
14142103316Sopenharmony_ci            GetCurrentFunctionInfo();
14242103316Sopenharmony_ci            break;
14342103316Sopenharmony_ci    }
14442103316Sopenharmony_ci}
14542103316Sopenharmony_ci
14642103316Sopenharmony_cistatic void GetPortsInfo()
14742103316Sopenharmony_ci{
14842103316Sopenharmony_ci    std::vector<UsbPort> usbports;
14942103316Sopenharmony_ci    int32_t ret = g_usbClient.GetPorts(usbports);
15042103316Sopenharmony_ci    if (ret) {
15142103316Sopenharmony_ci        printf("%s:%d error exit\n", __func__, __LINE__);
15242103316Sopenharmony_ci        return;
15342103316Sopenharmony_ci    }
15442103316Sopenharmony_ci
15542103316Sopenharmony_ci    if (usbports[0].usbPortStatus.currentMode == HOST_MODE) {
15642103316Sopenharmony_ci        printf("get current port %d: host\n", usbports[0].usbPortStatus.currentMode);
15742103316Sopenharmony_ci    } else {
15842103316Sopenharmony_ci        printf("get current port %d: device\n", usbports[0].usbPortStatus.currentMode);
15942103316Sopenharmony_ci    }
16042103316Sopenharmony_ci}
16142103316Sopenharmony_ci
16242103316Sopenharmony_cistatic void PortSwitch(UsbSrvClient &g_usbClient, int32_t mode)
16342103316Sopenharmony_ci{
16442103316Sopenharmony_ci    switch (mode) {
16542103316Sopenharmony_ci        case 0:
16642103316Sopenharmony_ci            GetPortsInfo();
16742103316Sopenharmony_ci            break;
16842103316Sopenharmony_ci        case DEFAULT_ROLE_HOST:
16942103316Sopenharmony_ci            g_usbClient.SetPortRole(DEFAULT_PORT_ID, DEFAULT_ROLE_HOST, DEFAULT_ROLE_HOST);
17042103316Sopenharmony_ci            GetPortsInfo();
17142103316Sopenharmony_ci            break;
17242103316Sopenharmony_ci        case DEFAULT_ROLE_DEVICE:
17342103316Sopenharmony_ci            g_usbClient.SetPortRole(DEFAULT_PORT_ID, DEFAULT_ROLE_DEVICE, DEFAULT_ROLE_DEVICE);
17442103316Sopenharmony_ci            GetPortsInfo();
17542103316Sopenharmony_ci            break;
17642103316Sopenharmony_ci        default:
17742103316Sopenharmony_ci            printf("%s:%d port param error\n", __func__, __LINE__);
17842103316Sopenharmony_ci            break;
17942103316Sopenharmony_ci    }
18042103316Sopenharmony_ci}
18142103316Sopenharmony_ci
18242103316Sopenharmony_cistatic void DeviceSpeed(UsbSrvClient &g_usbClient, int32_t &sp)
18342103316Sopenharmony_ci{
18442103316Sopenharmony_ci    vector<UsbDevice> devi;
18542103316Sopenharmony_ci    g_usbClient.GetDevices(devi);
18642103316Sopenharmony_ci    USBDevicePipe pipe;
18742103316Sopenharmony_ci    UsbDevice device = devi.front();
18842103316Sopenharmony_ci    g_usbClient.OpenDevice(device, pipe);
18942103316Sopenharmony_ci    uint8_t speed = -1;
19042103316Sopenharmony_ci    g_usbClient.GetDeviceSpeed(pipe, speed);
19142103316Sopenharmony_ci    sp = speed;
19242103316Sopenharmony_ci    return;
19342103316Sopenharmony_ci}
19442103316Sopenharmony_ci
19542103316Sopenharmony_cistatic void InterfaceStatus(UsbSrvClient &g_usbClient, int32_t &ds)
19642103316Sopenharmony_ci{
19742103316Sopenharmony_ci    vector<UsbDevice> devi;
19842103316Sopenharmony_ci    g_usbClient.GetDevices(devi);
19942103316Sopenharmony_ci    USBDevicePipe pipe;
20042103316Sopenharmony_ci    UsbDevice device = devi.front();
20142103316Sopenharmony_ci    g_usbClient.OpenDevice(device, pipe);
20242103316Sopenharmony_ci    UsbInterface interface = device.GetConfigs().front().GetInterfaces().at(0);
20342103316Sopenharmony_ci    bool unactivated = false;
20442103316Sopenharmony_ci    g_usbClient.GetInterfaceActiveStatus(pipe, interface, unactivated);
20542103316Sopenharmony_ci    unactivated ? ds = 1 : ds = 0;
20642103316Sopenharmony_ci    return;
20742103316Sopenharmony_ci}
20842103316Sopenharmony_ci
20942103316Sopenharmony_cistatic void ResetProxy(UsbSrvClient &g_usbClient, int32_t &sp)
21042103316Sopenharmony_ci{
21142103316Sopenharmony_ci    vector<UsbDevice> devi;
21242103316Sopenharmony_ci    g_usbClient.GetDevices(devi);
21342103316Sopenharmony_ci    USBDevicePipe pipe;
21442103316Sopenharmony_ci    UsbDevice device = devi.front();
21542103316Sopenharmony_ci    g_usbClient.OpenDevice(device, pipe);
21642103316Sopenharmony_ci    std::cout << "please kill service, press enter to continue" << std::endl;
21742103316Sopenharmony_ci    int32_t ch = 0;
21842103316Sopenharmony_ci    while (ch != EOF) {
21942103316Sopenharmony_ci        if ((ch = getchar()) == '\n') {
22042103316Sopenharmony_ci            break;
22142103316Sopenharmony_ci        }
22242103316Sopenharmony_ci    }
22342103316Sopenharmony_ci    uint8_t speed = -1;
22442103316Sopenharmony_ci    g_usbClient.GetDeviceSpeed(pipe, speed);
22542103316Sopenharmony_ci    sp = speed;
22642103316Sopenharmony_ci    return;
22742103316Sopenharmony_ci}
22842103316Sopenharmony_ci
22942103316Sopenharmony_cistatic void DeviceStatus(UsbSrvClient &g_usbClient, int32_t mode)
23042103316Sopenharmony_ci{
23142103316Sopenharmony_ci    switch (mode) {
23242103316Sopenharmony_ci        case 0:
23342103316Sopenharmony_ci            int32_t sp;
23442103316Sopenharmony_ci            DeviceSpeed(g_usbClient, sp);
23542103316Sopenharmony_ci            printf("%s:%d device speed=%d\n", __func__, __LINE__, sp);
23642103316Sopenharmony_ci            break;
23742103316Sopenharmony_ci        case 1:
23842103316Sopenharmony_ci            int32_t ds;
23942103316Sopenharmony_ci            InterfaceStatus(g_usbClient, ds);
24042103316Sopenharmony_ci            printf("%s:%d interface status=%d\n", __func__, __LINE__, ds);
24142103316Sopenharmony_ci            break;
24242103316Sopenharmony_ci        default:
24342103316Sopenharmony_ci            printf("%s:%d port param error\n", __func__, __LINE__);
24442103316Sopenharmony_ci            break;
24542103316Sopenharmony_ci    }
24642103316Sopenharmony_ci}
24742103316Sopenharmony_ci
24842103316Sopenharmony_cistatic void SetProxy(UsbSrvClient &g_usbClient, int32_t mode)
24942103316Sopenharmony_ci{
25042103316Sopenharmony_ci    switch (mode) {
25142103316Sopenharmony_ci        case 0:
25242103316Sopenharmony_ci            int32_t sp;
25342103316Sopenharmony_ci            ResetProxy(g_usbClient, sp);
25442103316Sopenharmony_ci            if (sp > 0) {
25542103316Sopenharmony_ci                printf("%s:%d ResetProxy Okay\n", __func__, __LINE__);
25642103316Sopenharmony_ci            } else {
25742103316Sopenharmony_ci                printf("%s:%d ResetProxy failed\n", __func__, __LINE__);
25842103316Sopenharmony_ci            }
25942103316Sopenharmony_ci            break;
26042103316Sopenharmony_ci        default:
26142103316Sopenharmony_ci            printf("%s:%d port param error\n", __func__, __LINE__);
26242103316Sopenharmony_ci            break;
26342103316Sopenharmony_ci    }
26442103316Sopenharmony_ci}
26542103316Sopenharmony_ci
26642103316Sopenharmony_cistatic inline bool isNumber(string_view strv)
26742103316Sopenharmony_ci{
26842103316Sopenharmony_ci    return (strv.find_first_not_of("0123456789") == strv.npos);
26942103316Sopenharmony_ci}
27042103316Sopenharmony_ci
27142103316Sopenharmony_ciint32_t main(int32_t argc, char *argv[])
27242103316Sopenharmony_ci{
27342103316Sopenharmony_ci    UsbCommonTest::GrantPermissionSysNative();
27442103316Sopenharmony_ci
27542103316Sopenharmony_ci    if (argc < MIN_ARG_NUM) {
27642103316Sopenharmony_ci        PrintHelp();
27742103316Sopenharmony_ci        return 0;
27842103316Sopenharmony_ci    }
27942103316Sopenharmony_ci
28042103316Sopenharmony_ci    if (!isNumber(argv[PARAM_INDEX])) {
28142103316Sopenharmony_ci        PrintHelp();
28242103316Sopenharmony_ci        return 0;
28342103316Sopenharmony_ci    }
28442103316Sopenharmony_ci
28542103316Sopenharmony_ci    uint32_t mode;
28642103316Sopenharmony_ci    if ((!strcmp(argv[CMD_INDEX], "-f"))) {
28742103316Sopenharmony_ci        mode = stoi(argv[PARAM_INDEX]);
28842103316Sopenharmony_ci        FunctionSwitch(g_usbClient, mode);
28942103316Sopenharmony_ci    } else if (!strcmp(argv[CMD_INDEX], "-p")) {
29042103316Sopenharmony_ci        mode = stoi(argv[PARAM_INDEX]);
29142103316Sopenharmony_ci        PortSwitch(g_usbClient, mode);
29242103316Sopenharmony_ci    } else if (!strcmp(argv[CMD_INDEX], "-s")) {
29342103316Sopenharmony_ci        mode = stoi(argv[PARAM_INDEX]);
29442103316Sopenharmony_ci        DeviceStatus(g_usbClient, mode);
29542103316Sopenharmony_ci    } else if (!strcmp(argv[CMD_INDEX], "-r")) {
29642103316Sopenharmony_ci        mode = stoi(argv[PARAM_INDEX]);
29742103316Sopenharmony_ci        SetProxy(g_usbClient, mode);
29842103316Sopenharmony_ci    } else if (!strcmp(argv[CMD_INDEX], "-c")) {
29942103316Sopenharmony_ci        AddCommonEvent();
30042103316Sopenharmony_ci        printf("Press input c to exit.\n");
30142103316Sopenharmony_ci        char ch = getchar();
30242103316Sopenharmony_ci        while (ch != 'c') {
30342103316Sopenharmony_ci            ch = getchar();
30442103316Sopenharmony_ci            if (ch == 'c') {
30542103316Sopenharmony_ci                StopSubscriberCommonEvent(0);
30642103316Sopenharmony_ci                break;
30742103316Sopenharmony_ci            }
30842103316Sopenharmony_ci            sleep(1);
30942103316Sopenharmony_ci        }
31042103316Sopenharmony_ci        printf("show boac exit.\n");
31142103316Sopenharmony_ci    } else {
31242103316Sopenharmony_ci        printf("param incorrect: please input -h for help\n");
31342103316Sopenharmony_ci    }
31442103316Sopenharmony_ci    return 0;
31542103316Sopenharmony_ci}
316