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 "NfcAdaptation.h"
19 
20 #include <aidl/android/hardware/nfc/BnNfc.h>
21 #include <aidl/android/hardware/nfc/BnNfcClientCallback.h>
22 #include <aidl/android/hardware/nfc/INfc.h>
23 #include <android-base/logging.h>
24 #include <android-base/properties.h>
25 #include <android-base/stringprintf.h>
26 #include <android/binder_ibinder.h>
27 #include <android/binder_manager.h>
28 #include <android/binder_process.h>
29 #include <android/hardware/nfc/1.1/INfc.h>
30 #include <android/hardware/nfc/1.2/INfc.h>
31 #include <cutils/properties.h>
32 #include <hwbinder/ProcessState.h>
33 
34 #include "debug_nfcsnoop.h"
35 #include "nfa_api.h"
36 #include "nfa_rw_api.h"
37 #include "nfc_config.h"
38 #include "nfc_int.h"
39 
40 using ::android::wp;
41 using ::android::hardware::hidl_death_recipient;
42 using ::android::hidl::base::V1_0::IBase;
43 
44 using android::OK;
45 using android::sp;
46 using android::status_t;
47 
48 using android::base::StringPrintf;
49 using android::hardware::ProcessState;
50 using android::hardware::Return;
51 using android::hardware::Void;
52 using android::hardware::nfc::V1_0::INfc;
53 using android::hardware::nfc::V1_1::PresenceCheckAlgorithm;
54 using INfcV1_1 = android::hardware::nfc::V1_1::INfc;
55 using INfcV1_2 = android::hardware::nfc::V1_2::INfc;
56 using NfcVendorConfigV1_1 = android::hardware::nfc::V1_1::NfcConfig;
57 using NfcVendorConfigV1_2 = android::hardware::nfc::V1_2::NfcConfig;
58 using android::hardware::nfc::V1_1::INfcClientCallback;
59 using android::hardware::hidl_vec;
60 using INfcAidl = ::aidl::android::hardware::nfc::INfc;
61 using NfcAidlConfig = ::aidl::android::hardware::nfc::NfcConfig;
62 using AidlPresenceCheckAlgorithm =
63     ::aidl::android::hardware::nfc::PresenceCheckAlgorithm;
64 using INfcAidlClientCallback =
65     ::aidl::android::hardware::nfc::INfcClientCallback;
66 using NfcAidlEvent = ::aidl::android::hardware::nfc::NfcEvent;
67 using NfcAidlStatus = ::aidl::android::hardware::nfc::NfcStatus;
68 using ::aidl::android::hardware::nfc::NfcCloseType;
69 using Status = ::ndk::ScopedAStatus;
70 
71 #define VERBOSE_VENDOR_LOG_PROPERTY "persist.nfc.vendor_debug_enabled"
72 
73 std::string NFC_AIDL_HAL_SERVICE_NAME = "android.hardware.nfc.INfc/default";
74 
75 extern void GKI_shutdown();
76 extern void verify_stack_non_volatile_store();
77 extern void delete_stack_non_volatile_store(bool forceDelete);
78 
79 NfcAdaptation* NfcAdaptation::mpInstance = nullptr;
80 ThreadMutex NfcAdaptation::sLock;
81 ThreadCondVar NfcAdaptation::mHalOpenCompletedEvent;
82 ThreadCondVar NfcAdaptation::mHalCloseCompletedEvent;
83 sp<INfc> NfcAdaptation::mHal;
84 sp<INfcV1_1> NfcAdaptation::mHal_1_1;
85 sp<INfcV1_2> NfcAdaptation::mHal_1_2;
86 INfcClientCallback* NfcAdaptation::mCallback;
87 std::shared_ptr<INfcAidlClientCallback> mAidlCallback;
88 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
89 std::shared_ptr<INfcAidl> mAidlHal;
90 
91 bool nfc_nci_reset_keep_cfg_enabled = false;
92 uint8_t nfc_nci_reset_type = 0x00;
93 std::string nfc_storage_path;
94 uint8_t appl_dta_mode_flag = 0x00;
95 bool isDownloadFirmwareCompleted = false;
96 bool use_aidl = false;
97 uint8_t mute_tech_route_option = 0x00;
98 
99 extern tNFA_DM_CFG nfa_dm_cfg;
100 extern tNFA_PROPRIETARY_CFG nfa_proprietary_cfg;
101 extern tNFA_HCI_CFG nfa_hci_cfg;
102 extern uint8_t nfa_ee_max_ee_cfg;
103 extern bool nfa_poll_bail_out_mode;
104 
105 // Whitelist for hosts allowed to create a pipe
106 // See ADM_CREATE_PIPE command in the ETSI test specification
107 // ETSI TS 102 622, section 6.1.3.1
108 static std::vector<uint8_t> host_allowlist;
109 
110 namespace {
initializeGlobalDebugEnabledFlag()111 void initializeGlobalDebugEnabledFlag() {
112   bool nfc_debug_enabled =
113       (NfcConfig::getUnsigned(NAME_NFC_DEBUG_ENABLED, 0) != 0) ||
114       property_get_bool("persist.nfc.debug_enabled", true);
115 
116   android::base::SetMinimumLogSeverity(nfc_debug_enabled ? android::base::DEBUG
117                                                          : android::base::INFO);
118 
119   LOG(VERBOSE) << StringPrintf("%s: level=%u", __func__, nfc_debug_enabled);
120 }
121 
122 // initialize NciResetType Flag
123 // NCI_RESET_TYPE
124 // 0x00 default, reset configurations every time.
125 // 0x01, reset configurations only once every boot.
126 // 0x02, keep configurations.
initializeNciResetTypeFlag()127 void initializeNciResetTypeFlag() {
128   nfc_nci_reset_type = NfcConfig::getUnsigned(NAME_NCI_RESET_TYPE, 0);
129   LOG(VERBOSE) << StringPrintf("%s: nfc_nci_reset_type=%u", __func__,
130                              nfc_nci_reset_type);
131 }
132 
133 // initialize MuteTechRouteOption Flag
134 // MUTE_TECH_ROUTE_OPTION
135 // 0x00: Default. Route mute techs to DH, enable block bit and set power state
136 // to 0x00 0x01: Remove mute techs from rf discover cmd
initializeNfcMuteTechRouteOptionFlag()137 void initializeNfcMuteTechRouteOptionFlag() {
138   mute_tech_route_option =
139       NfcConfig::getUnsigned(NAME_MUTE_TECH_ROUTE_OPTION, 0);
140   LOG(VERBOSE) << StringPrintf("%s: mute_tech_route_option=%u", __func__,
141                                mute_tech_route_option);
142 }
143 
144 // Abort nfc service when AIDL process died.
HalAidlBinderDied(void *)145 void HalAidlBinderDied(void* /* cookie */) {
146   LOG(ERROR) << __func__ << "INfc aidl hal died, exiting procces to restart";
147   exit(0);
148 }
149 
150 }  // namespace
151 
152 class NfcClientCallback : public INfcClientCallback {
153  public:
NfcClientCallback(tHAL_NFC_CBACK * eventCallback,tHAL_NFC_DATA_CBACK dataCallback)154   NfcClientCallback(tHAL_NFC_CBACK* eventCallback,
155                     tHAL_NFC_DATA_CBACK dataCallback) {
156     mEventCallback = eventCallback;
157     mDataCallback = dataCallback;
158   };
159   virtual ~NfcClientCallback() = default;
sendEvent_1_1(::android::hardware::nfc::V1_1::NfcEvent event,::android::hardware::nfc::V1_0::NfcStatus event_status)160   Return<void> sendEvent_1_1(
161       ::android::hardware::nfc::V1_1::NfcEvent event,
162       ::android::hardware::nfc::V1_0::NfcStatus event_status) override {
163     mEventCallback((uint8_t)event, (tHAL_NFC_STATUS)event_status);
164     return Void();
165   };
sendEvent(::android::hardware::nfc::V1_0::NfcEvent event,::android::hardware::nfc::V1_0::NfcStatus event_status)166   Return<void> sendEvent(
167       ::android::hardware::nfc::V1_0::NfcEvent event,
168       ::android::hardware::nfc::V1_0::NfcStatus event_status) override {
169     mEventCallback((uint8_t)event, (tHAL_NFC_STATUS)event_status);
170     return Void();
171   };
sendData(const::android::hardware::nfc::V1_0::NfcData & data)172   Return<void> sendData(
173       const ::android::hardware::nfc::V1_0::NfcData& data) override {
174     ::android::hardware::nfc::V1_0::NfcData copy = data;
175     mDataCallback(copy.size(), &copy[0]);
176     return Void();
177   };
178 
179  private:
180   tHAL_NFC_CBACK* mEventCallback;
181   tHAL_NFC_DATA_CBACK* mDataCallback;
182 };
183 
184 class NfcHalDeathRecipient : public hidl_death_recipient {
185  public:
186   android::sp<android::hardware::nfc::V1_0::INfc> mNfcDeathHal;
NfcHalDeathRecipient(android::sp<android::hardware::nfc::V1_0::INfc> & mHal)187   NfcHalDeathRecipient(android::sp<android::hardware::nfc::V1_0::INfc>& mHal) {
188     mNfcDeathHal = mHal;
189   }
190 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)191   virtual void serviceDied(
192       uint64_t /* cookie */,
193       const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
194     ALOGE(
195         "NfcHalDeathRecipient::serviceDied - Nfc-Hal service died. Killing "
196         "NfcService");
197     if (mNfcDeathHal) {
198       mNfcDeathHal->unlinkToDeath(this);
199     }
200     mNfcDeathHal = NULL;
201     exit(0);
202   }
finalize()203   void finalize() {
204     if (mNfcDeathHal) {
205       mNfcDeathHal->unlinkToDeath(this);
206     } else {
207       LOG(VERBOSE) << StringPrintf("%s: mNfcDeathHal is not set", __func__);
208     }
209 
210     ALOGI("NfcHalDeathRecipient::destructor - NfcService");
211     mNfcDeathHal = NULL;
212   }
213 };
214 
215 class NfcAidlClientCallback
216     : public ::aidl::android::hardware::nfc::BnNfcClientCallback {
217  public:
NfcAidlClientCallback(tHAL_NFC_CBACK * eventCallback,tHAL_NFC_DATA_CBACK dataCallback)218   NfcAidlClientCallback(tHAL_NFC_CBACK* eventCallback,
219                         tHAL_NFC_DATA_CBACK dataCallback) {
220     mEventCallback = eventCallback;
221     mDataCallback = dataCallback;
222   };
223   virtual ~NfcAidlClientCallback() = default;
224 
sendEvent(NfcAidlEvent event,NfcAidlStatus event_status)225   ::ndk::ScopedAStatus sendEvent(NfcAidlEvent event,
226                                  NfcAidlStatus event_status) override {
227     uint8_t e_num;
228     uint8_t s_num;
229     switch (event) {
230       case NfcAidlEvent::OPEN_CPLT:
231         e_num = HAL_NFC_OPEN_CPLT_EVT;
232         break;
233       case NfcAidlEvent::CLOSE_CPLT:
234         e_num = HAL_NFC_CLOSE_CPLT_EVT;
235         break;
236       case NfcAidlEvent::POST_INIT_CPLT:
237         e_num = HAL_NFC_POST_INIT_CPLT_EVT;
238         break;
239       case NfcAidlEvent::PRE_DISCOVER_CPLT:
240         e_num = HAL_NFC_PRE_DISCOVER_CPLT_EVT;
241         break;
242       case NfcAidlEvent::HCI_NETWORK_RESET:
243         e_num = HAL_HCI_NETWORK_RESET;
244         break;
245       case NfcAidlEvent::ERROR:
246       default:
247         e_num = HAL_NFC_ERROR_EVT;
248     }
249     switch (event_status) {
250       case NfcAidlStatus::OK:
251         s_num = HAL_NFC_STATUS_OK;
252         break;
253       case NfcAidlStatus::FAILED:
254         s_num = HAL_NFC_STATUS_FAILED;
255         break;
256       case NfcAidlStatus::ERR_TRANSPORT:
257         s_num = HAL_NFC_STATUS_ERR_TRANSPORT;
258         break;
259       case NfcAidlStatus::ERR_CMD_TIMEOUT:
260         s_num = HAL_NFC_STATUS_ERR_CMD_TIMEOUT;
261         break;
262       case NfcAidlStatus::REFUSED:
263         s_num = HAL_NFC_STATUS_REFUSED;
264         break;
265       default:
266         s_num = HAL_NFC_STATUS_FAILED;
267     }
268     mEventCallback(e_num, (tHAL_NFC_STATUS)s_num);
269     return ::ndk::ScopedAStatus::ok();
270   };
sendData(const std::vector<uint8_t> & data)271   ::ndk::ScopedAStatus sendData(const std::vector<uint8_t>& data) override {
272     std::vector<uint8_t> copy = data;
273     mDataCallback(copy.size(), &copy[0]);
274     return ::ndk::ScopedAStatus::ok();
275   };
276 
277  private:
278   tHAL_NFC_CBACK* mEventCallback;
279   tHAL_NFC_DATA_CBACK* mDataCallback;
280 };
281 
282 /*******************************************************************************
283 **
284 ** Function:    NfcAdaptation::NfcAdaptation()
285 **
286 ** Description: class constructor
287 **
288 ** Returns:     none
289 **
290 *******************************************************************************/
NfcAdaptation()291 NfcAdaptation::NfcAdaptation() {
292   memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
293   mDeathRecipient = ::ndk::ScopedAIBinder_DeathRecipient(
294       AIBinder_DeathRecipient_new(HalAidlBinderDied));
295 }
296 
297 /*******************************************************************************
298 **
299 ** Function:    NfcAdaptation::~NfcAdaptation()
300 **
301 ** Description: class destructor
302 **
303 ** Returns:     none
304 **
305 *******************************************************************************/
~NfcAdaptation()306 NfcAdaptation::~NfcAdaptation() { mpInstance = nullptr; }
307 
308 /*******************************************************************************
309 **
310 ** Function:    NfcAdaptation::GetInstance()
311 **
312 ** Description: access class singleton
313 **
314 ** Returns:     pointer to the singleton object
315 **
316 *******************************************************************************/
GetInstance()317 NfcAdaptation& NfcAdaptation::GetInstance() {
318   AutoThreadMutex a(sLock);
319 
320   if (!mpInstance) {
321     mpInstance = new NfcAdaptation;
322     mpInstance->InitializeHalDeviceContext();
323   }
324   return *mpInstance;
325 }
326 
GetVendorConfigs(std::map<std::string,ConfigValue> & configMap)327 void NfcAdaptation::GetVendorConfigs(
328     std::map<std::string, ConfigValue>& configMap) {
329   NfcVendorConfigV1_2 configValue;
330   NfcAidlConfig aidlConfigValue;
331   if (mAidlHal) {
332     mAidlHal->getConfig(&aidlConfigValue);
333   } else if (mHal_1_2) {
334     mHal_1_2->getConfig_1_2(
335         [&configValue](NfcVendorConfigV1_2 config) { configValue = config; });
336   } else if (mHal_1_1) {
337     mHal_1_1->getConfig([&configValue](NfcVendorConfigV1_1 config) {
338       configValue.v1_1 = config;
339       configValue.defaultIsoDepRoute = 0x00;
340     });
341   }
342 
343   if (mAidlHal) {
344     std::vector<int8_t> nfaPropCfg = {
345         aidlConfigValue.nfaProprietaryCfg.protocol18092Active,
346         aidlConfigValue.nfaProprietaryCfg.protocolBPrime,
347         aidlConfigValue.nfaProprietaryCfg.protocolDual,
348         aidlConfigValue.nfaProprietaryCfg.protocol15693,
349         aidlConfigValue.nfaProprietaryCfg.protocolKovio,
350         aidlConfigValue.nfaProprietaryCfg.protocolMifare,
351         aidlConfigValue.nfaProprietaryCfg.discoveryPollKovio,
352         aidlConfigValue.nfaProprietaryCfg.discoveryPollBPrime,
353         aidlConfigValue.nfaProprietaryCfg.discoveryListenBPrime};
354     configMap.emplace(NAME_NFA_PROPRIETARY_CFG, ConfigValue(nfaPropCfg));
355     configMap.emplace(NAME_NFA_POLL_BAIL_OUT_MODE,
356                       ConfigValue(aidlConfigValue.nfaPollBailOutMode ? 1 : 0));
357     if (aidlConfigValue.offHostRouteUicc.size() != 0) {
358       configMap.emplace(NAME_OFFHOST_ROUTE_UICC,
359                         ConfigValue(aidlConfigValue.offHostRouteUicc));
360     }
361     if (aidlConfigValue.offHostRouteEse.size() != 0) {
362       configMap.emplace(NAME_OFFHOST_ROUTE_ESE,
363                         ConfigValue(aidlConfigValue.offHostRouteEse));
364     }
365     // AIDL byte would be int8_t in C++.
366     // Here we force cast int8_t to uint8_t for ConfigValue
367     configMap.emplace(
368         NAME_DEFAULT_OFFHOST_ROUTE,
369         ConfigValue((uint8_t)aidlConfigValue.defaultOffHostRoute));
370     configMap.emplace(NAME_DEFAULT_ROUTE,
371                       ConfigValue((uint8_t)aidlConfigValue.defaultRoute));
372     configMap.emplace(
373         NAME_DEFAULT_NFCF_ROUTE,
374         ConfigValue((uint8_t)aidlConfigValue.defaultOffHostRouteFelica));
375     configMap.emplace(NAME_DEFAULT_ISODEP_ROUTE,
376                       ConfigValue((uint8_t)aidlConfigValue.defaultIsoDepRoute));
377     configMap.emplace(
378         NAME_DEFAULT_SYS_CODE_ROUTE,
379         ConfigValue((uint8_t)aidlConfigValue.defaultSystemCodeRoute));
380     configMap.emplace(
381         NAME_DEFAULT_SYS_CODE_PWR_STATE,
382         ConfigValue((uint8_t)aidlConfigValue.defaultSystemCodePowerState));
383     configMap.emplace(NAME_OFF_HOST_SIM_PIPE_ID,
384                       ConfigValue((uint8_t)aidlConfigValue.offHostSIMPipeId));
385     configMap.emplace(NAME_OFF_HOST_ESE_PIPE_ID,
386                       ConfigValue((uint8_t)aidlConfigValue.offHostESEPipeId));
387 
388     configMap.emplace(NAME_ISO_DEP_MAX_TRANSCEIVE,
389                       ConfigValue(aidlConfigValue.maxIsoDepTransceiveLength));
390     if (aidlConfigValue.hostAllowlist.size() != 0) {
391       configMap.emplace(NAME_DEVICE_HOST_ALLOW_LIST,
392                         ConfigValue(aidlConfigValue.hostAllowlist));
393     }
394     /* For Backwards compatibility */
395     if (aidlConfigValue.presenceCheckAlgorithm ==
396         AidlPresenceCheckAlgorithm::ISO_DEP_NAK) {
397       configMap.emplace(NAME_PRESENCE_CHECK_ALGORITHM,
398                         ConfigValue((uint32_t)NFA_RW_PRES_CHK_ISO_DEP_NAK));
399     } else {
400       configMap.emplace(
401           NAME_PRESENCE_CHECK_ALGORITHM,
402           ConfigValue((uint32_t)aidlConfigValue.presenceCheckAlgorithm));
403     }
404   } else if (mHal_1_1 || mHal_1_2) {
405     std::vector<uint8_t> nfaPropCfg = {
406         configValue.v1_1.nfaProprietaryCfg.protocol18092Active,
407         configValue.v1_1.nfaProprietaryCfg.protocolBPrime,
408         configValue.v1_1.nfaProprietaryCfg.protocolDual,
409         configValue.v1_1.nfaProprietaryCfg.protocol15693,
410         configValue.v1_1.nfaProprietaryCfg.protocolKovio,
411         configValue.v1_1.nfaProprietaryCfg.protocolMifare,
412         configValue.v1_1.nfaProprietaryCfg.discoveryPollKovio,
413         configValue.v1_1.nfaProprietaryCfg.discoveryPollBPrime,
414         configValue.v1_1.nfaProprietaryCfg.discoveryListenBPrime};
415     configMap.emplace(NAME_NFA_PROPRIETARY_CFG, ConfigValue(nfaPropCfg));
416     configMap.emplace(NAME_NFA_POLL_BAIL_OUT_MODE,
417                       ConfigValue(configValue.v1_1.nfaPollBailOutMode ? 1 : 0));
418     configMap.emplace(NAME_DEFAULT_OFFHOST_ROUTE,
419                       ConfigValue(configValue.v1_1.defaultOffHostRoute));
420     if (configValue.offHostRouteUicc.size() != 0) {
421       configMap.emplace(NAME_OFFHOST_ROUTE_UICC,
422                         ConfigValue(configValue.offHostRouteUicc));
423     }
424     if (configValue.offHostRouteEse.size() != 0) {
425       configMap.emplace(NAME_OFFHOST_ROUTE_ESE,
426                         ConfigValue(configValue.offHostRouteEse));
427     }
428     configMap.emplace(NAME_DEFAULT_ROUTE,
429                       ConfigValue(configValue.v1_1.defaultRoute));
430     configMap.emplace(NAME_DEFAULT_NFCF_ROUTE,
431                       ConfigValue(configValue.v1_1.defaultOffHostRouteFelica));
432     configMap.emplace(NAME_DEFAULT_ISODEP_ROUTE,
433                       ConfigValue(configValue.defaultIsoDepRoute));
434     configMap.emplace(NAME_DEFAULT_SYS_CODE_ROUTE,
435                       ConfigValue(configValue.v1_1.defaultSystemCodeRoute));
436     configMap.emplace(
437         NAME_DEFAULT_SYS_CODE_PWR_STATE,
438         ConfigValue(configValue.v1_1.defaultSystemCodePowerState));
439     configMap.emplace(NAME_OFF_HOST_SIM_PIPE_ID,
440                       ConfigValue(configValue.v1_1.offHostSIMPipeId));
441     configMap.emplace(NAME_OFF_HOST_ESE_PIPE_ID,
442                       ConfigValue(configValue.v1_1.offHostESEPipeId));
443     configMap.emplace(NAME_ISO_DEP_MAX_TRANSCEIVE,
444                       ConfigValue(configValue.v1_1.maxIsoDepTransceiveLength));
445     if (configValue.v1_1.hostWhitelist.size() != 0) {
446       configMap.emplace(NAME_DEVICE_HOST_ALLOW_LIST,
447                         ConfigValue(configValue.v1_1.hostWhitelist));
448     }
449     /* For Backwards compatibility */
450     if (configValue.v1_1.presenceCheckAlgorithm ==
451         PresenceCheckAlgorithm::ISO_DEP_NAK) {
452       configMap.emplace(NAME_PRESENCE_CHECK_ALGORITHM,
453                         ConfigValue((uint32_t)NFA_RW_PRES_CHK_ISO_DEP_NAK));
454     } else {
455       configMap.emplace(
456           NAME_PRESENCE_CHECK_ALGORITHM,
457           ConfigValue((uint32_t)configValue.v1_1.presenceCheckAlgorithm));
458     }
459   }
460 }
461 /*******************************************************************************
462 **
463 ** Function:    NfcAdaptation::Initialize()
464 **
465 ** Description: class initializer
466 **
467 ** Returns:     none
468 **
469 *******************************************************************************/
Initialize()470 void NfcAdaptation::Initialize() {
471   const char* func = "NfcAdaptation::Initialize";
472   // Init log tag
473   android::base::InitLogging(nullptr);
474   android::base::SetDefaultTag("libnfc_nci");
475 
476   initializeGlobalDebugEnabledFlag();
477   initializeNciResetTypeFlag();
478   initializeNfcMuteTechRouteOptionFlag();
479 
480   LOG(VERBOSE) << StringPrintf("%s: enter", func);
481 
482   nfc_storage_path = NfcConfig::getString(NAME_NFA_STORAGE, "/data/nfc");
483 
484   if (NfcConfig::hasKey(NAME_NFA_DM_CFG)) {
485     std::vector<uint8_t> dm_config = NfcConfig::getBytes(NAME_NFA_DM_CFG);
486     if (dm_config.size() > 0) nfa_dm_cfg.auto_detect_ndef = dm_config[0];
487     if (dm_config.size() > 1) nfa_dm_cfg.auto_read_ndef = dm_config[1];
488     if (dm_config.size() > 2) nfa_dm_cfg.auto_presence_check = dm_config[2];
489     if (dm_config.size() > 3) nfa_dm_cfg.presence_check_option = dm_config[3];
490     // NOTE: The timeout value is not configurable here because the endianness
491     // of a byte array is ambiguous and needlessly difficult to configure.
492     // If this value needs to be configurable, a numeric config option should
493     // be used.
494   }
495 
496   if (NfcConfig::hasKey(NAME_NFA_MAX_EE_SUPPORTED)) {
497     nfa_ee_max_ee_cfg = NfcConfig::getUnsigned(NAME_NFA_MAX_EE_SUPPORTED);
498     LOG(VERBOSE) << StringPrintf(
499         "%s: Overriding NFA_EE_MAX_EE_SUPPORTED to use %d", func,
500         nfa_ee_max_ee_cfg);
501   }
502 
503   if (NfcConfig::hasKey(NAME_NFA_POLL_BAIL_OUT_MODE)) {
504     nfa_poll_bail_out_mode =
505         NfcConfig::getUnsigned(NAME_NFA_POLL_BAIL_OUT_MODE);
506     LOG(VERBOSE) << StringPrintf(
507         "%s: Overriding NFA_POLL_BAIL_OUT_MODE to use %d", func,
508         nfa_poll_bail_out_mode);
509   }
510 
511   if (NfcConfig::hasKey(NAME_NFA_PROPRIETARY_CFG)) {
512     std::vector<uint8_t> p_config =
513         NfcConfig::getBytes(NAME_NFA_PROPRIETARY_CFG);
514     if (p_config.size() > 0)
515       nfa_proprietary_cfg.pro_protocol_18092_active = p_config[0];
516     if (p_config.size() > 1)
517       nfa_proprietary_cfg.pro_protocol_b_prime = p_config[1];
518     if (p_config.size() > 2)
519       nfa_proprietary_cfg.pro_protocol_dual = p_config[2];
520     if (p_config.size() > 3)
521       nfa_proprietary_cfg.pro_protocol_15693 = p_config[3];
522     if (p_config.size() > 4)
523       nfa_proprietary_cfg.pro_protocol_kovio = p_config[4];
524     if (p_config.size() > 5) nfa_proprietary_cfg.pro_protocol_mfc = p_config[5];
525     if (p_config.size() > 6)
526       nfa_proprietary_cfg.pro_discovery_kovio_poll = p_config[6];
527     if (p_config.size() > 7)
528       nfa_proprietary_cfg.pro_discovery_b_prime_poll = p_config[7];
529     if (p_config.size() > 8)
530       nfa_proprietary_cfg.pro_discovery_b_prime_listen = p_config[8];
531   }
532 
533   // Configure allowlist of HCI host ID's
534   // See specification: ETSI TS 102 622, section 6.1.3.1
535   if (NfcConfig::hasKey(NAME_DEVICE_HOST_ALLOW_LIST)) {
536     host_allowlist = NfcConfig::getBytes(NAME_DEVICE_HOST_ALLOW_LIST);
537     nfa_hci_cfg.num_allowlist_host = host_allowlist.size();
538     nfa_hci_cfg.p_allowlist = &host_allowlist[0];
539   }
540 
541   verify_stack_non_volatile_store();
542   if (NfcConfig::hasKey(NAME_PRESERVE_STORAGE) &&
543       NfcConfig::getUnsigned(NAME_PRESERVE_STORAGE) == 1) {
544     LOG(VERBOSE) << StringPrintf("%s: preserve stack NV store", __func__);
545   } else {
546     delete_stack_non_volatile_store(FALSE);
547   }
548 
549   GKI_init();
550   GKI_enable();
551   GKI_create_task((TASKPTR)NFCA_TASK, BTU_TASK, (int8_t*)"NFCA_TASK", nullptr, 0,
552                   (pthread_cond_t*)nullptr, nullptr);
553   {
554     AutoThreadMutex guard(mCondVar);
555     GKI_create_task((TASKPTR)Thread, MMI_TASK, (int8_t*)"NFCA_THREAD", nullptr, 0,
556                     (pthread_cond_t*)nullptr, nullptr);
557     mCondVar.wait();
558   }
559 
560   debug_nfcsnoop_init();
561   LOG(VERBOSE) << StringPrintf("%s: exit", func);
562 }
563 
564 /*******************************************************************************
565 **
566 ** Function:    NfcAdaptation::Finalize()
567 **
568 ** Description: class finalizer
569 **
570 ** Returns:     none
571 **
572 *******************************************************************************/
Finalize()573 void NfcAdaptation::Finalize() {
574   const char* func = "NfcAdaptation::Finalize";
575   AutoThreadMutex a(sLock);
576 
577   LOG(VERBOSE) << StringPrintf("%s: enter", func);
578   GKI_shutdown();
579 
580   NfcConfig::clear();
581 
582   if (mAidlHal != nullptr) {
583     AIBinder_unlinkToDeath(mAidlHal->asBinder().get(), mDeathRecipient.get(),
584                            nullptr);
585   } else if (mHal != nullptr) {
586     mNfcHalDeathRecipient->finalize();
587   }
588   LOG(VERBOSE) << StringPrintf("%s: exit", func);
589   delete this;
590 }
591 
FactoryReset()592 void NfcAdaptation::FactoryReset() {
593   if (mAidlHal != nullptr) {
594     mAidlHal->factoryReset();
595   } else if (mHal_1_2 != nullptr) {
596     mHal_1_2->factoryReset();
597   } else if (mHal_1_1 != nullptr) {
598     mHal_1_1->factoryReset();
599   }
600 }
601 
DeviceShutdown()602 void NfcAdaptation::DeviceShutdown() {
603   if (mAidlHal != nullptr) {
604     mAidlHal->close(NfcCloseType::HOST_SWITCHED_OFF);
605     AIBinder_unlinkToDeath(mAidlHal->asBinder().get(), mDeathRecipient.get(),
606                            nullptr);
607     mAidlHal = nullptr;
608   } else {
609     if (mHal_1_2 != nullptr) {
610       mHal_1_2->closeForPowerOffCase();
611     } else if (mHal_1_1 != nullptr) {
612       mHal_1_1->closeForPowerOffCase();
613     }
614     if (mHal != nullptr) {
615       mHal->unlinkToDeath(mNfcHalDeathRecipient);
616     }
617   }
618 }
619 
620 /*******************************************************************************
621 **
622 ** Function:    NfcAdaptation::Dump
623 **
624 ** Description: Native support for dumpsys function.
625 **
626 ** Returns:     None.
627 **
628 *******************************************************************************/
Dump(int fd)629 void NfcAdaptation::Dump(int fd) { debug_nfcsnoop_dump(fd); }
630 
631 /*******************************************************************************
632 **
633 ** Function:    NfcAdaptation::signal()
634 **
635 ** Description: signal the CondVar to release the thread that is waiting
636 **
637 ** Returns:     none
638 **
639 *******************************************************************************/
signal()640 void NfcAdaptation::signal() { mCondVar.signal(); }
641 
642 /*******************************************************************************
643 **
644 ** Function:    NfcAdaptation::NFCA_TASK()
645 **
646 ** Description: NFCA_TASK runs the GKI main task
647 **
648 ** Returns:     none
649 **
650 *******************************************************************************/
NFCA_TASK(uint32_t arg)651 uint32_t NfcAdaptation::NFCA_TASK(__attribute__((unused)) uint32_t arg) {
652   const char* func = "NfcAdaptation::NFCA_TASK";
653   LOG(VERBOSE) << StringPrintf("%s: enter", func);
654   GKI_run(nullptr);
655   LOG(VERBOSE) << StringPrintf("%s: exit", func);
656   return 0;
657 }
658 
659 /*******************************************************************************
660 **
661 ** Function:    NfcAdaptation::Thread()
662 **
663 ** Description: Creates work threads
664 **
665 ** Returns:     none
666 **
667 *******************************************************************************/
Thread(uint32_t arg)668 uint32_t NfcAdaptation::Thread(__attribute__((unused)) uint32_t arg) {
669   const char* func = "NfcAdaptation::Thread";
670   LOG(VERBOSE) << StringPrintf("%s: enter", func);
671 
672   {
673     ThreadCondVar CondVar;
674     AutoThreadMutex guard(CondVar);
675     GKI_create_task((TASKPTR)nfc_task, NFC_TASK, (int8_t*)"NFC_TASK", nullptr, 0,
676                     (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar);
677     CondVar.wait();
678   }
679 
680   NfcAdaptation::GetInstance().signal();
681 
682   GKI_exit_task(GKI_get_taskid());
683   LOG(VERBOSE) << StringPrintf("%s: exit", func);
684   return 0;
685 }
686 
687 /*******************************************************************************
688 **
689 ** Function:    NfcAdaptation::GetHalEntryFuncs()
690 **
691 ** Description: Get the set of HAL entry points.
692 **
693 ** Returns:     Functions pointers for HAL entry points.
694 **
695 *******************************************************************************/
GetHalEntryFuncs()696 tHAL_NFC_ENTRY* NfcAdaptation::GetHalEntryFuncs() { return &mHalEntryFuncs; }
697 
698 /*******************************************************************************
699 **
700 ** Function:    NfcAdaptation::InitializeHalDeviceContext
701 **
702 ** Description: Check validity of current handle to the nfc HAL service
703 **
704 ** Returns:     None.
705 **
706 *******************************************************************************/
InitializeHalDeviceContext()707 void NfcAdaptation::InitializeHalDeviceContext() {
708   const char* func = "NfcAdaptation::InitializeHalDeviceContext";
709 
710   mHalEntryFuncs.initialize = HalInitialize;
711   mHalEntryFuncs.terminate = HalTerminate;
712   mHalEntryFuncs.open = HalOpen;
713   mHalEntryFuncs.close = HalClose;
714   mHalEntryFuncs.core_initialized = HalCoreInitialized;
715   mHalEntryFuncs.write = HalWrite;
716   mHalEntryFuncs.prediscover = HalPrediscover;
717   mHalEntryFuncs.control_granted = HalControlGranted;
718   mHalEntryFuncs.power_cycle = HalPowerCycle;
719   mHalEntryFuncs.get_max_ee = HalGetMaxNfcee;
720   LOG(INFO) << StringPrintf("%s: INfc::getService()", func);
721   mAidlHal = nullptr;
722   mHal = mHal_1_1 = mHal_1_2 = nullptr;
723   if (!use_aidl) {
724     mHal = mHal_1_1 = mHal_1_2 = INfcV1_2::getService();
725   }
726   if (!use_aidl && mHal_1_2 == nullptr) {
727     mHal = mHal_1_1 = INfcV1_1::getService();
728     if (mHal_1_1 == nullptr) {
729       mHal = INfc::getService();
730     }
731   }
732   if (mHal == nullptr) {
733     // Try get AIDL
734     ::ndk::SpAIBinder binder(
735         AServiceManager_waitForService(NFC_AIDL_HAL_SERVICE_NAME.c_str()));
736     mAidlHal = INfcAidl::fromBinder(binder);
737     if (mAidlHal != nullptr) {
738       use_aidl = true;
739       AIBinder_linkToDeath(mAidlHal->asBinder().get(), mDeathRecipient.get(),
740                            nullptr /* cookie */);
741       mHal = mHal_1_1 = mHal_1_2 = nullptr;
742       LOG(INFO) << StringPrintf("%s: INfcAidl::fromBinder returned", func);
743     }
744     LOG_ALWAYS_FATAL_IF(mAidlHal == nullptr,
745                         "Failed to retrieve the NFC AIDL!");
746   } else {
747     LOG(INFO) << StringPrintf("%s: INfc::getService() returned %p (%s)", func,
748                               mHal.get(),
749                               (mHal->isRemote() ? "remote" : "local"));
750     mNfcHalDeathRecipient = new NfcHalDeathRecipient(mHal);
751     mHal->linkToDeath(mNfcHalDeathRecipient, 0);
752   }
753 }
754 
755 /*******************************************************************************
756 **
757 ** Function:    NfcAdaptation::HalInitialize
758 **
759 ** Description: Not implemented because this function is only needed
760 **              within the HAL.
761 **
762 ** Returns:     None.
763 **
764 *******************************************************************************/
HalInitialize()765 void NfcAdaptation::HalInitialize() {
766   const char* func = "NfcAdaptation::HalInitialize";
767   LOG(VERBOSE) << StringPrintf("%s", func);
768 }
769 
770 /*******************************************************************************
771 **
772 ** Function:    NfcAdaptation::HalTerminate
773 **
774 ** Description: Not implemented because this function is only needed
775 **              within the HAL.
776 **
777 ** Returns:     None.
778 **
779 *******************************************************************************/
HalTerminate()780 void NfcAdaptation::HalTerminate() {
781   const char* func = "NfcAdaptation::HalTerminate";
782   LOG(VERBOSE) << StringPrintf("%s", func);
783 }
784 
785 /*******************************************************************************
786 **
787 ** Function:    NfcAdaptation::HalOpen
788 **
789 ** Description: Turn on controller, download firmware.
790 **
791 ** Returns:     None.
792 **
793 *******************************************************************************/
HalOpen(tHAL_NFC_CBACK * p_hal_cback,tHAL_NFC_DATA_CBACK * p_data_cback)794 void NfcAdaptation::HalOpen(tHAL_NFC_CBACK* p_hal_cback,
795                             tHAL_NFC_DATA_CBACK* p_data_cback) {
796   const char* func = "NfcAdaptation::HalOpen";
797   LOG(VERBOSE) << StringPrintf("%s", func);
798 
799   if (mAidlHal != nullptr) {
800     mAidlCallback = ::ndk::SharedRefBase::make<NfcAidlClientCallback>(
801         p_hal_cback, p_data_cback);
802     Status status = mAidlHal->open(mAidlCallback);
803     if (!status.isOk()) {
804       LOG(ERROR) << "Open Error: "
805                  << ::aidl::android::hardware::nfc::toString(
806                         static_cast<NfcAidlStatus>(
807                             status.getServiceSpecificError()));
808     } else {
809       bool verbose_vendor_log =
810           android::base::GetBoolProperty(VERBOSE_VENDOR_LOG_PROPERTY, false);
811       mAidlHal->setEnableVerboseLogging(verbose_vendor_log);
812       LOG(VERBOSE) << StringPrintf("%s: verbose_vendor_log=%u", __func__,
813                                  verbose_vendor_log);
814     }
815   } else if (mHal_1_1 != nullptr) {
816     mCallback = new NfcClientCallback(p_hal_cback, p_data_cback);
817     mHal_1_1->open_1_1(mCallback);
818   } else if (mHal != nullptr) {
819     mCallback = new NfcClientCallback(p_hal_cback, p_data_cback);
820     mHal->open(mCallback);
821   }
822 }
823 
824 /*******************************************************************************
825 **
826 ** Function:    NfcAdaptation::HalClose
827 **
828 ** Description: Turn off controller.
829 **
830 ** Returns:     None.
831 **
832 *******************************************************************************/
HalClose()833 void NfcAdaptation::HalClose() {
834   const char* func = "NfcAdaptation::HalClose";
835   LOG(VERBOSE) << StringPrintf("%s", func);
836   if (mAidlHal != nullptr) {
837     mAidlHal->close(NfcCloseType::DISABLE);
838   } else if (mHal != nullptr) {
839     mHal->close();
840   }
841 }
842 
843 /*******************************************************************************
844 **
845 ** Function:    NfcAdaptation::HalWrite
846 **
847 ** Description: Write NCI message to the controller.
848 **
849 ** Returns:     None.
850 **
851 *******************************************************************************/
HalWrite(uint16_t data_len,uint8_t * p_data)852 void NfcAdaptation::HalWrite(uint16_t data_len, uint8_t* p_data) {
853   const char* func = "NfcAdaptation::HalWrite";
854   LOG(VERBOSE) << StringPrintf("%s", func);
855 
856   if (mAidlHal != nullptr) {
857     int ret;
858     std::vector<uint8_t> aidl_data(p_data, p_data + data_len);
859     mAidlHal->write(aidl_data, &ret);
860   } else if (mHal != nullptr) {
861     ::android::hardware::nfc::V1_0::NfcData data;
862     data.setToExternal(p_data, data_len);
863     mHal->write(data);
864   }
865 }
866 
867 /*******************************************************************************
868 **
869 ** Function:    NfcAdaptation::HalCoreInitialized
870 **
871 ** Description: Adjust the configurable parameters in the controller.
872 **
873 ** Returns:     None.
874 **
875 *******************************************************************************/
HalCoreInitialized(uint16_t data_len,uint8_t * p_core_init_rsp_params)876 void NfcAdaptation::HalCoreInitialized(uint16_t data_len,
877                                        uint8_t* p_core_init_rsp_params) {
878   const char* func = "NfcAdaptation::HalCoreInitialized";
879   LOG(VERBOSE) << StringPrintf("%s", func);
880   if (mAidlHal != nullptr) {
881     // AIDL coreInitialized doesn't send data to HAL.
882     mAidlHal->coreInitialized();
883   } else if (mHal != nullptr) {
884     hidl_vec<uint8_t> data;
885     data.setToExternal(p_core_init_rsp_params, data_len);
886     mHal->coreInitialized(data);
887   }
888 }
889 
890 /*******************************************************************************
891 **
892 ** Function:    NfcAdaptation::HalPrediscover
893 **
894 ** Description:     Perform any vendor-specific pre-discovery actions (if
895 **                  needed) If any actions were performed TRUE will be returned,
896 **                  and HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
897 **                  completed.
898 **
899 ** Returns:         TRUE if vendor-specific pre-discovery actions initialized
900 **                  FALSE if no vendor-specific pre-discovery actions are
901 **                  needed.
902 **
903 *******************************************************************************/
HalPrediscover()904 bool NfcAdaptation::HalPrediscover() {
905   const char* func = "NfcAdaptation::HalPrediscover";
906   LOG(VERBOSE) << StringPrintf("%s", func);
907   if (mAidlHal != nullptr) {
908     Status status = mAidlHal->preDiscover();
909     if (status.isOk()) {
910       LOG(VERBOSE) << StringPrintf("%s wait for NFC_PRE_DISCOVER_CPLT_EVT", func);
911       return true;
912     }
913   } else if (mHal != nullptr) {
914     mHal->prediscover();
915   }
916 
917   return false;
918 }
919 
920 /*******************************************************************************
921 **
922 ** Function:        HAL_NfcControlGranted
923 **
924 ** Description:     Grant control to HAL control for sending NCI commands.
925 **                  Call in response to HAL_REQUEST_CONTROL_EVT.
926 **                  Must only be called when there are no NCI commands pending.
927 **                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
928 **                  needs control of NCI.
929 **
930 ** Returns:         void
931 **
932 *******************************************************************************/
HalControlGranted()933 void NfcAdaptation::HalControlGranted() {
934   const char* func = "NfcAdaptation::HalControlGranted";
935   LOG(VERBOSE) << StringPrintf("%s", func);
936   if (mAidlHal != nullptr) {
937     LOG(ERROR) << StringPrintf("Unsupported function %s", func);
938   } else if (mHal != nullptr) {
939     mHal->controlGranted();
940   }
941 }
942 
943 /*******************************************************************************
944 **
945 ** Function:    NfcAdaptation::HalPowerCycle
946 **
947 ** Description: Turn off and turn on the controller.
948 **
949 ** Returns:     None.
950 **
951 *******************************************************************************/
HalPowerCycle()952 void NfcAdaptation::HalPowerCycle() {
953   const char* func = "NfcAdaptation::HalPowerCycle";
954   LOG(VERBOSE) << StringPrintf("%s", func);
955   if (mAidlHal != nullptr) {
956     mAidlHal->powerCycle();
957   } else if (mHal != nullptr) {
958     mHal->powerCycle();
959   }
960 }
961 
962 /*******************************************************************************
963 **
964 ** Function:    NfcAdaptation::HalGetMaxNfcee
965 **
966 ** Description: Turn off and turn on the controller.
967 **
968 ** Returns:     None.
969 **
970 *******************************************************************************/
HalGetMaxNfcee()971 uint8_t NfcAdaptation::HalGetMaxNfcee() {
972   const char* func = "NfcAdaptation::HalGetMaxNfcee";
973   LOG(VERBOSE) << StringPrintf("%s", func);
974 
975   return nfa_ee_max_ee_cfg;
976 }
977 
978 /*******************************************************************************
979 **
980 ** Function:    NfcAdaptation::DownloadFirmware
981 **
982 ** Description: Download firmware patch files.
983 **
984 ** Returns:     None.
985 **
986 *******************************************************************************/
DownloadFirmware()987 bool NfcAdaptation::DownloadFirmware() {
988   const char* func = "NfcAdaptation::DownloadFirmware";
989   isDownloadFirmwareCompleted = false;
990   LOG(VERBOSE) << StringPrintf("%s: enter", func);
991   HalInitialize();
992 
993   mHalOpenCompletedEvent.lock();
994   LOG(VERBOSE) << StringPrintf("%s: try open HAL", func);
995   HalOpen(HalDownloadFirmwareCallback, HalDownloadFirmwareDataCallback);
996   mHalOpenCompletedEvent.wait();
997 
998   LOG(VERBOSE) << StringPrintf("%s: try close HAL", func);
999   HalClose();
1000 
1001   HalTerminate();
1002   LOG(VERBOSE) << StringPrintf("%s: exit", func);
1003 
1004   return isDownloadFirmwareCompleted;
1005 }
1006 
1007 /*******************************************************************************
1008 **
1009 ** Function:    NfcAdaptation::HalDownloadFirmwareCallback
1010 **
1011 ** Description: Receive events from the HAL.
1012 **
1013 ** Returns:     None.
1014 **
1015 *******************************************************************************/
HalDownloadFirmwareCallback(nfc_event_t event,nfc_status_t event_status)1016 void NfcAdaptation::HalDownloadFirmwareCallback(nfc_event_t event,
1017                                                 __attribute__((unused))
1018                                                 nfc_status_t event_status) {
1019   const char* func = "NfcAdaptation::HalDownloadFirmwareCallback";
1020   LOG(VERBOSE) << StringPrintf("%s: event=0x%X", func, event);
1021   switch (event) {
1022     case HAL_NFC_OPEN_CPLT_EVT: {
1023       LOG(VERBOSE) << StringPrintf("%s: HAL_NFC_OPEN_CPLT_EVT", func);
1024       if (event_status == HAL_NFC_STATUS_OK) isDownloadFirmwareCompleted = true;
1025       mHalOpenCompletedEvent.signal();
1026       break;
1027     }
1028     case HAL_NFC_CLOSE_CPLT_EVT: {
1029       LOG(VERBOSE) << StringPrintf("%s: HAL_NFC_CLOSE_CPLT_EVT", func);
1030       break;
1031     }
1032   }
1033 }
1034 
1035 /*******************************************************************************
1036 **
1037 ** Function:    NfcAdaptation::HalDownloadFirmwareDataCallback
1038 **
1039 ** Description: Receive data events from the HAL.
1040 **
1041 ** Returns:     None.
1042 **
1043 *******************************************************************************/
HalDownloadFirmwareDataCallback(uint16_t data_len,uint8_t * p_data)1044 void NfcAdaptation::HalDownloadFirmwareDataCallback(__attribute__((unused))
1045                                                     uint16_t data_len,
1046                                                     __attribute__((unused))
1047                                                     uint8_t* p_data) {}
1048 
1049 /*******************************************************************************
1050 **
1051 ** Function:    ThreadMutex::ThreadMutex()
1052 **
1053 ** Description: class constructor
1054 **
1055 ** Returns:     none
1056 **
1057 *******************************************************************************/
ThreadMutex()1058 ThreadMutex::ThreadMutex() {
1059   pthread_mutexattr_t mutexAttr;
1060 
1061   pthread_mutexattr_init(&mutexAttr);
1062   pthread_mutex_init(&mMutex, &mutexAttr);
1063   pthread_mutexattr_destroy(&mutexAttr);
1064 }
1065 
1066 /*******************************************************************************
1067 **
1068 ** Function:    ThreadMutex::~ThreadMutex()
1069 **
1070 ** Description: class destructor
1071 **
1072 ** Returns:     none
1073 **
1074 *******************************************************************************/
~ThreadMutex()1075 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
1076 
1077 /*******************************************************************************
1078 **
1079 ** Function:    ThreadMutex::lock()
1080 **
1081 ** Description: lock kthe mutex
1082 **
1083 ** Returns:     none
1084 **
1085 *******************************************************************************/
lock()1086 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
1087 
1088 /*******************************************************************************
1089 **
1090 ** Function:    ThreadMutex::unblock()
1091 **
1092 ** Description: unlock the mutex
1093 **
1094 ** Returns:     none
1095 **
1096 *******************************************************************************/
unlock()1097 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
1098 
1099 /*******************************************************************************
1100 **
1101 ** Function:    ThreadCondVar::ThreadCondVar()
1102 **
1103 ** Description: class constructor
1104 **
1105 ** Returns:     none
1106 **
1107 *******************************************************************************/
ThreadCondVar()1108 ThreadCondVar::ThreadCondVar() {
1109   pthread_condattr_t CondAttr;
1110 
1111   pthread_condattr_init(&CondAttr);
1112   pthread_cond_init(&mCondVar, &CondAttr);
1113 
1114   pthread_condattr_destroy(&CondAttr);
1115 }
1116 
1117 /*******************************************************************************
1118 **
1119 ** Function:    ThreadCondVar::~ThreadCondVar()
1120 **
1121 ** Description: class destructor
1122 **
1123 ** Returns:     none
1124 **
1125 *******************************************************************************/
~ThreadCondVar()1126 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
1127 
1128 /*******************************************************************************
1129 **
1130 ** Function:    ThreadCondVar::wait()
1131 **
1132 ** Description: wait on the mCondVar
1133 **
1134 ** Returns:     none
1135 **
1136 *******************************************************************************/
wait()1137 void ThreadCondVar::wait() {
1138   pthread_cond_wait(&mCondVar, *this);
1139   pthread_mutex_unlock(*this);
1140 }
1141 
1142 /*******************************************************************************
1143 **
1144 ** Function:    ThreadCondVar::signal()
1145 **
1146 ** Description: signal the mCondVar
1147 **
1148 ** Returns:     none
1149 **
1150 *******************************************************************************/
signal()1151 void ThreadCondVar::signal() {
1152   AutoThreadMutex a(*this);
1153   pthread_cond_signal(&mCondVar);
1154 }
1155 
1156 /*******************************************************************************
1157 **
1158 ** Function:    AutoThreadMutex::AutoThreadMutex()
1159 **
1160 ** Description: class constructor, automatically lock the mutex
1161 **
1162 ** Returns:     none
1163 **
1164 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)1165 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
1166 
1167 /*******************************************************************************
1168 **
1169 ** Function:    AutoThreadMutex::~AutoThreadMutex()
1170 **
1171 ** Description: class destructor, automatically unlock the mutex
1172 **
1173 ** Returns:     none
1174 **
1175 *******************************************************************************/
~AutoThreadMutex()1176 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
1177