• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #include "napi_link_enhance_server.h"
16 
17 #include "napi_link_enhance_error_code.h"
18 #include "napi_link_enhance_utils.h"
19 #include "softbus_error_code.h"
20 #include "softbus_connection.h"
21 
22 namespace Communication {
23 namespace OHOS::Softbus {
24 
25 thread_local napi_ref NapiLinkEnhanceServer::consRef_ = nullptr;
26 
27 std::unordered_map<std::string, NapiLinkEnhanceServer *> NapiLinkEnhanceServer::enhanceServerMap_;
28 std::mutex NapiLinkEnhanceServer::serverMapMutex_;
29 
CheckCreateServerParams(napi_env env,napi_callback_info info,napi_value & outResult)30 static napi_status CheckCreateServerParams(napi_env env, napi_callback_info info, napi_value &outResult)
31 {
32     size_t argc = ARGS_SIZE_ONE;
33     napi_value argv[ARGS_SIZE_ONE] = { 0 };
34 
35     NAPI_SOFTBUS_CALL_RETURN(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
36     NAPI_SOFTBUS_RETURN_IF(
37         argc != ARGS_SIZE_ONE, "expect 1 args", napi_invalid_arg);
38 
39     std::string name {};
40     if (!ParseString(env, name, argv[ARGS_SIZE_ZERO])) {
41         COMM_LOGE(COMM_SDK, "expect string");
42         return napi_string_expected;
43     }
44     if (name.length() == 0) {
45         COMM_LOGE(COMM_SDK, "invalid name");
46         return napi_invalid_arg;
47     }
48     napi_value constructor = nullptr;
49     if (NapiLinkEnhanceServer::consRef_ == nullptr) {
50         return napi_string_expected;
51     }
52     NAPI_SOFTBUS_CALL_RETURN(napi_get_reference_value(env, NapiLinkEnhanceServer::consRef_, &constructor));
53     NAPI_SOFTBUS_CALL_RETURN(napi_new_instance(env, constructor, argc, argv, &outResult));
54     return napi_ok;
55 }
56 
Create(napi_env env,napi_callback_info info)57 napi_value NapiLinkEnhanceServer::Create(napi_env env, napi_callback_info info)
58 {
59     if (!CheckAccessToken()) {
60         HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
61         return NapiGetUndefinedRet(env);
62     }
63     napi_value result;
64     auto status = CheckCreateServerParams(env, info, result);
65     if (status != napi_ok) {
66         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
67         return NapiGetUndefinedRet(env);
68     }
69     return result;
70 }
71 
DefineJSClass(napi_env env)72 void NapiLinkEnhanceServer::DefineJSClass(napi_env env)
73 {
74     napi_property_descriptor serverDesc[] = {
75         DECLARE_NAPI_FUNCTION("start", Start),
76         DECLARE_NAPI_FUNCTION("stop", Stop),
77         DECLARE_NAPI_FUNCTION("close", Close),
78         DECLARE_NAPI_FUNCTION("on", On),
79         DECLARE_NAPI_FUNCTION("off", Off),
80     };
81 
82     napi_value constructor = nullptr;
83     napi_define_class(env, "Server", NAPI_AUTO_LENGTH, Constructor, nullptr,
84         sizeof(serverDesc) / sizeof(serverDesc[0]), serverDesc, &constructor);
85     napi_create_reference(env, constructor, 1, &consRef_);
86 }
87 
Constructor(napi_env env,napi_callback_info info)88 napi_value NapiLinkEnhanceServer::Constructor(napi_env env, napi_callback_info info)
89 {
90     napi_value thisVar = nullptr;
91 
92     size_t argc = ARGS_SIZE_ONE;
93     napi_value argv[ARGS_SIZE_ONE] = {0};
94 
95     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
96     if (argc != ARGS_SIZE_ONE) {
97         COMM_LOGE(COMM_SDK, "expect one args");
98         return NapiGetUndefinedRet(env);
99     }
100     std::string name = "";
101     if (!ParseString(env, name, argv[PARAM0])) {
102         COMM_LOGE(COMM_SDK, "Parse name failed ");
103         return NapiGetUndefinedRet(env);
104     }
105     {
106         std::lock_guard<std::mutex> guard(serverMapMutex_);
107         if (enhanceServerMap_.find(name) != enhanceServerMap_.end()) {
108             HandleSyncErr(env, LINK_ENHANCE_DUPLICATE_SERVER_NAME);
109             return NapiGetUndefinedRet(env);
110         }
111     }
112     NapiLinkEnhanceServer* enhanceServer = new NapiLinkEnhanceServer(name);
113     if (enhanceServer == nullptr) {
114         COMM_LOGE(COMM_SDK, "new enhanceServer failed");
115         return NapiGetUndefinedRet(env);
116     }
117     auto status = napi_wrap(
118         env, thisVar, enhanceServer,
119         [](napi_env env, void* data, void* hint) {
120             NapiLinkEnhanceServer* server = static_cast<NapiLinkEnhanceServer*>(data);
121             if (server) {
122                 delete server;
123                 server = nullptr;
124             }
125         },
126         nullptr,
127         nullptr);
128     if (status != napi_ok) {
129         COMM_LOGE(COMM_SDK, "napi_wrap failed");
130         delete enhanceServer;
131         enhanceServer = nullptr;
132         return thisVar;
133     }
134     enhanceServer->env_ = env;
135     {
136         std::lock_guard<std::mutex> guard(serverMapMutex_);
137         enhanceServerMap_[name] = enhanceServer;
138     }
139 
140     return thisVar;
141 }
142 
NapiGetEnhanceServer(napi_env env,napi_value thisVar)143 static NapiLinkEnhanceServer *NapiGetEnhanceServer(napi_env env, napi_value thisVar)
144 {
145     NapiLinkEnhanceServer *enhanceServer = nullptr;
146     auto status = napi_unwrap(env, thisVar, (void **)&enhanceServer);
147     if (status != napi_ok) {
148         return nullptr;
149     }
150     return enhanceServer;
151 }
152 
NapiGetEnhanceServer(napi_env env,napi_callback_info info)153 static NapiLinkEnhanceServer *NapiGetEnhanceServer(napi_env env, napi_callback_info info)
154 {
155     size_t argc = 0;
156     napi_value thisVar = nullptr;
157     if (napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr) != napi_ok) {
158         return nullptr;
159     }
160     return NapiGetEnhanceServer(env, thisVar);
161 }
162 
CheckAccessTokenAndParams(napi_env env,napi_callback_info info,std::string & funcName)163 static bool CheckAccessTokenAndParams(napi_env env, napi_callback_info info, std::string &funcName)
164 {
165     if (!CheckAccessToken()) {
166         HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
167         return false;
168     }
169     size_t argc = ARGS_SIZE_TWO;
170     napi_value args[ARGS_SIZE_TWO];
171     napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
172     if (status != napi_ok || argc != ARGS_SIZE_TWO) {
173         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
174         return false;
175     }
176     napi_valuetype valueType = napi_null;
177     napi_typeof(env, args[PARAM1], &valueType);
178     if (valueType != napi_function) {
179         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
180         return false;
181     }
182 
183     size_t typeLen = 0;
184     status = napi_get_value_string_utf8(env, args[ARGS_SIZE_ZERO], nullptr, -1, &typeLen);
185     if (status != napi_ok || typeLen >= ARGS_TYPE_MAX_LEN) {
186         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
187         return false;
188     }
189     char type[ARGS_TYPE_MAX_LEN];
190     status = napi_get_value_string_utf8(env, args[ARGS_SIZE_ZERO], type, sizeof(type), &typeLen);
191     if (status != napi_ok) {
192         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
193         return false;
194     }
195     funcName = type;
196     return true;
197 }
198 
On(napi_env env,napi_callback_info info)199 napi_value NapiLinkEnhanceServer::On(napi_env env, napi_callback_info info)
200 {
201     std::string funcName = "";
202     if (!CheckAccessTokenAndParams(env, info, funcName)) {
203         return NapiGetUndefinedRet(env);
204     }
205     NapiLinkEnhanceServer *enhanceServer = NapiGetEnhanceServer(env, info);
206     size_t argc = ARGS_SIZE_TWO;
207     napi_value args[ARGS_SIZE_TWO];
208     napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
209     if (status != napi_ok || argc != ARGS_SIZE_TWO || enhanceServer == nullptr) {
210         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
211         return NapiGetUndefinedRet(env);
212     }
213 
214     if (strcmp(funcName.c_str(), "connectionAccepted") == 0) {
215         COMM_LOGE(COMM_SDK, "register connectionAccepted");
216         if (enhanceServer->acceptConnectRef_ != nullptr) {
217             napi_delete_reference(env, enhanceServer->acceptConnectRef_);
218         }
219         napi_create_reference(env, args[ARGS_SIZE_ONE], 1, &(enhanceServer->acceptConnectRef_));
220         enhanceServer->SetAcceptedEnable(true);
221     } else if (strcmp(funcName.c_str(), "serverStopped") == 0) {
222         COMM_LOGE(COMM_SDK, "register serverStopped");
223         if (enhanceServer->serverStopRef_ != nullptr) {
224             napi_delete_reference(env, enhanceServer->serverStopRef_);
225         }
226         napi_create_reference(env, args[ARGS_SIZE_ONE], 1, &(enhanceServer->serverStopRef_));
227         enhanceServer->SetStopEnable(true);
228     } else {
229         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
230         return NapiGetUndefinedRet(env);
231     }
232     return NapiGetUndefinedRet(env);
233 }
234 
Off(napi_env env,napi_callback_info info)235 napi_value NapiLinkEnhanceServer::Off(napi_env env, napi_callback_info info)
236 {
237     std::string funcName = "";
238     if (!CheckAccessTokenAndParams(env, info, funcName)) {
239         return NapiGetUndefinedRet(env);
240     }
241 
242     NapiLinkEnhanceServer *enhanceServer = NapiGetEnhanceServer(env, info);
243     if (enhanceServer == nullptr) {
244         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
245         return NapiGetUndefinedRet(env);
246     }
247     if (strcmp(funcName.c_str(), "onAcceptConnect") == 0) {
248         if (enhanceServer->acceptConnectRef_ != nullptr) {
249             napi_delete_reference(env, enhanceServer->acceptConnectRef_);
250         }
251         enhanceServer->acceptConnectRef_ = nullptr;
252         enhanceServer->SetAcceptedEnable(false);
253     } else if (strcmp(funcName.c_str(), "serverStopped") == 0) {
254         if (enhanceServer->serverStopRef_ != nullptr) {
255             napi_delete_reference(env, enhanceServer->serverStopRef_);
256         }
257         enhanceServer->serverStopRef_ = nullptr;
258         enhanceServer->SetStopEnable(false);
259     } else {
260         HandleSyncErr(env, LINK_ENHANCE_PARAMETER_INVALID);
261         return NapiGetUndefinedRet(env);
262     }
263     return NapiGetUndefinedRet(env);
264 }
265 
Start(napi_env env,napi_callback_info info)266 napi_value NapiLinkEnhanceServer::Start(napi_env env, napi_callback_info info)
267 {
268     if (!CheckAccessToken()) {
269         HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
270         return NapiGetUndefinedRet(env);
271     }
272     size_t argc = 0;
273     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
274     if (status != napi_ok || argc > ARGS_SIZE_ZERO) {
275         HandleSyncErr(env, LINK_ENHANCE_INTERVAL_ERR);
276         return NapiGetUndefinedRet(env);
277     }
278     NapiLinkEnhanceServer *enhanceServer = NapiGetEnhanceServer(env, info);
279     if (enhanceServer == nullptr) {
280         HandleSyncErr(env, LINK_ENHANCE_INTERVAL_ERR);
281         return NapiGetUndefinedRet(env);
282     }
283     int32_t ret = GeneralCreateServer(PKG_NAME.c_str(), enhanceServer->name_.c_str());
284     if (ret != 0) {
285         COMM_LOGE(COMM_SDK, "create server failed, ret=%{public}d", ret);
286         int32_t errCode = ConvertToJsErrcode(ret);
287         HandleSyncErr(env, errCode);
288     }
289     return NapiGetUndefinedRet(env);
290 }
291 
Stop(napi_env env,napi_callback_info info)292 napi_value NapiLinkEnhanceServer::Stop(napi_env env, napi_callback_info info)
293 {
294     if (!CheckAccessToken()) {
295         HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
296         return NapiGetUndefinedRet(env);
297     }
298     size_t argc = 0;
299     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
300     if (status != napi_ok || argc > ARGS_SIZE_ZERO) {
301         COMM_LOGE(COMM_SDK, "no needed arguments");
302         return NapiGetUndefinedRet(env);
303     }
304     NapiLinkEnhanceServer *enhanceServer = NapiGetEnhanceServer(env, info);
305     if (enhanceServer == nullptr) {
306         COMM_LOGE(COMM_SDK, "get server failed");
307         return NapiGetUndefinedRet(env);
308     }
309     enhanceServer->lock_.lock();
310     enhanceServer->isAcceptedEnable_ = false;
311     enhanceServer->isStopEnable_ = false;
312     enhanceServer->lock_.unlock();
313 
314     int32_t ret = GeneralRemoveServer(PKG_NAME.c_str(), enhanceServer->name_.c_str());
315     if (ret != 0) {
316         COMM_LOGE(COMM_SDK, "remove server failed, ret=%{public}d", ret);
317         if (ConvertToJsErrcode(ret) == LINK_ENHANCE_PERMISSION_DENIED) {
318             HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
319         }
320     }
321     return NapiGetUndefinedRet(env);
322 }
323 
Close(napi_env env,napi_callback_info info)324 napi_value NapiLinkEnhanceServer::Close(napi_env env, napi_callback_info info)
325 {
326     COMM_LOGI(COMM_SDK, "enter");
327     if (!CheckAccessToken()) {
328         HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
329         return NapiGetUndefinedRet(env);
330     }
331     size_t argc = 0;
332     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
333     if (status != napi_ok || argc > ARGS_SIZE_ZERO) {
334         COMM_LOGE(COMM_SDK, "no needed arguments");
335         return NapiGetUndefinedRet(env);
336     }
337     NapiLinkEnhanceServer *enhanceServer = NapiGetEnhanceServer(env, info);
338     if (enhanceServer == nullptr) {
339         COMM_LOGE(COMM_SDK, "get server failed");
340         return NapiGetUndefinedRet(env);
341     }
342     int32_t ret = GeneralRemoveServer(PKG_NAME.c_str(), enhanceServer->name_.c_str());
343     if (ret != 0) {
344         COMM_LOGE(COMM_SDK, "remove server failed, ret=%{public}d", ret);
345         if (ConvertToJsErrcode(ret) == LINK_ENHANCE_PERMISSION_DENIED) {
346             HandleSyncErr(env, LINK_ENHANCE_PERMISSION_DENIED);
347         }
348     }
349     enhanceServer->lock_.lock();
350     enhanceServer->isAcceptedEnable_ = false;
351     enhanceServer->isStopEnable_ = false;
352     enhanceServer->lock_.unlock();
353     if (enhanceServer->acceptConnectRef_ != nullptr) {
354         napi_delete_reference(env, enhanceServer->acceptConnectRef_);
355         enhanceServer->acceptConnectRef_ = nullptr;
356     }
357     if (enhanceServer->serverStopRef_ != nullptr) {
358         napi_delete_reference(env, enhanceServer->serverStopRef_);
359         enhanceServer->serverStopRef_ = nullptr;
360     }
361     {
362         std::lock_guard<std::mutex> guard(serverMapMutex_);
363         if (enhanceServerMap_.find(enhanceServer->name_) != enhanceServerMap_.end()) {
364             enhanceServerMap_.erase(enhanceServer->name_);
365         }
366     }
367     return NapiGetUndefinedRet(env);
368 }
369 
IsAcceptedEnable()370 bool NapiLinkEnhanceServer::IsAcceptedEnable()
371 {
372     this->lock_.lock();
373     bool isEnable = this->isAcceptedEnable_;
374     this->lock_.unlock();
375     return isEnable;
376 }
377 
IsStopEnable()378 bool NapiLinkEnhanceServer::IsStopEnable()
379 {
380     this->lock_.lock();
381     bool isEnable = this->isStopEnable_;
382     this->lock_.unlock();
383     return isEnable;
384 }
385 } // namespace SoftBus
386 } // namespace Communication