• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(), &copy[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