Home | History | Annotate | Download | only in adaptation
      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"
     20 extern "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 
     31 extern "C" void GKI_shutdown();
     32 extern void resetConfig();
     33 extern "C" void verify_stack_non_volatile_store ();
     34 extern "C" void delete_stack_non_volatile_store (BOOLEAN forceDelete);
     35 
     36 NfcAdaptation* NfcAdaptation::mpInstance = NULL;
     37 ThreadMutex NfcAdaptation::sLock;
     38 nfc_nci_device_t* NfcAdaptation::mHalDeviceContext = NULL;
     39 tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
     40 tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
     41 ThreadCondVar NfcAdaptation::mHalOpenCompletedEvent;
     42 ThreadCondVar NfcAdaptation::mHalCloseCompletedEvent;
     43 
     44 UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
     45 UINT8 appl_trace_level = 0xff;
     46 char bcm_nfc_location[120];
     47 char nci_hal_module[64];
     48 
     49 static UINT8 nfa_dm_cfg[sizeof ( tNFA_DM_CFG ) ];
     50 extern tNFA_DM_CFG *p_nfa_dm_cfg;
     51 extern UINT8 nfa_ee_max_ee_cfg;
     52 extern const UINT8  nfca_version_string [];
     53 extern const UINT8  nfa_version_string [];
     54 static UINT8 deviceHostWhiteList [NFA_HCI_MAX_HOST_IN_NETWORK];
     55 static tNFA_HCI_CFG jni_nfa_hci_cfg;
     56 extern 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 *******************************************************************************/
     67 NfcAdaptation::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 *******************************************************************************/
     81 NfcAdaptation::~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 *******************************************************************************/
     95 NfcAdaptation& 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 *******************************************************************************/
    113 void 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 
    134     initializeProtocolLogLevel ();
    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 *******************************************************************************/
    192 void 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 *******************************************************************************/
    220 void 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 *******************************************************************************/
    234 UINT32 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 *******************************************************************************/
    252 UINT32 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 *******************************************************************************/
    280 tHAL_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 *******************************************************************************/
    294 void 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 *******************************************************************************/
    339 void 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 *******************************************************************************/
    355 void 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 *******************************************************************************/
    370 void 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 *******************************************************************************/
    391 void 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 *******************************************************************************/
    411 void 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 *******************************************************************************/
    429 void 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 *******************************************************************************/
    446 void 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 *******************************************************************************/
    465 void 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 *******************************************************************************/
    488 BOOLEAN 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 *******************************************************************************/
    514 void 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 *******************************************************************************/
    533 void 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 *******************************************************************************/
    552 UINT8 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 *******************************************************************************/
    578 void 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 *******************************************************************************/
    607 void 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 *******************************************************************************/
    637 void 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 *******************************************************************************/
    651 ThreadMutex::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 *******************************************************************************/
    669 ThreadMutex::~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 *******************************************************************************/
    683 void 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 *******************************************************************************/
    697 void 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 *******************************************************************************/
    711 ThreadCondVar::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 *******************************************************************************/
    730 ThreadCondVar::~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 *******************************************************************************/
    744 void 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 *******************************************************************************/
    759 void 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 *******************************************************************************/
    774 AutoThreadMutex::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 *******************************************************************************/
    789 AutoThreadMutex::~AutoThreadMutex()
    790 {
    791     mm.unlock();
    792 }
    793