• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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_bluetooth_utils.h"
16 #include "napi_bluetooth_spp_server.h"
17 
18 namespace OHOS {
19 namespace Bluetooth {
20 const int num_20 = 20;
21 using namespace std;
22 int NapiSppServer::count = 0;
23 std::map<int, std::shared_ptr<NapiSppServer>> NapiSppServer::serverMap;
24 
DefineSppFunctions(napi_env env,napi_value exports)25 void DefineSppFunctions(napi_env env, napi_value exports)
26 {
27     napi_property_descriptor desc[] = {
28         DECLARE_NAPI_FUNCTION("sppListen", NapiSppServer::SppListen),
29         DECLARE_NAPI_FUNCTION("sppAccept", NapiSppServer::SppAccept),
30         DECLARE_NAPI_FUNCTION("sppConnect", NapiSppClient::SppConnect),
31         DECLARE_NAPI_FUNCTION("sppCloseServerSocket", NapiSppServer::SppCloseServerSocket),
32         DECLARE_NAPI_FUNCTION("sppCloseClientSocket", NapiSppClient::SppCloseClientSocket),
33         DECLARE_NAPI_FUNCTION("sppWrite", NapiSppClient::SppWrite),
34     };
35     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
36 }
37 
SppListen(napi_env env,napi_callback_info info)38 napi_value NapiSppServer::SppListen(napi_env env, napi_callback_info info)
39 {
40     HILOGI("SppListen called");
41     size_t expectedArgsCount = ARGS_SIZE_THREE;
42     size_t argc = expectedArgsCount;
43     napi_value argv[ARGS_SIZE_THREE] = {0};
44 
45     napi_value ret = nullptr;
46     napi_get_undefined(env, &ret);
47 
48     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
49     if (argc != expectedArgsCount && argc != expectedArgsCount - CALLBACK_SIZE) {
50         HILOGE("Requires 2 or 3 arguments.");
51         return ret;
52     }
53 
54     string name;
55     if (!ParseString(env, name, argv[PARAM0])) {
56         HILOGE("Wrong argument type. String expected.");
57         return ret;
58     }
59 
60     SppListenCallbackInfo *callbackInfo = new SppListenCallbackInfo();
61     callbackInfo->env_ = env;
62     callbackInfo->sppOption_ = GetSppOptionFromJS(env, argv[PARAM1]);
63     callbackInfo->name_ = name;
64 
65     napi_value promise = nullptr;
66 
67     if (argc == expectedArgsCount) {
68         HILOGI("SppListen callback mode");
69         napi_valuetype valueType = napi_undefined;
70         napi_typeof(env, argv[PARAM2], &valueType);
71         if (valueType != napi_function) {
72             HILOGE("Wrong argument type. Function expected.");
73             return ret;
74         }
75         napi_create_reference(env, argv[PARAM2], 1, &callbackInfo->callback_);
76         napi_get_undefined(env, &promise);
77     } else {
78         HILOGI("SppListen promise mode");
79         napi_create_promise(env, &callbackInfo->deferred_, &promise);
80     }
81 
82     napi_value resource = nullptr;
83     napi_create_string_utf8(env, "SppListen", NAPI_AUTO_LENGTH, &resource);
84 
85     napi_create_async_work(
86         env, nullptr, resource,
87         [](napi_env env, void* data) {
88             HILOGI("SppListen execute");
89             SppListenCallbackInfo* callbackInfo = (SppListenCallbackInfo*)data;
90             callbackInfo->server_ = std::make_shared<SppServerSocket>(callbackInfo->name_,
91                 UUID::FromString(callbackInfo->sppOption_->uuid_), callbackInfo->sppOption_->type_,
92                 callbackInfo->sppOption_->secure_);
93             HILOGI("SppListen SppServerSocket constructor end");
94             if (callbackInfo->server_ ->GetStringTag() != "") {
95                 HILOGI("SppListen execute listen success");
96                 callbackInfo->errorCode_ = CODE_SUCCESS;
97             } else {
98                 HILOGI("SppListen execute listen failed");
99                 callbackInfo->errorCode_ = CODE_FAILED;
100             }
101         },
102         [](napi_env env, napi_status status, void* data) {
103             HILOGI("SppListen execute back");
104             SppListenCallbackInfo* callbackInfo = (SppListenCallbackInfo*)data;
105             napi_value result[ARGS_SIZE_TWO] = {0};
106             napi_value callback = 0;
107             napi_value undefined = 0;
108             napi_value callResult = 0;
109             napi_get_undefined(env, &undefined);
110 
111             if (callbackInfo->errorCode_ == CODE_SUCCESS) {
112                 HILOGI("SppListen execute back listen success");
113                 std::shared_ptr<NapiSppServer> server =  std::make_shared<NapiSppServer>();
114                 server->id_ = NapiSppServer::count++;
115                 napi_create_int32(env, server->id_, &result[PARAM1]);
116                 server->server_ = callbackInfo->server_;
117                 serverMap.insert(std::make_pair(server->id_, server));
118             } else {
119                 HILOGI("SppListen execute back listen failed");
120                 napi_get_undefined(env, &result[PARAM1]);
121             }
122 
123             if (callbackInfo->callback_) {
124                 HILOGI("SppListen execute back listen Callback mode success");
125                 result[PARAM0] = GetCallbackErrorValue(callbackInfo->env_, callbackInfo->errorCode_);
126                 napi_get_reference_value(env, callbackInfo->callback_, &callback);
127                 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
128                 napi_delete_reference(env, callbackInfo->callback_);
129             } else {
130                 if (callbackInfo->errorCode_ == CODE_SUCCESS) {
131                     HILOGI("SppListen execute back listen Promise mode success");
132                     napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
133                 } else {
134                     HILOGI("SppListen execute back listen Promise mode failed");
135                     napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM1]);
136                 }
137             }
138             napi_delete_async_work(env, callbackInfo->asyncWork_);
139             delete callbackInfo;
140             callbackInfo = nullptr;
141         },
142         (void*)callbackInfo,
143         &callbackInfo->asyncWork_);
144 
145     napi_queue_async_work(env, callbackInfo->asyncWork_);
146 
147     return ret;
148 }
149 
150 
SppAccept(napi_env env,napi_callback_info info)151 napi_value NapiSppServer::SppAccept(napi_env env, napi_callback_info info)
152 {
153     HILOGI("SppAccept called");
154     size_t expectedArgsCount = ARGS_SIZE_TWO;
155     size_t argc = expectedArgsCount;
156     napi_value argv[ARGS_SIZE_TWO] = {0};
157 
158     napi_value ret = nullptr;
159     napi_get_undefined(env, &ret);
160 
161     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
162     if (argc != expectedArgsCount && argc != expectedArgsCount - CALLBACK_SIZE) {
163         HILOGE("Requires 2 or 3 arguments.");
164         return ret;
165     }
166 
167     int32_t serverSocketNum = -1;
168     if (!ParseInt32(env, serverSocketNum, argv[PARAM0])) {
169         HILOGE("Wrong argument type. int expected.");
170         return ret;
171     }
172     std::shared_ptr<NapiSppServer> server = serverMap[serverSocketNum];
173     if (!server) {
174         HILOGE("server is null");
175         return ret;
176     }
177 
178     SppAcceptCallbackInfo *callbackInfo = new SppAcceptCallbackInfo();
179     callbackInfo->env_ = env;
180     callbackInfo->server_ = server->server_;
181 
182     napi_value promise = nullptr;
183 
184     if (argc == expectedArgsCount) {
185         HILOGI("SppAccept callback mode");
186         napi_valuetype valueType = napi_undefined;
187         napi_typeof(env, argv[PARAM1], &valueType);
188         if (valueType != napi_function) {
189             HILOGE("Wrong argument type. Function expected.");
190             delete callbackInfo;
191             callbackInfo = nullptr;
192             return ret;
193         }
194         napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
195         napi_get_undefined(env, &promise);
196     } else {
197         HILOGI("SppAccept promise mode");
198         napi_create_promise(env, &callbackInfo->deferred_, &promise);
199     }
200 
201     napi_value resource = nullptr;
202     napi_create_string_utf8(env, "SppAccept", NAPI_AUTO_LENGTH, &resource);
203 
204     napi_create_async_work(
205         env, nullptr, resource,
206         [](napi_env env, void* data) {
207             HILOGI("SppAccept execute");
208             SppAcceptCallbackInfo* callbackInfo = (SppAcceptCallbackInfo*)data;
209             callbackInfo->client_ = callbackInfo->server_->Accept(num_20);
210             if (callbackInfo->client_ != nullptr) {
211                 callbackInfo->errorCode_ = CODE_SUCCESS;
212             } else {
213                 callbackInfo->errorCode_ = CODE_FAILED;
214             }
215         },
216         [](napi_env env, napi_status status, void* data) {
217             HILOGI("SppAccept execute back");
218             SppAcceptCallbackInfo* callbackInfo = (SppAcceptCallbackInfo*)data;
219             napi_value result[ARGS_SIZE_TWO] = {0};
220             napi_value callback = 0;
221             napi_value undefined = 0;
222             napi_value callResult = 0;
223             napi_get_undefined(env, &undefined);
224 
225             if (callbackInfo->errorCode_ == CODE_SUCCESS) {
226                 std::shared_ptr<NapiSppClient> client =  std::make_shared<NapiSppClient>();
227                 client->id_ = NapiSppClient::count++;
228                 napi_create_int32(env, client->id_, &result[PARAM1]);
229                 client->client_ = callbackInfo->client_;
230                 NapiSppClient::clientMap.insert(std::make_pair(client->id_, client));
231             } else {
232                 napi_get_undefined(env, &result[PARAM1]);
233             }
234 
235             if (callbackInfo->callback_) {
236                 result[PARAM0] = GetCallbackErrorValue(callbackInfo->env_, callbackInfo->errorCode_);
237                 napi_get_reference_value(env, callbackInfo->callback_, &callback);
238                 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
239                 napi_delete_reference(env, callbackInfo->callback_);
240             } else {
241                 if (callbackInfo->errorCode_ == CODE_SUCCESS) {
242                     napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
243                 } else {
244                     napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM1]);
245                 }
246             }
247             napi_delete_async_work(env, callbackInfo->asyncWork_);
248             delete callbackInfo;
249             callbackInfo = nullptr;
250         },
251         (void*)callbackInfo,
252         &callbackInfo->asyncWork_);
253 
254     napi_queue_async_work(env, callbackInfo->asyncWork_);
255 
256     return ret;
257 }
258 
SppCloseServerSocket(napi_env env,napi_callback_info info)259 napi_value NapiSppServer::SppCloseServerSocket(napi_env env, napi_callback_info info)
260 {
261     HILOGI("SppCloseServerSocket called");
262     size_t expectedArgsCount = ARGS_SIZE_ONE;
263     size_t argc = expectedArgsCount;
264     napi_value argv[ARGS_SIZE_ONE] = {0};
265     napi_value thisVar = nullptr;
266     bool isOK = false;
267     napi_value ret = nullptr;
268 
269     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
270     if (argc != expectedArgsCount) {
271         HILOGE("Requires 1 argument.");
272         return ret;
273     }
274 
275     std::shared_ptr<NapiSppServer> server = nullptr;
276     std::shared_ptr<NapiSppClient> client = nullptr;
277     int id =  -1;
278     ParseInt32(env, id, argv[PARAM0]);
279 
280     if (NapiSppClient::clientMap[id] != nullptr) {
281         client = NapiSppClient::clientMap[id];
282         if (client->client_) {
283             client->client_->Close();
284             NapiSppClient::clientMap.erase(id);
285         }
286     } else {
287         HILOGE("no such key in clientMap.");
288     }
289 
290     if (serverMap[id] != nullptr) {
291         server = serverMap[id];
292         if (server->server_) {
293             server->server_->Close();
294             serverMap.erase(id);
295             isOK = true;
296         }
297     } else {
298         HILOGE("no such key in serverMap.");
299     }
300 
301     napi_get_boolean(env, isOK, &ret);
302     return ret;
303 }
304 } // namespace Bluetooth
305 } // namespace OHOS
306