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_stub.h"
17 #include "wifi_logger.h"
18 #include "wifi_msg.h"
19 #include "define.h"
20 #include "wifi_manager_service_ipc_interface_code.h"
21 #include "wifi_scan_callback_proxy.h"
22 #include "wifi_internal_event_dispatcher.h"
23 #include "wifi_scan_death_recipient.h"
24 #include "wifi_common_def.h"
25 #include "wifi_config_center.h"
26 #include "wifi_common_util.h"
27 #include "wifi_watchdog_utils.h"
28
29 DEFINE_WIFILOG_SCAN_LABEL("WifiScanStub");
30
31 namespace OHOS {
32 namespace Wifi {
33 static std::map<int, std::string> g_HicollieScanMap = {
34 { static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_START_PNO_SCAN), "WIFI_SVR_CMD_START_PNO_SCAN" },
35 };
WifiScanStub()36 WifiScanStub::WifiScanStub() : mSingleCallback(false)
37 {
38 InitHandleMap();
39 deathRecipient_ = nullptr;
40 }
41
WifiScanStub(int instId)42 WifiScanStub::WifiScanStub(int instId) : mSingleCallback(false), m_instId(instId)
43 {
44 InitHandleMap();
45 deathRecipient_ = nullptr;
46 }
47
~WifiScanStub()48 WifiScanStub::~WifiScanStub()
49 {
50 deathRecipient_ = nullptr;
51 }
52
InitHandleMap()53 void WifiScanStub::InitHandleMap()
54 {
55 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SET_SCAN_CONTROL_INFO)] =
56 &WifiScanStub::OnSetScanControlInfo;
57 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_FULL_SCAN)] = &WifiScanStub::OnScan;
58 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SPECIFIED_PARAMS_SCAN)] =
59 &WifiScanStub::OnScanByParams;
60 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_IS_SCAN_ALWAYS_ACTIVE)] =
61 &WifiScanStub::OnIsWifiClosedScan;
62 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_GET_SCAN_INFO_LIST)] =
63 &WifiScanStub::OnGetScanInfoList;
64 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_REGISTER_SCAN_CALLBACK)] =
65 &WifiScanStub::OnRegisterCallBack;
66 handleFuncMap[static_cast<uint32_t>(DevInterfaceCode::WIFI_SVR_CMD_GET_SUPPORTED_FEATURES)] =
67 &WifiScanStub::OnGetSupportedFeatures;
68 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_SET_WIFI_SCAN_ONLY)] =
69 &WifiScanStub::OnSetScanOnlyAvailable;
70 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_GET_WIFI_SCAN_ONLY)] =
71 &WifiScanStub::OnGetScanOnlyAvailable;
72 handleFuncMap[static_cast<uint32_t>(ScanInterfaceCode::WIFI_SVR_CMD_START_PNO_SCAN)] =
73 &WifiScanStub::OnStartWifiPnoScan;
74 }
75
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)76 int WifiScanStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
77 {
78 WIFI_LOGD("WifiScanStub::OnRemoteRequest,code:%{public}u", code);
79
80 if (data.ReadInterfaceToken() != GetDescriptor()) {
81 WIFI_LOGE("Scan stub token verification error: %{public}d", code);
82 return WIFI_OPT_FAILED;
83 }
84
85 HandleFuncMap::iterator iter = handleFuncMap.find(code);
86 if (iter == handleFuncMap.end()) {
87 WIFI_LOGI("not find function to deal, code %{public}u", code);
88 reply.WriteInt32(0);
89 reply.WriteInt32(WIFI_OPT_NOT_SUPPORTED);
90 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
91 } else {
92 int exception = data.ReadInt32();
93 if (exception) {
94 return WIFI_OPT_FAILED;
95 }
96 std::map<int, std::string>::const_iterator itCollieId = g_HicollieScanMap.find(code);
97 if (itCollieId != g_HicollieScanMap.end()) {
98 int idTimer = 0;
99 idTimer = WifiWatchDogUtils::GetInstance()->StartWatchDogForFunc(itCollieId->second);
100 WIFI_LOGI("SetTimer id: %{public}d, name: %{public}s.", idTimer, itCollieId->second.c_str());
101 (this->*(iter->second))(code, data, reply, option);
102 WifiWatchDogUtils::GetInstance()->StopWatchDogForFunc(itCollieId->second, idTimer);
103 } else {
104 (this->*(iter->second))(code, data, reply, option);
105 }
106 }
107 return 0;
108 }
109
OnSetScanControlInfo(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)110 int WifiScanStub::OnSetScanControlInfo(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
111 {
112 WIFI_LOGD("run OnSetScanControlInfo code %{public}u, datasize %{public}zu", code, data.GetRawDataSize());
113 constexpr int MAX_SIZE = 1024;
114 ScanControlInfo info;
115 int forbidListSize = data.ReadInt32();
116 if (forbidListSize > MAX_SIZE) {
117 reply.WriteInt32(0);
118 reply.WriteInt32(WIFI_OPT_INVALID_PARAM);
119 return WIFI_OPT_INVALID_PARAM;
120 }
121 for (int i = 0; i < forbidListSize; i++) {
122 ScanForbidMode scanForbidMode;
123 scanForbidMode.scanScene = data.ReadInt32();
124 scanForbidMode.scanMode = static_cast<ScanMode>(data.ReadInt32());
125 scanForbidMode.forbidTime = data.ReadInt32();
126 scanForbidMode.forbidCount = data.ReadInt32();
127 info.scanForbidList.push_back(scanForbidMode);
128 }
129
130 int intervalSize = data.ReadInt32();
131 if (intervalSize > MAX_SIZE) {
132 reply.WriteInt32(0);
133 reply.WriteInt32(WIFI_OPT_INVALID_PARAM);
134 return WIFI_OPT_INVALID_PARAM;
135 }
136 for (int i = 0; i < intervalSize; i++) {
137 ScanIntervalMode scanIntervalMode;
138 scanIntervalMode.scanScene = data.ReadInt32();
139 scanIntervalMode.scanMode = static_cast<ScanMode>(data.ReadInt32());
140 scanIntervalMode.isSingle = data.ReadBool();
141 scanIntervalMode.intervalMode = static_cast<IntervalMode>(data.ReadInt32());
142 scanIntervalMode.interval = data.ReadInt32();
143 scanIntervalMode.count = data.ReadInt32();
144 info.scanIntervalList.push_back(scanIntervalMode);
145 }
146
147 ErrCode ret = SetScanControlInfo(info);
148 reply.WriteInt32(0);
149 reply.WriteInt32(ret);
150
151 return ret;
152 }
153
OnScan(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)154 int WifiScanStub::OnScan(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
155 {
156 bool compatible = data.ReadBool();
157 std::string name = data.ReadString();
158 WIFI_LOGD("run OnScan code %{public}u, datasize %{public}zu, compatible:%{public}d",
159 code, data.GetRawDataSize(), compatible);
160 WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetAppPackageName(name);
161 ErrCode ret = Scan(compatible);
162 WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetAppPackageName("");
163 reply.WriteInt32(0);
164 reply.WriteInt32(ret);
165
166 return ret;
167 }
168
OnScanByParams(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)169 int WifiScanStub::OnScanByParams(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
170 {
171 WIFI_LOGD("run OnScanByParams code %{public}u, datasize %{public}zu", code, data.GetRawDataSize());
172 const char *readStr = nullptr;
173 constexpr int MAX_FREQS_SIZE = 512;
174 WifiScanParams params;
175 readStr = data.ReadCString();
176 params.ssid = (readStr != nullptr) ? readStr : "";
177 readStr = data.ReadCString();
178 params.bssid = (readStr != nullptr) ? readStr : "";
179 int size = data.ReadInt32();
180 if (size > MAX_FREQS_SIZE) {
181 reply.WriteInt32(0);
182 reply.WriteInt32(WIFI_OPT_INVALID_PARAM);
183 return WIFI_OPT_INVALID_PARAM;
184 }
185 for (int i = 0; i < size; i++) {
186 int tmp = data.ReadInt32();
187 params.freqs.push_back(tmp);
188 }
189 params.band = static_cast<uint32_t>(data.ReadInt32());
190 std::string name = data.ReadString();
191
192 WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetAppPackageName(name);
193 ErrCode ret = AdvanceScan(params);
194 WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetAppPackageName("");
195 reply.WriteInt32(0);
196 reply.WriteInt32(ret);
197
198 return ret;
199 }
200
OnIsWifiClosedScan(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)201 int WifiScanStub::OnIsWifiClosedScan(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
202 {
203 WIFI_LOGD("run OnIsWifiClosedScan code %{public}u, datasize %{public}zu", code, data.GetRawDataSize());
204 bool bOpen = false;
205 ErrCode ret = IsWifiClosedScan(bOpen);
206 reply.WriteInt32(0);
207 reply.WriteInt32(ret);
208 if (ret == WIFI_OPT_SUCCESS) {
209 reply.WriteBool(bOpen);
210 }
211 return ret;
212 }
213
214 constexpr int32_t ASH_MEM_SIZE = 1024 * 300;
SendScanInfo(int32_t contentSize,std::vector<WifiScanInfo> & result,MessageParcel & reply)215 void WifiScanStub::SendScanInfo(int32_t contentSize, std::vector<WifiScanInfo> &result, MessageParcel &reply)
216 {
217 WIFI_LOGI("WifiScanStub SendScanInfo");
218 sptr<Ashmem> ashmem = Ashmem::CreateAshmem("scaninfo", ASH_MEM_SIZE);
219 if (ashmem == nullptr || !ashmem->MapReadAndWriteAshmem()) {
220 reply.WriteInt32(WIFI_OPT_FAILED);
221 if (ashmem != nullptr) {
222 ashmem->UnmapAshmem();
223 ashmem->CloseAshmem();
224 }
225 return;
226 }
227 std::stringstream scanInfoStream;
228 for (int32_t i = 0; i < contentSize; ++i) {
229 scanInfoStream << StringToHex(result[i].bssid) << ";";
230 scanInfoStream << StringToHex(result[i].ssid) << ";";
231 scanInfoStream << result[i].bssidType << ";";
232 scanInfoStream << StringToHex(result[i].capabilities) << ";";
233 scanInfoStream << result[i].frequency << ";";
234 scanInfoStream << result[i].band << ";";
235 scanInfoStream << static_cast<int32_t>(result[i].channelWidth) << ";";
236 scanInfoStream << result[i].centerFrequency0 << ";";
237 scanInfoStream << result[i].centerFrequency1 << ";";
238 scanInfoStream << result[i].rssi << ";";
239 scanInfoStream << static_cast<int32_t>(result[i].securityType) << ";";
240 scanInfoStream << result[i].infoElems.size() << ";";
241 for (const auto &elem : result[i].infoElems) {
242 scanInfoStream << elem.id << ";";
243 scanInfoStream << elem.content.size() << ";";
244 for (const auto &byte : elem.content) {
245 scanInfoStream << static_cast<int32_t>(byte) << ";";
246 }
247 }
248 scanInfoStream << result[i].features << ";";
249 scanInfoStream << result[i].timestamp << ";";
250 scanInfoStream << result[i].wifiStandard << ";";
251 scanInfoStream << result[i].maxSupportedRxLinkSpeed << ";";
252 scanInfoStream << result[i].maxSupportedTxLinkSpeed << ";";
253 scanInfoStream << result[i].disappearCount << ";";
254 scanInfoStream << result[i].isHiLinkNetwork << ";";
255 scanInfoStream << static_cast<int32_t>(result[i].supportedWifiCategory) << ";";
256 }
257 int32_t scanInfoSize = static_cast<int32_t>(scanInfoStream.str().length());
258 ashmem->WriteToAshmem(scanInfoStream.str().c_str(), scanInfoStream.str().length(), 0);
259 reply.WriteInt32(WIFI_OPT_SUCCESS);
260 reply.WriteInt32(contentSize);
261 reply.WriteInt32(scanInfoSize);
262 reply.WriteAshmem(ashmem);
263 ashmem->UnmapAshmem();
264 ashmem->CloseAshmem();
265 }
266
SendScanInfoSmall(int32_t contentSize,std::vector<WifiScanInfo> & result,MessageParcel & reply)267 void WifiScanStub::SendScanInfoSmall(int32_t contentSize, std::vector<WifiScanInfo> &result, MessageParcel &reply)
268 {
269 reply.WriteInt32(WIFI_OPT_SUCCESS);
270 reply.WriteInt32(contentSize);
271 for (int32_t i = 0; i < contentSize; i++) {
272 reply.WriteString(result[i].bssid);
273 reply.WriteString(result[i].ssid);
274 reply.WriteInt32(result[i].bssidType);
275 reply.WriteString(result[i].capabilities);
276 reply.WriteInt32(result[i].frequency);
277 reply.WriteInt32(result[i].band);
278 reply.WriteInt32(static_cast<int>(result[i].channelWidth));
279 reply.WriteInt32(result[i].centerFrequency0);
280 reply.WriteInt32(result[i].centerFrequency1);
281 reply.WriteInt32(result[i].rssi);
282 reply.WriteInt32(static_cast<int>(result[i].securityType));
283 reply.WriteUint32(result[i].infoElems.size());
284 for (const auto &elem : result[i].infoElems) {
285 reply.WriteInt32(elem.id);
286 reply.WriteUint32(elem.content.size());
287 for (const auto &byte : elem.content) {
288 reply.WriteInt32(static_cast<int>(byte));
289 }
290 }
291 reply.WriteInt64(result[i].features);
292 reply.WriteInt64(result[i].timestamp);
293 reply.WriteInt32(result[i].wifiStandard);
294 reply.WriteInt32(result[i].maxSupportedRxLinkSpeed);
295 reply.WriteInt32(result[i].maxSupportedTxLinkSpeed);
296 reply.WriteInt32(result[i].disappearCount);
297 reply.WriteBool(result[i].isHiLinkNetwork);
298 reply.WriteInt32(static_cast<int>(result[i].supportedWifiCategory));
299 }
300 }
301
OnGetScanInfoList(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)302 int WifiScanStub::OnGetScanInfoList(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
303 {
304 bool compatible = data.ReadBool();
305 WIFI_LOGD("run OnGetScanInfoList code %{public}u, datasize %{public}zu, compatible:%{public}d", code,
306 data.GetRawDataSize(), compatible);
307 std::vector<WifiScanInfo> result;
308 ErrCode ret = GetScanInfoList(result, compatible);
309 reply.WriteInt32(0);
310 if (ret != WIFI_OPT_SUCCESS) {
311 reply.WriteInt32(ret);
312 return ret;
313 }
314 int32_t size = static_cast<int>(result.size());
315 constexpr int maxSize = 200;
316 constexpr int bigSize = 150;
317 if (size > maxSize) {
318 size = maxSize;
319 }
320 if (size > bigSize) {
321 SendScanInfo(size, result, reply);
322 } else {
323 SendScanInfoSmall(size, result, reply);
324 }
325 return ret;
326 }
327
OnRegisterCallBack(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)328 int WifiScanStub::OnRegisterCallBack(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
329 {
330 WIFI_LOGD("run %{public}s code %{public}u, datasize %{public}zu", __func__, code, data.GetRawDataSize());
331 ErrCode ret = WIFI_OPT_FAILED;
332 do {
333 sptr<IRemoteObject> remote = data.ReadRemoteObject();
334 if (remote == nullptr) {
335 WIFI_LOGE("Failed to readRemoteObject!");
336 break;
337 }
338
339 sptr<IWifiScanCallback> callback_ = iface_cast<IWifiScanCallback>(remote);
340 if (callback_ == nullptr) {
341 callback_ = new (std::nothrow) WifiScanCallbackProxy(remote);
342 WIFI_LOGI("create new `WifiScanCallbackProxy`!");
343 }
344
345 int pid = data.ReadInt32();
346 int tokenId = data.ReadInt32();
347 int eventNum = data.ReadInt32();
348 std::vector<std::string> event;
349 if (eventNum > 0 && eventNum <= MAX_READ_EVENT_SIZE) {
350 for (int i = 0; i < eventNum; ++i) {
351 event.emplace_back(data.ReadString());
352 }
353 }
354 WIFI_LOGD("%{public}s, get pid: %{public}d, tokenId: %{private}d", __func__, pid, tokenId);
355
356 if (mSingleCallback) {
357 ret = RegisterCallBack(callback_, event);
358 } else {
359 std::unique_lock<std::mutex> lock(deathRecipientMutex);
360 if (deathRecipient_ == nullptr) {
361 deathRecipient_ = new (std::nothrow) WifiScanDeathRecipient();
362 }
363 // Add death recipient to remote object if this is the first time to register callback.
364 if ((remote->IsProxyObject()) &&
365 !WifiInternalEventDispatcher::GetInstance().HasScanRemote(remote, m_instId)) {
366 remote->AddDeathRecipient(deathRecipient_);
367 }
368
369 if (callback_ != nullptr) {
370 for (const auto &eventName : event) {
371 ret = WifiInternalEventDispatcher::GetInstance().AddScanCallback(remote, callback_, pid, eventName,
372 tokenId, m_instId);
373 }
374 }
375 }
376 } while (0);
377
378 reply.WriteInt32(0);
379 reply.WriteInt32(ret);
380 return 0;
381 }
382
OnGetSupportedFeatures(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)383 int WifiScanStub::OnGetSupportedFeatures(uint32_t code, MessageParcel &data, MessageParcel &reply,
384 MessageOption &option)
385 {
386 WIFI_LOGD("run %{public}s code %{public}u, datasize %{public}zu", __func__, code, data.GetRawDataSize());
387 long features = 0;
388 int ret = GetSupportedFeatures(features);
389 reply.WriteInt32(0);
390 reply.WriteInt32(ret);
391
392 if (ret == WIFI_OPT_SUCCESS) {
393 reply.WriteInt64(features);
394 }
395
396 return ret;
397 }
398
IsSingleCallback() const399 bool WifiScanStub::IsSingleCallback() const
400 {
401 return mSingleCallback;
402 }
403
SetSingleCallback(const bool isSingleCallback)404 void WifiScanStub::SetSingleCallback(const bool isSingleCallback)
405 {
406 mSingleCallback = true;
407 }
408
OnSetScanOnlyAvailable(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)409 int WifiScanStub::OnSetScanOnlyAvailable(uint32_t code, MessageParcel &data, MessageParcel &reply,
410 MessageOption &option)
411 {
412 bool enabled = data.ReadBool();
413 WIFI_LOGI("In WifiScanStub::OnSetScanOnlyAvailable enabled is %{public}d", enabled);
414 reply.WriteInt32(0);
415 reply.WriteInt32(SetScanOnlyAvailable(enabled));
416 return 0;
417 }
418
OnGetScanOnlyAvailable(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)419 int WifiScanStub::OnGetScanOnlyAvailable(uint32_t code, MessageParcel &data, MessageParcel &reply,
420 MessageOption &option)
421 {
422 WIFI_LOGI("In WifiScanStub::OnGetScanOnlyAvailable");
423 bool state = false;
424 ErrCode ret = GetScanOnlyAvailable(state);
425 reply.WriteInt32(0);
426 reply.WriteInt32(ret);
427 if (ret == WIFI_OPT_SUCCESS) {
428 reply.WriteBool(state);
429 }
430 return 0;
431 }
432
OnStartWifiPnoScan(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)433 int WifiScanStub::OnStartWifiPnoScan(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
434 {
435 WIFI_LOGI("In WifiScanStub::OnStartWifiPnoScan");
436 bool isStart = data.ReadBool();
437 int periodMs = data.ReadInt32();
438 int suspendReason = data.ReadInt32();
439 ErrCode ret = StartWifiPnoScan(isStart, periodMs, suspendReason);
440 reply.WriteInt32(0);
441 reply.WriteInt32(ret);
442 return 0;
443 }
444 } // namespace Wifi
445 } // namespace OHOS
446