• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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