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