15bbf6e98Sopenharmony_ci/* 25bbf6e98Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 35bbf6e98Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 45bbf6e98Sopenharmony_ci * you may not use this file except in compliance with the License. 55bbf6e98Sopenharmony_ci * You may obtain a copy of the License at 65bbf6e98Sopenharmony_ci * 75bbf6e98Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 85bbf6e98Sopenharmony_ci * 95bbf6e98Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 105bbf6e98Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 115bbf6e98Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125bbf6e98Sopenharmony_ci * See the License for the specific language governing permissions and 135bbf6e98Sopenharmony_ci * limitations under the License. 145bbf6e98Sopenharmony_ci */ 155bbf6e98Sopenharmony_ci 165bbf6e98Sopenharmony_ci#include "devattest_log.h" 175bbf6e98Sopenharmony_ci#include "devattest_errno.h" 185bbf6e98Sopenharmony_ci#include "devattest_client.h" 195bbf6e98Sopenharmony_ci#include "devattest_napi.h" 205bbf6e98Sopenharmony_ci 215bbf6e98Sopenharmony_ciusing namespace std; 225bbf6e98Sopenharmony_ciusing namespace OHOS; 235bbf6e98Sopenharmony_ciusing namespace OHOS::DevAttest; 245bbf6e98Sopenharmony_ci 255bbf6e98Sopenharmony_cistruct DevAttestAsyncContext { 265bbf6e98Sopenharmony_ci napi_async_work work; 275bbf6e98Sopenharmony_ci napi_ref callbackRef = nullptr; // 用于callback模式 285bbf6e98Sopenharmony_ci napi_deferred deferred; // 用于promise模式 295bbf6e98Sopenharmony_ci AttestResultInfo value; // 返回值 305bbf6e98Sopenharmony_ci int32_t ret = DEVATTEST_ERR_JS_SYSTEM_SERVICE_EXCEPTION; 315bbf6e98Sopenharmony_ci}; 325bbf6e98Sopenharmony_ci 335bbf6e98Sopenharmony_cistatic napi_value GenerateDevAttestHandle(napi_env env, int32_t auth, int32_t software, string ticketStr, 345bbf6e98Sopenharmony_ci vector<int32_t> &softwareDetail) 355bbf6e98Sopenharmony_ci{ 365bbf6e98Sopenharmony_ci napi_value resultObject; 375bbf6e98Sopenharmony_ci napi_create_object(env, &resultObject); 385bbf6e98Sopenharmony_ci napi_value authResult; 395bbf6e98Sopenharmony_ci napi_value softwareResult; 405bbf6e98Sopenharmony_ci napi_value ticket; 415bbf6e98Sopenharmony_ci 425bbf6e98Sopenharmony_ci napi_create_int32(env, auth, &authResult); 435bbf6e98Sopenharmony_ci napi_create_int32(env, software, &softwareResult); 445bbf6e98Sopenharmony_ci napi_create_string_utf8(env, ticketStr.c_str(), ticketStr.length(), &ticket); 455bbf6e98Sopenharmony_ci napi_set_named_property(env, resultObject, "authResult", authResult); 465bbf6e98Sopenharmony_ci napi_set_named_property(env, resultObject, "softwareResult", softwareResult); 475bbf6e98Sopenharmony_ci napi_set_named_property(env, resultObject, "ticket", ticket); 485bbf6e98Sopenharmony_ci 495bbf6e98Sopenharmony_ci napi_value softwareResultDetail; 505bbf6e98Sopenharmony_ci napi_create_array(env, &softwareResultDetail); 515bbf6e98Sopenharmony_ci size_t index = 0; 525bbf6e98Sopenharmony_ci for (auto& vecData : softwareDetail) { 535bbf6e98Sopenharmony_ci napi_value id; 545bbf6e98Sopenharmony_ci napi_create_int32(env, vecData, &id); 555bbf6e98Sopenharmony_ci napi_set_element(env, softwareResultDetail, index, id); 565bbf6e98Sopenharmony_ci index++; 575bbf6e98Sopenharmony_ci } 585bbf6e98Sopenharmony_ci napi_set_named_property(env, resultObject, "softwareResultDetail", softwareResultDetail); 595bbf6e98Sopenharmony_ci return resultObject; 605bbf6e98Sopenharmony_ci} 615bbf6e98Sopenharmony_ci 625bbf6e98Sopenharmony_cistatic napi_value GenerateBusinessError(napi_env env, int32_t code) 635bbf6e98Sopenharmony_ci{ 645bbf6e98Sopenharmony_ci napi_value result; 655bbf6e98Sopenharmony_ci int32_t jsErrCode = ConvertToJsErrCode(code); 665bbf6e98Sopenharmony_ci if (jsErrCode == DEVATTEST_SUCCESS) { 675bbf6e98Sopenharmony_ci napi_get_undefined(env, &result); 685bbf6e98Sopenharmony_ci } else { 695bbf6e98Sopenharmony_ci napi_value errCode = nullptr; 705bbf6e98Sopenharmony_ci napi_create_int32(env, jsErrCode, &errCode); 715bbf6e98Sopenharmony_ci 725bbf6e98Sopenharmony_ci string errMsgStr = ConvertToJsErrMsg(jsErrCode); 735bbf6e98Sopenharmony_ci napi_value errMsg = nullptr; 745bbf6e98Sopenharmony_ci napi_create_string_utf8(env, errMsgStr.c_str(), NAPI_AUTO_LENGTH, &errMsg); 755bbf6e98Sopenharmony_ci 765bbf6e98Sopenharmony_ci napi_create_error(env, nullptr, errMsg, &result); 775bbf6e98Sopenharmony_ci napi_set_named_property(env, result, "code", errCode); 785bbf6e98Sopenharmony_ci } 795bbf6e98Sopenharmony_ci return result; 805bbf6e98Sopenharmony_ci} 815bbf6e98Sopenharmony_ci 825bbf6e98Sopenharmony_cistatic napi_value GenerateReturnValue(napi_env env, DevAttestAsyncContext* callback) 835bbf6e98Sopenharmony_ci{ 845bbf6e98Sopenharmony_ci napi_value result; 855bbf6e98Sopenharmony_ci if (callback->ret == DEVATTEST_SUCCESS) { 865bbf6e98Sopenharmony_ci result = GenerateDevAttestHandle(env, callback->value.authResult_, callback->value.softwareResult_, 875bbf6e98Sopenharmony_ci callback->value.ticket_, callback->value.softwareResultDetail_); 885bbf6e98Sopenharmony_ci } else { 895bbf6e98Sopenharmony_ci napi_get_undefined(env, &result); 905bbf6e98Sopenharmony_ci } 915bbf6e98Sopenharmony_ci return result; 925bbf6e98Sopenharmony_ci} 935bbf6e98Sopenharmony_ci 945bbf6e98Sopenharmony_ci/* 耗时操作 */ 955bbf6e98Sopenharmony_cistatic void Execute(napi_env env, void* data) 965bbf6e98Sopenharmony_ci{ 975bbf6e98Sopenharmony_ci if (data == nullptr) { 985bbf6e98Sopenharmony_ci HILOGE("[Execute] Invalid parameter"); 995bbf6e98Sopenharmony_ci return; 1005bbf6e98Sopenharmony_ci } 1015bbf6e98Sopenharmony_ci DevAttestAsyncContext *asyncContext = static_cast<DevAttestAsyncContext*>(data); 1025bbf6e98Sopenharmony_ci int32_t ret = DevAttestClient::GetInstance().GetAttestStatus(asyncContext->value); 1035bbf6e98Sopenharmony_ci if (ret == DEVATTEST_FAIL) { 1045bbf6e98Sopenharmony_ci asyncContext->ret = DEVATTEST_ERR_JS_SYSTEM_SERVICE_EXCEPTION; 1055bbf6e98Sopenharmony_ci } else { 1065bbf6e98Sopenharmony_ci asyncContext->ret = ret; 1075bbf6e98Sopenharmony_ci } 1085bbf6e98Sopenharmony_ci} 1095bbf6e98Sopenharmony_ci 1105bbf6e98Sopenharmony_ci/* 传参,不耗时 */ 1115bbf6e98Sopenharmony_cistatic void Complete(napi_env env, napi_status status, void* data) 1125bbf6e98Sopenharmony_ci{ 1135bbf6e98Sopenharmony_ci DevAttestAsyncContext* callback = static_cast<DevAttestAsyncContext*>(data); 1145bbf6e98Sopenharmony_ci 1155bbf6e98Sopenharmony_ci // 根据Execute函数的结果进行返回值的赋值, result[0]存放error; result[1]存放返回值 1165bbf6e98Sopenharmony_ci napi_value result[2] = {0}; 1175bbf6e98Sopenharmony_ci result[0] = GenerateBusinessError(env, callback->ret); 1185bbf6e98Sopenharmony_ci result[1] = GenerateReturnValue(env, callback); 1195bbf6e98Sopenharmony_ci 1205bbf6e98Sopenharmony_ci if (callback->callbackRef != nullptr) { // callback模式 1215bbf6e98Sopenharmony_ci // 调用对应的js的callback函数 1225bbf6e98Sopenharmony_ci napi_value callbackfunc = nullptr; 1235bbf6e98Sopenharmony_ci napi_get_reference_value(env, callback->callbackRef, &callbackfunc); 1245bbf6e98Sopenharmony_ci napi_value returnValue; 1255bbf6e98Sopenharmony_ci // 此函数的最后一个参数不可传nullptr,否则程序会崩溃 1265bbf6e98Sopenharmony_ci napi_call_function(env, nullptr, callbackfunc, sizeof(result) / sizeof(result[0]), result, &returnValue); 1275bbf6e98Sopenharmony_ci napi_delete_reference(env, callback->callbackRef); 1285bbf6e98Sopenharmony_ci } else { // promise模式 1295bbf6e98Sopenharmony_ci if (callback->ret == DEVATTEST_SUCCESS) { 1305bbf6e98Sopenharmony_ci napi_resolve_deferred(env, callback->deferred, result[1]); 1315bbf6e98Sopenharmony_ci } else { 1325bbf6e98Sopenharmony_ci napi_reject_deferred(env, callback->deferred, result[0]); 1335bbf6e98Sopenharmony_ci } 1345bbf6e98Sopenharmony_ci } 1355bbf6e98Sopenharmony_ci napi_delete_async_work(env, callback->work); // 异步任务完成之后删除任务 1365bbf6e98Sopenharmony_ci delete callback; 1375bbf6e98Sopenharmony_ci} 1385bbf6e98Sopenharmony_ci 1395bbf6e98Sopenharmony_ci/* [js] getAttestStatus(callback: AsyncCallback<AttestResultInfo>) : void */ 1405bbf6e98Sopenharmony_ci/* [js] getAttestStatus() : Promise<AttestResultInfo> */ 1415bbf6e98Sopenharmony_cinapi_value DevAttestNapi::GetAttestResultInfo(napi_env env, napi_callback_info info) 1425bbf6e98Sopenharmony_ci{ 1435bbf6e98Sopenharmony_ci // 获取js的入参数据 1445bbf6e98Sopenharmony_ci size_t argc = PARAM1; // 参数个数 1455bbf6e98Sopenharmony_ci napi_value argv[1] = {0}; // 参数的值 1465bbf6e98Sopenharmony_ci napi_value thisVar = nullptr; // js对象的this指针 1475bbf6e98Sopenharmony_ci void* data = nullptr; // 回调数据指针 1485bbf6e98Sopenharmony_ci napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 1495bbf6e98Sopenharmony_ci if (argc > PARAM1) { 1505bbf6e98Sopenharmony_ci HILOGE("[GetAttestResultInfo] Input at most 1 paramter"); 1515bbf6e98Sopenharmony_ci napi_throw(env, GenerateBusinessError(env, DEVATTEST_ERR_JS_PARAMETER_ERROR)); 1525bbf6e98Sopenharmony_ci } 1535bbf6e98Sopenharmony_ci 1545bbf6e98Sopenharmony_ci // 判断入参的类型是否正确 1555bbf6e98Sopenharmony_ci napi_valuetype type = napi_undefined; 1565bbf6e98Sopenharmony_ci if (argc == PARAM1) { 1575bbf6e98Sopenharmony_ci napi_typeof(env, argv[0], &type); 1585bbf6e98Sopenharmony_ci if (type != napi_function) { 1595bbf6e98Sopenharmony_ci HILOGE("[GetAttestResultInfo] the type of argv[0] is not function"); 1605bbf6e98Sopenharmony_ci napi_throw(env, GenerateBusinessError(env, DEVATTEST_ERR_JS_PARAMETER_ERROR)); 1615bbf6e98Sopenharmony_ci } 1625bbf6e98Sopenharmony_ci } 1635bbf6e98Sopenharmony_ci 1645bbf6e98Sopenharmony_ci std::unique_ptr<DevAttestAsyncContext> callback = std::make_unique<DevAttestAsyncContext>(); 1655bbf6e98Sopenharmony_ci 1665bbf6e98Sopenharmony_ci // 解析入参callback,判断callback 1675bbf6e98Sopenharmony_ci if (argc == PARAM1) { 1685bbf6e98Sopenharmony_ci napi_create_reference(env, argv[0], 1, &callback->callbackRef); 1695bbf6e98Sopenharmony_ci } 1705bbf6e98Sopenharmony_ci 1715bbf6e98Sopenharmony_ci // 判断模式,callback ref为空,说明是promise模式,反之是callback模式 1725bbf6e98Sopenharmony_ci napi_value promise = nullptr; 1735bbf6e98Sopenharmony_ci if (!callback->callbackRef) { 1745bbf6e98Sopenharmony_ci napi_create_promise(env, &callback->deferred, &promise); 1755bbf6e98Sopenharmony_ci } else { 1765bbf6e98Sopenharmony_ci napi_get_undefined(env, &promise); 1775bbf6e98Sopenharmony_ci } 1785bbf6e98Sopenharmony_ci 1795bbf6e98Sopenharmony_ci napi_value resource = nullptr; 1805bbf6e98Sopenharmony_ci napi_create_string_utf8(env, "GetAttestResultInfo", NAPI_AUTO_LENGTH, &resource); 1815bbf6e98Sopenharmony_ci napi_create_async_work(env, nullptr, resource, 1825bbf6e98Sopenharmony_ci Execute, 1835bbf6e98Sopenharmony_ci Complete, 1845bbf6e98Sopenharmony_ci static_cast<void*>(callback.get()), 1855bbf6e98Sopenharmony_ci &callback->work); 1865bbf6e98Sopenharmony_ci napi_queue_async_work(env, callback->work); 1875bbf6e98Sopenharmony_ci callback.release(); 1885bbf6e98Sopenharmony_ci return promise; 1895bbf6e98Sopenharmony_ci} 1905bbf6e98Sopenharmony_ci 1915bbf6e98Sopenharmony_ci/* [js] getAttestStatusSync() : AttestResultInfo */ 1925bbf6e98Sopenharmony_cinapi_value DevAttestNapi::GetAttestResultInfoSync(napi_env env, napi_callback_info info) 1935bbf6e98Sopenharmony_ci{ 1945bbf6e98Sopenharmony_ci AttestResultInfo attestResultInfo; 1955bbf6e98Sopenharmony_ci int32_t errCode = DevAttestClient::GetInstance().GetAttestStatus(attestResultInfo); 1965bbf6e98Sopenharmony_ci if (errCode != DEVATTEST_SUCCESS) { 1975bbf6e98Sopenharmony_ci HILOGE("[GetAttestResultInfoSync] GetAttestStatus failed errCode:%{public}d", errCode); 1985bbf6e98Sopenharmony_ci napi_throw(env, GenerateBusinessError(env, errCode)); 1995bbf6e98Sopenharmony_ci } 2005bbf6e98Sopenharmony_ci 2015bbf6e98Sopenharmony_ci return GenerateDevAttestHandle(env, attestResultInfo.authResult_, attestResultInfo.softwareResult_, 2025bbf6e98Sopenharmony_ci attestResultInfo.ticket_, attestResultInfo.softwareResultDetail_); 2035bbf6e98Sopenharmony_ci} 2045bbf6e98Sopenharmony_ci 2055bbf6e98Sopenharmony_cinapi_value DevAttestNapi::Init(napi_env env, napi_value exports) 2065bbf6e98Sopenharmony_ci{ 2075bbf6e98Sopenharmony_ci napi_property_descriptor desc[] = { 2085bbf6e98Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getAttestStatus", GetAttestResultInfo), 2095bbf6e98Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getAttestStatusSync", GetAttestResultInfoSync) 2105bbf6e98Sopenharmony_ci }; 2115bbf6e98Sopenharmony_ci NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); 2125bbf6e98Sopenharmony_ci return exports; 2135bbf6e98Sopenharmony_ci} 2145bbf6e98Sopenharmony_ci 2155bbf6e98Sopenharmony_ciEXTERN_C_START 2165bbf6e98Sopenharmony_cistatic napi_value DevattestInit(napi_env env, napi_value exports) 2175bbf6e98Sopenharmony_ci{ 2185bbf6e98Sopenharmony_ci HILOGI("Initialize the DevAttestNapi module"); 2195bbf6e98Sopenharmony_ci napi_value ret = DevAttestNapi::Init(env, exports); 2205bbf6e98Sopenharmony_ci HILOGI("The initialization of the DevAttestNapi module is complete"); 2215bbf6e98Sopenharmony_ci return ret; 2225bbf6e98Sopenharmony_ci} 2235bbf6e98Sopenharmony_ciEXTERN_C_END 2245bbf6e98Sopenharmony_ci 2255bbf6e98Sopenharmony_cistatic napi_module _module = { 2265bbf6e98Sopenharmony_ci .nm_version = 1, 2275bbf6e98Sopenharmony_ci .nm_flags = 0, 2285bbf6e98Sopenharmony_ci .nm_filename = nullptr, 2295bbf6e98Sopenharmony_ci .nm_register_func = DevattestInit, 2305bbf6e98Sopenharmony_ci .nm_modname = "deviceAttest", 2315bbf6e98Sopenharmony_ci .nm_priv = ((void *)0), 2325bbf6e98Sopenharmony_ci .reserved = { 0 } 2335bbf6e98Sopenharmony_ci}; 2345bbf6e98Sopenharmony_ci 2355bbf6e98Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterModule(void) 2365bbf6e98Sopenharmony_ci{ 2375bbf6e98Sopenharmony_ci napi_module_register(&_module); 2385bbf6e98Sopenharmony_ci} 239