• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "nfc_napi_hce_adapter.h"
17 #include "loghelper.h"
18 #include "hce_service.h"
19 #include <uv.h>
20 #include "iservice_registry.h"
21 #include <thread>
22 
23 namespace OHOS {
24 namespace NFC {
25 namespace KITS {
26 static const uint16_t DEFAULT_REF_COUNT = 1;
27 constexpr uint32_t INVALID_REF_COUNT = 0xFF;
28 constexpr uint32_t TYPE_MAX_LEN = 64;
29 static std::set<std::string> g_supportEventList = {
30     KITS::EVENT_HCE_CMD,
31 };
32 
33 static std::mutex g_regInfoMutex;
34 static std::map<std::string, RegObj> g_eventRegisterInfo;
35 
36 class NapiEvent {
37 public:
38     napi_value CreateResult(const napi_env& env, const std::vector<uint8_t>& data);
39     bool CheckIsRegister(const std::string& type);
40     void EventNotify(AsyncEventData* asyncEvent);
41 
42     template <typename T>
CheckAndNotify(const std::string & type,const T & obj)43     void CheckAndNotify(const std::string& type, const T& obj)
44     {
45         std::lock_guard<std::mutex> guard(g_regInfoMutex);
46         if (!CheckIsRegister(type)) {
47             return;
48         }
49 
50         const RegObj& regObj = g_eventRegisterInfo[type];
51 
52         auto result = [this, env = regObj.m_regEnv, obj]() -> napi_value { return CreateResult(env, obj); };
53         AsyncEventData* asyncEvent =
54             new (std::nothrow) AsyncEventData(regObj.m_regEnv, regObj.m_regHanderRef, result);
55         if (asyncEvent == nullptr) {
56             return;
57         }
58         EventNotify(asyncEvent);
59     }
60 };
61 
62 class HceCmdListenerEvent : public IHceCmdCallback, public NapiEvent {
63 public:
HceCmdListenerEvent()64     HceCmdListenerEvent() {}
65 
~HceCmdListenerEvent()66     virtual ~HceCmdListenerEvent() {}
67 
68 public:
OnCeApduData(const std::vector<uint8_t> & data)69     void OnCeApduData(const std::vector<uint8_t>& data) override
70     {
71         std::string dataStr(data.begin(), data.end());
72         InfoLog("OnNotify rcvd ce adpu data: Data Length = %{public}zu; Data "
73                 "as String = %{public}s",
74                 data.size(), dataStr.c_str());
75         CheckAndNotify(KITS::EVENT_HCE_CMD, data);
76     }
77 
AsObject()78     OHOS::sptr<OHOS::IRemoteObject> AsObject() override { return nullptr; }
79 };
80 
81 sptr<HceCmdListenerEvent> hceCmdListenerEvent = sptr<HceCmdListenerEvent>(new HceCmdListenerEvent());
82 
Init(napi_env env,napi_value exports)83 napi_value NfcNapiHceAdapter::Init(napi_env env, napi_value exports)
84 {
85     napi_status status;
86     napi_property_descriptor properties[] = {
87         DECLARE_NAPI_FUNCTION("on", NfcNapiHceAdapter::OnHceCmd),
88         DECLARE_NAPI_FUNCTION("off", NfcNapiHceAdapter::OffHceCmd),
89         DECLARE_NAPI_FUNCTION("transmit", NfcNapiHceAdapter::Transmit),
90         DECLARE_NAPI_FUNCTION("stop", NfcNapiHceAdapter::StopHce),
91         DECLARE_NAPI_FUNCTION("stopHCE", NfcNapiHceAdapter::StopHCEDeprecated),
92         DECLARE_NAPI_FUNCTION("startHCE", NfcNapiHceAdapter::StartHCEDeprecated),
93         DECLARE_NAPI_FUNCTION("start", NfcNapiHceAdapter::StartHCE),
94         DECLARE_NAPI_FUNCTION("sendResponse", NfcNapiHceAdapter::SendResponse),
95     };
96 
97     char hceClassName[] = "HceService";
98 
99     napi_value cons;
100     status = napi_define_class(env, hceClassName, NAPI_AUTO_LENGTH, NfcNapiHceAdapter::Constructor, nullptr,
101                                sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons);
102     NAPI_ASSERT(env, status == napi_ok, "NfcNapiHceAdapter define class failed");
103 
104     status = napi_set_named_property(env, exports, hceClassName, cons);
105     NAPI_ASSERT(env, status == napi_ok, "NfcNapiHceAdapter set name property failed");
106     return cons;
107 }
108 
Constructor(napi_env env,napi_callback_info info)109 napi_value NfcNapiHceAdapter::Constructor(napi_env env, napi_callback_info info)
110 {
111     DebugLog("NfcNapiHceAdapter Constructor");
112     napi_status status;
113     napi_value jsHceService;
114     size_t argc = 1;
115     napi_value args[1];
116     status = napi_get_cb_info(env, info, &argc, args, &jsHceService, nullptr);
117     NAPI_ASSERT(env, status == napi_ok, "NfcNapiHceAdapter Constructor get_cb_info failed");
118     NfcNapiHceAdapter* hceService = new NfcNapiHceAdapter();
119     status = napi_wrap(env, jsHceService, hceService, NfcNapiHceAdapter::Destructor, nullptr, nullptr);
120     if (status != napi_ok && hceService != nullptr) {
121         ErrorLog("hce Constructor napi_wrap failed");
122         delete hceService;
123         hceService = nullptr;
124         return CreateUndefined(env);
125     }
126     NAPI_ASSERT(env, status == napi_ok, "NfcNapiHceAdapter Constructor wrap failed");
127     return jsHceService;
128 }
129 
Destructor(napi_env env,void * nativeObject,void * hint)130 void NfcNapiHceAdapter::Destructor(napi_env env, void* nativeObject, void* hint)
131 {
132     NfcNapiHceAdapter* nfcNapiHceAdapter = static_cast<NfcNapiHceAdapter*>(nativeObject);
133     nfcNapiHceAdapter->~NfcNapiHceAdapter();
134     delete nfcNapiHceAdapter;
135 }
136 
OnHceCmd(napi_env env,napi_callback_info info)137 napi_value NfcNapiHceAdapter::OnHceCmd(napi_env env, napi_callback_info info)
138 {
139     // js method on("hce",callback)
140     size_t requireArgc = ARGV_NUM_2;
141     size_t argc = ARGV_NUM_2;
142     napi_value argv[ARGV_NUM_2] = {0};
143     napi_value thisVar = 0;
144     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
145     NAPI_ASSERT(env, argc == requireArgc, "requires 2 parameter");
146 
147     napi_valuetype eventName = napi_undefined;
148     napi_typeof(env, argv[ARGV_NUM_0], &eventName);
149     NAPI_ASSERT(env, eventName == napi_string, "type mismatch for parameter 1");
150 
151     napi_valuetype handler = napi_undefined;
152     napi_typeof(env, argv[ARGV_NUM_1], &handler);
153     NAPI_ASSERT(env, handler == napi_function, "type mismatch for parameter 2");
154 
155     char type[TYPE_MAX_LEN] = {0};
156     size_t typeLen = 0;
157     napi_get_value_string_utf8(env, argv[ARGV_NUM_0], type, sizeof(type), &typeLen);
158     EventRegister::GetInstance().Register(env, type, argv[ARGV_NUM_1]);
159     napi_value result = nullptr;
160     napi_get_undefined(env, &result);
161     return result;
162 }
163 
OffHceCmd(napi_env env,napi_callback_info info)164 napi_value NfcNapiHceAdapter::OffHceCmd(napi_env env, napi_callback_info info)
165 {
166     // js method off("hce",callback)
167     size_t requireArgc = ARGV_NUM_2;
168     size_t argc = ARGV_NUM_2;
169     napi_value argv[ARGV_NUM_2] = {0};
170     napi_value thisVar = 0;
171     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
172     NAPI_ASSERT(env, argc == requireArgc, "requires 2 parameter");
173 
174     napi_valuetype eventName = napi_undefined;
175     napi_typeof(env, argv[ARGV_NUM_0], &eventName);
176     NAPI_ASSERT(env, eventName == napi_string, "type mismatch for parameter 1");
177 
178     if (argc == ARGV_NUM_2) {
179         napi_valuetype handler = napi_undefined;
180         napi_typeof(env, argv[ARGV_NUM_1], &handler);
181         NAPI_ASSERT(env, handler == napi_function, "type mismatch for parameter 2");
182     }
183 
184     char type[TYPE_MAX_LEN] = {0};
185     size_t typeLen = 0;
186     napi_get_value_string_utf8(env, argv[ARGV_NUM_0], type, sizeof(type), &typeLen);
187     EventRegister::GetInstance().UnregisterForOffIntf(env, type);
188     napi_value result = nullptr;
189     napi_get_undefined(env, &result);
190     return result;
191 }
192 
CheckTransmitParametersAndThrow(napi_env env,const napi_value parameters[],size_t parameterCount)193 static bool CheckTransmitParametersAndThrow(napi_env env, const napi_value parameters[],
194                                             size_t parameterCount)
195 {
196     if (parameterCount == ARGV_NUM_1) {
197         if (!CheckParametersAndThrow(env, parameters, {napi_object}, "data", "number[]")) {
198             return false;
199         }
200         return true;
201     } else if (parameterCount == ARGV_NUM_2) {
202         if (!CheckParametersAndThrow(env, parameters, {napi_object, napi_function}, "data & callback",
203                                      "number[] & function") ||
204             !CheckArrayNumberAndThrow(env, parameters[ARGV_NUM_0], "data", "number[]")) {
205             return false;
206         }
207         return true;
208     } else {
209         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM,
210                                               BuildErrorMessage(BUSI_ERR_PARAM, "", "", "", "")));
211         return false;
212     }
213 }
214 
GetInstance()215 EventRegister& EventRegister::GetInstance()
216 {
217     static EventRegister inst;
218     return inst;
219 }
220 
IsEventSupport(const std::string & type)221 bool EventRegister::IsEventSupport(const std::string& type)
222 {
223     return g_supportEventList.find(type) != g_supportEventList.end();
224 }
225 
Register(const napi_env & env,const std::string & type,napi_value handler)226 void EventRegister::Register(const napi_env& env, const std::string& type, napi_value handler)
227 {
228     InfoLog("Register eventType: %{public}s", type.c_str());
229     if (!IsEventSupport(type)) {
230         DebugLog("Register eventType error or not support!");
231         return;
232     }
233     std::lock_guard<std::mutex> guard(g_regInfoMutex);
234     if (RegHceCmdCallbackEvents(env, type) != KITS::ERR_NONE) {
235         return;
236     }
237     napi_ref handlerRef = nullptr;
238     napi_create_reference(env, handler, 1, &handlerRef);
239     RegObj regObj(env, handlerRef);
240     auto iter = g_eventRegisterInfo.find(type);
241     if (iter == g_eventRegisterInfo.end()) {
242         g_eventRegisterInfo[type] = regObj;
243         DebugLog("Register, add new type.");
244         return;
245     }
246 
247     auto oldRegObj = iter->second;
248     if (env == oldRegObj.m_regEnv) {
249         DebugLog("handler env is same");
250         napi_value oldHandler = nullptr;
251         napi_get_reference_value(oldRegObj.m_regEnv, oldRegObj.m_regHanderRef, &oldHandler);
252         bool isEqual = false;
253         napi_strict_equals(oldRegObj.m_regEnv, oldHandler, handler, &isEqual);
254         if (isEqual) {
255             DebugLog("handler function is same");
256         } else {
257             iter->second = regObj;
258         }
259     } else {
260         DebugLog("handler env is different");
261         iter->second = regObj;
262     }
263 }
264 
UnregisterForOffIntf(const napi_env & env,const std::string & type)265 void EventRegister::UnregisterForOffIntf(const napi_env& env, const std::string& type)
266 {
267     InfoLog("UnregisterForOffIntf eventType: %{public}s", type.c_str());
268     if (!IsEventSupport(type)) {
269         DebugLog("UnregisterForOffIntf eventType error or not support!");
270         return;
271     }
272     std::lock_guard<std::mutex> guard(g_regInfoMutex);
273     auto iter = g_eventRegisterInfo.find(type);
274     if (iter == g_eventRegisterInfo.end()) {
275         ErrorLog("eventType not registered!");
276         return;
277     }
278     if (UnRegHceCmdCallbackEvents(env, type) != KITS::ERR_NONE) {
279         ErrorLog("UnRegHceCmdCallbackEvents failed!");
280         return;
281     }
282     DeleteHceCmdRegisterObj(env);
283     g_eventRegisterInfo.erase(type);
284     iter = g_eventRegisterInfo.find(type);
285     if (iter == g_eventRegisterInfo.end()) {
286         InfoLog("eventType %{public}s, removed", type.c_str());
287     }
288     return;
289 }
290 
RegHceCmdCallbackEvents(const napi_env & env,const std::string & type)291 ErrorCode EventRegister::RegHceCmdCallbackEvents(const napi_env& env, const std::string& type)
292 {
293     HceService hceService = HceService::GetInstance();
294     ErrorCode ret = hceService.RegHceCmdCallback(hceCmdListenerEvent, type);
295     if (!CheckHceStatusCodeAndThrow(env, ret, "on")) {
296         ErrorLog("RegHceCmdCallback, statusCode = %{public}d", ret);
297     }
298     if (ret != KITS::ERR_NONE) {
299         DebugLog("RegHceCmdCallbackEvents failed!");
300         return ret;
301     }
302     return ret;
303 }
304 
UnRegHceCmdCallbackEvents(const napi_env & env,const std::string & type)305 ErrorCode EventRegister::UnRegHceCmdCallbackEvents(const napi_env& env, const std::string& type)
306 {
307     HceService hceService = HceService::GetInstance();
308     ErrorCode ret = hceService.UnRegHceCmdCallback(hceCmdListenerEvent, type);
309     if (!CheckHceStatusCodeAndThrow(env, ret, "off")) {
310         ErrorLog("UnRegHceCmdCallback, statusCode = %{public}d", ret);
311     }
312     if (ret != KITS::ERR_NONE) {
313         DebugLog("UnRegHceCmdCallbackEvents failed!");
314         return ret;
315     }
316     return ret;
317 }
318 
Unregister(const napi_env & env,ElementName & element)319 void EventRegister::Unregister(const napi_env& env, ElementName& element)
320 {
321     std::lock_guard<std::mutex> guard(g_regInfoMutex);
322     if (!g_eventRegisterInfo.empty()) {
323         if (UnregisterHceEvents(env, element) != KITS::ERR_NONE) {
324             ErrorLog("hce EventRegister::Unregister, unreg event failed.");
325             return;
326         }
327     }
328 
329     DeleteHceCmdRegisterObj(env);
330 
331     if (!g_eventRegisterInfo.empty()) {
332         g_eventRegisterInfo.erase(KITS::EVENT_HCE_CMD);
333     }
334     InfoLog("hce Event UnRegister");
335 }
336 
DeleteHceCmdRegisterObj(const napi_env & env)337 void EventRegister::DeleteHceCmdRegisterObj(const napi_env& env)
338 {
339     auto iter = g_eventRegisterInfo.find(KITS::EVENT_HCE_CMD);
340     if (iter == g_eventRegisterInfo.end()) {
341         InfoLog("no hce cmd register info.");
342         return;
343     }
344 
345     auto oldRegObj = iter->second;
346     if (env == oldRegObj.m_regEnv) {
347         DebugLog("env is same");
348         uint32_t refCount = INVALID_REF_COUNT;
349         napi_reference_unref(oldRegObj.m_regEnv, oldRegObj.m_regHanderRef, &refCount);
350         InfoLog(
351             "DeleteHceCmdRegisterObj, m_regEnv: %{private}p, m_regHanderRef: %{private}p, refCount: %{public}d",
352             oldRegObj.m_regEnv, oldRegObj.m_regHanderRef, refCount);
353         if (refCount == 0) {
354             InfoLog("DeleteHceCmdRegisterObj, ref count is zero");
355             napi_delete_reference(oldRegObj.m_regEnv, oldRegObj.m_regHanderRef);
356         }
357     } else {
358         InfoLog("DeleteHceCmdRegisterObj, env is different, env: %{private}p m_regEnv:: %{private}p", env,
359                 oldRegObj.m_regEnv);
360     }
361 }
362 
UnregisterHceEvents(const napi_env & env,ElementName & element)363 ErrorCode EventRegister::UnregisterHceEvents(const napi_env& env, ElementName& element)
364 {
365     HceService hceService = HceService::GetInstance();
366     ErrorCode ret = hceService.StopHce(element);
367     if (!CheckHceStatusCodeAndThrow(env, ret, "stop")) {
368         ErrorLog("StopHce, statusCode = %{public}d", ret);
369     }
370     if (ret != KITS::ERR_NONE) {
371         ErrorLog("UnregisterHceEvents  failed!");
372         return ret;
373     }
374     return ret;
375 }
376 
after_work_cb(uv_work_t * work,int status)377 static void after_work_cb(uv_work_t* work, int status)
378 {
379     AsyncEventData* asyncData = static_cast<AsyncEventData*>(work->data);
380     InfoLog("Napi event uv_queue_work, env: %{private}p, status: %{public}d", asyncData->env, status);
381     napi_handle_scope scope = nullptr;
382     uint32_t refCount = INVALID_REF_COUNT;
383     napi_open_handle_scope(asyncData->env, &scope);
384     napi_value handler = nullptr;
385     if (scope == nullptr) {
386         ErrorLog("after_work_cb: scope is nullptr");
387         goto EXIT;
388     }
389 
390     napi_get_reference_value(asyncData->env, asyncData->callbackRef, &handler);
391     if (handler == nullptr) {
392         ErrorLog("after_work_cb: handler is nullptr");
393         goto EXIT;
394     }
395     napi_value resArgs[ARGV_INDEX_2];
396     napi_get_undefined(asyncData->env, &resArgs[ARGV_INDEX_0]);
397     resArgs[ARGV_INDEX_1] = asyncData->packResult();
398     napi_value returnVal;
399     napi_get_undefined(asyncData->env, &returnVal);
400     if (napi_call_function(asyncData->env, nullptr, handler, ARGV_INDEX_2, resArgs, &returnVal) != napi_ok) {
401         DebugLog("Report event to Js failed");
402     } else {
403         DebugLog("Report event to Js success");
404     }
405 
406 EXIT:
407     napi_close_handle_scope(asyncData->env, scope);
408     napi_reference_unref(asyncData->env, asyncData->callbackRef, &refCount);
409     InfoLog("after_work_cb unref, env: %{private}p, callbackRef: %{private}p, "
410             "refCount: %{public}d",
411             asyncData->env, asyncData->callbackRef, refCount);
412     if (refCount == 0) {
413         napi_delete_reference(asyncData->env, asyncData->callbackRef);
414     }
415     delete asyncData;
416     delete work;
417     asyncData = nullptr;
418     work = nullptr;
419 }
420 
EventNotify(AsyncEventData * asyncEvent)421 void NapiEvent::EventNotify(AsyncEventData* asyncEvent)
422 {
423     DebugLog("Enter hce cmd event notify");
424     if (asyncEvent == nullptr) {
425         DebugLog("hce asyncEvent is null.");
426         return;
427     }
428     uv_loop_s* loop = nullptr;
429     napi_get_uv_event_loop(asyncEvent->env, &loop);
430     if (loop == nullptr) {
431         ErrorLog("loop is null");
432         delete asyncEvent;
433         asyncEvent = nullptr;
434         return;
435     }
436     uv_work_t* work = new uv_work_t;
437     if (work == nullptr) {
438         DebugLog("hce uv_work_t work is null.");
439         delete asyncEvent;
440         asyncEvent = nullptr;
441         return;
442     }
443 
444     uint32_t refCount = INVALID_REF_COUNT;
445     napi_reference_ref(asyncEvent->env, asyncEvent->callbackRef, &refCount);
446     work->data = asyncEvent;
447     uv_after_work_cb tmp_after_work_cb = after_work_cb;
448     int ret = uv_queue_work(loop, work, [](uv_work_t* work) {}, tmp_after_work_cb);
449     if (ret != 0) {
450         ErrorLog("uv_queue_work failed!");
451         delete asyncEvent;
452         delete work;
453     }
454 }
455 
CreateResult(const napi_env & env,const std::vector<uint8_t> & data)456 napi_value NapiEvent::CreateResult(const napi_env& env, const std::vector<uint8_t>& data)
457 {
458     napi_value result;
459     napi_create_array_with_length(env, data.size(), &result);
460     for (uint32_t i = 0; i < data.size(); i++) {
461         napi_value item;
462         napi_create_uint32(env, static_cast<uint32_t>(data[i]), &item);
463         napi_set_element(env, result, i, item);
464     }
465     return result;
466 }
467 
CheckIsRegister(const std::string & type)468 bool NapiEvent::CheckIsRegister(const std::string& type)
469 {
470     return g_eventRegisterInfo.find(type) != g_eventRegisterInfo.end();
471 }
472 
NativeTransmit(napi_env env,void * data)473 static void NativeTransmit(napi_env env, void* data)
474 {
475     auto context = static_cast<NfcHceSessionContext*>(data);
476     context->errorCode = BUSI_ERR_TAG_STATE_INVALID;
477     std::string hexRespData;
478     HceService hceService = HceService::GetInstance();
479     context->errorCode = hceService.SendRawFrame(context->dataBytes, true, hexRespData);
480     context->value = hexRespData;
481     context->resolved = true;
482 }
483 
TransmitCallback(napi_env env,napi_status status,void * data)484 static void TransmitCallback(napi_env env, napi_status status, void* data)
485 {
486     auto nfcHaEventReport = std::make_shared<NfcHaEventReport>(SDK_NAME, "Transmit");
487     if (nfcHaEventReport == nullptr) {
488         ErrorLog("nfcHaEventReport is nullptr");
489         return;
490     }
491     auto context = static_cast<NfcHceSessionContext*>(data);
492     napi_value callbackValue = nullptr;
493     if (status == napi_ok && context->resolved && context->errorCode == ErrorCode::ERR_NONE) {
494         napi_get_undefined(env, &callbackValue);
495         context->eventReport = nfcHaEventReport;
496         DoAsyncCallbackOrPromise(env, context, callbackValue);
497     } else {
498         int errCode = BuildOutputErrorCodeHce(context->errorCode);
499         nfcHaEventReport->ReportSdkEvent(RESULT_FAIL, errCode);
500         std::string errMessage = BuildErrorMessage(errCode, "transmit", CARD_EMULATION_PERM_DESC, "", "");
501         ThrowAsyncError(env, context, errCode, errMessage);
502     }
503 }
504 
Transmit(napi_env env,napi_callback_info info)505 napi_value NfcNapiHceAdapter::Transmit(napi_env env, napi_callback_info info)
506 {
507     // JS API define1: Transmit(data: number[]): Promise<number[]>
508     // JS API define2: Transmit(data: number[], callback:
509     // AsyncCallback<number[]>): void
510     size_t paramsCount = ARGV_NUM_2;
511     napi_value params[ARGV_NUM_2] = {0};
512     void* data = nullptr;
513     napi_value thisVar = nullptr;
514     napi_get_cb_info(env, info, &paramsCount, params, &thisVar, &data);
515 
516     if (!CheckTransmitParametersAndThrow(env, params, paramsCount)) {
517         return CreateUndefined(env);
518     }
519 
520     auto context = std::make_unique<NfcHceSessionContext>().release();
521     if (!CheckContextAndThrow(env, context, BUSI_ERR_TAG_STATE_INVALID)) {
522         return CreateUndefined(env);
523     }
524 
525     // parse the params
526     int32_t hexCmdData = 0;
527     napi_value hexCmdDataValue = nullptr;
528     uint32_t arrayLength = 0;
529     std::vector<unsigned char> dataBytes = {};
530     NAPI_CALL(env, napi_get_array_length(env, params[ARGV_INDEX_0], &arrayLength));
531     for (uint32_t i = 0; i < arrayLength; ++i) {
532         NAPI_CALL(env, napi_get_element(env, params[ARGV_INDEX_0], i, &hexCmdDataValue));
533         NAPI_CALL(env, napi_get_value_int32(env, hexCmdDataValue, &hexCmdData));
534         dataBytes.push_back(hexCmdData);
535     }
536     context->dataBytes =
537         NfcSdkCommon::BytesVecToHexString(static_cast<unsigned char*>(dataBytes.data()), dataBytes.size());
538     if (paramsCount == ARGV_NUM_2) {
539         napi_create_reference(env, params[ARGV_INDEX_1], DEFAULT_REF_COUNT, &context->callbackRef);
540     }
541 
542     napi_value result = HandleAsyncWork(env, context, "Transmit", NativeTransmit, TransmitCallback);
543     return result;
544 }
545 
StopHce(napi_env env,napi_callback_info cbinfo)546 napi_value NfcNapiHceAdapter::StopHce(napi_env env, napi_callback_info cbinfo)
547 {
548     size_t argc = ARGV_NUM_1;
549     napi_value argv[ARGV_NUM_1] = {0};
550     napi_value thisVar = 0;
551     napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr);
552     ElementName element;
553     if (!CheckArgCountAndThrow(env, argc, ARGV_NUM_1) ||
554         !ParseElementName(env, element, argv[ARGV_INDEX_0])) {
555         ErrorLog("Stop hce: parse args failed");
556         return CreateUndefined(env);
557     }
558 
559     EventRegister::GetInstance().Unregister(env, element);
560     napi_value result = nullptr;
561     napi_get_undefined(env, &result);
562     return result;
563 }
StartHCEDeprecated(napi_env env,napi_callback_info cbinfo)564 napi_value NfcNapiHceAdapter::StartHCEDeprecated(napi_env env, napi_callback_info cbinfo)
565 {
566     return CreateUndefined(env);
567 }
StartHCE(napi_env env,napi_callback_info cbinfo)568 napi_value NfcNapiHceAdapter::StartHCE(napi_env env, napi_callback_info cbinfo)
569 {
570     size_t argc = ARGV_NUM_2;
571     napi_value argv[ARGV_NUM_2] = {0};
572     napi_value thisVar = 0;
573     napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr);
574     ElementName element;
575     std::vector<std::string> aidVec;
576     if (!CheckArgCountAndThrow(env, argc, ARGV_NUM_2) || !ParseElementName(env, element, argv[ARGV_INDEX_0]) ||
577         !ParseStringVector(env, aidVec, argv[ARGV_INDEX_1], MAX_AID_LIST_NUM_PER_APP)) {
578         ErrorLog("Start hce: parse args failed");
579         return CreateUndefined(env);
580     }
581 
582     HceService hceService = HceService::GetInstance();
583     ErrorCode ret = hceService.StartHce(element, aidVec);
584     if (!CheckHceStatusCodeAndThrow(env, ret, "start")) {
585         ErrorLog("StartHce, statusCode = %{public}d", ret);
586     }
587     return CreateUndefined(env);
588 }
StopHCEDeprecated(napi_env env,napi_callback_info cbinfo)589 napi_value NfcNapiHceAdapter::StopHCEDeprecated(napi_env env, napi_callback_info cbinfo)
590 {
591     return CreateUndefined(env);
592 }
SendResponse(napi_env env,napi_callback_info cbinfo)593 napi_value NfcNapiHceAdapter::SendResponse(napi_env env, napi_callback_info cbinfo)
594 {
595     return CreateUndefined(env);
596 }
597 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)598 void NfcNapiHceAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
599 {
600     // sleep 3s to wait Nfc turn on
601     std::this_thread::sleep_for(std::chrono::seconds(3));
602     std::lock_guard<std::mutex> guard(g_regInfoMutex);
603     for (auto it = g_eventRegisterInfo.begin(); it != g_eventRegisterInfo.end(); ++it) {
604         ErrorCode ret = HceService::GetInstance().RegHceCmdCallback(hceCmdListenerEvent, it->first);
605         InfoLog("OnAddSystemAbility: RegHceCmdCallback, statusCode = %{public}d", ret);
606     }
607 }
608 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)609 void NfcNapiHceAbilityStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
610 {
611     InfoLog("%{public}s, systemAbilityId = %{public}d, ClearHceSessionProxy", __func__, systemAbilityId);
612     HceService::GetInstance().ClearHceSessionProxy();
613 }
614 
Init(int32_t systemAbilityId)615 void NfcNapiHceAbilityStatusChange::Init(int32_t systemAbilityId)
616 {
617     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
618     if (!samgrProxy) {
619         ErrorLog("samgrProxy is nullptr");
620         return;
621     }
622     int32_t ret = samgrProxy->SubscribeSystemAbility(systemAbilityId, this);
623     InfoLog("SubscribeSystemAbility, systemAbilityId = %{public}d, ret = %{public}d", systemAbilityId, ret);
624 }
625 } // namespace KITS
626 } // namespace NFC
627 } // namespace OHOS