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