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