1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 * Copyright 2018-2019 NXP
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 #include "UwbAdaptation.h"
21
22 #include <aidl/android/hardware/uwb/BnUwb.h>
23 #include <aidl/android/hardware/uwb/BnUwbClientCallback.h>
24 #include <aidl/android/hardware/uwb/IUwb.h>
25 #include <aidl/android/hardware/uwb/IUwbChip.h>
26 #include <android-base/logging.h>
27 #include <android/binder_ibinder.h>
28 #include <android/binder_manager.h>
29 #include <android/binder_process.h>
30 #include <binder/IMemory.h>
31 #include <binder/IServiceManager.h>
32 #include <binder/MemoryDealer.h>
33 #include <cutils/properties.h>
34 #include <pthread.h>
35
36 #include <algorithm>
37
38 #include "uci_log.h"
39 #include "uwa_api.h"
40 #include "uwb_config.h"
41 #include "uwb_hal_int.h"
42 #include "uwb_int.h"
43 #include "uwb_target.h"
44
45 using IUwbV1_0 = aidl::android::hardware::uwb::IUwb;
46 using IUwbChipV1_0 = aidl::android::hardware::uwb::IUwbChip;
47 using UwbStatus = aidl::android::hardware::uwb::UwbStatus;
48 using aidl::android::hardware::uwb::BnUwbClientCallback;
49 using aidl::android::hardware::uwb::IUwbClientCallback;
50
51 std::string UWB_HAL_SERVICE_NAME = "android.hardware.uwb.IUwb/default";
52 extern bool uwb_debug_enabled;
53
54 bool uwb_debug_enabled = false;
55 bool IsdebugLogEnabled = false;
56
57 extern void phUwb_GKI_shutdown();
58
59 UwbAdaptation* UwbAdaptation::mpInstance = NULL;
60 ThreadMutex UwbAdaptation::sLock;
61 ThreadMutex UwbAdaptation::sIoctlLock;
62 std::mutex sIoctlMutex;
63
64 tHAL_UWB_CBACK* UwbAdaptation::mHalCallback = NULL;
65 tHAL_UWB_DATA_CBACK* UwbAdaptation::mHalDataCallback = NULL;
66 std::shared_ptr<IUwbChipV1_0> mHal = nullptr;
67
68 namespace {
initializeGlobalDebugEnabledFlag()69 void initializeGlobalDebugEnabledFlag() {
70 uwb_debug_enabled = true;
71
72 UCI_TRACE_I("%s: Debug log is enabled =%u", __func__, uwb_debug_enabled);
73 }
74
getHalService()75 std::shared_ptr<IUwbChipV1_0> getHalService() {
76 ::ndk::SpAIBinder binder(AServiceManager_getService(UWB_HAL_SERVICE_NAME.c_str()));
77 std::shared_ptr<IUwbV1_0> iUwb = IUwbV1_0::fromBinder(binder);
78 if (iUwb == nullptr) {
79 ALOGE("Failed to connect to the AIDL HAL service.");
80 return nullptr;
81 }
82 std::vector<std::string> chipNames;
83 ndk::ScopedAStatus status = iUwb->getChips(&chipNames);
84 if (!status.isOk() || chipNames.empty()) {
85 ALOGE("Failed to retrieve the HAL chip names");
86 return nullptr;
87 }
88 // TODO (b/197638976): We pick the first chip here. Need to fix this
89 // for supporting multiple chips in the future.
90 std::shared_ptr<IUwbChipV1_0> iUwbChip;
91 status = iUwb->getChip(chipNames.front(), &iUwbChip);
92 if (!status.isOk() || iUwbChip == nullptr) {
93 ALOGE("Failed to retrieve the HAL chip");
94 return nullptr;
95 }
96 return iUwbChip;
97 }
98
99 } // namespace
100
101 class UwbClientCallback
102 : public aidl::android::hardware::uwb::BnUwbClientCallback {
103 public:
UwbClientCallback(tHAL_UWB_CBACK * eventCallback,tHAL_UWB_DATA_CBACK dataCallback)104 UwbClientCallback(tHAL_UWB_CBACK* eventCallback,
105 tHAL_UWB_DATA_CBACK dataCallback) {
106 mEventCallback = eventCallback;
107 mDataCallback = dataCallback;
108 };
109 virtual ~UwbClientCallback() = default;
110
onHalEvent(aidl::android::hardware::uwb::UwbEvent event,aidl::android::hardware::uwb::UwbStatus event_status)111 ::ndk::ScopedAStatus onHalEvent(
112 aidl::android::hardware::uwb::UwbEvent event,
113 aidl::android::hardware::uwb::UwbStatus event_status) override {
114 mEventCallback((uint8_t)event, (uint16_t)event_status);
115 return ::ndk::ScopedAStatus::ok();
116 };
117
onUciMessage(const std::vector<uint8_t> & data)118 ::ndk::ScopedAStatus onUciMessage(const std::vector<uint8_t>& data) override {
119 std::vector<uint8_t> copy = data;
120 mDataCallback(copy.size(), ©[0]);
121 return ::ndk::ScopedAStatus::ok();
122 };
123
124 private:
125 tHAL_UWB_CBACK* mEventCallback;
126 tHAL_UWB_DATA_CBACK* mDataCallback;
127 };
128
129 /*******************************************************************************
130 **
131 ** Function: UwbAdaptation::UwbAdaptation()
132 **
133 ** Description: class constructor
134 **
135 ** Returns: none
136 **
137 *******************************************************************************/
UwbAdaptation()138 UwbAdaptation::UwbAdaptation() {
139 memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
140 }
141
142 /*******************************************************************************
143 **
144 ** Function: UwbAdaptation::~UwbAdaptation()
145 **
146 ** Description: class destructor
147 **
148 ** Returns: none
149 **
150 *******************************************************************************/
~UwbAdaptation()151 UwbAdaptation::~UwbAdaptation() { mpInstance = NULL; }
152
153 /*******************************************************************************
154 **
155 ** Function: UwbAdaptation::GetInstance()
156 **
157 ** Description: access class singleton
158 **
159 ** Returns: pointer to the singleton object
160 **
161 *******************************************************************************/
GetInstance()162 UwbAdaptation& UwbAdaptation::GetInstance() {
163 AutoThreadMutex a(sLock);
164
165 if (!mpInstance) mpInstance = new UwbAdaptation;
166 CHECK(mpInstance);
167 return *mpInstance;
168 }
169
170 /*******************************************************************************
171 **
172 ** Function: UwbAdaptation::Initialize()
173 **
174 ** Description: class initializer
175 **
176 ** Returns: none
177 **
178 *******************************************************************************/
Initialize()179 void UwbAdaptation::Initialize() {
180 const char* func = "UwbAdaptation::Initialize";
181 UNUSED(func);
182 UCI_TRACE_I("%s: enter", func);
183 initializeGlobalDebugEnabledFlag();
184 phUwb_GKI_init();
185 phUwb_GKI_enable();
186 phUwb_GKI_create_task((TASKPTR)UWBA_TASK, BTU_TASK, (int8_t*)"UWBA_TASK", 0,
187 0, (pthread_cond_t*)NULL, NULL);
188 {
189 AutoThreadMutex guard(mCondVar);
190 phUwb_GKI_create_task((TASKPTR)Thread, MMI_TASK, (int8_t*)"UWBA_THREAD", 0,
191 0, (pthread_cond_t*)NULL, NULL);
192 mCondVar.wait();
193 }
194
195 mHalCallback = NULL;
196 memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
197 InitializeHalDeviceContext();
198 UCI_TRACE_I("%s: exit", func);
199 }
200
201 /*******************************************************************************
202 **
203 ** Function: UwbAdaptation::Finalize(bool exitStatus)
204 **
205 ** Description: class finalizer
206 **
207 ** Returns: none
208 **
209 *******************************************************************************/
Finalize(bool graceExit)210 void UwbAdaptation::Finalize(bool graceExit) {
211 const char* func = "UwbAdaptation::Finalize";
212 UNUSED(func);
213 AutoThreadMutex a(sLock);
214
215 UCI_TRACE_I("%s: enter, graceful: %d", func, graceExit);
216 phUwb_GKI_shutdown();
217
218 memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
219 if (graceExit) {
220 UwbConfig::clear();
221 }
222
223 UCI_TRACE_I("%s: exit", func);
224 delete this;
225 }
226
227 /*******************************************************************************
228 **
229 ** Function: UwbAdaptation::signal()
230 **
231 ** Description: signal the CondVar to release the thread that is waiting
232 **
233 ** Returns: none
234 **
235 *******************************************************************************/
signal()236 void UwbAdaptation::signal() { mCondVar.signal(); }
237
238 /*******************************************************************************
239 **
240 ** Function: UwbAdaptation::UWBA_TASK()
241 **
242 ** Description: UWBA_TASK runs the GKI main task
243 **
244 ** Returns: none
245 **
246 *******************************************************************************/
UWBA_TASK(uint32_t arg)247 uint32_t UwbAdaptation::UWBA_TASK(__attribute__((unused)) uint32_t arg) {
248 const char* func = "UwbAdaptation::UWBA_TASK";
249 UNUSED(func);
250 UCI_TRACE_I("%s: enter", func);
251 phUwb_GKI_run(0);
252 UCI_TRACE_I("%s: exit", func);
253 return 0;
254 }
255
256 /*******************************************************************************
257 **
258 ** Function: UwbAdaptation::Thread()
259 **
260 ** Description: Creates work threads
261 **
262 ** Returns: none
263 **
264 *******************************************************************************/
Thread(uint32_t arg)265 uint32_t UwbAdaptation::Thread(__attribute__((unused)) uint32_t arg) {
266 const char* func = "UwbAdaptation::Thread";
267 UNUSED(func);
268 UCI_TRACE_I("%s: enter", func);
269
270 {
271 ThreadCondVar CondVar;
272 AutoThreadMutex guard(CondVar);
273 phUwb_GKI_create_task((TASKPTR)uwb_task, UWB_TASK, (int8_t*)"UWB_TASK", 0,
274 0, (pthread_cond_t*)CondVar,
275 (pthread_mutex_t*)CondVar);
276 CondVar.wait();
277 }
278
279 UwbAdaptation::GetInstance().signal();
280
281 phUwb_GKI_exit_task(phUwb_GKI_get_taskid());
282 UCI_TRACE_I("%s: exit", func);
283 return 0;
284 }
285
286 /*******************************************************************************
287 **
288 ** Function: UwbAdaptation::GetHalEntryFuncs()
289 **
290 ** Description: Get the set of HAL entry points.
291 **
292 ** Returns: Functions pointers for HAL entry points.
293 **
294 *******************************************************************************/
GetHalEntryFuncs()295 tHAL_UWB_ENTRY* UwbAdaptation::GetHalEntryFuncs() { return &mHalEntryFuncs; }
296
297 /*******************************************************************************
298 **
299 ** Function: UwbAdaptation::InitializeHalDeviceContext
300 **
301 ** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
302 **
303 ** Returns: None.
304 **
305 *******************************************************************************/
InitializeHalDeviceContext()306 void UwbAdaptation::InitializeHalDeviceContext() {
307 const char* func = "UwbAdaptation::InitializeHalDeviceContext";
308 UNUSED(func);
309 UCI_TRACE_I("%s: enter", func);
310
311 mHalEntryFuncs.open = HalOpen;
312 mHalEntryFuncs.close = HalClose;
313 mHalEntryFuncs.write = HalWrite;
314 mHalEntryFuncs.CoreInitialization = CoreInitialization;
315 mHalEntryFuncs.SessionInitialization = SessionInitialization;
316 mHal = getHalService();
317 if (mHal == nullptr) {
318 UCI_TRACE_I("%s: Failed to retrieve the UWB HAL!", func);
319 } else {
320 UCI_TRACE_I("%s: IUwb::getService() returned %p (%s)", func, mHal.get(),
321 (mHal->isRemote() ? "remote" : "local"));
322 }
323 }
324
325 /*******************************************************************************
326 **
327 ** Function: UwbAdaptation::HalOpen
328 **
329 ** Description: Turn on controller, download firmware.
330 **
331 ** Returns: None.
332 **
333 *******************************************************************************/
HalOpen(tHAL_UWB_CBACK * p_hal_cback,tHAL_UWB_DATA_CBACK * p_data_cback)334 void UwbAdaptation::HalOpen(tHAL_UWB_CBACK* p_hal_cback,
335 tHAL_UWB_DATA_CBACK* p_data_cback) {
336 const char* func = "UwbAdaptation::HalOpen";
337 UNUSED(func);
338 UCI_TRACE_I("%s", func);
339 ndk::ScopedAStatus status;
340 std::shared_ptr<IUwbClientCallback> mCallback;
341 mCallback =
342 ndk::SharedRefBase::make<UwbClientCallback>(p_hal_cback, p_data_cback);
343
344 if (mHal != nullptr) {
345 status = mHal->open(mCallback);
346 } else {
347 UCI_TRACE_E("%s mHal is NULL", func);
348 }
349 }
350 /*******************************************************************************
351 **
352 ** Function: UwbAdaptation::HalClose
353 **
354 ** Description: Turn off controller.
355 **
356 ** Returns: None.
357 **
358 *******************************************************************************/
HalClose()359 void UwbAdaptation::HalClose() {
360 const char* func = "UwbAdaptation::HalClose";
361 UNUSED(func);
362 ndk::ScopedAStatus status;
363 UCI_TRACE_I("%s HalClose Enter", func);
364 if (mHal != nullptr) status = mHal->close();
365 }
366
367 /*******************************************************************************
368 **
369 ** Function: UwbAdaptation::HalWrite
370 **
371 ** Description: Write UCI message to the controller.
372 **
373 ** Returns: None.
374 **
375 *******************************************************************************/
HalWrite(uint16_t data_len,uint8_t * p_data)376 void UwbAdaptation::HalWrite(__attribute__((unused)) uint16_t data_len,
377 __attribute__((unused)) uint8_t* p_data) {
378 const char* func = "UwbAdaptation::HalWrite";
379 UNUSED(func);
380 UCI_TRACE_I("%s: Enter", func);
381 std::vector<uint8_t> data;
382 if (p_data == NULL) {
383 UCI_TRACE_E("p_data is null");
384 return;
385 }
386 int ret;
387 copy(&p_data[0], &p_data[data_len], back_inserter(data));
388 if (mHal != nullptr) {
389 mHal->sendUciMessage(data, &ret);
390 } else {
391 UCI_TRACE_E("mHal is NULL");
392 }
393 }
394
395 /*******************************************************************************
396 **
397 ** Function: UwbAdaptation::CoreInitialization
398 **
399 ** Description: Performs UWB CoreInitialization.
400 **
401 ** Returns: UwbStatus::OK on success and UwbStatus::FAILED on error.
402 **
403 *******************************************************************************/
CoreInitialization()404 tUWB_STATUS UwbAdaptation::CoreInitialization() {
405 const char* func = "UwbAdaptation::CoreInitialization";
406 UNUSED(func);
407 UCI_TRACE_I("%s: enter", func);
408 if (mHal != nullptr) {
409 if (!mHal->coreInit().isOk()) return UWB_STATUS_FAILED;
410 } else {
411 UCI_TRACE_E("mHal is NULL");
412 return UWB_STATUS_FAILED;
413 }
414 return UWB_STATUS_OK;
415 }
416
417 /*******************************************************************************
418 **
419 ** Function: UwbAdaptation::SessionInitialization
420 **
421 ** Description: Performs UWB SessionInitialization.
422 **
423 ** Returns: UwbStatus::OK on success and UwbStatus::FAILED on error.
424 **
425 *******************************************************************************/
SessionInitialization(int sessionId)426 tUWB_STATUS UwbAdaptation::SessionInitialization(int sessionId) {
427 const char* func = "UwbAdaptation::SessionInitialization";
428 UNUSED(func);
429 UCI_TRACE_I("%s: enter", func);
430 if (mHal != nullptr) {
431 if (!mHal->sessionInit(sessionId).isOk()) return UWB_STATUS_FAILED;
432 } else {
433 UCI_TRACE_E("mHal is NULL");
434 return UWB_STATUS_FAILED;
435 }
436 return UWB_STATUS_OK;
437 }
438
439 /*******************************************************************************
440 **
441 ** Function: ThreadMutex::ThreadMutex()
442 **
443 ** Description: class constructor
444 **
445 ** Returns: none
446 **
447 *******************************************************************************/
ThreadMutex()448 ThreadMutex::ThreadMutex() {
449 pthread_mutexattr_t mutexAttr;
450
451 pthread_mutexattr_init(&mutexAttr);
452 pthread_mutex_init(&mMutex, &mutexAttr);
453 pthread_mutexattr_destroy(&mutexAttr);
454 }
455
456 /*******************************************************************************
457 **
458 ** Function: ThreadMutex::~ThreadMutex()
459 **
460 ** Description: class destructor
461 **
462 ** Returns: none
463 **
464 *******************************************************************************/
~ThreadMutex()465 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
466
467 /*******************************************************************************
468 **
469 ** Function: ThreadMutex::lock()
470 **
471 ** Description: lock the mutex
472 **
473 ** Returns: none
474 **
475 *******************************************************************************/
lock()476 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
477
478 /*******************************************************************************
479 **
480 ** Function: ThreadMutex::unblock()
481 **
482 ** Description: unlock the mutex
483 **
484 ** Returns: none
485 **
486 *******************************************************************************/
unlock()487 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
488
489 /*******************************************************************************
490 **
491 ** Function: ThreadCondVar::ThreadCondVar()
492 **
493 ** Description: class constructor
494 **
495 ** Returns: none
496 **
497 *******************************************************************************/
ThreadCondVar()498 ThreadCondVar::ThreadCondVar() {
499 pthread_condattr_t CondAttr;
500
501 pthread_condattr_init(&CondAttr);
502 pthread_cond_init(&mCondVar, &CondAttr);
503
504 pthread_condattr_destroy(&CondAttr);
505 }
506
507 /*******************************************************************************
508 **
509 ** Function: ThreadCondVar::~ThreadCondVar()
510 **
511 ** Description: class destructor
512 **
513 ** Returns: none
514 **
515 *******************************************************************************/
~ThreadCondVar()516 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
517
518 /*******************************************************************************
519 **
520 ** Function: ThreadCondVar::wait()
521 **
522 ** Description: wait on the mCondVar
523 **
524 ** Returns: none
525 **
526 *******************************************************************************/
wait()527 void ThreadCondVar::wait() {
528 pthread_cond_wait(&mCondVar, *this);
529 pthread_mutex_unlock(*this);
530 }
531
532 /*******************************************************************************
533 **
534 ** Function: ThreadCondVar::signal()
535 **
536 ** Description: signal the mCondVar
537 **
538 ** Returns: none
539 **
540 *******************************************************************************/
signal()541 void ThreadCondVar::signal() {
542 AutoThreadMutex a(*this);
543 pthread_cond_signal(&mCondVar);
544 }
545
546 /*******************************************************************************
547 **
548 ** Function: AutoThreadMutex::AutoThreadMutex()
549 **
550 ** Description: class constructor, automatically lock the mutex
551 **
552 ** Returns: none
553 **
554 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)555 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
556
557 /*******************************************************************************
558 **
559 ** Function: AutoThreadMutex::~AutoThreadMutex()
560 **
561 ** Description: class destructor, automatically unlock the mutex
562 **
563 ** Returns: none
564 **
565 *******************************************************************************/
~AutoThreadMutex()566 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
567