* Copyright (c) 2021-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cstdio"
#include "usb_common_test.h"
#include "usb_srv_client.h"
#include "cJSON.h"
#include "common_event_manager.h"
#include "common_event_support.h"
using namespace std;
using namespace OHOS;
using namespace OHOS::USB;
using namespace OHOS::USB::Common;
using namespace OHOS::EventFwk;
static constexpr int32_t MIN_ARG_NUM = 3;
static constexpr uint32_t CMD_INDEX = 1;
static constexpr uint32_t PARAM_INDEX = 2;
constexpr uint32_t CASE1 = 1;
constexpr uint32_t CASE2 = 2;
constexpr int32_t PORT_OK = 0;
constexpr int32_t PORT_FAILED = -1;
static UsbSrvClient &g_usbClient = UsbSrvClient::GetInstance();
static void PrintHelp()
{
printf("2 args\n");
printf("-p 0: Query Port\n");
printf("-p 1: get port supportmode\n");
printf("-p 2: set port role\n");
printf("-f 0: Query function\n");
printf("-f 1: Switch to function:acm\n");
printf("-f 2: Switch to function:ecm\n");
printf("-f 3: Switch to function:acm&ecm\n");
printf("-f 4: Switch to function:hdc\n");
printf("-f 5: Switch to function:acm&hdc\n");
printf("-f 6: Switch to function:ecm&hdc\n");
printf("-f 8: Switch to function:mtp\n");
printf("-f 16: Switch to function:ptp\n");
printf("-f 32: Switch to function:rndis\n");
printf("-f 512: Switch to function:storage\n");
printf("-f 36: Switch to function:rndis&hdc\n");
printf("-f 516: Switch to function:storage&hdc\n");
printf("-c 1: Switch to recv braodcast\n");
printf("-s 0: Get devicespeed\n");
printf("-s 1: Get interface actived\n");
printf("-r 0: Reset proxy\n");
}
class UsbSubscriberTest : public CommonEventSubscriber {
public:
explicit UsbSubscriberTest(const CommonEventSubscribeInfo &sp) : CommonEventSubscriber(sp) {}
void OnReceiveEvent(const CommonEventData &data) override
{
USB_HILOGI(MODULE_USB_SERVICE, "recv event ok");
eventData_ = data;
std::string deviceStr = eventData_.GetData();
USB_HILOGI(MODULE_USB_SERVICE, "recv broadcast: %{public}s", deviceStr.c_str());
cJSON* pDevice = cJSON_Parse(deviceStr.c_str());
UsbDevice device(pDevice);
std::string strConfig = "null";
if (device.GetConfigCount() > 0) {
USBConfig config;
device.GetConfig(0, config);
strConfig = config.ToString();
}
USB_HILOGI(MODULE_USB_SERVICE, "recv broadcast:Name: %{public}s, config size: %{public}d, config0: %{public}s",
device.GetName().c_str(), device.GetConfigCount(), strConfig.c_str());
}
static CommonEventData eventData_;
};
CommonEventData UsbSubscriberTest::eventData_ {};
std::shared_ptr<UsbSubscriberTest> subscriber = nullptr;
static void AddCommonEvent()
{
MatchingSkills matchingSkills;
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USB_STATE);
CommonEventSubscribeInfo subscriberInfo(matchingSkills);
subscriber = std::make_shared<UsbSubscriberTest>(subscriberInfo);
bool ret = CommonEventManager::SubscribeCommonEvent(subscriber);
if (!ret) {
USB_HILOGW(MODULE_USB_SERVICE, "subscriber event for failed: %{public}d", ret);
}
}
static void StopSubscriberCommonEvent(int32_t signo)
{
(void) signo;
if (subscriber != nullptr) {
CommonEventManager::UnSubscribeCommonEvent(subscriber);
}
std::cout << "stop recv broadcast."<< std::endl;
USB_HILOGI(MODULE_USB_SERVICE, "stop recv broadcast.");
}
static void GetCurrentFunctionInfo()
{
int32_t funcs = 0;
string strFun = "";
int32_t ret = g_usbClient.GetCurrentFunctions(funcs);
if (ret) {
printf("%s:%d error exit\n", __func__, __LINE__);
return;
}
strFun = g_usbClient.UsbFunctionsToString(funcs);
printf("%s:%d get current function: %s\n", __func__, __LINE__, strFun.c_str());
}
static void FunctionSwitch(UsbSrvClient &g_usbClient, int32_t mode)
{
switch (mode) {
case 0:
GetCurrentFunctionInfo();
break;
default:
int32_t ret = g_usbClient.SetCurrentFunctions(mode);
if (ret) {
printf("%s:%d error exit\n", __func__, __LINE__);
break;
}
GetCurrentFunctionInfo();
break;
}
}
static void GetPortsInfo()
{
std::vector<UsbPort> usbports;
int32_t ret = g_usbClient.GetPorts(usbports);
if (ret) {
printf("%s:%d error exit\n", __func__, __LINE__);
return;
}
for (auto it : usbports) {
printf("portId: %d, supportedModes: %d, currentMode: %d, currentPowerRole: %d, currentDataRole:%d\n",
it.id, it.supportedModes, it.usbPortStatus.currentMode,
it.usbPortStatus.currentPowerRole, it.usbPortStatus.currentDataRole);
}
}
int32_t GetSupportMode(UsbSrvClient &g_usbClient)
{
printf("Please enter the portid:");
int portId;
std::cin >> portId;
int32_t result = 0;
int32_t ret = g_usbClient.GetSupportedModes(portId, result);
if (ret != PORT_OK) {
printf("get SupportMode failed\n");
return PORT_FAILED;
}
printf("supportMode: %d\n", result);
return PORT_OK;
}
int32_t SetPortRole(UsbSrvClient &g_usbClient)
{
int portId;
int powerRole;
int dataRole;
printf("Please enter the portid:");
std::cin >> portId;
printf("\n");
printf("Please enter the powerRole:");
std::cin >> powerRole;
printf("\n");
printf("Please enter the dataRole:");
std::cin >> dataRole;
printf("\n");
int32_t ret = g_usbClient.SetPortRole(portId, powerRole, dataRole);
if (ret != PORT_OK) {
printf("set PortRole failed\n");
return PORT_FAILED;
}
printf("set PortRole success\n");
return PORT_OK;
}
static void PortSwitch(UsbSrvClient &g_usbClient, int32_t mode)
{
switch (mode) {
case 0:
GetPortsInfo();
break;
case CASE1:
GetSupportMode(g_usbClient);
break;
case CASE2:
SetPortRole(g_usbClient);
GetPortsInfo();
break;
default:
printf("%s:%d port param error\n", __func__, __LINE__);
break;
}
}
static void DeviceSpeed(UsbSrvClient &g_usbClient, int32_t &sp)
{
vector<UsbDevice> devi;
g_usbClient.GetDevices(devi);
USBDevicePipe pipe;
UsbDevice device = devi.front();
g_usbClient.OpenDevice(device, pipe);
uint8_t speed = -1;
g_usbClient.GetDeviceSpeed(pipe, speed);
sp = speed;
return;
}
static void InterfaceStatus(UsbSrvClient &g_usbClient, int32_t &ds)
{
vector<UsbDevice> devi;
g_usbClient.GetDevices(devi);
USBDevicePipe pipe;
UsbDevice device = devi.front();
g_usbClient.OpenDevice(device, pipe);
UsbInterface interface = device.GetConfigs().front().GetInterfaces().at(0);
bool unactivated = false;
g_usbClient.GetInterfaceActiveStatus(pipe, interface, unactivated);
unactivated ? ds = 1 : ds = 0;
return;
}
static void ResetProxy(UsbSrvClient &g_usbClient, int32_t &sp)
{
vector<UsbDevice> devi;
g_usbClient.GetDevices(devi);
USBDevicePipe pipe;
UsbDevice device = devi.front();
g_usbClient.OpenDevice(device, pipe);
std::cout << "please kill service, press enter to continue" << std::endl;
int32_t ch = 0;
while (ch != EOF) {
if ((ch = getchar()) == '\n') {
break;
}
}
uint8_t speed = -1;
g_usbClient.GetDeviceSpeed(pipe, speed);
sp = speed;
return;
}
static void DeviceStatus(UsbSrvClient &g_usbClient, int32_t mode)
{
switch (mode) {
case 0:
int32_t sp;
DeviceSpeed(g_usbClient, sp);
printf("%s:%d device speed=%d\n", __func__, __LINE__, sp);
break;
case 1:
int32_t ds;
InterfaceStatus(g_usbClient, ds);
printf("%s:%d interface status=%d\n", __func__, __LINE__, ds);
break;
default:
printf("%s:%d port param error\n", __func__, __LINE__);
break;
}
}
static void SetProxy(UsbSrvClient &g_usbClient, int32_t mode)
{
switch (mode) {
case 0:
int32_t sp;
ResetProxy(g_usbClient, sp);
if (sp > 0) {
printf("%s:%d ResetProxy Okay\n", __func__, __LINE__);
} else {
printf("%s:%d ResetProxy failed\n", __func__, __LINE__);
}
break;
default:
printf("%s:%d port param error\n", __func__, __LINE__);
break;
}
}
static inline bool isNumber(string_view strv)
{
return (strv.find_first_not_of("0123456789") == strv.npos);
}
int32_t main(int32_t argc, char *argv[])
{
UsbCommonTest::GrantPermissionSysNative();
if (argc < MIN_ARG_NUM) {
PrintHelp();
return 0;
}
if (!isNumber(argv[PARAM_INDEX])) {
PrintHelp();
return 0;
}
uint32_t mode;
if ((!strcmp(argv[CMD_INDEX], "-f"))) {
mode = stoi(argv[PARAM_INDEX]);
FunctionSwitch(g_usbClient, mode);
} else if (!strcmp(argv[CMD_INDEX], "-p")) {
mode = stoi(argv[PARAM_INDEX]);
PortSwitch(g_usbClient, mode);
} else if (!strcmp(argv[CMD_INDEX], "-s")) {
mode = stoi(argv[PARAM_INDEX]);
DeviceStatus(g_usbClient, mode);
} else if (!strcmp(argv[CMD_INDEX], "-r")) {
mode = stoi(argv[PARAM_INDEX]);
SetProxy(g_usbClient, mode);
} else if (!strcmp(argv[CMD_INDEX], "-c")) {
AddCommonEvent();
printf("Press input c to exit.\n");
char ch = getchar();
while (ch != 'c') {
ch = getchar();
if (ch == 'c') {
StopSubscriberCommonEvent(0);
break;
}
sleep(1);
}
printf("show boac exit.\n");
} else {
printf("param incorrect: please input -h for help\n");
}
return 0;
}