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