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
16 #include "wifi_napi_p2p.h"
17 #include "wifi_logger.h"
18
19 namespace OHOS {
20 namespace Wifi {
21 DEFINE_WIFILOG_LABEL("WifiNAPIP2p");
22
23 std::unique_ptr<WifiP2p> wifiP2pPtr = WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
DeviceInfoToJs(const napi_env & env,const WifiP2pDevice & device,napi_value & result)24 static void DeviceInfoToJs(const napi_env& env, const WifiP2pDevice& device, napi_value& result)
25 {
26 SetValueUtf8String(env, "deviceName", device.GetDeviceName().c_str(), result);
27 SetValueUtf8String(env, "deviceAddress", device.GetDeviceAddress().c_str(), result);
28 SetValueUtf8String(env, "primaryDeviceType", device.GetPrimaryDeviceType().c_str(), result);
29 SetValueInt32(env, "deviceStatus", static_cast<int>(device.GetP2pDeviceStatus()), result);
30 SetValueInt32(env, "groupCapabilitys", device.GetGroupCapabilitys(), result);
31 }
32
DevicesToJsArray(const napi_env & env,const std::vector<WifiP2pDevice> & vecDevices,napi_value & arrayResult)33 static ErrCode DevicesToJsArray(const napi_env& env,
34 const std::vector<WifiP2pDevice>& vecDevices, napi_value& arrayResult)
35 {
36 uint32_t idx = 0;
37 for (auto& each : vecDevices) {
38 napi_value eachObj;
39 napi_create_object(env, &eachObj);
40 DeviceInfoToJs(env, each, eachObj);
41 napi_status status = napi_set_element(env, arrayResult, idx++, eachObj);
42 if (status != napi_ok) {
43 WIFI_LOGE("wifi napi set element error: %{public}d, idx: %{public}d", status, idx - 1);
44 return WIFI_OPT_FAILED;
45 }
46 }
47 return WIFI_OPT_SUCCESS;
48 }
49
GroupInfosToJs(const napi_env & env,WifiP2pGroupInfo & groupInfo,napi_value & result)50 static ErrCode GroupInfosToJs(const napi_env& env, WifiP2pGroupInfo& groupInfo, napi_value& result)
51 {
52 SetValueBool(env, "isP2pGo", groupInfo.IsGroupOwner(), result);
53
54 WifiP2pDevice ownerDevice = groupInfo.GetOwner();
55 napi_value owner;
56 napi_create_object(env, &owner);
57 DeviceInfoToJs(env, ownerDevice, owner);
58 napi_status status = napi_set_named_property(env, result, "ownerInfo", owner);
59 if (status != napi_ok) {
60 WIFI_LOGE("napi_set_named_property ownerInfo fail");
61 return WIFI_OPT_FAILED;
62 }
63
64 SetValueUtf8String(env, "passphrase", groupInfo.GetPassphrase().c_str(), result);
65 SetValueUtf8String(env, "interface", groupInfo.GetInterface().c_str(), result);
66 SetValueUtf8String(env, "groupName", groupInfo.GetGroupName().c_str(), result);
67 SetValueInt32(env, "networkId", groupInfo.GetNetworkId(), result);
68 SetValueInt32(env, "frequency", groupInfo.GetFrequency(), result);
69
70 if (!groupInfo.IsClientDevicesEmpty()) {
71 const std::vector<OHOS::Wifi::WifiP2pDevice>& vecDevices = groupInfo.GetClientDevices();
72 napi_value devices;
73 napi_create_array_with_length(env, vecDevices.size(), &devices);
74 if (DevicesToJsArray(env, vecDevices, devices) != WIFI_OPT_SUCCESS) {
75 return WIFI_OPT_FAILED;
76 }
77 status = napi_set_named_property(env, result, "clientDevices", devices);
78 if (status != napi_ok) {
79 WIFI_LOGE("napi_set_named_property clientDevices fail");
80 return WIFI_OPT_FAILED;
81 }
82 }
83 SetValueUtf8String(env, "goIpAddress", groupInfo.GetGoIpAddress().c_str(), result);
84 return WIFI_OPT_SUCCESS;
85 }
86
GetCurrentGroup(napi_env env,napi_callback_info info)87 napi_value GetCurrentGroup(napi_env env, napi_callback_info info)
88 {
89 TRACE_FUNC_CALL;
90 size_t argc = 1;
91 napi_value argv[argc];
92 napi_value thisVar = nullptr;
93 void *data = nullptr;
94 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
95
96 P2pGroupInfoAsyncContext *asyncContext = new P2pGroupInfoAsyncContext(env);
97 NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
98 napi_create_string_latin1(env, "getCurrentGroup", NAPI_AUTO_LENGTH, &asyncContext->resourceName);
99
100 asyncContext->executeFunc = [&](void* data) -> void {
101 P2pGroupInfoAsyncContext *context = static_cast<P2pGroupInfoAsyncContext *>(data);
102 TRACE_FUNC_CALL_NAME("wifiP2pPtr->GetCurrentGroup");
103 context->errorCode = wifiP2pPtr->GetCurrentGroup(context->groupInfo);
104 };
105
106 asyncContext->completeFunc = [&](void* data) -> void {
107 P2pGroupInfoAsyncContext *context = static_cast<P2pGroupInfoAsyncContext *>(data);
108 napi_create_object(context->env, &context->result);
109 context->errorCode = GroupInfosToJs(context->env, context->groupInfo, context->result);
110 WIFI_LOGI("Push get current group result to client");
111 };
112
113 size_t nonCallbackArgNum = 0;
114 return DoAsyncWork(env, asyncContext, argc, argv, nonCallbackArgNum);
115 }
116
DeletePersistentGroup(napi_env env,napi_callback_info info)117 napi_value DeletePersistentGroup(napi_env env, napi_callback_info info)
118 {
119 TRACE_FUNC_CALL;
120 size_t argc = 1;
121 napi_value argv[argc];
122 napi_value thisVar;
123 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
124
125 napi_valuetype valueType;
126 napi_typeof(env, argv[0], &valueType);
127 NAPI_ASSERT(env, valueType == napi_number, "Wrong argument type. napi_number expected.");
128
129 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
130 WifiP2pGroupInfo groupInfo;
131 int netId = -999;
132 napi_get_value_int32(env, argv[0], &netId);
133 groupInfo.SetNetworkId(netId);
134 ErrCode ret = wifiP2pPtr->DeleteGroup(groupInfo);
135 napi_value result;
136 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
137 return result;
138 }
139
StartDiscoverDevices(napi_env env,napi_callback_info info)140 napi_value StartDiscoverDevices(napi_env env, napi_callback_info info)
141 {
142 TRACE_FUNC_CALL;
143 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
144
145 ErrCode ret = wifiP2pPtr->DiscoverDevices();
146 napi_value result;
147 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
148 return result;
149 }
150
StopDiscoverDevices(napi_env env,napi_callback_info info)151 napi_value StopDiscoverDevices(napi_env env, napi_callback_info info)
152 {
153 TRACE_FUNC_CALL;
154 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
155
156 ErrCode ret = wifiP2pPtr->StopDiscoverDevices();
157 napi_value result;
158 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
159 return result;
160 }
161
GetP2pDevices(napi_env env,napi_callback_info info)162 napi_value GetP2pDevices(napi_env env, napi_callback_info info)
163 {
164 size_t argc = 1;
165 napi_value argv[argc];
166 napi_value thisVar = nullptr;
167 void *data = nullptr;
168 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
169 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
170
171 QueryP2pDeviceAsyncContext *asyncContext = new QueryP2pDeviceAsyncContext(env);
172 NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
173 napi_create_string_latin1(env, "GetP2pDevices", NAPI_AUTO_LENGTH, &asyncContext->resourceName);
174
175 asyncContext->executeFunc = [&](void* data) -> void {
176 QueryP2pDeviceAsyncContext *context = static_cast<QueryP2pDeviceAsyncContext *>(data);
177 context->errorCode = wifiP2pPtr->QueryP2pDevices(context->vecP2pDevices);
178 WIFI_LOGI("GetP2pDeviceList, size: %{public}zu", context->vecP2pDevices.size());
179 };
180
181 asyncContext->completeFunc = [&](void* data) -> void {
182 QueryP2pDeviceAsyncContext *context = static_cast<QueryP2pDeviceAsyncContext *>(data);
183 napi_create_array_with_length(context->env, context->vecP2pDevices.size(), &context->result);
184 context->errorCode = DevicesToJsArray(context->env, context->vecP2pDevices, context->result);
185 WIFI_LOGI("Push P2p Device List to client");
186 };
187
188 size_t nonCallbackArgNum = 0;
189 return DoAsyncWork(env, asyncContext, argc, argv, nonCallbackArgNum);
190 }
191
SetDeviceName(napi_env env,napi_callback_info info)192 napi_value SetDeviceName(napi_env env, napi_callback_info info)
193 {
194 TRACE_FUNC_CALL;
195 size_t argc = 1;
196 napi_value argv[1];
197 napi_value thisVar;
198 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
199 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
200
201 napi_valuetype valueType;
202 napi_typeof(env, argv[0], &valueType);
203 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument type. napi_number expected.");
204
205 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
206
207 char name[64] = {0};
208 size_t typeLen = 0;
209 napi_get_value_string_utf8(env, argv[0], name, sizeof(name), &typeLen);
210 ErrCode ret = wifiP2pPtr->SetP2pDeviceName(name);
211 napi_value result;
212 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
213 return result;
214 }
215
JsObjToP2pConfig(const napi_env & env,const napi_value & object,WifiP2pConfig & config)216 static void JsObjToP2pConfig(const napi_env& env, const napi_value& object, WifiP2pConfig& config)
217 {
218 std::string address = "";
219 int netId = -1;
220 std::string passphrase = "";
221 std::string groupName = "";
222 int band = static_cast<int>(GroupOwnerBand::GO_BAND_AUTO);
223 JsObjectToString(env, object, "deviceAddress", WIFI_STR_MAC_LENGTH + 1, address);
224 JsObjectToInt(env, object, "netId", netId);
225 JsObjectToString(env, object, "passphrase", MAX_PASSPHRASE_LENGTH + 1, passphrase);
226 JsObjectToString(env, object, "groupName", DEVICE_NAME_LENGTH + 1, groupName);
227 JsObjectToInt(env, object, "goBand", band);
228 config.SetDeviceAddress(address);
229 config.SetNetId(netId);
230 config.SetPassphrase(passphrase);
231 config.SetGroupName(groupName);
232 config.SetGoBand(static_cast<GroupOwnerBand>(band));
233 }
234
P2pConnect(napi_env env,napi_callback_info info)235 napi_value P2pConnect(napi_env env, napi_callback_info info)
236 {
237 TRACE_FUNC_CALL;
238 size_t argc = 1;
239 napi_value argv[argc];
240 napi_value thisVar;
241 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
242
243 napi_valuetype valueType;
244 napi_typeof(env, argv[0], &valueType);
245 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type. Object expected.");
246
247 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
248 WifiP2pConfig config;
249 JsObjToP2pConfig(env, argv[0], config);
250 ErrCode ret = wifiP2pPtr->P2pConnect(config);
251 if (ret != WIFI_OPT_SUCCESS) {
252 WIFI_LOGE("Connect to device fail: %{public}d", ret);
253 }
254 napi_value result;
255 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
256 return result;
257 }
258
P2pCancelConnect(napi_env env,napi_callback_info info)259 napi_value P2pCancelConnect(napi_env env, napi_callback_info info)
260 {
261 TRACE_FUNC_CALL;
262 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
263
264 ErrCode ret = wifiP2pPtr->P2pDisConnect();
265 napi_value result;
266 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
267 return result;
268 }
269
CreateGroup(napi_env env,napi_callback_info info)270 napi_value CreateGroup(napi_env env, napi_callback_info info)
271 {
272 TRACE_FUNC_CALL;
273 size_t argc = 1;
274 napi_value argv[1];
275 napi_value thisVar;
276 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
277
278 napi_valuetype valueType;
279 napi_typeof(env, argv[0], &valueType);
280 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type. Object expected.");
281
282 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
283 WifiP2pConfig config;
284 JsObjToP2pConfig(env, argv[0], config);
285 ErrCode ret = wifiP2pPtr->FormGroup(config);
286 napi_value result;
287 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
288 return result;
289 }
290
RemoveGroup(napi_env env,napi_callback_info info)291 napi_value RemoveGroup(napi_env env, napi_callback_info info)
292 {
293 TRACE_FUNC_CALL;
294 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
295
296 ErrCode ret = wifiP2pPtr->RemoveGroup();
297 napi_value result;
298 napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
299 return result;
300 }
301
LinkedInfoToJs(const napi_env & env,WifiP2pLinkedInfo & linkedInfo,napi_value & result)302 static void LinkedInfoToJs(const napi_env& env, WifiP2pLinkedInfo& linkedInfo, napi_value& result)
303 {
304 SetValueInt32(env, "connectState", static_cast<int>(linkedInfo.GetConnectState()), result);
305 SetValueBool(env, "isGroupOwner", linkedInfo.IsGroupOwner(), result);
306 SetValueUtf8String(env, "groupOwnerAddr", linkedInfo.GetGroupOwnerAddress().c_str(), result);
307 }
308
GetP2pLinkedInfo(napi_env env,napi_callback_info info)309 napi_value GetP2pLinkedInfo(napi_env env, napi_callback_info info)
310 {
311 TRACE_FUNC_CALL;
312 size_t argc = 1;
313 napi_value argv[argc];
314 napi_value thisVar = nullptr;
315 void *data = nullptr;
316 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
317 NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
318
319 P2pLinkedInfoAsyncContext *asyncContext = new P2pLinkedInfoAsyncContext(env);
320 NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
321 napi_create_string_latin1(env, "queryP2pLinkedInfo", NAPI_AUTO_LENGTH, &asyncContext->resourceName);
322
323 asyncContext->executeFunc = [&](void* data) -> void {
324 P2pLinkedInfoAsyncContext *context = static_cast<P2pLinkedInfoAsyncContext *>(data);
325 TRACE_FUNC_CALL_NAME("wifiP2pPtr->QueryP2pLinkedInfo");
326 context->errorCode = wifiP2pPtr->QueryP2pLinkedInfo(context->linkedInfo);
327 };
328
329 asyncContext->completeFunc = [&](void* data) -> void {
330 P2pLinkedInfoAsyncContext *context = static_cast<P2pLinkedInfoAsyncContext *>(data);
331 napi_create_object(context->env, &context->result);
332 LinkedInfoToJs(context->env, context->linkedInfo, context->result);
333 WIFI_LOGI("Push get linkedInfo result to client");
334 };
335
336 size_t nonCallbackArgNum = 0;
337 return DoAsyncWork(env, asyncContext, argc, argv, nonCallbackArgNum);
338 }
339 } // namespace Wifi
340 } // namespace OHOS
341