1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include "_OverrideLog.h"
19
20 #include <android/hardware/nfc/1.0/INfc.h>
21 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
22 #include <hwbinder/ProcessState.h>
23 #include <pthread.h>
24 #include "NfcAdaptation.h"
25 extern "C" {
26 #include "gki.h"
27 #include "nfa_api.h"
28 #include "nfc_int.h"
29 #include "vendor_cfg.h"
30 }
31 #include "android_logmsg.h"
32 #include "config.h"
33
34 #undef LOG_TAG
35 #define LOG_TAG "NfcAdaptation"
36
37 using android::OK;
38 using android::sp;
39 using android::status_t;
40
41 using android::hardware::ProcessState;
42 using android::hardware::Return;
43 using android::hardware::Void;
44 using android::hardware::nfc::V1_0::INfc;
45 using android::hardware::nfc::V1_0::INfcClientCallback;
46 using android::hardware::hidl_vec;
47
48 extern "C" void GKI_shutdown();
49 extern void resetConfig();
50 extern "C" void verify_stack_non_volatile_store();
51 extern "C" void delete_stack_non_volatile_store(bool forceDelete);
52
53 NfcAdaptation* NfcAdaptation::mpInstance = NULL;
54 ThreadMutex NfcAdaptation::sLock;
55 tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
56 tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
57 ThreadCondVar NfcAdaptation::mHalOpenCompletedEvent;
58 ThreadCondVar NfcAdaptation::mHalCloseCompletedEvent;
59 sp<INfc> NfcAdaptation::mHal;
60 INfcClientCallback* NfcAdaptation::mCallback;
61
62 uint32_t ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; // 0x017F00;
63 uint8_t appl_trace_level = 0xff;
64 char bcm_nfc_location[120];
65
66 static uint8_t nfa_dm_cfg[sizeof(tNFA_DM_CFG)];
67 static uint8_t nfa_proprietary_cfg[sizeof(tNFA_PROPRIETARY_CFG)];
68 extern tNFA_DM_CFG* p_nfa_dm_cfg;
69 extern tNFA_PROPRIETARY_CFG* p_nfa_proprietary_cfg;
70 extern uint8_t nfa_ee_max_ee_cfg;
71 extern const uint8_t nfca_version_string[];
72 extern const uint8_t nfa_version_string[];
73 static uint8_t deviceHostWhiteList[NFA_HCI_MAX_HOST_IN_NETWORK];
74 static tNFA_HCI_CFG jni_nfa_hci_cfg;
75 extern tNFA_HCI_CFG* p_nfa_hci_cfg;
76 extern bool nfa_poll_bail_out_mode;
77
78 class NfcClientCallback : public INfcClientCallback {
79 public:
NfcClientCallback(tHAL_NFC_CBACK * eventCallback,tHAL_NFC_DATA_CBACK dataCallback)80 NfcClientCallback(tHAL_NFC_CBACK* eventCallback,
81 tHAL_NFC_DATA_CBACK dataCallback) {
82 mEventCallback = eventCallback;
83 mDataCallback = dataCallback;
84 };
85 virtual ~NfcClientCallback() = default;
sendEvent(::android::hardware::nfc::V1_0::NfcEvent event,::android::hardware::nfc::V1_0::NfcStatus event_status)86 Return<void> sendEvent(
87 ::android::hardware::nfc::V1_0::NfcEvent event,
88 ::android::hardware::nfc::V1_0::NfcStatus event_status) override {
89 mEventCallback((uint8_t)event, (tHAL_NFC_STATUS)event_status);
90 return Void();
91 };
sendData(const::android::hardware::nfc::V1_0::NfcData & data)92 Return<void> sendData(
93 const ::android::hardware::nfc::V1_0::NfcData& data) override {
94 ::android::hardware::nfc::V1_0::NfcData copy = data;
95 mDataCallback(copy.size(), ©[0]);
96 return Void();
97 };
98
99 private:
100 tHAL_NFC_CBACK* mEventCallback;
101 tHAL_NFC_DATA_CBACK* mDataCallback;
102 };
103
104 /*******************************************************************************
105 **
106 ** Function: NfcAdaptation::NfcAdaptation()
107 **
108 ** Description: class constructor
109 **
110 ** Returns: none
111 **
112 *******************************************************************************/
NfcAdaptation()113 NfcAdaptation::NfcAdaptation() {
114 memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
115 }
116
117 /*******************************************************************************
118 **
119 ** Function: NfcAdaptation::~NfcAdaptation()
120 **
121 ** Description: class destructor
122 **
123 ** Returns: none
124 **
125 *******************************************************************************/
~NfcAdaptation()126 NfcAdaptation::~NfcAdaptation() { mpInstance = NULL; }
127
128 /*******************************************************************************
129 **
130 ** Function: NfcAdaptation::GetInstance()
131 **
132 ** Description: access class singleton
133 **
134 ** Returns: pointer to the singleton object
135 **
136 *******************************************************************************/
GetInstance()137 NfcAdaptation& NfcAdaptation::GetInstance() {
138 AutoThreadMutex a(sLock);
139
140 if (!mpInstance) mpInstance = new NfcAdaptation;
141 return *mpInstance;
142 }
143
144 /*******************************************************************************
145 **
146 ** Function: NfcAdaptation::Initialize()
147 **
148 ** Description: class initializer
149 **
150 ** Returns: none
151 **
152 *******************************************************************************/
Initialize()153 void NfcAdaptation::Initialize() {
154 const char* func = "NfcAdaptation::Initialize";
155 ALOGD("%s: enter", func);
156 ALOGE("%s: ver=%s nfa=%s", func, nfca_version_string, nfa_version_string);
157 unsigned long num;
158
159 if (GetNumValue(NAME_USE_RAW_NCI_TRACE, &num, sizeof(num))) {
160 if (num == 1) {
161 // display protocol traces in raw format
162 ProtoDispAdapterUseRawOutput(TRUE);
163 ALOGD("%s: logging protocol in raw format", func);
164 }
165 }
166 if (!GetStrValue(NAME_NFA_STORAGE, bcm_nfc_location,
167 sizeof(bcm_nfc_location))) {
168 strlcpy(bcm_nfc_location, "/data/nfc", sizeof(bcm_nfc_location));
169 }
170
171 initializeProtocolLogLevel();
172
173 if (GetStrValue(NAME_NFA_DM_CFG, (char*)nfa_dm_cfg, sizeof(nfa_dm_cfg)))
174 p_nfa_dm_cfg = (tNFA_DM_CFG*)&nfa_dm_cfg[0];
175
176 if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num))) {
177 nfa_ee_max_ee_cfg = num;
178 ALOGD("%s: Overriding NFA_EE_MAX_EE_SUPPORTED to use %d", func,
179 nfa_ee_max_ee_cfg);
180 }
181 if (GetNumValue(NAME_NFA_POLL_BAIL_OUT_MODE, &num, sizeof(num))) {
182 nfa_poll_bail_out_mode = num;
183 ALOGD("%s: Overriding NFA_POLL_BAIL_OUT_MODE to use %d", func,
184 nfa_poll_bail_out_mode);
185 }
186
187 if (GetStrValue(NAME_NFA_PROPRIETARY_CFG, (char*)nfa_proprietary_cfg,
188 sizeof(tNFA_PROPRIETARY_CFG))) {
189 p_nfa_proprietary_cfg = (tNFA_PROPRIETARY_CFG*)&nfa_proprietary_cfg[0];
190 }
191
192 // configure device host whitelist of HCI host ID's; see specification ETSI TS
193 // 102 622 V11.1.10
194 //(2012-10), section 6.1.3.1
195 num = GetStrValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)deviceHostWhiteList,
196 sizeof(deviceHostWhiteList));
197 if (num) {
198 memmove(&jni_nfa_hci_cfg, p_nfa_hci_cfg, sizeof(jni_nfa_hci_cfg));
199 jni_nfa_hci_cfg.num_whitelist_host =
200 (uint8_t)num; // number of HCI host ID's in the whitelist
201 jni_nfa_hci_cfg.p_whitelist = deviceHostWhiteList; // array of HCI host
202 // ID's
203 p_nfa_hci_cfg = &jni_nfa_hci_cfg;
204 }
205
206 initializeGlobalAppLogLevel();
207
208 verify_stack_non_volatile_store();
209 if (GetNumValue(NAME_PRESERVE_STORAGE, (char*)&num, sizeof(num)) &&
210 (num == 1))
211 ALOGD("%s: preserve stack NV store", __func__);
212 else {
213 delete_stack_non_volatile_store(FALSE);
214 }
215
216 GKI_init();
217 GKI_enable();
218 GKI_create_task((TASKPTR)NFCA_TASK, BTU_TASK, (int8_t*)"NFCA_TASK", 0, 0,
219 (pthread_cond_t*)NULL, NULL);
220 {
221 AutoThreadMutex guard(mCondVar);
222 GKI_create_task((TASKPTR)Thread, MMI_TASK, (int8_t*)"NFCA_THREAD", 0, 0,
223 (pthread_cond_t*)NULL, NULL);
224 mCondVar.wait();
225 }
226
227 mHalCallback = NULL;
228 memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
229 InitializeHalDeviceContext();
230 ALOGD("%s: exit", func);
231 }
232
233 /*******************************************************************************
234 **
235 ** Function: NfcAdaptation::Finalize()
236 **
237 ** Description: class finalizer
238 **
239 ** Returns: none
240 **
241 *******************************************************************************/
Finalize()242 void NfcAdaptation::Finalize() {
243 const char* func = "NfcAdaptation::Finalize";
244 AutoThreadMutex a(sLock);
245
246 ALOGD("%s: enter", func);
247 GKI_shutdown();
248
249 resetConfig();
250
251 mCallback = NULL;
252 memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
253
254 ALOGD("%s: exit", func);
255 delete this;
256 }
257
258 /*******************************************************************************
259 **
260 ** Function: NfcAdaptation::signal()
261 **
262 ** Description: signal the CondVar to release the thread that is waiting
263 **
264 ** Returns: none
265 **
266 *******************************************************************************/
signal()267 void NfcAdaptation::signal() { mCondVar.signal(); }
268
269 /*******************************************************************************
270 **
271 ** Function: NfcAdaptation::NFCA_TASK()
272 **
273 ** Description: NFCA_TASK runs the GKI main task
274 **
275 ** Returns: none
276 **
277 *******************************************************************************/
NFCA_TASK(uint32_t arg)278 uint32_t NfcAdaptation::NFCA_TASK(uint32_t arg) {
279 const char* func = "NfcAdaptation::NFCA_TASK";
280 ALOGD("%s: enter", func);
281 GKI_run(0);
282 ALOGD("%s: exit", func);
283 return 0;
284 }
285
286 /*******************************************************************************
287 **
288 ** Function: NfcAdaptation::Thread()
289 **
290 ** Description: Creates work threads
291 **
292 ** Returns: none
293 **
294 *******************************************************************************/
Thread(uint32_t arg)295 uint32_t NfcAdaptation::Thread(uint32_t arg) {
296 const char* func = "NfcAdaptation::Thread";
297 ALOGD("%s: enter", func);
298
299 {
300 ThreadCondVar CondVar;
301 AutoThreadMutex guard(CondVar);
302 GKI_create_task((TASKPTR)nfc_task, NFC_TASK, (int8_t*)"NFC_TASK", 0, 0,
303 (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar);
304 CondVar.wait();
305 }
306
307 NfcAdaptation::GetInstance().signal();
308
309 GKI_exit_task(GKI_get_taskid());
310 ALOGD("%s: exit", func);
311 return 0;
312 }
313
314 /*******************************************************************************
315 **
316 ** Function: NfcAdaptation::GetHalEntryFuncs()
317 **
318 ** Description: Get the set of HAL entry points.
319 **
320 ** Returns: Functions pointers for HAL entry points.
321 **
322 *******************************************************************************/
GetHalEntryFuncs()323 tHAL_NFC_ENTRY* NfcAdaptation::GetHalEntryFuncs() { return &mHalEntryFuncs; }
324
325 /*******************************************************************************
326 **
327 ** Function: NfcAdaptation::InitializeHalDeviceContext
328 **
329 ** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
330 **
331 ** Returns: None.
332 **
333 *******************************************************************************/
InitializeHalDeviceContext()334 void NfcAdaptation::InitializeHalDeviceContext() {
335 const char* func = "NfcAdaptation::InitializeHalDeviceContext";
336 ALOGD("%s: enter", func);
337 int ret = 0; // 0 means success
338
339 mHalEntryFuncs.initialize = HalInitialize;
340 mHalEntryFuncs.terminate = HalTerminate;
341 mHalEntryFuncs.open = HalOpen;
342 mHalEntryFuncs.close = HalClose;
343 mHalEntryFuncs.core_initialized = HalCoreInitialized;
344 mHalEntryFuncs.write = HalWrite;
345 mHalEntryFuncs.prediscover = HalPrediscover;
346 mHalEntryFuncs.control_granted = HalControlGranted;
347 mHalEntryFuncs.power_cycle = HalPowerCycle;
348 mHalEntryFuncs.get_max_ee = HalGetMaxNfcee;
349 ALOGI("%s: INfc::getService()", func);
350 mHal = INfc::getService();
351 LOG_FATAL_IF(mHal == nullptr, "Failed to retrieve the NFC HAL!");
352 ALOGI("%s: INfc::getService() returned %p (%s)", func, mHal.get(),
353 (mHal->isRemote() ? "remote" : "local"));
354 ALOGD("%s: exit", func);
355 }
356
357 /*******************************************************************************
358 **
359 ** Function: NfcAdaptation::HalInitialize
360 **
361 ** Description: Not implemented because this function is only needed
362 ** within the HAL.
363 **
364 ** Returns: None.
365 **
366 *******************************************************************************/
HalInitialize()367 void NfcAdaptation::HalInitialize() {
368 const char* func = "NfcAdaptation::HalInitialize";
369 ALOGD("%s", func);
370 }
371
372 /*******************************************************************************
373 **
374 ** Function: NfcAdaptation::HalTerminate
375 **
376 ** Description: Not implemented because this function is only needed
377 ** within the HAL.
378 **
379 ** Returns: None.
380 **
381 *******************************************************************************/
HalTerminate()382 void NfcAdaptation::HalTerminate() {
383 const char* func = "NfcAdaptation::HalTerminate";
384 ALOGD("%s", func);
385 }
386
387 /*******************************************************************************
388 **
389 ** Function: NfcAdaptation::HalOpen
390 **
391 ** Description: Turn on controller, download firmware.
392 **
393 ** Returns: None.
394 **
395 *******************************************************************************/
HalOpen(tHAL_NFC_CBACK * p_hal_cback,tHAL_NFC_DATA_CBACK * p_data_cback)396 void NfcAdaptation::HalOpen(tHAL_NFC_CBACK* p_hal_cback,
397 tHAL_NFC_DATA_CBACK* p_data_cback) {
398 const char* func = "NfcAdaptation::HalOpen";
399 ALOGD("%s", func);
400 mCallback = new NfcClientCallback(p_hal_cback, p_data_cback);
401 mHal->open(mCallback);
402 }
403
404 /*******************************************************************************
405 **
406 ** Function: NfcAdaptation::HalClose
407 **
408 ** Description: Turn off controller.
409 **
410 ** Returns: None.
411 **
412 *******************************************************************************/
HalClose()413 void NfcAdaptation::HalClose() {
414 const char* func = "NfcAdaptation::HalClose";
415 ALOGD("%s", func);
416 mHal->close();
417 }
418
419 /*******************************************************************************
420 **
421 ** Function: NfcAdaptation::HalDeviceContextCallback
422 **
423 ** Description: Translate generic Android HAL's callback into Broadcom-specific
424 ** callback function.
425 **
426 ** Returns: None.
427 **
428 *******************************************************************************/
HalDeviceContextCallback(nfc_event_t event,nfc_status_t event_status)429 void NfcAdaptation::HalDeviceContextCallback(nfc_event_t event,
430 nfc_status_t event_status) {
431 const char* func = "NfcAdaptation::HalDeviceContextCallback";
432 ALOGD("%s: event=%u", func, event);
433 if (mHalCallback) mHalCallback(event, (tHAL_NFC_STATUS)event_status);
434 }
435
436 /*******************************************************************************
437 **
438 ** Function: NfcAdaptation::HalDeviceContextDataCallback
439 **
440 ** Description: Translate generic Android HAL's callback into Broadcom-specific
441 ** callback function.
442 **
443 ** Returns: None.
444 **
445 *******************************************************************************/
HalDeviceContextDataCallback(uint16_t data_len,uint8_t * p_data)446 void NfcAdaptation::HalDeviceContextDataCallback(uint16_t data_len,
447 uint8_t* p_data) {
448 const char* func = "NfcAdaptation::HalDeviceContextDataCallback";
449 ALOGD("%s: len=%u", func, data_len);
450 if (mHalDataCallback) mHalDataCallback(data_len, p_data);
451 }
452
453 /*******************************************************************************
454 **
455 ** Function: NfcAdaptation::HalWrite
456 **
457 ** Description: Write NCI message to the controller.
458 **
459 ** Returns: None.
460 **
461 *******************************************************************************/
HalWrite(uint16_t data_len,uint8_t * p_data)462 void NfcAdaptation::HalWrite(uint16_t data_len, uint8_t* p_data) {
463 const char* func = "NfcAdaptation::HalWrite";
464 ALOGD("%s", func);
465 ::android::hardware::nfc::V1_0::NfcData data;
466 data.setToExternal(p_data, data_len);
467 mHal->write(data);
468 }
469
470 /*******************************************************************************
471 **
472 ** Function: NfcAdaptation::HalCoreInitialized
473 **
474 ** Description: Adjust the configurable parameters in the controller.
475 **
476 ** Returns: None.
477 **
478 *******************************************************************************/
HalCoreInitialized(uint16_t data_len,uint8_t * p_core_init_rsp_params)479 void NfcAdaptation::HalCoreInitialized(uint16_t data_len,
480 uint8_t* p_core_init_rsp_params) {
481 const char* func = "NfcAdaptation::HalCoreInitialized";
482 ALOGD("%s", func);
483 hidl_vec<uint8_t> data;
484 data.setToExternal(p_core_init_rsp_params, data_len);
485
486 mHal->coreInitialized(data);
487 }
488
489 /*******************************************************************************
490 **
491 ** Function: NfcAdaptation::HalPrediscover
492 **
493 ** Description: Perform any vendor-specific pre-discovery actions (if
494 ** needed) If any actions were performed TRUE will be returned,
495 ** and HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
496 ** completed.
497 **
498 ** Returns: TRUE if vendor-specific pre-discovery actions initialized
499 ** FALSE if no vendor-specific pre-discovery actions are
500 ** needed.
501 **
502 *******************************************************************************/
HalPrediscover()503 bool NfcAdaptation::HalPrediscover() {
504 const char* func = "NfcAdaptation::HalPrediscover";
505 ALOGD("%s", func);
506 bool retval = FALSE;
507 mHal->prediscover();
508 return retval;
509 }
510
511 /*******************************************************************************
512 **
513 ** Function: HAL_NfcControlGranted
514 **
515 ** Description: Grant control to HAL control for sending NCI commands.
516 ** Call in response to HAL_REQUEST_CONTROL_EVT.
517 ** Must only be called when there are no NCI commands pending.
518 ** HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
519 ** needs control of NCI.
520 **
521 ** Returns: void
522 **
523 *******************************************************************************/
HalControlGranted()524 void NfcAdaptation::HalControlGranted() {
525 const char* func = "NfcAdaptation::HalControlGranted";
526 ALOGD("%s", func);
527 mHal->controlGranted();
528 }
529
530 /*******************************************************************************
531 **
532 ** Function: NfcAdaptation::HalPowerCycle
533 **
534 ** Description: Turn off and turn on the controller.
535 **
536 ** Returns: None.
537 **
538 *******************************************************************************/
HalPowerCycle()539 void NfcAdaptation::HalPowerCycle() {
540 const char* func = "NfcAdaptation::HalPowerCycle";
541 ALOGD("%s", func);
542 mHal->powerCycle();
543 }
544
545 /*******************************************************************************
546 **
547 ** Function: NfcAdaptation::HalGetMaxNfcee
548 **
549 ** Description: Turn off and turn on the controller.
550 **
551 ** Returns: None.
552 **
553 *******************************************************************************/
HalGetMaxNfcee()554 uint8_t NfcAdaptation::HalGetMaxNfcee() {
555 const char* func = "NfcAdaptation::HalPowerCycle";
556 uint8_t maxNfcee = 0;
557 ALOGD("%s", func);
558
559 return nfa_ee_max_ee_cfg;
560 }
561
562 /*******************************************************************************
563 **
564 ** Function: NfcAdaptation::DownloadFirmware
565 **
566 ** Description: Download firmware patch files.
567 **
568 ** Returns: None.
569 **
570 *******************************************************************************/
DownloadFirmware()571 void NfcAdaptation::DownloadFirmware() {
572 const char* func = "NfcAdaptation::DownloadFirmware";
573 ALOGD("%s: enter", func);
574 HalInitialize();
575
576 mHalOpenCompletedEvent.lock();
577 ALOGD("%s: try open HAL", func);
578 HalOpen(HalDownloadFirmwareCallback, HalDownloadFirmwareDataCallback);
579 mHalOpenCompletedEvent.wait();
580
581 mHalCloseCompletedEvent.lock();
582 ALOGD("%s: try close HAL", func);
583 HalClose();
584 mHalCloseCompletedEvent.wait();
585
586 HalTerminate();
587 ALOGD("%s: exit", func);
588 }
589
590 /*******************************************************************************
591 **
592 ** Function: NfcAdaptation::HalDownloadFirmwareCallback
593 **
594 ** Description: Receive events from the HAL.
595 **
596 ** Returns: None.
597 **
598 *******************************************************************************/
HalDownloadFirmwareCallback(nfc_event_t event,nfc_status_t event_status)599 void NfcAdaptation::HalDownloadFirmwareCallback(nfc_event_t event,
600 nfc_status_t event_status) {
601 const char* func = "NfcAdaptation::HalDownloadFirmwareCallback";
602 ALOGD("%s: event=0x%X", func, event);
603 switch (event) {
604 case HAL_NFC_OPEN_CPLT_EVT: {
605 ALOGD("%s: HAL_NFC_OPEN_CPLT_EVT", func);
606 mHalOpenCompletedEvent.signal();
607 break;
608 }
609 case HAL_NFC_CLOSE_CPLT_EVT: {
610 ALOGD("%s: HAL_NFC_CLOSE_CPLT_EVT", func);
611 mHalCloseCompletedEvent.signal();
612 break;
613 }
614 }
615 }
616
617 /*******************************************************************************
618 **
619 ** Function: NfcAdaptation::HalDownloadFirmwareDataCallback
620 **
621 ** Description: Receive data events from the HAL.
622 **
623 ** Returns: None.
624 **
625 *******************************************************************************/
HalDownloadFirmwareDataCallback(uint16_t data_len,uint8_t * p_data)626 void NfcAdaptation::HalDownloadFirmwareDataCallback(uint16_t data_len,
627 uint8_t* p_data) {}
628
629 /*******************************************************************************
630 **
631 ** Function: ThreadMutex::ThreadMutex()
632 **
633 ** Description: class constructor
634 **
635 ** Returns: none
636 **
637 *******************************************************************************/
ThreadMutex()638 ThreadMutex::ThreadMutex() {
639 pthread_mutexattr_t mutexAttr;
640
641 pthread_mutexattr_init(&mutexAttr);
642 pthread_mutex_init(&mMutex, &mutexAttr);
643 pthread_mutexattr_destroy(&mutexAttr);
644 }
645
646 /*******************************************************************************
647 **
648 ** Function: ThreadMutex::~ThreadMutex()
649 **
650 ** Description: class destructor
651 **
652 ** Returns: none
653 **
654 *******************************************************************************/
~ThreadMutex()655 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
656
657 /*******************************************************************************
658 **
659 ** Function: ThreadMutex::lock()
660 **
661 ** Description: lock kthe mutex
662 **
663 ** Returns: none
664 **
665 *******************************************************************************/
lock()666 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
667
668 /*******************************************************************************
669 **
670 ** Function: ThreadMutex::unblock()
671 **
672 ** Description: unlock the mutex
673 **
674 ** Returns: none
675 **
676 *******************************************************************************/
unlock()677 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
678
679 /*******************************************************************************
680 **
681 ** Function: ThreadCondVar::ThreadCondVar()
682 **
683 ** Description: class constructor
684 **
685 ** Returns: none
686 **
687 *******************************************************************************/
ThreadCondVar()688 ThreadCondVar::ThreadCondVar() {
689 pthread_condattr_t CondAttr;
690
691 pthread_condattr_init(&CondAttr);
692 pthread_cond_init(&mCondVar, &CondAttr);
693
694 pthread_condattr_destroy(&CondAttr);
695 }
696
697 /*******************************************************************************
698 **
699 ** Function: ThreadCondVar::~ThreadCondVar()
700 **
701 ** Description: class destructor
702 **
703 ** Returns: none
704 **
705 *******************************************************************************/
~ThreadCondVar()706 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
707
708 /*******************************************************************************
709 **
710 ** Function: ThreadCondVar::wait()
711 **
712 ** Description: wait on the mCondVar
713 **
714 ** Returns: none
715 **
716 *******************************************************************************/
wait()717 void ThreadCondVar::wait() {
718 pthread_cond_wait(&mCondVar, *this);
719 pthread_mutex_unlock(*this);
720 }
721
722 /*******************************************************************************
723 **
724 ** Function: ThreadCondVar::signal()
725 **
726 ** Description: signal the mCondVar
727 **
728 ** Returns: none
729 **
730 *******************************************************************************/
signal()731 void ThreadCondVar::signal() {
732 AutoThreadMutex a(*this);
733 pthread_cond_signal(&mCondVar);
734 }
735
736 /*******************************************************************************
737 **
738 ** Function: AutoThreadMutex::AutoThreadMutex()
739 **
740 ** Description: class constructor, automatically lock the mutex
741 **
742 ** Returns: none
743 **
744 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)745 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
746
747 /*******************************************************************************
748 **
749 ** Function: AutoThreadMutex::~AutoThreadMutex()
750 **
751 ** Description: class destructor, automatically unlock the mutex
752 **
753 ** Returns: none
754 **
755 *******************************************************************************/
~AutoThreadMutex()756 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
757