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, ¶msCount, 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