1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 
16 #include "usbd_accessory.h"
17 #include <cerrno>
18 #include <unistd.h>
19 #include <securec.h>
20 
21 #include "hdf_base.h"
22 #include "hdf_log.h"
23 #include "usbd_wrapper.h"
24 #include "usbd_type.h"
25 
26 namespace OHOS {
27 namespace HDI {
28 namespace Usb {
29 namespace V1_1 {
30 
31 const char *ACCESSORY_DRIVER_NAME = "/dev/usb_accessory";
32 constexpr int BUFFER_SIZE = 256;
33 static const std::vector<int32_t> accStringList = { ACCESSORY_GET_STRING_MANUFACTURER, ACCESSORY_GET_STRING_MODEL,
34                                                     ACCESSORY_GET_STRING_DESCRIPTION, ACCESSORY_GET_STRING_VERSION,
35                                                     ACCESSORY_GET_STRING_SERIAL, AOA_GET_EXTRA_DATA };
36 
37 const std::string base64_chars =
38              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
39              "abcdefghijklmnopqrstuvwxyz"
40              "0123456789+/";
41 
42 static const uint32_t BASE64_VAL_SHIFT = 8;
43 static const int32_t MIN_LENGTH_REQUIRED = 10;
44 const int INDEX_FIRST = 0;
45 const int INDEX_SECOND = 1;
46 const int INDEX_THIRD = 2;
47 const int INDEX_FORTH = 3;
48 const int INDEX_FIFTH = 4;
49 const uint8_t PARAM_FC = 0xfc;
50 const uint8_t PARAM_03 = 0x03;
51 const uint8_t PARAM_F0 = 0xf0;
52 const uint8_t PARAM_0F = 0x0f;
53 const uint8_t PARAM_C0 = 0xc0;
54 const uint8_t PARAM_3F = 0x3f;
55 const uint32_t OFFSET2 = 2;
56 const uint32_t OFFSET4 = 4;
57 const uint32_t OFFSET6 = 6;
58 
GetInstance()59 UsbdAccessory &UsbdAccessory::GetInstance()
60 {
61     static UsbdAccessory instance;
62     return instance;
63 }
64 
init_base64_char_map()65 void UsbdAccessory::init_base64_char_map()
66 {
67     for (size_t i = 0; i < base64_chars.size(); ++i) {
68         base64_char_map[base64_chars[i]] = static_cast<int>(i);
69     }
70 }
71 
base64_encode(char * buffer,int32_t len)72 std::string UsbdAccessory::base64_encode(char *buffer, int32_t len)
73 {
74     if (buffer == nullptr) {
75         HDF_LOGE("%{public}s: buffer is nullptr", __func__);
76         return "";
77     }
78 
79     std::string ret;
80     uint32_t i = 0;
81     uint8_t charArray3[INDEX_FORTH];
82     uint8_t charArray4[INDEX_FIFTH];
83 
84     while (len > 0) {
85         charArray3[i++] = *(buffer++);
86         if (i == sizeof(charArray3)) {
87             charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & PARAM_FC) >> OFFSET2;
88             charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & PARAM_03) << OFFSET4) +
89                                        ((charArray3[INDEX_SECOND] & PARAM_F0) >> OFFSET4);
90             charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & PARAM_0F) << OFFSET2) +
91                                       ((charArray3[INDEX_THIRD] & PARAM_C0) >> OFFSET6);
92             charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & PARAM_3F;
93             for (i = 0; i < sizeof(charArray4); i++) {
94                 ret += base64_chars[charArray4[i]];
95             }
96             i = 0;
97         }
98         len--;
99     }
100 
101     if (i == 0) {
102         return ret;
103     }
104 
105     if (i) {
106         uint32_t j = 0;
107         for (j = i; j < sizeof(charArray3); j++) {
108             charArray3[j] = '\0';
109         }
110         charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & PARAM_FC) >> OFFSET2;
111         charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & PARAM_03) << OFFSET4) +
112                                    ((charArray3[INDEX_SECOND] & PARAM_F0) >> OFFSET4);
113         charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & PARAM_0F) << OFFSET2) +
114                                   ((charArray3[INDEX_THIRD] & PARAM_C0) >> OFFSET6);
115         charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & PARAM_3F;
116         for (j = 0; j < i + 1; j++) {
117             ret += base64_chars[charArray4[j]];
118         }
119         while (i < sizeof(charArray3)) {
120             ret += '=';
121             i++;
122         }
123     }
124     return ret;
125 }
126 
ExtraToString(char * buffer,int32_t len,std::string & extraData)127 int32_t UsbdAccessory::ExtraToString(char* buffer, int32_t len, std::string &extraData)
128 {
129     if (buffer == nullptr) {
130         HDF_LOGE("%{public}s: buffer is nullptr", __func__);
131         return HDF_FAILURE;
132     }
133     if (len < MIN_LENGTH_REQUIRED) {
134         return HDF_FAILURE;
135     }
136     int16_t actLen = *(buffer + BASE64_VAL_SHIFT);
137     actLen = actLen >= len ? len: actLen;
138     if (base64_char_map.empty()) {
139         init_base64_char_map();
140     }
141     extraData = base64_encode(buffer, actLen);
142     return HDF_SUCCESS;
143 }
144 
GetAccessoryString(int32_t fd,int32_t cmd,std::string & accInfoString)145 int32_t UsbdAccessory::GetAccessoryString(int32_t fd, int32_t cmd, std::string &accInfoString)
146 {
147     char buffer[BUFFER_SIZE];
148     if (memset_s(buffer, BUFFER_SIZE, 0, BUFFER_SIZE) != HDF_SUCCESS) {
149         HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
150         return HDF_FAILURE;
151     }
152     int32_t ret = ioctl(fd, cmd, buffer);
153     if (ret < 0) {
154         HDF_LOGE("%{public}s:%{public}d ioctl failed, ret: %{public}d", __func__, __LINE__, ret);
155         return ret;
156     }
157 
158     accInfoString = buffer;
159     if (cmd == AOA_GET_EXTRA_DATA) {
160         return ExtraToString(buffer, ret, accInfoString);
161     }
162     return HDF_SUCCESS;
163 }
164 
GetAccessoryInfo(std::vector<std::string> & accessoryInfo)165 int32_t UsbdAccessory::GetAccessoryInfo(std::vector<std::string> &accessoryInfo)
166 {
167     int32_t fd = open(ACCESSORY_DRIVER_NAME, O_RDWR);
168     if (fd < 0) {
169         HDF_LOGE("%{public}s:%{public}d open failed", __func__, __LINE__);
170         return HDF_FAILURE;
171     }
172     int32_t ret = HDF_FAILURE;
173     std::string accInfoString;
174     for (size_t i = 0; i < accStringList.size(); i++) {
175         ret = GetAccessoryString(fd, accStringList[i], accInfoString);
176         if (ret != HDF_SUCCESS) {
177             HDF_LOGE("%{public}s:%{public}d SetAccessoryString failed", __func__, __LINE__);
178             continue;
179         }
180         accessoryInfo.push_back(accInfoString);
181     }
182     close(fd);
183     return HDF_SUCCESS;
184 }
185 
OpenAccessory(int32_t & fd)186 int32_t UsbdAccessory::OpenAccessory(int32_t &fd)
187 {
188     if (accFd > 0) {
189         fd = accFd;
190         return HDF_ERR_DEVICE_BUSY;
191     }
192     accFd = open(ACCESSORY_DRIVER_NAME, O_RDWR);
193     if (accFd < 0) {
194         HDF_LOGE("%{public}s:%{public}d open failed", __func__, __LINE__);
195         return HDF_FAILURE;
196     }
197     fd = accFd;
198     return HDF_SUCCESS;
199 }
200 
CloseAccessory(int32_t fd)201 int32_t UsbdAccessory::CloseAccessory(int32_t fd)
202 {
203     if (accFd > 0) {
204         close(accFd);
205     }
206     close(fd);
207     accFd = 0;
208     return HDF_SUCCESS;
209 }
210 
HandleEvent(int32_t state)211 void UsbdAccessory::HandleEvent(int32_t state)
212 {
213     if (state == ACT_DOWNDEVICE && accFd > 0) {
214         close(accFd);
215         accFd = 0;
216     }
217 }
218 }  // namespace V1_1
219 }  // namespace Usb
220 }  // namespace HDI
221 }  // namespace OHOS
222