1 /* 2 * Copyright (C) 2024 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 #ifndef HDC_HOST_USB_H 16 #define HDC_HOST_USB_H 17 18 #include <memory> 19 #include <libusb.h> 20 #include "ctimer.h" 21 #include <map> 22 #include <vector> 23 #include <mutex> 24 #include <condition_variable> 25 #include "securec.h" 26 #include "ffi_utils.h" 27 28 namespace Hdc { 29 using namespace std; 30 constexpr uint16_t MAX_USBFFS_BULK = 62464; 31 constexpr uint16_t MAX_USBFFS_BULK2 = 63488; 32 enum ConnType { CONN_USB = 0, CONN_TCP, CONN_SERIAL, CONN_BT }; 33 enum ConnStatus { STATUS_UNKNOW = 0, STATUS_READY, STATUS_CONNECTED, STATUS_OFFLINE }; 34 35 enum OperateID { 36 OP_ADD, 37 OP_REMOVE, 38 OP_QUERY, 39 OP_QUERY_REF, // crossthread query, manually reduce ref 40 OP_GET_STRLIST, 41 OP_GET_STRLIST_FULL, 42 OP_GET_READY_STRLIST, 43 OP_GET_ANY, 44 OP_UPDATE, 45 OP_CLEAR, 46 OP_INIT, 47 OP_GET_ONLY, 48 OP_VOTE_RESET, 49 OP_WAIT_FOR_ANY 50 }; 51 struct PersistBuffer { 52 char *ptr; 53 uint64_t size; 54 }; 55 struct HdcDaemonInformation { 56 uint8_t connType; 57 uint8_t connStatus; 58 std::string connectKey; 59 std::string usbMountPoint; 60 std::string devName; 61 std::string version; 62 }; 63 using HDaemonInfo = struct HdcDaemonInformation *; 64 struct HostUSBEndpoint { HostUSBEndpointHostUSBEndpoint65 explicit HostUSBEndpoint(uint16_t epBufSize) 66 { 67 endpoint = 0; 68 sizeEpBuf = epBufSize; // MAX_USBFFS_BULK 69 transfer = libusb_alloc_transfer(0); 70 isShutdown = true; 71 isComplete = true; 72 bulkInOut = false; 73 buf = new (std::nothrow) uint8_t[sizeEpBuf]; 74 (void)memset_s(buf, sizeEpBuf, 0, sizeEpBuf); 75 } ~HostUSBEndpointHostUSBEndpoint76 ~HostUSBEndpoint() 77 { 78 libusb_free_transfer(transfer); 79 delete[] buf; 80 } 81 uint8_t endpoint; 82 uint8_t *buf; // MAX_USBFFS_BULK 83 bool isComplete; 84 bool isShutdown; 85 bool bulkInOut; // true is bulkIn 86 uint16_t sizeEpBuf; 87 std::mutex mutexIo; 88 std::mutex mutexCb; 89 condition_variable cv; 90 libusb_transfer *transfer; 91 }; 92 93 struct HdcUSB { 94 libusb_context *ctxUSB = nullptr; // child-use, main null 95 libusb_device *device; 96 libusb_device_handle *devHandle; 97 uint16_t retryCount; 98 uint8_t devId; 99 uint8_t busId; 100 uint8_t interfaceNumber; 101 std::string serialNumber; 102 std::string usbMountPoint; 103 HostUSBEndpoint hostBulkIn; 104 HostUSBEndpoint hostBulkOut; HdcUSBHdcUSB105 HdcUSB() : hostBulkIn(MAX_USBFFS_BULK2), hostBulkOut(MAX_USBFFS_BULK) {} 106 107 uint32_t payloadSize; 108 uint16_t wMaxPacketSizeSend; 109 bool resetIO; // if true, must break write and read,default false 110 std::mutex lockDeviceHandle; 111 std::mutex lockSendUsbBlock; 112 }; 113 using HUSB = struct HdcUSB *; 114 115 enum UsbCheckStatus { 116 HOST_USB_IGNORE = 1, 117 HOST_USB_READY, 118 HOST_USB_REGISTER, 119 }; 120 121 class HostUsb { 122 public: 123 HostUsb(); 124 ~HostUsb(); 125 int Initial(); 126 void Stop(); 127 static void UsbWorkThread(void *arg); // 3rd thread 128 static void WatchUsbNodeChange(void *arg); 129 static void LIBUSB_CALL USBBulkCallback(struct libusb_transfer *transfer); 130 void CancelUsbIo(HUSB hUsb); 131 PersistBuffer ReadUsbIO(HUSB hUsb, int exceptedSize); 132 int WriteUsbIO(HUSB hUsb, SerializedBuffer buf); 133 HUSB GetUsbDevice(std::string connectKey); 134 string AdminDaemonMap(uint8_t opType, const string &connectKey, HDaemonInfo &hDaemonInfoInOut); 135 void UpdateUSBDaemonInfo(HUSB hUSB, uint8_t connStatus); 136 private: 137 bool DetectMyNeed(libusb_device *device, string &sn); 138 void ReviewUsbNodeLater(string &nodeKey); 139 void RemoveIgnoreDevice(string &mountInfo); 140 void CheckUsbEndpoint(int& ret, HUSB hUSB, libusb_config_descriptor *descConfig); 141 #ifdef HOST_MAC 142 int CheckActiveConfig(libusb_device *device, HUSB hUSB, libusb_device_descriptor& desc); 143 #else 144 int CheckActiveConfig(libusb_device *device, HUSB hUSB); 145 #endif 146 int OpenDeviceMyNeed(HUSB hUSB); 147 bool HasValidDevice(libusb_device *device); 148 int CheckDescriptor(HUSB hUSB, libusb_device_descriptor& desc); 149 bool IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor); 150 bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB); 151 string GetDaemonMapList(uint8_t opType); 152 153 libusb_context *ctxUSB; 154 bool running; 155 std::map<string, UsbCheckStatus> mapIgnoreDevice; 156 std::unique_ptr<CTimer> timer; 157 std::map<string, HUSB> mapUsbDevice; 158 std::mutex lockMapDaemon; 159 map<string, HDaemonInfo> mapDaemon; 160 }; 161 } 162 #endif 163