• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 #include "oh_usb.h"
16 #include "usb_ffs.h"
17 #include "usb_util.h"
18 #include "sys_para.h"
19 #include "log.h"
20 
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <cstring>
24 #include <cerrno>
25 
26 using namespace Hdc;
27 
28 static constexpr int CONFIG_COUNT2 = 2;
29 static constexpr int CONFIG_COUNT3 = 3;
30 static constexpr int CONFIG_COUNT5 = 5;
31 
32 // make gnuc++ happy. Clang support direct assignment value to structure, buf g++ weakness
FillUsbV2Head(struct Hdc::UsbFunctionfsDescV2 & descUsbFfs)33 void FillUsbV2Head(struct Hdc::UsbFunctionfsDescV2 &descUsbFfs)
34 {
35     descUsbFfs.head.magic = LONG_LE(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
36     descUsbFfs.head.length = LONG_LE(sizeof(descUsbFfs));
37     descUsbFfs.head.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
38                             FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
39     descUsbFfs.config1Count = CONFIG_COUNT3;
40     descUsbFfs.config2Count = CONFIG_COUNT3;
41     descUsbFfs.config3Count = CONFIG_COUNT5;
42     descUsbFfs.configWosCount = CONFIG_COUNT2;
43     descUsbFfs.config1Desc = Hdc::config1;
44     descUsbFfs.config2Desc = Hdc::config2;
45     descUsbFfs.config3Desc = Hdc::config3;
46     descUsbFfs.wosHead = Hdc::g_wosHead;
47     descUsbFfs.wosDesc = Hdc::g_wosDesc;
48     descUsbFfs.osPropHead = Hdc::g_osPropHead;
49     descUsbFfs.osPropValues = Hdc::g_osPropValues;
50 }
51 
ConfigEpPoint(int & controlEp,const std::string & path)52 int ConfigEpPoint(int& controlEp, const std::string& path)
53 {
54     struct Hdc::UsbFunctionfsDescV2 descUsbFfs = {};
55     FillUsbV2Head(descUsbFfs);
56     while (true) {
57         if (controlEp <= 0) {
58             // After the control port sends the instruction, the device is initialized by the device to the HOST host,
59             // which can be found for USB devices. Do not send initialization to the EP0 control port, the USB
60             // device will not be initialized by Host
61             WRITE_LOG(LOG_INFO, "Begin send to control(EP0) for usb descriptor init\n");
62             if ((controlEp = open(path.c_str(), O_RDWR)) < 0) {
63                 WRITE_LOG(LOG_WARN, "%s: cannot open control endpoint: errno=%d\n", path.c_str(), errno);
64                 break;
65             }
66             if (write(controlEp, &descUsbFfs, sizeof(descUsbFfs)) < 0) {
67                 WRITE_LOG(LOG_WARN, "%s: write ffs configs failed: errno=%d\n", path.c_str(), errno);
68                 break;
69             }
70             if (write(controlEp, &Hdc::USB_FFS_VALUE, sizeof(Hdc::USB_FFS_VALUE)) < 0) {
71                 WRITE_LOG(LOG_WARN, "%s: write USB_FFS_VALUE failed: errno=%d\n", path.c_str(), errno);
72                 break;
73             }
74             // active usbrc, Send USB initialization signal
75             WRITE_LOG(LOG_INFO, "ConnectEPPoint ctrl init finish, set usb-ffs ready\n");
76             fcntl(controlEp, F_SETFD, FD_CLOEXEC);
77             Hdc::SetDevItem("sys.usb.ffs.ready.hdc", "0");
78             Hdc::SetDevItem("sys.usb.ffs.ready", "1");
79             Hdc::SetDevItem("sys.usb.ffs.ready.hdc", "1");
80             return ERR_SUCCESS;
81         }
82     }
83     return ERR_GENERIC;
84 }
85 
OpenEpPoint(int & fd,const std::string path)86 int OpenEpPoint(int &fd, const std::string path)
87 {
88     if ((fd = open(path.c_str(), O_RDWR)) < 0) {
89         WRITE_LOG(LOG_WARN, "%s: cannot open ep: errno=%d\n", path.c_str(), errno);
90         return ERR_GENERIC;
91     }
92     fcntl(fd, F_SETFD, FD_CLOEXEC);
93     return ERR_SUCCESS;
94 }
95 
CloseUsbFd(int & fd)96 int CloseUsbFd(int &fd)
97 {
98         int rc = 0;
99 #ifndef HDC_HOST
100         WRITE_LOG(LOG_INFO, "CloseFd fd:%d\n", fd);
101 #endif
102         if (fd > 0) {
103             rc = close(fd);
104             if (rc < 0) {
105                 char buffer[Hdc::BUF_SIZE_DEFAULT] = { 0 };
106 #ifdef _WIN32
107                 strerror_s(buffer, Hdc::BUF_SIZE_DEFAULT, errno);
108 #else
109                 strerror_r(errno, buffer, Hdc::BUF_SIZE_DEFAULT);
110 #endif
111                 WRITE_LOG(LOG_WARN, "close failed errno:%d %s\n", errno, buffer);
112             } else {
113                 fd = -1;
114             }
115         }
116         return rc;
117 }
118 
CloseEndpoint(int & bulkInFd,int & bulkOutFd,int & controlEp,bool closeCtrlEp)119 void CloseEndpoint(int &bulkInFd, int &bulkOutFd, int &controlEp, bool closeCtrlEp)
120 {
121     CloseUsbFd(bulkInFd);
122     CloseUsbFd(bulkOutFd);
123     if (controlEp > 0 && closeCtrlEp) {
124         CloseUsbFd(controlEp);
125         controlEp = 0;
126     }
127     WRITE_LOG(LOG_INFO, "close endpoint ok\n");
128 }
129 
WriteData(int bulkIn,const uint8_t * data,const int length)130 int WriteData(int bulkIn, const uint8_t *data, const int length)
131 {
132     int ret;
133     int offset = 0;
134     int retryTimes = 10;
135     // 10ms
136     int retryInterval = 10000;
137 
138     while (retryTimes > 0) {
139         ret = write(bulkIn, const_cast<uint8_t *>(data) + offset, length - offset);
140         if ((ret < 0) && (errno != EINTR)) {
141             return ret;
142         } else if ((ret < 0) && (errno == EINTR)) {
143             usleep(retryInterval);
144             retryTimes--;
145             continue;
146         }
147         offset += ret;
148         if (offset >= length) {
149             return offset;
150         }
151     }
152 
153     return -1;
154 }
155 
ReadData(int bulkOut,uint8_t * buf,const int readMaxSize)156 int ReadData(int bulkOut, uint8_t* buf, const int readMaxSize)
157 {
158     int ret;
159     int retryTimes = 10;
160     // 10ms
161     int retryInterval = 10000;
162 
163     while (retryTimes > 0) {
164         ret = read(bulkOut, buf, readMaxSize);
165         if (ret >= 0) {
166             break;
167         }
168 
169         if (errno != EINTR) {
170             break;
171         }
172 
173         usleep(retryInterval);
174         retryTimes--;
175     }
176 
177     return ret;
178 }
179