1 /*
2 * Copyright (c) 2025 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
16 #include <regex>
17 #include <unistd.h>
18 #include "hisysevent.h"
19 #include "usb_errors.h"
20 #include "securec.h"
21 #include "serial_manager.h"
22 #include "hilog_wrapper.h"
23 #include "tokenid_kit.h"
24 #include "accesstoken_kit.h"
25
26 #define DUMP_PARAMS_NUM_2 2
27
28 using namespace OHOS::HiviewDFX;
29 using OHOS::USB::USB_MGR_LABEL;
30 using OHOS::USB::MODULE_USB_SERVICE;
31 using OHOS::USB::UEC_OK;
32
33 namespace OHOS {
34 namespace SERIAL {
35 constexpr int32_t PARAM_COUNT_ONE = 1;
36 constexpr int32_t ERR_CODE_IOEXCEPTION = -1;
37 constexpr int32_t ERR_CODE_DEVICENOTOPEN = -6;
38 constexpr int32_t ERR_CODE_TIMEOUT = -7;
39 constexpr int32_t ERR_CODE_ERROR_OVERFLOW = -8;
40
SerialManager()41 SerialManager::SerialManager()
42 {
43 if (serial_ == nullptr) {
44 serial_ = OHOS::HDI::Usb::Serial::V1_0::ISerialInterface::Get("serial_interface_service", true);
45 if (serial_ == nullptr) {
46 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
47 }
48 }
49
50 usbRightManager_ = std::make_shared<USB::UsbRightManager>();
51 }
52
~SerialManager()53 SerialManager::~SerialManager()
54 {
55 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
56 }
57
ErrorCodeWrap(int32_t errorCode)58 inline int32_t ErrorCodeWrap(int32_t errorCode)
59 {
60 if (errorCode == ERR_CODE_IOEXCEPTION || errorCode == ERR_CODE_ERROR_OVERFLOW) {
61 return USB::UEC_SERIAL_IO_EXCEPTION;
62 } else if (errorCode == ERR_CODE_DEVICENOTOPEN) {
63 return USB::UEC_SERIAL_DEVICENOTOPEN;
64 } else if (errorCode == ERR_CODE_TIMEOUT) {
65 return USB::UEC_INTERFACE_TIMED_OUT;
66 } else {
67 return USB::UEC_SERIAL_OTHER_ERROR;
68 }
69 }
70
CheckPortAndTokenId(int32_t portId)71 int32_t SerialManager::CheckPortAndTokenId(int32_t portId)
72 {
73 if (serial_ == nullptr) {
74 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
75 return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
76 }
77
78 if (!IsPortStatus(portId)) {
79 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The port is not open", __func__);
80 return OHOS::USB::UEC_SERIAL_PORT_NOT_OPEN;
81 }
82
83 if (!CheckTokenIdValidity(portId)) {
84 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: Application ID mismatch", __func__);
85 return OHOS::USB::UEC_SERIAL_PORT_NOT_OPEN;
86 }
87
88 return UEC_OK;
89 }
90
SerialOpen(int32_t portId)91 int32_t SerialManager::SerialOpen(int32_t portId)
92 {
93 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
94 if (serial_ == nullptr) {
95 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
96 return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
97 }
98
99 if (portTokenMap_.find(portId) != portTokenMap_.end()) {
100 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The port has been opened", __func__);
101 return OHOS::USB::UEC_SERIAL_PORT_REPEAT_OPEN;
102 }
103
104 uint32_t tokenId;
105 if (GetTokenId(tokenId) != UEC_OK) {
106 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: get tokenId failed", __func__);
107 return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
108 }
109
110 int32_t ret = serial_->SerialOpen(portId);
111 if (ret != UEC_OK) {
112 return ErrorCodeWrap(ret);
113 }
114
115 portTokenMap_[portId] = tokenId;
116 return ret;
117 }
118
SerialClose(int32_t portId)119 int32_t SerialManager::SerialClose(int32_t portId)
120 {
121 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
122 if (serial_ == nullptr) {
123 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
124 return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
125 }
126
127 if (!IsPortStatus(portId)) {
128 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The port not open", __func__);
129 return OHOS::USB::UEC_SERIAL_PORT_NOT_OPEN;
130 }
131
132 if (!CheckTokenIdValidity(portId)) {
133 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The port not open", __func__);
134 return OHOS::USB::UEC_SERIAL_PORT_NOT_OPEN;
135 }
136
137 int32_t ret = serial_->SerialClose(portId);
138 if (ret != UEC_OK) {
139 return ErrorCodeWrap(ret);
140 }
141
142 portTokenMap_.erase(portId);
143 return ret;
144 }
145
SerialRead(int32_t portId,std::vector<uint8_t> & data,uint32_t size,uint32_t & actualSize,uint32_t timeout)146 int32_t SerialManager::SerialRead(int32_t portId, std::vector<uint8_t> &data, uint32_t size,
147 uint32_t &actualSize, uint32_t timeout)
148 {
149 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
150
151 int32_t ret = CheckPortAndTokenId(portId);
152 if (ret != UEC_OK) {
153 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
154 return ret;
155 }
156
157 ret = serial_->SerialRead(portId, data, size, timeout);
158 if (ret < UEC_OK) {
159 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: SerialRead failed ret = %{public}d", __func__, ret);
160 return ErrorCodeWrap(ret);
161 }
162 actualSize = ret;
163 return UEC_OK;
164 }
165
SerialWrite(int32_t portId,const std::vector<uint8_t> & data,uint32_t size,uint32_t & actualSize,uint32_t timeout)166 int32_t SerialManager::SerialWrite(int32_t portId, const std::vector<uint8_t>& data, uint32_t size,
167 uint32_t &actualSize, uint32_t timeout)
168 {
169 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
170 int32_t ret = CheckPortAndTokenId(portId);
171 if (ret != UEC_OK) {
172 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
173 return ret;
174 }
175
176 ret = serial_->SerialWrite(portId, data, size, timeout);
177 if (ret < UEC_OK) {
178 return ErrorCodeWrap(ret);
179 }
180 actualSize = ret;
181 return UEC_OK;
182 }
183
SerialGetAttribute(int32_t portId,OHOS::HDI::Usb::Serial::V1_0::SerialAttribute & attribute)184 int32_t SerialManager::SerialGetAttribute(int32_t portId, OHOS::HDI::Usb::Serial::V1_0::SerialAttribute& attribute)
185 {
186 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
187 int32_t ret = CheckPortAndTokenId(portId);
188 if (ret != UEC_OK) {
189 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
190 return ret;
191 }
192
193 ret = serial_->SerialGetAttribute(portId, attribute);
194 if (ret != UEC_OK) {
195 return ErrorCodeWrap(ret);
196 }
197
198 return ret;
199 }
200
SerialSetAttribute(int32_t portId,const OHOS::HDI::Usb::Serial::V1_0::SerialAttribute & attribute)201 int32_t SerialManager::SerialSetAttribute(int32_t portId,
202 const OHOS::HDI::Usb::Serial::V1_0::SerialAttribute& attribute)
203 {
204 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
205 int32_t ret = CheckPortAndTokenId(portId);
206 if (ret != UEC_OK) {
207 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
208 return ret;
209 }
210
211 ret = serial_->SerialSetAttribute(portId, attribute);
212 if (ret != UEC_OK) {
213 return ErrorCodeWrap(ret);
214 }
215
216 return ret;
217 }
218
SerialGetPortList(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> & serialPortList)219 int32_t SerialManager::SerialGetPortList(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort>& serialPortList)
220 {
221 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
222
223 if (serial_ == nullptr) {
224 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
225 return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
226 }
227
228 int32_t ret = serial_->SerialGetPortList(serialPortList);
229 if (ret != UEC_OK) {
230 return ret;
231 }
232
233 UpdateSerialPortMap(serialPortList);
234 return ret;
235 }
236
UpdateSerialPortMap(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> & serialPortList)237 void SerialManager::UpdateSerialPortMap(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort>& serialPortList)
238 {
239 std::lock_guard<std::mutex> guard(serialPortMapMutex_);
240 for (auto& it : serialPortList) {
241 serialPortMap_[it.portId] = it;
242 }
243 }
244
IsPortIdExist(int32_t portId)245 bool SerialManager::IsPortIdExist(int32_t portId)
246 {
247 std::lock_guard<std::mutex> guard(serialPortMapMutex_);
248 if (serialPortMap_.find(portId) == serialPortMap_.end()) {
249 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: port %{public}d not exist", __func__, portId);
250 return false;
251 }
252
253 return true;
254 }
255
IsPortStatus(int32_t portId)256 bool SerialManager::IsPortStatus(int32_t portId)
257 {
258 if (portTokenMap_.find(portId) == portTokenMap_.end()) {
259 return false;
260 }
261
262 return true;
263 }
264
CheckTokenIdValidity(int32_t portId)265 bool SerialManager::CheckTokenIdValidity(int32_t portId)
266 {
267 uint32_t tokenId;
268 if (GetTokenId(tokenId) != UEC_OK) {
269 USB_HILOGE(MODULE_USB_SERVICE, "get tokenId failed");
270 return false;
271 }
272
273 if (tokenId != portTokenMap_[portId]) {
274 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The tokenId corresponding to the port is incorrect", __func__);
275 return false;
276 }
277
278 return true;
279 }
280
281
GetTokenId(uint32_t & tokenId)282 int32_t SerialManager::GetTokenId(uint32_t &tokenId)
283 {
284 USB_HILOGI(MODULE_USB_SERVICE, "GetTokenId start");
285 OHOS::Security::AccessToken::AccessTokenID token = IPCSkeleton::GetCallingTokenID();
286 OHOS::Security::AccessToken::HapTokenInfo hapTokenInfoRes;
287 int32_t ret = OHOS::Security::AccessToken::AccessTokenKit::GetHapTokenInfo(token, hapTokenInfoRes);
288 if (ret != ERR_OK) {
289 if (usbRightManager_->IsSystemAppOrSa()) {
290 tokenId = token;
291 return UEC_OK;
292 }
293 USB_HILOGE(MODULE_USB_SERVICE, "GetTokenId failed");
294 return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
295 }
296
297 tokenId = token;
298 return ERR_OK;
299 }
300
FreeTokenId(int32_t portId,uint32_t tokenId)301 void SerialManager::FreeTokenId(int32_t portId, uint32_t tokenId)
302 {
303 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
304 if ((portTokenMap_.find(portId) == portTokenMap_.end()) || (portTokenMap_[portId] != tokenId)) {
305 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: portid not exist or tokenId failed", __func__);
306 return;
307 }
308
309 if (serial_ != nullptr) {
310 serial_->SerialClose(portId);
311 }
312
313 portTokenMap_.erase(portId);
314 }
315
SerialPortListDump(int32_t fd,const std::vector<std::string> & args)316 void SerialManager::SerialPortListDump(int32_t fd, const std::vector<std::string>& args)
317 {
318 if (args.size() != PARAM_COUNT_ONE) {
319 dprintf(fd, "port param error: exactly %d parameters are required\n", PARAM_COUNT_ONE);
320 ListGetDumpHelp(fd);
321 return;
322 }
323
324 if (args[0] == "-l") {
325 std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> serialPortList;
326 SerialGetPortList(serialPortList);
327 dprintf(fd, "=========== dump the serial port list ===========\n");
328 for (size_t i = 0; i < serialPortList.size(); ++i) {
329 char portName[20];
330 snprintf_s(portName, sizeof(portName), sizeof(portName)-1, "ttyUSB%zu", i);
331 dprintf(fd, "%s\n", portName);
332 }
333 dprintf(fd, "------------------------------------------------\n");
334 } else {
335 dprintf(fd, "port param error: invalid command '%s'\n", args[0].c_str());
336 ListGetDumpHelp(fd);
337 }
338 }
339
SerialGetAttributeDump(int32_t fd,const std::vector<std::string> & args)340 void SerialManager::SerialGetAttributeDump(int32_t fd, const std::vector<std::string>& args)
341 {
342 size_t size = args.size();
343 OHOS::HDI::Usb::Serial::V1_0::SerialAttribute attribute;
344 if (size == 1) {
345 std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> serialPortList;
346 int32_t ret = SerialGetPortList(serialPortList);
347 if (ret != UEC_OK) {
348 USB_HILOGE(MODULE_USB_SERVICE, "SerialGetPortList failed");
349 return;
350 }
351 size_t portCount = serialPortList.size();
352 for (size_t i = 0; i <portCount; ++i) {
353 int32_t portId = i;
354 ret = SerialGetAttribute(portId, attribute);
355 if (ret != UEC_OK) {
356 SerialOpen(portId);
357 SerialGetAttribute(portId, attribute);
358 SerialClose(portId);
359 }
360 dprintf(fd, "Port %zu: baudrate: %zu stopBits:%zu parity:%zu dataBits:%zu\n",
361 i, attribute.baudrate, attribute.stopBits, attribute.parity, attribute.dataBits);
362 }
363 } else if (size == DUMP_PARAMS_NUM_2) {
364 int32_t portId = std::stoi(args[1]);
365 int32_t ret = SerialGetAttribute(portId, attribute);
366 if (ret != UEC_OK) {
367 ret = SerialOpen(portId);
368 if (ret != UEC_OK) {
369 USB_HILOGE(MODULE_USB_SERVICE, "SerialOpen failed");
370 dprintf(fd, "Port %zu: port does not exist\n", portId);
371 return;
372 }
373 ret = SerialGetAttribute(portId, attribute);
374 if (ret != UEC_OK) {
375 USB_HILOGE(MODULE_USB_SERVICE, "SerialGetAttribute failed");
376 }
377 SerialClose(portId);
378 }
379 dprintf(fd, "Port %zu: baudrate: %zu stopBits:%zu parity:%zu dataBits:%zu\n",
380 portId, attribute.baudrate, attribute.stopBits, attribute.parity, attribute.dataBits);
381 } else {
382 ListGetDumpHelp(fd);
383 }
384 }
385
ListGetDumpHelp(int32_t fd)386 void SerialManager::ListGetDumpHelp(int32_t fd)
387 {
388 dprintf(fd, "=========== dump the serial port information ===========\n");
389 dprintf(fd, "serail -l: Query All Serial Port List\n");
390 dprintf(fd, "serial -h: Serial port help\n");
391 dprintf(fd, "serial -g : Gets the properties of all ports\n");
392 dprintf(fd, "serial \"-g [port number]\": Gets the properties of the specified port\n");
393 dprintf(fd, "------------------------------------------------\n");
394 }
395
GetSerialPort(int32_t portId,OHOS::HDI::Usb::Serial::V1_0::SerialPort & serialPort)396 bool SerialManager::GetSerialPort(int32_t portId, OHOS::HDI::Usb::Serial::V1_0::SerialPort& serialPort)
397 {
398 if (serialPortMap_.find(portId) == serialPortMap_.end()) {
399 USB_HILOGI(MODULE_USB_SERVICE, "serialPort not found");
400 return false;
401 }
402
403 serialPort = serialPortMap_[portId];
404 return true;
405 }
406 } //namespace SERIAL
407 } //namespace OHOS
408