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