* Copyright (C) 2021 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.
*/
#ifndef HDC_HOST_USB_H
#define HDC_HOST_USB_H
#include "host_common.h"
namespace Hdc {
struct ClearUsbChannelWorkInfo {
int result = 0;
HSession hSession = nullptr;
HDaemonInfo pDaemonInfo = nullptr;
};
using HClearUsbChannelWorkInfo = struct ClearUsbChannelWorkInfo *;
class HdcHostUSB : public HdcUSBBase {
public:
enum class UsbCheckStatus {
HOST_USB_IGNORE = 1,
HOST_USB_READY,
HOST_USB_REGISTER,
HOST_USB_SUSPENDED
};
HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctxUSBin);
virtual ~HdcHostUSB();
int Initial();
static void InitLogging(void *ctxUSB);
int SendUSBRaw(HSession hSession, uint8_t *data, const int length) override;
HSession ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi);
void Stop();
static libusb_log_level GetLibusbLogLevel(void);
static void SetLibusbLogLevelEnv(libusb_log_level logLevel);
void SendSoftResetToDaemon(HSession hSession, uint32_t sessionIdOld);
static void WatchUsbNodeChange(HdcHostUSB *thisClass);
void ReviewUsbNodeLater(const string &nodeKey, UsbCheckStatus status = UsbCheckStatus::HOST_USB_IGNORE);
void AllowUsbNodeRescan(string &usbMountPoint);
private:
enum class DetectReturnType {
NEW_OBJECT_FAIL,
OPEN_DEVICE_FAIL,
WRONG_SERIAL_FAIL,
MALLOC_SESSION_FAIL,
DETECT_SUCCESS
};
static int LIBUSB_CALL HotplugHostUSBCallback(libusb_context *ctx, libusb_device *device,
libusb_hotplug_event event, void *userData);
static void UsbWorkThread(void *arg);
static void WatchUsbNodeChange(uv_timer_t *handle);
static void KickoutZombie(HSession hSession);
static void LIBUSB_CALL USBBulkCallback(struct libusb_transfer *transfer);
static void ClearUsbChannel(uv_work_t *req);
static void ClearUsbChannelFinished(uv_work_t *req, int status);
static void SendSoftResetToDaemonSync(HSession hSession, uint32_t sessionIdOld);
int StartupUSBWork();
void CheckUsbEndpoint(int& ret, HUSB hUSB, libusb_config_descriptor *descConfig);
int CheckActiveConfig(libusb_device *device, HUSB hUSB, libusb_device_descriptor& desc);
int OpenDeviceMyNeed(HUSB hUSB);
bool HasValidDevice(libusb_device *device);
int CheckDescriptor(HUSB hUSB, libusb_device_descriptor& desc);
bool IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor);
bool ReadyForWorkThread(HSession hSession) override;
bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB);
DetectReturnType DetectMyNeed(libusb_device *device, string &sn);
void RestoreHdcProtocol(HUSB hUsb, const uint8_t *buf, int bufSize);
void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus);
void BeginUsbRead(HSession hSession);
void RemoveIgnoreDevice(string &mountInfo, bool force = false);
void CancelUsbIo(HSession hSession) override;
int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize) override;
int SubmitUsbBio(HSession hSession, bool sendOrRecv, uint8_t *buf, int bufSize);
libusb_context *ctxUSB;
uv_timer_t devListWatcher;
map<string, UsbCheckStatus> mapIgnoreDevice;
int logRePrintTimer;
int logRePrintCount;
private:
uv_thread_t threadUsbWork;
};
}
#endif