1 /*
2  * Copyright (C) 2022 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 "hid_host_uhid.h"
17 #include "hid_host_service.h"
18 #include "log_util.h"
19 
20 namespace OHOS {
21 namespace bluetooth {
HidHostUhid(std::string address)22 HidHostUhid::HidHostUhid(std::string address)
23 {
24     address_ = address;
25     pollThreadId_ = -1;
26     fd_ = -1;
27     keepPolling_ = false;
28     readyForData_ = false;
29     task_id_ = 0;
30 }
31 
~HidHostUhid()32 HidHostUhid::~HidHostUhid()
33 {
34     Close();
35     Destroy();
36 }
37 
Open()38 int HidHostUhid::Open()
39 {
40     pthread_t threadId;
41 
42     if (fd_ < 0) {
43         LOG_INFO("[UHID]%{public}s():fd is null,creat fd", __FUNCTION__);
44         fd_ = open(UHID_DEVICE_PATH, O_RDWR);
45         if (fd_ < 0) {
46             LOG_ERROR("[UHID]%{public}s():open %{public}s failed", __FUNCTION__, UHID_DEVICE_PATH);
47             return HID_HOST_FAILURE;
48         } else {
49             LOG_INFO("[UHID]%{public}s():uhid fd = %{public}d", __FUNCTION__, fd_);
50         }
51 
52         LOG_INFO("[UHID]%{public}s():recreate thread", __FUNCTION__);
53         threadId = CreateThread(PollEventThread, this);
54         if (threadId == static_cast<pthread_t>(-1)) {
55             LOG_ERROR("[UHID]%{public}s():create thread failed", __FUNCTION__);
56             return HID_HOST_FAILURE;
57         } else {
58             pollThreadId_ = threadId;
59             return HID_HOST_SUCCESS;
60         }
61     }
62 
63     LOG_INFO("[UHID]%{public}s():uhid fd is not null,fd = %{public}d", __FUNCTION__, fd_);
64     return HID_HOST_SUCCESS;
65 }
66 
Close()67 int HidHostUhid::Close()
68 {
69     ClosePollThread();
70     return HID_HOST_SUCCESS;
71 }
72 
SendData(uint8_t * pRpt,uint16_t len)73 int HidHostUhid::SendData(uint8_t* pRpt, uint16_t len)
74 {
75     LOG_INFO("[UHID]%{public}s", __FUNCTION__);
76     if (fd_ >= 0) {
77         uint32_t polling_attempts = 0;
78         while (!readyForData_ && polling_attempts < MAX_POLLING_ATTEMPTS) {
79             usleep(POLLING_SLEEP_DURATION_US);
80             polling_attempts++;
81         }
82     }
83     // Send the HID data to the kernel.
84     if ((fd_ >= 0) && readyForData_) {
85         WritePackUhid(fd_, pRpt, len);
86     } else {
87         LOG_ERROR("[UHID]%{public}s failed, fd_:%{public}d, readyForData_:%{public}d, len:%{public}d",
88             __FUNCTION__, fd_, readyForData_, len);
89         return HID_HOST_FAILURE;
90     }
91     return HID_HOST_SUCCESS;
92 }
93 
SendControlData(uint8_t * pRpt,uint16_t len)94 int HidHostUhid::SendControlData(uint8_t* pRpt, uint16_t len)
95 {
96     LOG_INFO("[UHID]%{public}s", __FUNCTION__);
97     if (fd_ >= 0) {
98         uint32_t polling_attempts = 0;
99         while (!readyForData_ && polling_attempts < MAX_POLLING_ATTEMPTS) {
100             usleep(POLLING_SLEEP_DURATION_US);
101             polling_attempts++;
102         }
103     }
104     // Send the HID control data to the kernel.
105     if ((fd_ >= 0) && readyForData_) {
106         if (task_type_ == HID_HOST_DATA_TYPE_GET_REPORT) {
107             SendGetReportReplyUhid(fd_, task_id_, HID_HOST_SUCCESS, pRpt, len);
108         } else if (task_type_ == HID_HOST_DATA_TYPE_SET_REPORT) {
109             SendSetReportReplyUhid(fd_, task_id_, HID_HOST_SUCCESS);
110         } else {
111             LOG_ERROR("[UHID]%{public}s, Unknow task_type_:%{public}d", __FUNCTION__, task_type_);
112         }
113         task_id_ = 0;
114         task_type_ = -1;
115     } else {
116         LOG_ERROR("[UHID]%{public}s failed, fd_:%{public}d, readyForData_:%{public}d, len:%{public}d",
117             __FUNCTION__, fd_, readyForData_, len);
118         return HID_HOST_FAILURE;
119     }
120     return HID_HOST_SUCCESS;
121 }
122 
SendHandshake(uint16_t err)123 int HidHostUhid::SendHandshake(uint16_t err)
124 {
125     LOG_INFO("[UHID]%{public}s, err:%{public}d", __FUNCTION__, err);
126     if (fd_ >= 0) {
127         uint32_t polling_attempts = 0;
128         while (!readyForData_ && polling_attempts < MAX_POLLING_ATTEMPTS) {
129             usleep(POLLING_SLEEP_DURATION_US);
130             polling_attempts++;
131         }
132     }
133     // Send the HID handshake to the kernel.
134     if ((fd_ >= 0) && readyForData_) {
135         if (task_type_ == HID_HOST_DATA_TYPE_GET_REPORT) {
136             SendGetReportReplyUhid(fd_, task_id_, err, nullptr, 0);
137         } else if (task_type_ == HID_HOST_DATA_TYPE_SET_REPORT) {
138             SendSetReportReplyUhid(fd_, task_id_, err);
139         } else {
140             LOG_ERROR("[UHID]%{public}s, Unknow task_type_:%{public}d", __FUNCTION__, task_type_);
141         }
142         task_id_ = 0;
143         task_type_ = -1;
144     } else {
145         LOG_ERROR("[UHID]%{public}s failed, fd_:%{public}d, readyForData_:%{public}d",
146             __FUNCTION__, fd_, readyForData_);
147         return HID_HOST_FAILURE;
148     }
149     return HID_HOST_SUCCESS;
150 }
151 
SendGetReportReplyUhid(int fd,int id,uint16_t err,uint8_t * rpt,uint16_t len)152 int HidHostUhid::SendGetReportReplyUhid(int fd, int id, uint16_t err, uint8_t* rpt, uint16_t len)
153 {
154     struct uhid_event ev;
155     memset_s(&ev, sizeof(ev), 0, sizeof(ev));
156     ev.type = UHID_FEATURE_ANSWER;
157     ev.u.feature_answer.id = id;
158     ev.u.feature_answer.err = err;
159     ev.u.feature_answer.size = len;
160     if (len > sizeof(ev.u.feature_answer.data)) {
161         LOG_WARN("[UHID]%{public}s(): Report size greater than allowed size", __FUNCTION__);
162         return HID_HOST_FAILURE;
163     }
164     if (memcpy_s(ev.u.feature_answer.data, sizeof(ev.u.feature_answer.data), rpt, len) != EOK) {
165         LOG_ERROR("[UHID] %{public}s() memcpy error", __FUNCTION__);
166         return HID_HOST_FAILURE;
167     }
168     return WriteUhid(fd, &ev);
169 }
170 
SendSetReportReplyUhid(int fd,int id,uint16_t err)171 int HidHostUhid::SendSetReportReplyUhid(int fd, int id, uint16_t err)
172 {
173     struct uhid_event ev;
174     memset_s(&ev, sizeof(ev), 0, sizeof(ev));
175     ev.type = UHID_SET_REPORT_REPLY;
176     ev.u.set_report_reply.id = id;
177     ev.u.set_report_reply.err = err;
178     return WriteUhid(fd, &ev);
179 }
180 
SendHidInfo(const char * devName,PnpInformation & pnpInf,HidInformation & hidInf)181 int HidHostUhid::SendHidInfo(const char* devName, PnpInformation& pnpInf, HidInformation& hidInf)
182 {
183     struct uhid_event ev;
184     int ret ;
185 
186     if (fd_ < 0) {
187         LOG_WARN("[UHID]%{public}s(): Error: fd = %{public}d, dscp_len = %{public}d", __FUNCTION__, fd_,
188             hidInf.descLength);
189         return HID_HOST_FAILURE;
190     }
191     // Create and send hid descriptor to kernel
192     memset_s(&ev, sizeof(ev), 0, sizeof(ev));
193     ev.type = UHID_CREATE;
194     if (strncpy_s((char*)ev.u.create.name, sizeof(ev.u.create.name), devName, sizeof(ev.u.create.name) - 1)
195         != EOK) {
196         LOG_ERROR("[UHID]%{public}s(): memcpy error", __FUNCTION__);
197     }
198     int uniqLength = snprintf_s(reinterpret_cast<char*>(ev.u.create.uniq), sizeof(ev.u.create.uniq), address_.length(),
199         "%s", address_.c_str());
200     if (uniqLength < 0) {
201         LOG_ERROR("[UHID]%{public}s(): snprintf length error, uniqLength = %{public}d", __FUNCTION__, uniqLength);
202     }
203     ev.u.create.rd_size = hidInf.descLength;
204     ev.u.create.rd_data = hidInf.descInfo.get();
205     ev.u.create.bus = BUS_BLUETOOTH;
206     ev.u.create.vendor = pnpInf.vendorId;
207     ev.u.create.product = pnpInf.productId;
208     ev.u.create.version = pnpInf.version;
209     ev.u.create.country = hidInf.ctryCode;
210     ret = WriteUhid(fd_, &ev);
211 
212     LOG_INFO("[UHID]%{public}s(): wrote descriptor to fd = %{public}d, dscp_len = %{public}d,result = %{public}d",
213         __FUNCTION__, fd_, hidInf.descLength, ret);
214 
215     if (ret) {
216         LOG_ERROR("[UHID]%{public}s(): Error: failed to send DSCP, result = %{public}d", __FUNCTION__, ret);
217         /* The HID report descriptor is corrupted. Close the driver. */
218         close(fd_);
219         fd_ = -1;
220         return HID_HOST_FAILURE;
221     }
222 
223     return HID_HOST_SUCCESS;
224 }
225 
Destroy()226 int HidHostUhid::Destroy()
227 {
228     if (fd_ >= 0) {
229         struct uhid_event ev;
230         memset_s(&ev, sizeof(ev), 0, sizeof(ev));
231         ev.type = UHID_DESTROY;
232 
233         WriteUhid(fd_, &ev);
234         LOG_INFO("[UHID]%{public}s(): Closing fd=%{public}d", __FUNCTION__, fd_);
235         close(fd_);
236         fd_ = -1;
237     }
238     return HID_HOST_SUCCESS;
239 }
240 
WriteUhid(int fd,const struct uhid_event * ev)241 int HidHostUhid::WriteUhid(int fd, const struct uhid_event* ev)
242 {
243     ssize_t ret;
244     do {
245     } while ((ret = write(fd, ev, sizeof(*ev))) == -1 && errno == EINTR);
246     if (ret < 0) {
247         int rtn = errno;
248         LOG_ERROR("[UHID]%{public}s(): Cannot write to uhid:%{public}s", __FUNCTION__, strerror(errno));
249         return rtn;
250     } else if (ret != static_cast<ssize_t>(sizeof(*ev))) {
251         LOG_ERROR("[UHID]%{public}s(): Wrong size written to uhid: %{public}zd != %{public}zu", __FUNCTION__,
252             ret, sizeof(*ev));
253         return EFAULT;
254     }
255     return HID_HOST_SUCCESS;
256 }
257 
WritePackUhid(int fd,uint8_t * rpt,uint16_t len)258 int HidHostUhid::WritePackUhid(int fd, uint8_t* rpt, uint16_t len)
259 {
260     struct uhid_event ev;
261     memset_s(&ev, sizeof(ev), 0, sizeof(ev));
262     ev.type = UHID_INPUT;
263     ev.u.input.size = len;
264     if (len > sizeof(ev.u.input.data)) {
265         LOG_WARN("[UHID]%{public}s(): Report size greater than allowed size", __FUNCTION__);
266         return HID_HOST_FAILURE;
267     }
268     if (memcpy_s(ev.u.input.data, sizeof(ev.u.input.data), rpt, len) != EOK) {
269         LOG_ERROR("[UHID]%{public}s(): memcpy error", __FUNCTION__);
270         return HID_HOST_FAILURE;
271     }
272     return WriteUhid(fd, &ev);
273 }
274 
ClosePollThread()275 int HidHostUhid::ClosePollThread()
276 {
277     LOG_INFO("[UHID]%{public}s():", __FUNCTION__);
278     readyForData_ = false;
279     if (keepPolling_) {
280         keepPolling_ = false;
281         pthread_join(pollThreadId_, nullptr);
282     }
283     pollThreadId_ = -1;
284     return HID_HOST_SUCCESS;
285 }
286 
CreateThread(void * (* startRoutine)(void *),void * arg)287 pthread_t HidHostUhid::CreateThread(void* (*startRoutine)(void*), void* arg)
288 {
289     LOG_INFO("[UHID]%{public}s():create_thread: entered", __FUNCTION__);
290     pthread_attr_t threadAttr;
291 
292     pthread_attr_init(&threadAttr);
293     pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE);
294     pthread_t threadId = static_cast<pthread_t>(-1);
295     if (pthread_create(&threadId, &threadAttr, startRoutine, arg) != 0) {
296         LOG_ERROR("[UHID]%{public}s():pthread_create : %{public}s", __FUNCTION__, strerror(errno));
297         return static_cast<pthread_t>(-1);
298     }
299     LOG_INFO("[UHID]%{public}s():%{public}lu: threadcreated successfully", __FUNCTION__, threadId);
300     return threadId;
301 }
302 
PollEventThread(void * arg)303 void* HidHostUhid::PollEventThread(void* arg)
304 {
305     HidHostUhid *uhid = (HidHostUhid*)arg;
306     if (uhid != nullptr) {
307         uhid->PollEventThread_();
308     } else {
309         LOG_ERROR("[UHID]%{public}s():Thread creat fail,uhid is null", __FUNCTION__);
310     }
311     return nullptr;
312 }
313 
PollEventThread_()314 void HidHostUhid::PollEventThread_()
315 {
316     HILOGI("Thread:%{public}d, fd:%{public}d execute", static_cast<int>(pollThreadId_), fd_);
317     struct pollfd pfds[1];
318     keepPolling_ = true;
319     pfds[0].fd = fd_;
320     pfds[0].events = POLLIN;
321 
322     // Set the uhid fd as non-blocking to ensure we never block the BTU thread
323     SetUhidNonBlocking(fd_);
324 
325     while (keepPolling_) {
326         int ret;
327         do {
328         } while ((ret = poll(pfds, 1, POLL_TIMEOUT)) == -1 && errno == EINTR);
329         if (ret < 0) {
330             LOG_ERROR("[UHID]%{public}s(): Cannot poll for fds: %{public}s", __FUNCTION__,
331                 strerror(errno));
332             break;
333         }
334         if (pfds[0].revents & POLLIN) {
335             LOG_INFO("[UHID]%{public}s(): POLLIN", __FUNCTION__);
336             ret = ReadUhidEvent();
337             if (ret != 0) {
338                 break;
339             }
340         }
341     }
342     LOG_INFO("[UHID]%{public}s(): exit", __FUNCTION__);
343 
344     pollThreadId_ = -1;
345 }
346 
SetUhidNonBlocking(int fd)347 void HidHostUhid::SetUhidNonBlocking(int fd)
348 {
349     int opts = fcntl(fd, F_GETFL);
350     if (opts < 0) {
351         LOG_ERROR("[UHID]%{public}s(): Getting flags failed (%{public}s)", __FUNCTION__, strerror(errno));
352         return;
353     }
354 
355     if (fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {
356         LOG_ERROR("[UHID]%{public}s(): Setting non-blocking flag failed (%{public}s)", __FUNCTION__, strerror(errno));
357     }
358 }
359 
ReadUhidEvent()360 int HidHostUhid::ReadUhidEvent()
361 {
362     struct uhid_event ev;
363     ssize_t ret;
364 
365     memset_s(&ev, sizeof(ev), 0, sizeof(ev));
366 
367     do {
368     } while ((ret = read(fd_, &ev, sizeof(ev))) == -1 && errno == EINTR);
369 
370     if (ret <= 0) {
371         LOG_ERROR("[UHID]%{public}s():read err", __FUNCTION__);
372         return HID_HOST_FAILURE;
373     }
374     LOG_INFO("[UHID]%{public}s():ev.type:%{public}d", __FUNCTION__, ev.type);
375 
376     switch (ev.type) {
377         case UHID_START:
378             LOG_INFO("[UHID]%{public}s():UHID_START from uhid-dev", __FUNCTION__);
379             readyForData_ = true;
380             break;
381         case UHID_STOP:
382             LOG_INFO("[UHID]%{public}s():UHID_STOP from uhid-dev", __FUNCTION__);
383             readyForData_ = false;
384             break;
385         case UHID_OPEN:
386             LOG_INFO("[UHID]%{public}s():UHID_OPEN from uhid-dev", __FUNCTION__);
387             readyForData_ = true;
388             break;
389         case UHID_CLOSE:
390             LOG_INFO("[UHID]%{public}s():UHID_CLOSE from uhid-dev", __FUNCTION__);
391             readyForData_ = false;
392             break;
393         case UHID_OUTPUT:
394             ReadUhidOutPut(ev);
395             break;
396         case UHID_OUTPUT_EV:
397             LOG_INFO("[UHID]%{public}s():UHID_OUTPUT_EV from uhid-dev", __FUNCTION__);
398             break;
399         case UHID_FEATURE:
400             ReadUhidFeature(ev);
401             break;
402         case UHID_SET_REPORT:
403             ReadUhidSetReport(ev);
404             break;
405         default:
406             LOG_INFO("[UHID]%{public}s():Invalid event from uhid-dev: %{public}u", __FUNCTION__, ev.type);
407     }
408 
409     return HID_HOST_SUCCESS;
410 }
411 
ReadUhidOutPut(uhid_event ev)412 void HidHostUhid::ReadUhidOutPut(uhid_event ev)
413 {
414     if (ev.u.output.rtype == UHID_FEATURE_REPORT) {
415         HidHostService::GetService()->HidHostSetReport(address_, HID_HOST_FEATURE_REPORT, ev.u.output.size,
416             ev.u.output.data);
417     } else if (ev.u.output.rtype == UHID_OUTPUT_REPORT) {
418         HidHostService::GetService()->HidHostSetReport(address_, HID_HOST_OUTPUT_REPORT, ev.u.output.size,
419             ev.u.output.data);
420     } else {
421         HidHostService::GetService()->HidHostSetReport(address_, HID_HOST_INPUT_REPORT, ev.u.output.size,
422             ev.u.output.data);
423     }
424 }
425 
ReadUhidFeature(uhid_event ev)426 void HidHostUhid::ReadUhidFeature(uhid_event ev)
427 {
428     LOG_INFO("[UHID]%{public}s():UHID_FEATURE from uhid-dev id=%{public}d,rnum=%{public}d,rtype=%{public}d",
429         __FUNCTION__, ev.u.feature.id, ev.u.feature.rnum, ev.u.feature.rtype);
430     if (ev.u.feature.rtype == UHID_FEATURE_REPORT) {
431         HidHostService::GetService()->HidHostGetReport(address_, ev.u.feature.rnum, 0,
432             HID_HOST_FEATURE_REPORT);
433     } else if (ev.u.feature.rtype == UHID_OUTPUT_REPORT) {
434         HidHostService::GetService()->HidHostGetReport(address_, ev.u.feature.rnum, 0,
435             HID_HOST_OUTPUT_REPORT);
436     } else {
437         HidHostService::GetService()->HidHostGetReport(address_, ev.u.feature.rnum, 0,
438             HID_HOST_INPUT_REPORT);
439     }
440     task_id_ = ev.u.feature.id;
441     task_type_ = HID_HOST_DATA_TYPE_GET_REPORT;
442 }
443 
ReadUhidSetReport(uhid_event ev)444 void HidHostUhid::ReadUhidSetReport(uhid_event ev)
445 {
446     LOG_INFO("[UHID]%{public}s():UHID_SET_REPORT id=%{public}d,rnum=%{public}d,rtype=%{public}d,size=%{public}d",
447         __FUNCTION__, ev.u.set_report.id, ev.u.set_report.rnum, ev.u.set_report.rtype, ev.u.set_report.size);
448     if (ev.u.set_report.rtype == UHID_FEATURE_REPORT) {
449         HidHostService::GetService()->HidHostSetReport(address_, HID_HOST_FEATURE_REPORT, ev.u.set_report.size,
450             ev.u.set_report.data);
451     } else if (ev.u.set_report.rtype == UHID_OUTPUT_REPORT) {
452         HidHostService::GetService()->HidHostSetReport(address_, HID_HOST_OUTPUT_REPORT, ev.u.set_report.size,
453             ev.u.set_report.data);
454     } else {
455         HidHostService::GetService()->HidHostSetReport(address_, HID_HOST_INPUT_REPORT, ev.u.set_report.size,
456             ev.u.set_report.data);
457     }
458     task_id_ = ev.u.feature.id;
459     task_type_ = HID_HOST_DATA_TYPE_SET_REPORT;
460 }
461 }  // namespace bluetooth
462 }  // namespace OHOS
463