• 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     int32_t ret = serial_->SerialOpen(portId);
105     if (ret != UEC_OK) {
106         return ErrorCodeWrap(ret);
107     }
108 
109     portTokenMap_[portId] = IPCSkeleton::GetCallingTokenID();
110     return ret;
111 }
112 
SerialClose(int32_t portId)113 int32_t SerialManager::SerialClose(int32_t portId)
114 {
115     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
116     if (serial_ == nullptr) {
117         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
118         return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
119     }
120 
121     if (!IsPortStatus(portId)) {
122         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The port not open", __func__);
123         return OHOS::USB::UEC_SERIAL_PORT_NOT_OPEN;
124     }
125 
126     if (!CheckTokenIdValidity(portId)) {
127         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The port not open", __func__);
128         return OHOS::USB::UEC_SERIAL_PORT_NOT_OPEN;
129     }
130 
131     int32_t ret = serial_->SerialClose(portId);
132     if (ret != UEC_OK) {
133         return ErrorCodeWrap(ret);
134     }
135 
136     portTokenMap_.erase(portId);
137     return ret;
138 }
139 
SerialRead(int32_t portId,std::vector<uint8_t> & data,uint32_t size,uint32_t & actualSize,uint32_t timeout)140 int32_t SerialManager::SerialRead(int32_t portId, std::vector<uint8_t> &data, uint32_t size,
141     uint32_t &actualSize, uint32_t timeout)
142 {
143     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
144 
145     int32_t ret = CheckPortAndTokenId(portId);
146     if (ret != UEC_OK) {
147         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
148         return ret;
149     }
150 
151     ret = serial_->SerialRead(portId, data, size, timeout);
152     if (ret < UEC_OK) {
153         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: SerialRead failed ret = %{public}d", __func__, ret);
154         return ErrorCodeWrap(ret);
155     }
156     actualSize = static_cast<uint32_t>(ret);
157     return UEC_OK;
158 }
159 
SerialWrite(int32_t portId,const std::vector<uint8_t> & data,uint32_t size,uint32_t & actualSize,uint32_t timeout)160 int32_t SerialManager::SerialWrite(int32_t portId, const std::vector<uint8_t>& data, uint32_t size,
161     uint32_t &actualSize, uint32_t timeout)
162 {
163     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
164     int32_t ret = CheckPortAndTokenId(portId);
165     if (ret != UEC_OK) {
166         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
167         return ret;
168     }
169 
170     ret = serial_->SerialWrite(portId, data, size, timeout);
171     if (ret < UEC_OK) {
172         return ErrorCodeWrap(ret);
173     }
174     actualSize = static_cast<uint32_t>(ret);
175     return UEC_OK;
176 }
177 
SerialGetAttribute(int32_t portId,OHOS::HDI::Usb::Serial::V1_0::SerialAttribute & attribute)178 int32_t SerialManager::SerialGetAttribute(int32_t portId, OHOS::HDI::Usb::Serial::V1_0::SerialAttribute& attribute)
179 {
180     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
181     int32_t ret = CheckPortAndTokenId(portId);
182     if (ret != UEC_OK) {
183         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
184         return ret;
185     }
186 
187     ret = serial_->SerialGetAttribute(portId, attribute);
188     if (ret != UEC_OK) {
189         return ErrorCodeWrap(ret);
190     }
191 
192     return ret;
193 }
194 
SerialSetAttribute(int32_t portId,const OHOS::HDI::Usb::Serial::V1_0::SerialAttribute & attribute)195 int32_t SerialManager::SerialSetAttribute(int32_t portId,
196     const OHOS::HDI::Usb::Serial::V1_0::SerialAttribute& attribute)
197 {
198     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
199     int32_t ret = CheckPortAndTokenId(portId);
200     if (ret != UEC_OK) {
201         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: CheckPortAndTokenId failed", __func__);
202         return ret;
203     }
204 
205     ret = serial_->SerialSetAttribute(portId, attribute);
206     if (ret != UEC_OK) {
207         return ErrorCodeWrap(ret);
208     }
209 
210     return ret;
211 }
212 
SerialGetPortList(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> & serialPortList)213 int32_t SerialManager::SerialGetPortList(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort>& serialPortList)
214 {
215     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
216 
217     if (serial_ == nullptr) {
218         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: serial_ is nullptr", __func__);
219         return OHOS::USB::UEC_SERVICE_INVALID_VALUE;
220     }
221 
222     int32_t ret = serial_->SerialGetPortList(serialPortList);
223     if (ret != UEC_OK) {
224         return ret;
225     }
226 
227     UpdateSerialPortMap(serialPortList);
228     return ret;
229 }
230 
UpdateSerialPortMap(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> & serialPortList)231 void SerialManager::UpdateSerialPortMap(std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort>& serialPortList)
232 {
233     std::lock_guard<std::mutex> guard(serialPortMapMutex_);
234     for (auto& it : serialPortList) {
235         serialPortMap_[it.portId] = it;
236     }
237 }
238 
IsPortIdExist(int32_t portId)239 bool SerialManager::IsPortIdExist(int32_t portId)
240 {
241     std::lock_guard<std::mutex> guard(serialPortMapMutex_);
242     if (serialPortMap_.find(portId) == serialPortMap_.end()) {
243         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: port %{public}d not exist", __func__, portId);
244         return false;
245     }
246 
247     return true;
248 }
249 
IsPortStatus(int32_t portId)250 bool SerialManager::IsPortStatus(int32_t portId)
251 {
252     return portTokenMap_.find(portId) != portTokenMap_.end();
253 }
254 
CheckTokenIdValidity(int32_t portId)255 bool SerialManager::CheckTokenIdValidity(int32_t portId)
256 {
257     if (IPCSkeleton::GetCallingTokenID() != portTokenMap_[portId]) {
258         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: The tokenId corresponding to the port is incorrect", __func__);
259         return false;
260     }
261 
262     return true;
263 }
264 
FreeTokenId(int32_t portId,uint32_t tokenId)265 void SerialManager::FreeTokenId(int32_t portId, uint32_t tokenId)
266 {
267     USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: start", __func__);
268     if ((portTokenMap_.find(portId) == portTokenMap_.end()) || (portTokenMap_[portId] != tokenId)) {
269         USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: portid not exist or tokenId failed", __func__);
270         return;
271     }
272 
273     if (serial_ != nullptr) {
274         serial_->SerialClose(portId);
275     }
276 
277     portTokenMap_.erase(portId);
278 }
279 
SerialPortListDump(int32_t fd,const std::vector<std::string> & args)280 void SerialManager::SerialPortListDump(int32_t fd, const std::vector<std::string>& args)
281 {
282     if (args.size() != PARAM_COUNT_ONE) {
283         dprintf(fd, "port param error: exactly %d parameters are required\n", PARAM_COUNT_ONE);
284         ListGetDumpHelp(fd);
285         return;
286     }
287 
288     if (args[0] == "-l") {
289         std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> serialPortList;
290         SerialGetPortList(serialPortList);
291         dprintf(fd, "=========== dump the serial port list ===========\n");
292         for (size_t i = 0; i < serialPortList.size(); ++i) {
293             char portName[20];
294             snprintf_s(portName, sizeof(portName), sizeof(portName)-1, "ttyUSB%zu", i);
295             dprintf(fd, "%s\n", portName);
296         }
297         dprintf(fd, "------------------------------------------------\n");
298     } else {
299         dprintf(fd, "port param error: invalid command '%s'\n", args[0].c_str());
300         ListGetDumpHelp(fd);
301     }
302 }
303 
CheckDataAndProcessPortId(int32_t fd,const std::vector<std::string> & args,OHOS::HDI::Usb::Serial::V1_0::SerialAttribute attribute)304 bool SerialManager::CheckDataAndProcessPortId(int32_t fd, const std::vector<std::string>& args,
305     OHOS::HDI::Usb::Serial::V1_0::SerialAttribute attribute)
306 {
307     if (!args.empty() && !std::regex_match(args[1], std::regex("^[0-9]+$"))) {
308         dprintf(fd, "Invalid input, please enter a valid integer\n");
309         return false;
310     }
311     int32_t portId = std::stoi(args[1]);
312     int32_t ret = SerialGetAttribute(portId, attribute);
313     if (ret != UEC_OK) {
314         ret = SerialOpen(portId);
315         if (ret != UEC_OK) {
316             USB_HILOGE(MODULE_USB_SERVICE, "SerialOpen failed");
317             dprintf(fd, "Port %zu: port does not exist\n", portId);
318             return false;
319         }
320         ret = SerialGetAttribute(portId, attribute);
321         if (ret != UEC_OK) {
322             USB_HILOGE(MODULE_USB_SERVICE, "SerialGetAttribute failed");
323         }
324         SerialClose(portId);
325     }
326     dprintf(fd, "Port %zu: baudrate: %zu stopBits:%zu parity:%zu dataBits:%zu\n",
327         portId, attribute.baudrate, attribute.stopBits, attribute.parity, attribute.dataBits);
328     return true;
329 }
330 
SerialGetAttributeDump(int32_t fd,const std::vector<std::string> & args)331 void SerialManager::SerialGetAttributeDump(int32_t fd, const std::vector<std::string>& args)
332 {
333     size_t size = args.size();
334     OHOS::HDI::Usb::Serial::V1_0::SerialAttribute attribute;
335     if (size == 1) {
336         std::vector<OHOS::HDI::Usb::Serial::V1_0::SerialPort> serialPortList;
337         int32_t ret = SerialGetPortList(serialPortList);
338         if (ret != UEC_OK) {
339             USB_HILOGE(MODULE_USB_SERVICE, "SerialGetPortList failed");
340             return;
341         }
342         size_t portCount = serialPortList.size();
343         for (size_t i = 0; i < portCount; ++i) {
344             if (i > INT32_MAX) {
345                 USB_HILOGE(MODULE_USB_SERVICE, "SerialGetPortList port index out of range");
346                 break;
347             }
348             int32_t portId = static_cast<int32_t>(serialPortList[i].portId);
349             ret = SerialGetAttribute(portId, attribute);
350             if (ret != UEC_OK) {
351                 SerialOpen(portId);
352                 SerialGetAttribute(portId, attribute);
353                 SerialClose(portId);
354             }
355             dprintf(fd, "Port %zu: baudrate: %zu stopBits:%zu parity:%zu dataBits:%zu\n",
356                 i, attribute.baudrate, attribute.stopBits, attribute.parity, attribute.dataBits);
357         }
358     } else if (size == DUMP_PARAMS_NUM_2) {
359         if (!CheckDataAndProcessPortId(fd, args, attribute)) {
360             USB_HILOGE(MODULE_USB_SERVICE, "CheckDataAndProcessPortId failed");
361             return;
362         }
363     } else {
364         ListGetDumpHelp(fd);
365     }
366 }
367 
ListGetDumpHelp(int32_t fd)368 void SerialManager::ListGetDumpHelp(int32_t fd)
369 {
370     dprintf(fd, "=========== dump the serial port information ===========\n");
371     dprintf(fd, "serail -l: Query All Serial Port List\n");
372     dprintf(fd, "serial -h: Serial port help\n");
373     dprintf(fd, "serial -g : Gets the properties of all ports\n");
374     dprintf(fd, "serial \"-g [port number]\": Gets the properties of the specified port\n");
375     dprintf(fd, "------------------------------------------------\n");
376 }
377 
GetSerialPort(int32_t portId,OHOS::HDI::Usb::Serial::V1_0::SerialPort & serialPort)378 bool SerialManager::GetSerialPort(int32_t portId, OHOS::HDI::Usb::Serial::V1_0::SerialPort& serialPort)
379 {
380     if (serialPortMap_.find(portId) == serialPortMap_.end()) {
381         USB_HILOGI(MODULE_USB_SERVICE, "serialPort not found");
382         return false;
383     }
384 
385     serialPort = serialPortMap_[portId];
386     return true;
387 }
388 }  //namespace SERIAL
389 }  //namespace OHOS
390