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