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_scan_proxy.h"
17 #include <cstddef>
18 #include <cstdint>
19 #include <new>
20 #include <string>
21 #include "define.h"
22 #include "wifi_manager_service_ipc_interface_code.h"
23 #include "ipc_types.h"
24 #include "iremote_proxy.h"
25 #include "message_option.h"
26 #include "message_parcel.h"
27 #include "wifi_common_util.h"
28 #include "wifi_hisysevent.h"
29 #include "wifi_logger.h"
30 #include "wifi_scan_callback_stub.h"
31
32 namespace OHOS {
33 DEFINE_WIFILOG_SCAN_LABEL("WifiScanProxy");
34 namespace Wifi {
35 static sptr<WifiScanCallbackStub> g_wifiScanCallbackStub =
36 sptr<WifiScanCallbackStub>(new (std::nothrow) WifiScanCallbackStub());
37
WifiScanProxy(const sptr<IRemoteObject> & remote)38 WifiScanProxy::WifiScanProxy(const sptr<IRemoteObject> &remote) : IRemoteProxy<IWifiScan>(remote),
39 mRemoteDied(false), remote_(nullptr), deathRecipient_(nullptr)
40 {
41 std::lock_guard<std::mutex> lock(mutex_);
42 if (remote) {
43 if (!remote->IsProxyObject()) {
44 WIFI_LOGW("not proxy object!");
45 return;
46 }
47 deathRecipient_ = new (std::nothrow) WifiDeathRecipient(*this);
48 if (deathRecipient_ == nullptr) {
49 WIFI_LOGW("deathRecipient_ is nullptr!");
50 }
51 if (!remote->AddDeathRecipient(deathRecipient_)) {
52 WIFI_LOGW("AddDeathRecipient failed!");
53 return;
54 }
55 remote_ = remote;
56 WIFI_LOGI("AddDeathRecipient success! deathRecipient_");
57 }
58 }
59
~WifiScanProxy()60 WifiScanProxy::~WifiScanProxy()
61 {
62 WIFI_LOGI("enter ~WifiScanProxy!");
63 RemoveDeathRecipient();
64 }
65
RemoveDeathRecipient(void)66 void WifiScanProxy::RemoveDeathRecipient(void)
67 {
68 WIFI_LOGI("enter RemoveDeathRecipient, deathRecipient_!");
69 std::lock_guard<std::mutex> lock(mutex_);
70 if (remote_ == nullptr) {
71 WIFI_LOGI("remote_ is nullptr!");
72 return;
73 }
74 if (deathRecipient_ == nullptr) {
75 WIFI_LOGI("deathRecipient_ is nullptr!");
76 return;
77 }
78 remote_->RemoveDeathRecipient(deathRecipient_);
79 remote_ = nullptr;
80 }
81
SetScanControlInfo(const ScanControlInfo & info)82 ErrCode WifiScanProxy::SetScanControlInfo(const ScanControlInfo &info)
83 {
84 if (mRemoteDied) {
85 WIFI_LOGW("failed to SetScanControlInfo, remote service is died!");
86 return WIFI_OPT_FAILED;
87 }
88 MessageOption option;
89 MessageParcel data;
90 MessageParcel reply;
91 if (!data.WriteInterfaceToken(GetDescriptor())) {
92 WIFI_LOGE("SetScanControlInfo Write interface token error!");
93 return WIFI_OPT_FAILED;
94 }
95 data.WriteInt32(0);
96 data.WriteInt32(info.scanForbidList.size());
97 for (auto iter = info.scanForbidList.begin(); iter != info.scanForbidList.end(); iter++) {
98 data.WriteInt32(iter->scanScene);
99 data.WriteInt32(static_cast<int>(iter->scanMode));
100 data.WriteInt32(iter->forbidTime);
101 data.WriteInt32(iter->forbidCount);
102 }
103
104 data.WriteInt32(info.scanIntervalList.size());
105 for (auto iter2 = info.scanIntervalList.begin(); iter2 != info.scanIntervalList.end(); iter2++) {
106 data.WriteInt32(iter2->scanScene);
107 data.WriteInt32(static_cast<int>(iter2->scanMode));
108 data.WriteBool(iter2->isSingle);
109 data.WriteInt32(static_cast<int>(iter2->intervalMode));
110 data.WriteInt32(iter2->interval);
111 data.WriteInt32(iter2->count);
112 }
113
114 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SET_SCAN_CONTROL_INFO),
115 data, reply, option);
116 if (error != ERR_NONE) {
117 WIFI_LOGW("Set Attr(%{public}d) failed",
118 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SET_SCAN_CONTROL_INFO));
119 return WIFI_OPT_FAILED;
120 }
121 int exception = reply.ReadInt32();
122 if (exception) {
123 WIFI_LOGE("SetScanControlInfo Reply exception failed!");
124 return WIFI_OPT_FAILED;
125 }
126 int ret = reply.ReadInt32();
127 if (ErrCode(ret) != WIFI_OPT_SUCCESS) {
128 WIFI_LOGE("SetScanControlInfo Reply ReadInt32 failed, ret:%{public}d", ret);
129 return ErrCode(ret);
130 }
131 return WIFI_OPT_SUCCESS;
132 }
133
Scan(bool compatible)134 ErrCode WifiScanProxy::Scan(bool compatible)
135 {
136 if (mRemoteDied) {
137 WIFI_LOGW("failed to Scan, remote service is died!");
138 return WIFI_OPT_FAILED;
139 }
140 MessageOption option;
141 MessageParcel data;
142 MessageParcel reply;
143 if (!data.WriteInterfaceToken(GetDescriptor())) {
144 WIFI_LOGE("Scan Write interface token error!");
145 return WIFI_OPT_FAILED;
146 }
147 data.WriteInt32(0);
148 data.WriteBool(compatible);
149 data.WriteString(GetBundleName());
150 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_FULL_SCAN), data, reply,
151 option);
152 if (error != ERR_NONE) {
153 WIFI_LOGW("Set Attr(%{public}d) failed", static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_FULL_SCAN));
154 return WIFI_OPT_FAILED;
155 }
156 int exception = reply.ReadInt32();
157 if (exception) {
158 return WIFI_OPT_FAILED;
159 }
160 int ret = reply.ReadInt32();
161 /* Record sysevent for scan */
162 WriteWifiScanHiSysEvent(static_cast<int>(ret), GetBundleName());
163 if (ErrCode(ret) != WIFI_OPT_SUCCESS) {
164 return ErrCode(ret);
165 }
166 return WIFI_OPT_SUCCESS;
167 }
168
AdvanceScan(const WifiScanParams & params)169 ErrCode WifiScanProxy::AdvanceScan(const WifiScanParams ¶ms)
170 {
171 if (mRemoteDied) {
172 WIFI_LOGW("failed to AdvanceScan, remote service is died!");
173 return WIFI_OPT_FAILED;
174 }
175 MessageOption option;
176 MessageParcel data;
177 MessageParcel reply;
178 if (!data.WriteInterfaceToken(GetDescriptor())) {
179 WIFI_LOGE("AdvanceScan Write interface token error!");
180 return WIFI_OPT_FAILED;
181 }
182 data.WriteInt32(0);
183 data.WriteCString(params.ssid.c_str());
184 data.WriteCString(params.bssid.c_str());
185 data.WriteInt32(params.freqs.size());
186 for (std::size_t i = 0; i < params.freqs.size(); i++) {
187 data.WriteInt32(params.freqs[i]);
188 }
189 data.WriteInt32(params.band);
190 data.WriteString(GetBundleName());
191
192 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SPECIFIED_PARAMS_SCAN),
193 data, reply, option);
194 if (error != ERR_NONE) {
195 WIFI_LOGW("Set Attr(%{public}d) failed",
196 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SPECIFIED_PARAMS_SCAN));
197 return WIFI_OPT_FAILED;
198 }
199 int exception = reply.ReadInt32();
200 if (exception) {
201 return WIFI_OPT_FAILED;
202 }
203 int ret = reply.ReadInt32();
204 /* Record sysevent for scan */
205 WriteWifiScanHiSysEvent(static_cast<int>(ret), GetBundleName());
206 if (ErrCode(ret) != WIFI_OPT_SUCCESS) {
207 return ErrCode(ret);
208 }
209 return WIFI_OPT_SUCCESS;
210 }
211
IsWifiClosedScan(bool & bOpen)212 ErrCode WifiScanProxy::IsWifiClosedScan(bool &bOpen)
213 {
214 if (mRemoteDied) {
215 WIFI_LOGW("failed to IsWifiClosedScan, remote service is died!");
216 return WIFI_OPT_FAILED;
217 }
218 MessageOption option;
219 MessageParcel data;
220 MessageParcel reply;
221 if (!data.WriteInterfaceToken(GetDescriptor())) {
222 WIFI_LOGE("IsWifiClosedScan Write interface token error!");
223 return WIFI_OPT_FAILED;
224 }
225 data.WriteInt32(0);
226 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_IS_SCAN_ALWAYS_ACTIVE),
227 data, reply, option);
228 if (error != ERR_NONE) {
229 WIFI_LOGW("Set Attr(%{public}d) failed",
230 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_IS_SCAN_ALWAYS_ACTIVE));
231 return WIFI_OPT_FAILED;
232 }
233 int exception = reply.ReadInt32();
234 if (exception) {
235 WIFI_LOGE("IsWifiClosedScan Reply exception failed!");
236 return WIFI_OPT_FAILED;
237 }
238 int ret = reply.ReadInt32();
239 if (ErrCode(ret) != WIFI_OPT_SUCCESS) {
240 WIFI_LOGE("IsWifiClosedScan Reply ReadInt32 failed, ret:%{public}d", ret);
241 return ErrCode(ret);
242 }
243 bOpen = reply.ReadBool();
244 return WIFI_OPT_SUCCESS;
245 }
246
GetScanInfoList(std::vector<WifiScanInfo> & result,bool compatible)247 ErrCode WifiScanProxy::GetScanInfoList(std::vector<WifiScanInfo> &result, bool compatible)
248 {
249 if (mRemoteDied) {
250 WIFI_LOGW("failed to GetScanInfoList, remote service is died!");
251 return WIFI_OPT_FAILED;
252 }
253 MessageOption option;
254 MessageParcel data;
255 MessageParcel reply;
256 if (!data.WriteInterfaceToken(GetDescriptor())) {
257 WIFI_LOGE("GetScanInfoList Write interface token error!");
258 return WIFI_OPT_FAILED;
259 }
260 data.WriteInt32(0);
261 data.WriteBool(compatible);
262 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_GET_SCAN_INFO_LIST), data,
263 reply, option);
264 if (error != ERR_NONE) {
265 WIFI_LOGW("Set Attr(%{public}d) failed",
266 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_GET_SCAN_INFO_LIST));
267 return WIFI_OPT_FAILED;
268 }
269 int exception = reply.ReadInt32();
270 if (exception) {
271 WIFI_LOGE("GetScanInfoList Reply exception failed!");
272 return WIFI_OPT_FAILED;
273 }
274 int ret = reply.ReadInt32();
275 if (ErrCode(ret) != WIFI_OPT_SUCCESS) {
276 WIFI_LOGE("GetScanInfoList Reply ReadInt32 failed, ret:%{public}d", ret);
277 return ErrCode(ret);
278 }
279
280 constexpr int MAX_SIZE = 4096;
281 int tmpsize = reply.ReadInt32();
282 if (tmpsize > MAX_SIZE) {
283 WIFI_LOGE("Scan info size exceeds maximum allowed size: %{public}d", tmpsize);
284 return WIFI_OPT_FAILED;
285 }
286 for (int i = 0; i < tmpsize; ++i) {
287 WifiScanInfo info;
288 info.bssid = reply.ReadString();
289 info.bssidType = reply.ReadInt32();
290 info.ssid = reply.ReadString();
291 info.capabilities = reply.ReadString();
292 info.frequency = reply.ReadInt32();
293 info.rssi = reply.ReadInt32();
294 info.timestamp = reply.ReadInt64();
295 info.band = reply.ReadInt32();
296 info.securityType = static_cast<WifiSecurity>(reply.ReadInt32());
297 info.channelWidth = static_cast<WifiChannelWidth>(reply.ReadInt32());
298 info.centerFrequency0 = reply.ReadInt32();
299 info.centerFrequency1 = reply.ReadInt32();
300 info.features = reply.ReadInt64();
301
302 constexpr int IE_SIZE_MAX = 256;
303 int ieSize = reply.ReadInt32();
304 if (ieSize > IE_SIZE_MAX) {
305 WIFI_LOGE("ie size error: %{public}d", ieSize);
306 return WIFI_OPT_FAILED;
307 }
308 for (int m = 0; m < ieSize; ++m) {
309 WifiInfoElem tempWifiInfoElem;
310 tempWifiInfoElem.id = reply.ReadInt32();
311 int contentSize = reply.ReadInt32();
312 for (int n = 0; n < contentSize; n++) {
313 char tempChar = static_cast<char>(reply.ReadInt8());
314 tempWifiInfoElem.content.emplace_back(tempChar);
315 }
316 info.infoElems.emplace_back(tempWifiInfoElem);
317 }
318 result.emplace_back(info);
319 }
320 return WIFI_OPT_SUCCESS;
321 }
322
RegisterCallBack(const sptr<IWifiScanCallback> & callback,const std::vector<std::string> & event)323 ErrCode WifiScanProxy::RegisterCallBack(const sptr<IWifiScanCallback> &callback, const std::vector<std::string> &event)
324 {
325 if (mRemoteDied) {
326 WIFI_LOGW("failed to `%{public}s`,remote service is died!", __func__);
327 return WIFI_OPT_FAILED;
328 }
329 WIFI_LOGD("RegisterCallBack start!");
330 MessageParcel data;
331 MessageParcel reply;
332 MessageOption option(MessageOption::TF_ASYNC);
333
334 if (g_wifiScanCallbackStub == nullptr) {
335 WIFI_LOGE("g_wifiScanCallbackStub is nullptr!");
336 return WIFI_OPT_FAILED;
337 }
338 g_wifiScanCallbackStub->RegisterCallBack(callback);
339 if (!data.WriteInterfaceToken(GetDescriptor())) {
340 WIFI_LOGE("Write interface token error: %{public}s", __func__);
341 return WIFI_OPT_FAILED;
342 }
343 data.WriteInt32(0);
344 if (!data.WriteRemoteObject(g_wifiScanCallbackStub->AsObject())) {
345 WIFI_LOGE("RegisterCallBack WriteRemoteObject failed!");
346 return WIFI_OPT_FAILED;
347 }
348
349 int pid = GetCallingPid();
350 data.WriteInt32(pid);
351 int tokenId = GetCallingTokenId();
352 data.WriteInt32(tokenId);
353 int eventNum = event.size();
354 data.WriteInt32(eventNum);
355 if (eventNum > 0) {
356 for (auto &eventName : event) {
357 data.WriteString(eventName);
358 }
359 }
360 WIFI_LOGD("%{public}s, calling uid: %{public}d, pid: %{public}d, tokenId: %{private}d",
361 __func__, GetCallingUid(), pid, tokenId);
362 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_REGISTER_SCAN_CALLBACK),
363 data, reply, option);
364 if (error != ERR_NONE) {
365 WIFI_LOGE("RegisterCallBack failed, error code is %{public}d", error);
366 return WIFI_OPT_FAILED;
367 }
368 int32_t ret = reply.ReadInt32();
369 WIFI_LOGD("RegisterCallBack is finished: result=%{public}d", ret);
370 return WIFI_OPT_SUCCESS;
371 }
372
GetSupportedFeatures(long & features)373 ErrCode WifiScanProxy::GetSupportedFeatures(long &features)
374 {
375 if (mRemoteDied) {
376 WIFI_LOGW("failed to `%{public}s`,remote service is died!", __func__);
377 return WIFI_OPT_FAILED;
378 }
379 MessageOption option;
380 MessageParcel data, reply;
381 if (!data.WriteInterfaceToken(GetDescriptor())) {
382 WIFI_LOGE("Write interface token error: %{public}s", __func__);
383 return WIFI_OPT_FAILED;
384 }
385 data.WriteInt32(0);
386 int error = Remote()->SendRequest(static_cast<uint32_t>(DevInterfaceCode::WIFI_SVR_CMD_GET_SUPPORTED_FEATURES),
387 data, reply, option);
388 if (error != ERR_NONE) {
389 WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
390 static_cast<int32_t>(DevInterfaceCode::WIFI_SVR_CMD_GET_SUPPORTED_FEATURES), error);
391 return ErrCode(error);
392 }
393 int exception = reply.ReadInt32();
394 if (exception) {
395 return WIFI_OPT_FAILED;
396 }
397 int ret = reply.ReadInt32();
398 if (ret != WIFI_OPT_SUCCESS) {
399 return ErrCode(ret);
400 }
401
402 features = reply.ReadInt64();
403 return WIFI_OPT_SUCCESS;
404 }
405
OnRemoteDied(const wptr<IRemoteObject> & remoteObject)406 void WifiScanProxy::OnRemoteDied(const wptr<IRemoteObject>& remoteObject)
407 {
408 WIFI_LOGW("Remote service is died!");
409 mRemoteDied = true;
410 if (g_wifiScanCallbackStub == nullptr) {
411 WIFI_LOGE("g_wifiScanCallbackStub is nullptr!");
412 return;
413 }
414 g_wifiScanCallbackStub->SetRemoteDied(true);
415 }
416
IsRemoteDied(void)417 bool WifiScanProxy::IsRemoteDied(void)
418 {
419 if (mRemoteDied) {
420 WIFI_LOGW("IsRemoteDied! remote is died now!");
421 }
422 return mRemoteDied;
423 }
SetScanOnlyAvailable(bool bScanOnlyAvailable)424 ErrCode WifiScanProxy::SetScanOnlyAvailable(bool bScanOnlyAvailable)
425 {
426 if (mRemoteDied) {
427 WIFI_LOGE("failed to SetScanOnlyAvailable, remote service is died!");
428 return WIFI_OPT_FAILED;
429 }
430 MessageOption option;
431 MessageParcel data;
432 MessageParcel reply;
433 if (!data.WriteInterfaceToken(GetDescriptor())) {
434 WIFI_LOGE("SetScanOnlyAvailable Write interface token error!");
435 return WIFI_OPT_FAILED;
436 }
437 data.WriteInt32(0);
438 data.WriteBool(bScanOnlyAvailable);
439 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SET_WIFI_SCAN_ONLY),
440 data, reply, option);
441 if (error != ERR_NONE) {
442 WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
443 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SET_WIFI_SCAN_ONLY), error);
444 return WIFI_OPT_FAILED;
445 }
446
447 int exception = reply.ReadInt32();
448 if (exception) {
449 return WIFI_OPT_FAILED;
450 }
451 return ErrCode(reply.ReadInt32());
452 }
453
GetScanOnlyAvailable(bool & bScanOnlyAvailable)454 ErrCode WifiScanProxy::GetScanOnlyAvailable(bool &bScanOnlyAvailable)
455 {
456 if (mRemoteDied) {
457 WIFI_LOGE("failed to GetScanOnlyAvailable,remote service is died!");
458 return WIFI_OPT_FAILED;
459 }
460 MessageOption option;
461 MessageParcel data, reply;
462 if (!data.WriteInterfaceToken(GetDescriptor())) {
463 WIFI_LOGE("GetScanOnlyAvailable Write interface token error!");
464 return WIFI_OPT_FAILED;
465 }
466 data.WriteInt32(0);
467 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_GET_WIFI_SCAN_ONLY),
468 data, reply, option);
469 if (error != ERR_NONE) {
470 WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
471 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_GET_WIFI_SCAN_ONLY), error);
472 return WIFI_OPT_FAILED;
473 }
474 int exception = reply.ReadInt32();
475 if (exception) {
476 WIFI_LOGE("GetScanOnlyAvailable Reply exception failed!");
477 return WIFI_OPT_FAILED;
478 }
479 int ret = reply.ReadInt32();
480 if (ret != WIFI_OPT_SUCCESS) {
481 WIFI_LOGE("GetScanOnlyAvailable Reply ReadInt32 failed, ret:%{public}d", ret);
482 return ErrCode(ret);
483 }
484 bScanOnlyAvailable = reply.ReadBool();
485 return WIFI_OPT_SUCCESS;
486 }
487
StartWifiPnoScan(bool isStartAction,int periodMs,int suspendReason)488 ErrCode WifiScanProxy::StartWifiPnoScan(bool isStartAction, int periodMs, int suspendReason)
489 {
490 if (mRemoteDied) {
491 WIFI_LOGE("failed to StartWifiPnoScan, remote service is died!");
492 return WIFI_OPT_FAILED;
493 }
494 MessageOption option;
495 MessageParcel data, reply;
496 if (!data.WriteInterfaceToken(GetDescriptor())) {
497 WIFI_LOGE("StartWifiPnoScan Write interface token error!");
498 return WIFI_OPT_FAILED;
499 }
500 data.WriteInt32(0);
501 data.WriteBool(isStartAction);
502 data.WriteInt32(periodMs);
503 data.WriteInt32(suspendReason);
504 int error = Remote()->SendRequest(static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_START_PNO_SCAN),
505 data, reply, option);
506 if (error != ERR_NONE) {
507 WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
508 static_cast<int32_t>(ScanInterfaceCode::WIFI_SVR_CMD_START_PNO_SCAN), error);
509 return WIFI_OPT_FAILED;
510 }
511 int exception = reply.ReadInt32();
512 if (exception) {
513 WIFI_LOGE("StartWifiPnoScan Reply exception failed!");
514 return WIFI_OPT_FAILED;
515 }
516 int ret = reply.ReadInt32();
517 if (ret != WIFI_OPT_SUCCESS) {
518 WIFI_LOGE("StartWifiPnoScan Reply ReadInt32 failed, ret:%{public}d", ret);
519 return ErrCode(ret);
520 }
521 return WIFI_OPT_SUCCESS;
522 }
523 } // namespace Wifi
524 } // namespace OHOS
525