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