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 #ifndef NFC_NAPI_COMMON_UTILS_H
17 #define NFC_NAPI_COMMON_UTILS_H
18 #include <chrono>
19 #include "element_name.h"
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 #include "ndef_message.h"
23 
24 namespace OHOS {
25 namespace NFC {
26 namespace KITS {
27 using OHOS::AppExecFwk::ElementName;
28 
29 // business error code, throw these errors to applcation.
30 const static int BUSI_ERR_PERM = 201; // Permission denied.
31 const static int BUSI_ERR_NOT_SYSTEM_APP = 202; // not system app.
32 const static int BUSI_ERR_PARAM = 401; // The parameter check failed.
33 const static int BUSI_ERR_CAPABILITY = 801; // Capability not supported.
34 
35 const static int BUSI_ERR_TAG_STATE_INVALID = 3100201; // nfc tag state invalid.
36 const static int BUSI_ERR_ELEMENT_STATE_INVALID = 3100202; // The element state is invalid.
37 const static int BUSI_ERR_REGISTER_STATE_INVALID = 3100203; // The off() can be called only when the on()
38                                                             // has been called.
39 const static int BUSI_ERR_IO_OPERATION_INVALID = 3100204; // Tag I/O operation failed.
40 const static uint32_t MAX_NUM_TECH_LIST = 12;
41 
42 const static int BUSI_ERR_HCE_STATE_INVALID = 3100301; // nfc hce state invalid.
43 
44 const std::string KEY_CODE = "code";
45 const std::string TAG_PERM_DESC = "ohos.permission.NFC_TAG";
46 const std::string CARD_EMULATION_PERM_DESC = "ohos.permission.NFC_CARD_EMULATION";
47 const std::string ERR_INIT_CONTEXT = "Initialize context failed.";
48 
49 enum JS_CALLBACK_ARGV : size_t {
50     CALLBACK_ARGV_INDEX_0 = 0,
51     CALLBACK_ARGV_INDEX_1,
52     CALLBACK_ARGV_CNT,
53 };
54 
55 enum JS_ARGV_NUM : size_t {
56     ARGV_NUM_0 = 0,
57     ARGV_NUM_1 = 1,
58     ARGV_NUM_2 = 2,
59     ARGV_NUM_3 = 3,
60     ARGV_NUM_4 = 4,
61     ARGV_NUM_5 = 5,
62 };
63 
64 enum JS_ARGV_INDEX : size_t {
65     ARGV_INDEX_0 = 0,
66     ARGV_INDEX_1,
67     ARGV_INDEX_2,
68     ARGV_INDEX_3,
69     ARGV_INDEX_4,
70 };
71 
72 struct NfcAsyncContext {
73     napi_async_work work = nullptr;
74     napi_deferred deferred = nullptr;
75     napi_ref callbackRef = nullptr;
76     int32_t result;
77     int32_t uid = 0;
78     bool flag = false;
79 };
80 
81 struct BaseContext {
82     napi_async_work work = nullptr;
83     napi_deferred deferred = nullptr;
84     napi_ref callbackRef = nullptr;
85     bool resolved = false;
86     int32_t errorCode = 0;
87 };
88 
89 class AsyncContext {
90 public:
91     napi_env env;
92     napi_async_work work;
93     napi_deferred deferred;
94     napi_ref callback[2] = {0};
95     std::function<void(void *)> executeFunc;
96     std::function<void(void *)> completeFunc;
97     napi_value resourceName;
98     napi_value result;
99     int errorCode = 0;
100 
101     explicit AsyncContext(napi_env e, napi_async_work w = nullptr, napi_deferred d = nullptr)
102         :env(e),
103         work(w),
104         deferred(d),
105         executeFunc(nullptr),
106         completeFunc(nullptr),
107         result(nullptr) {};
108 
109     AsyncContext() = delete;
110 
~AsyncContext()111     virtual ~AsyncContext() {}
112 };
113 
114 template<typename T, typename D>
115 struct CallBackContext : BaseContext {
116     T value;
117     D *objectInfo;
118 };
119 template<typename T, std::enable_if_t<std::is_same_v<T, bool>, int32_t> = 0>
GetNapiValue(napi_env env,T val)120 napi_value GetNapiValue(napi_env env, T val)
121 {
122     napi_value result = nullptr;
123     NAPI_CALL(env, napi_get_boolean(env, val, &result));
124     return result;
125 }
126 
127 template<typename T, std::enable_if_t<std::is_same_v<T, int32_t>, int32_t> = 0>
GetNapiValue(napi_env env,T val)128 napi_value GetNapiValue(napi_env env, T val)
129 {
130     napi_value result = nullptr;
131     NAPI_CALL(env, napi_create_int32(env, val, &result));
132     return result;
133 }
134 
135 template<typename T, std::enable_if_t<std::is_same_v<T, int64_t>, int64_t> = 0>
GetNapiValue(napi_env env,T val)136 napi_value GetNapiValue(napi_env env, T val)
137 {
138     napi_value result = nullptr;
139     NAPI_CALL(env, napi_create_int64(env, val, &result));
140     return result;
141 }
142 
143 template<typename T, std::enable_if_t<std::is_same_v<T, std::string>, int32_t> = 0>
GetNapiValue(napi_env env,const T & val)144 napi_value GetNapiValue(napi_env env, const T &val)
145 {
146     napi_value result = nullptr;
147     NAPI_CALL(env, napi_create_string_utf8(env, val.c_str(), val.length(), &result));
148     return result;
149 }
150 
151 template<typename T, std::enable_if_t<std::is_same_v<T, char>, int32_t> = 0>
GetNapiValue(napi_env env,const T * val)152 napi_value GetNapiValue(napi_env env, const T *val)
153 {
154     napi_value result = nullptr;
155     NAPI_CALL(env, napi_create_string_utf8(env, val, NAPI_AUTO_LENGTH, &result));
156     return result;
157 }
158 
159 template<typename T, std::enable_if_t<std::is_same_v<T, napi_value>, int32_t> = 0>
GetNapiValue(napi_env env,T val)160 napi_value GetNapiValue(napi_env env, T val)
161 {
162     return val;
163 }
164 
165 bool ParseString(napi_env env, std::string &param, napi_value args);
166 bool ParseInt32(napi_env env, int32_t &param, napi_value args);
167 bool ParseBool(napi_env env, bool &param, napi_value args);
168 bool ParseBytesVector(napi_env env, std::vector<unsigned char> &vec, napi_value args);
169 bool ParseUInt32Vector(napi_env &env, std::vector<uint32_t> &vec, napi_value &args);
170 bool ParseStringVector(napi_env& env, std::vector<std::string>& vec, napi_value &args, uint32_t maxLen);
171 bool ParseElementName(napi_env &env, ElementName &element, napi_value &args);
172 bool ParseArrayBuffer(napi_env env, uint8_t **data, size_t &size, napi_value args);
173 std::vector<std::string> ConvertStringVector(napi_env env, napi_value jsValue);
174 napi_value CreateErrorMessage(napi_env env, const std::string &msg, int32_t errorCode = 0);
175 napi_value CreateUndefined(napi_env env);
176 std::string GetNapiStringValue(
177     napi_env env, napi_value napiValue, const std::string &name, const std::string &defValue = "");
178 std::string GetStringFromValue(napi_env env, napi_value value);
179 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName);
180 int32_t GetNapiInt32Value(napi_env env, napi_value napiValue, const std::string &name, const int32_t &defValue = 0);
181 std::string UnwrapStringFromJS(napi_env env, napi_value param);
182 void ConvertStringVectorToJS(napi_env env, napi_value &result, std::vector<std::string> &stringVector);
183 void JsStringToBytesVector(napi_env env, napi_value &src, std::vector<unsigned char> &values);
184 void BytesVectorToJS(napi_env env, napi_value &result, std::vector<unsigned char> &src);
185 void ConvertStringToNumberArray(napi_env env, napi_value &result, std::string srcValue);
186 void ConvertNdefRecordVectorToJS(napi_env env, napi_value &result,
187                                  std::vector<std::shared_ptr<NdefRecord>> &ndefRecords);
188 void ConvertNdefRecordToJS(napi_env env, napi_value &result, std::shared_ptr<NdefRecord> &ndefRecord);
189 bool MatchParameters(napi_env env, const napi_value parameters[], std::initializer_list<napi_valuetype> valueTypes);
190 napi_value HandleAsyncWork(napi_env env, BaseContext *baseContext, const std::string &workName,
191     napi_async_execute_callback execute, napi_async_complete_callback complete);
192 void DoAsyncCallbackOrPromise(const napi_env &env, BaseContext *baseContext, napi_value callbackValue);
193 void ThrowAsyncError(const napi_env &env, BaseContext *baseContext, int errCode, const std::string &errMsg);
194 bool IsNumberArray(const napi_env &env, const napi_value &param);
195 bool IsObjectArray(const napi_env &env, const napi_value &param);
196 bool IsArray(const napi_env &env, const napi_value &param);
197 bool IsNumber(const napi_env &env, const napi_value &param);
198 bool IsString(const napi_env &env, const napi_value &param);
199 bool IsObject(const napi_env &env, const napi_value &param);
200 bool IsFunction(const napi_env &env, const napi_value &param);
201 int BuildOutputErrorCode(int errCode);
202 int BuildOutputErrorCodeHce(int errCode);
203 std::string BuildErrorMessage(int errCode, std::string funcName, std::string forbiddenPerm,
204     std::string paramName, std::string expertedType);
205 napi_value GenerateBusinessError(const napi_env &env, int errCode, const std::string &errMessage);
206 bool CheckUnwrapStatusAndThrow(const napi_env &env, napi_status status, int errCode);
207 bool CheckContextAndThrow(const napi_env &env, const BaseContext *context, int errCode);
208 bool CheckParametersAndThrow(const napi_env &env, const napi_value parameters[],
209     std::initializer_list<napi_valuetype> types, const std::string &argName, const std::string &argType);
210 bool CheckArrayNumberAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
211     const std::string &argType);
212 bool CheckNumberAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
213     const std::string &argType);
214 bool CheckStringAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
215     const std::string &argType);
216 bool CheckObjectAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
217     const std::string &argType);
218 bool CheckFunctionAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
219     const std::string &argType);
220 bool CheckArgCountAndThrow(const napi_env &env, int argCount, int expCount);
221 bool CheckTagStatusCodeAndThrow(const napi_env &env, int statusCode, const std::string &funcName);
222 bool CheckHceStatusCodeAndThrow(const napi_env &env, int statusCode, const std::string &funcName);
223 } // namespace KITS
224 } // namespace NFC
225 } // namespace OHOS
226 #endif