1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "sta.h"
10 #include "securec.h"
11 #include "message/message_router.h"
12 #include "message/sidecar.h"
13 #include "wifi_base.h"
14 #include "hdf_wlan_services.h"
15 #include "hdf_wlan_utils.h"
16
17 #define HDF_LOG_TAG HDF_WIFI_CORE
18 #define ATTR_MIN_LEN 2
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
Connect(struct NetDevice * netDev,struct WlanConnectParams * param)24 inline static int32_t Connect(struct NetDevice *netDev, struct WlanConnectParams *param)
25 {
26 struct HdfChipDriver *chipDriver = GetChipDriver(netDev);
27 if (chipDriver == NULL) {
28 HDF_LOGE("%s:bad net device found!", __func__);
29 return HDF_FAILURE;
30 }
31 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->staOps, Connect);
32 return chipDriver->staOps->Connect(netDev, param);
33 }
34
Disconnect(struct NetDevice * netDev,uint16_t reasonCode)35 inline static int32_t Disconnect(struct NetDevice *netDev, uint16_t reasonCode)
36 {
37 struct HdfChipDriver *chipDriver = GetChipDriver(netDev);
38 if (chipDriver == NULL) {
39 HDF_LOGE("%s:bad net device found!", __func__);
40 return HDF_FAILURE;
41 }
42 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->staOps, Disconnect);
43 return chipDriver->staOps->Disconnect(netDev, reasonCode);
44 }
45
ScanAll(struct NetDevice * netDev,struct WlanScanRequest * params)46 inline static int32_t ScanAll(struct NetDevice *netDev, struct WlanScanRequest *params)
47 {
48 struct HdfChipDriver *chipDriver = GetChipDriver(netDev);
49 if (chipDriver == NULL) {
50 HDF_LOGE("%s:bad net device found!", __func__);
51 return HDF_FAILURE;
52 }
53 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->staOps, StartScan);
54 return chipDriver->staOps->StartScan(netDev, params);
55 }
56
AbortScan(struct NetDevice * netDev)57 inline static int32_t AbortScan(struct NetDevice *netDev)
58 {
59 struct HdfChipDriver *chipDriver = GetChipDriver(netDev);
60 if (chipDriver == NULL) {
61 HDF_LOGE("%s:bad net device found!", __func__);
62 return HDF_FAILURE;
63 }
64 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->staOps, AbortScan);
65 return chipDriver->staOps->AbortScan(netDev);
66 }
67
WifiFillScanParam(struct WlanScanRequest * params,struct HdfSBuf * reqData)68 static int WifiFillScanParam(struct WlanScanRequest *params, struct HdfSBuf *reqData)
69 {
70 uint32_t dataSize = 0;
71 if (!HdfSbufReadBuffer(reqData, (const void **)¶ms->bssid, &dataSize)) {
72 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "apSettings");
73 return HDF_FAILURE;
74 }
75 if (!HdfSbufReadBuffer(reqData, (const void **)¶ms->ssids, &dataSize)) {
76 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ssids");
77 return HDF_FAILURE;
78 }
79 params->ssidCount = dataSize / sizeof(params->ssids[0]);
80 if (!HdfSbufReadBuffer(reqData, (const void **)¶ms->extraIEs, &dataSize)) {
81 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "extraIes");
82 return HDF_FAILURE;
83 }
84 params->extraIEsLen = dataSize;
85 if (!HdfSbufReadBuffer(reqData, (const void **)¶ms->freqs, &dataSize)) {
86 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "freqs");
87 return HDF_FAILURE;
88 }
89 params->freqsCount =
90 (dataSize / sizeof(params->freqs[0])) < MAX_FREQ_FTILTER_COUNT ? (dataSize / sizeof(params->freqs[0])) : 0;
91
92 return HDF_SUCCESS;
93 }
94
WifiValidIeAttr(const uint8_t * ie,uint32_t len)95 static uint8_t WifiValidIeAttr(const uint8_t *ie, uint32_t len)
96 {
97 uint8_t elemLen;
98 if (ie == NULL) { // ie null is normal
99 return true;
100 }
101 while (len != 0) {
102 if (len < ATTR_MIN_LEN) {
103 return false;
104 }
105 len -= ATTR_MIN_LEN;
106 elemLen = ie[1];
107 if (elemLen > len) {
108 return false;
109 }
110 len -= elemLen;
111 ie += ATTR_MIN_LEN + elemLen;
112 }
113 return true;
114 }
115
WifiFillAssocParams(WifiAssociateParams * assoc,struct HdfSBuf * reqData)116 static int WifiFillAssocParams(WifiAssociateParams *assoc, struct HdfSBuf *reqData)
117 {
118 uint32_t dataSize = 0;
119 if (!HdfSbufReadBuffer(reqData, (const void **)&assoc->bssid, &dataSize) || dataSize != ETH_ADDR_LEN) {
120 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "bssid");
121 return HDF_FAILURE;
122 }
123 if (!HdfSbufReadBuffer(reqData, (const void **)&assoc->ssid, &(assoc->ssidLen))) {
124 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ssid");
125 return HDF_FAILURE;
126 }
127 if (!HdfSbufReadBuffer(reqData, (const void **)&assoc->ie, &(assoc->ieLen))) {
128 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ie");
129 return HDF_FAILURE;
130 }
131 if (!HdfSbufReadBuffer(reqData, (const void **)&assoc->key, &dataSize)) {
132 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "key");
133 return HDF_FAILURE;
134 }
135 if (!HdfSbufReadUint8(reqData, &assoc->authType)) {
136 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "authType");
137 return HDF_FAILURE;
138 }
139 if (!HdfSbufReadUint8(reqData, &assoc->privacy)) {
140 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "privacy");
141 return HDF_FAILURE;
142 }
143 if (!HdfSbufReadUint8(reqData, &assoc->keyIdx)) {
144 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "keyIdx");
145 return HDF_FAILURE;
146 }
147 if (!HdfSbufReadUint8(reqData, &assoc->mfp)) {
148 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "mfp");
149 return HDF_FAILURE;
150 }
151 if (!HdfSbufReadUint32(reqData, &assoc->freq)) {
152 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "freq");
153 return HDF_FAILURE;
154 }
155 if (!HdfSbufReadBuffer(reqData, (const void **)&assoc->crypto, &dataSize)) {
156 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "crypto");
157 return HDF_FAILURE;
158 }
159 if ((assoc->ssid == NULL) || (assoc->ssidLen == 0)) {
160 HDF_LOGE("%s:void ssid", __func__);
161 return HDF_FAILURE;
162 }
163 if (WifiValidIeAttr(assoc->ie, assoc->ieLen) == false) {
164 HDF_LOGE("%s:illegal ie", __func__);
165 return HDF_FAILURE;
166 }
167 return HDF_SUCCESS;
168 }
169
WifiSetAssocParams(const WifiAssociateParams * assoc,const struct NetDevice * netdev,struct WlanConnectParams * params)170 static int WifiSetAssocParams(const WifiAssociateParams *assoc, const struct NetDevice *netdev,
171 struct WlanConnectParams *params)
172 {
173 params->ssid = assoc->ssid;
174 params->ssidLen = assoc->ssidLen;
175 params->ie = assoc->ie;
176 params->ieLen = assoc->ieLen;
177 if ((assoc->authType > WIFI_AUTHTYPE_AUTOMATIC) || (assoc->authType == WIFI_AUTHTYPE_SAE)) {
178 HDF_LOGE("%s:illegal authType %u", __func__, assoc->authType);
179 return HDF_FAILURE;
180 }
181 params->authType = assoc->authType;
182 params->bssid = assoc->bssid;
183 params->privacy = assoc->privacy;
184 if ((assoc->mfp != WIFI_MFP_REQUIRED) && (assoc->mfp != WIFI_MFP_NO) && (assoc->mfp != WIFI_MFP_OPTIONAL)) {
185 HDF_LOGE("%s:unexpected mfp.mfp=%u", __func__, assoc->mfp);
186 return HDF_FAILURE;
187 }
188 params->mfp = (WifiMfp)assoc->mfp;
189 if (assoc->key != NULL) {
190 params->key = assoc->key;
191 params->keyLen = assoc->keyLen;
192 params->keyIdx = assoc->keyIdx;
193 }
194 if (memcpy_s(¶ms->crypto, sizeof(WifiCryptoSetting), assoc->crypto, sizeof(WifiCryptoSetting)) != EOK) {
195 HDF_LOGE("%s:copy crypto failed!", __func__);
196 return HDF_FAILURE;
197 }
198 return HDF_SUCCESS;
199 }
200
WifiCmdAssoc(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)201 static int32_t WifiCmdAssoc(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
202 {
203 struct WlanConnectParams params = { 0 };
204 WifiAssociateParams assoc = { 0 };
205 struct NetDevice *netdev = NULL;
206 struct WlanHwCapability *capability = NULL;
207 const char *ifName = NULL;
208 int32_t ret;
209 (void)context;
210 (void)rspData;
211 if (reqData == NULL) {
212 HDF_LOGE("%s: reqData is NULL", __func__);
213 return HDF_ERR_INVALID_PARAM;
214 }
215 ifName = HdfSbufReadString(reqData);
216 if (ifName == NULL) {
217 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
218 return HDF_FAILURE;
219 }
220 if (WifiFillAssocParams(&assoc, reqData) != HDF_SUCCESS) {
221 return HDF_FAILURE;
222 }
223 if ((netdev = NetDeviceGetInstByName(ifName)) == NULL) {
224 HDF_LOGE("%s:netdev not found!ifName=%s", __func__, ifName);
225 return HDF_FAILURE;
226 }
227 if (WifiSetAssocParams(&assoc, netdev, ¶ms) != HDF_SUCCESS) {
228 return HDF_FAILURE;
229 }
230 capability = GetHwCapability(netdev);
231 if (capability == NULL) {
232 HDF_LOGE("%s:GetHwCapability failed!", __func__);
233 return HDF_FAILURE;
234 }
235 do {
236 params.centerFreq = assoc.freq;
237 HDF_LOGI("%s:%s connecting to AP ...", __func__, ifName);
238 ret = Connect(netdev, ¶ms);
239 if (ret != HDF_SUCCESS) {
240 HDF_LOGE("%s:fail to do connect,%d", __func__, ret);
241 break;
242 }
243 } while (false);
244 if (capability->Release != NULL) {
245 capability->Release(capability);
246 capability = NULL;
247 }
248 return ret;
249 }
250
WifiCmdDisconnect(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)251 static int32_t WifiCmdDisconnect(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
252 {
253 struct NetDevice *netdev = NULL;
254 uint16_t reasonCode;
255 const char *ifName = NULL;
256 int ret;
257 (void)context;
258 (void)rspData;
259 if (reqData == NULL) {
260 HDF_LOGE("%s: reqData is NULL", __func__);
261 return HDF_ERR_INVALID_PARAM;
262 }
263 ifName = HdfSbufReadString(reqData);
264 if (ifName == NULL) {
265 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
266 return HDF_FAILURE;
267 }
268 if (!HdfSbufReadUint16(reqData, &reasonCode)) {
269 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "reasonCode");
270 return HDF_FAILURE;
271 }
272 netdev = NetDeviceGetInstByName(ifName);
273 if (netdev == NULL) {
274 HDF_LOGE("%s:netdev not found!ifName=%s", __func__, ifName);
275 return HDF_FAILURE;
276 }
277 HDF_LOGW("%s:%s disconnecting from AP...", __func__, ifName);
278 ret = Disconnect(netdev, reasonCode);
279 if (ret != HDF_SUCCESS) {
280 HDF_LOGE("%s:fail to do disconnect,%d", __func__, ret);
281 }
282 return ret;
283 }
284
WifiCmdScan(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)285 static int32_t WifiCmdScan(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
286 {
287 struct NetDevice *netdev = NULL;
288 const char *ifName = NULL;
289 struct WlanScanRequest params = { 0 };
290 int32_t ret;
291 (void)context;
292 (void)rspData;
293 if (reqData == NULL) {
294 HDF_LOGE("%s: reqData is NULL", __func__);
295 return HDF_ERR_INVALID_PARAM;
296 }
297 ifName = HdfSbufReadString(reqData);
298 if (ifName == NULL) {
299 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
300 return HDF_FAILURE;
301 }
302 netdev = NetDeviceGetInstByName(ifName);
303 if (netdev == NULL) {
304 HDF_LOGE("%s:netdev not found!ifName=%s", __func__, ifName);
305 return HDF_FAILURE;
306 }
307 ret = WifiFillScanParam(¶ms, reqData);
308 if (ret != HDF_SUCCESS) {
309 return ret;
310 }
311 ret = ScanAll(netdev, ¶ms);
312 if (ret != HDF_SUCCESS) {
313 HDF_LOGE("%s:ScanAll failed!ret=%d", __func__, ret);
314 }
315 return ret;
316 }
317
WifiCmdAbortScan(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)318 static int32_t WifiCmdAbortScan(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
319 {
320 struct NetDevice *netdev = NULL;
321 int32_t ret;
322 const char *ifName = HdfSbufReadString(reqData);
323 (void)context;
324 (void)rspData;
325 if (ifName == NULL) {
326 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
327 return HDF_FAILURE;
328 }
329 netdev = NetDeviceGetInstByName(ifName);
330 if (netdev == NULL) {
331 HDF_LOGE("%s:netdev not found!ifName=%s", __func__, ifName);
332 return HDF_FAILURE;
333 }
334 ret = AbortScan(netdev);
335 if (ret != HDF_SUCCESS) {
336 HDF_LOGE("%s:AbortScan failed!ret=%d", __func__, ret);
337 }
338 // keep return SUCCESS if AbortScan return FAILED
339 return HDF_SUCCESS;
340 }
341
WifiCmdSetScanningMacAddress(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)342 static int32_t WifiCmdSetScanningMacAddress(const RequestContext *context, struct HdfSBuf *reqData,
343 struct HdfSBuf *rspData)
344 {
345 int32_t ret;
346 uint8_t isFuncValid;
347 struct NetDevice *netdev = NULL;
348 const char *ifName = NULL;
349 unsigned char *mac = NULL;
350 uint32_t replayDataSize;
351 struct HdfChipDriver *chipDriver = NULL;
352 (void)context;
353 if (reqData == NULL || rspData == NULL) {
354 return HDF_ERR_INVALID_PARAM;
355 }
356 ifName = HdfSbufReadString(reqData);
357 if (ifName == NULL) {
358 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
359 return HDF_FAILURE;
360 }
361 netdev = NetDeviceGetInstByName(ifName);
362 if (netdev == NULL) {
363 HDF_LOGE("%s:netdev not found!ifName=%s", __func__, ifName);
364 return HDF_FAILURE;
365 }
366 if (!HdfSbufReadBuffer(reqData, (const void **)&mac, &replayDataSize) || mac == NULL ||
367 replayDataSize != IEEE80211_MAC_ADDR_LEN) {
368 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "mac");
369 return HDF_FAILURE;
370 }
371 chipDriver = GetChipDriver(netdev);
372 if (chipDriver == NULL) {
373 HDF_LOGE("%s:bad net device found!", __func__);
374 return HDF_FAILURE;
375 }
376 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->staOps, SetScanningMacAddress);
377 ret = chipDriver->staOps->SetScanningMacAddress(netdev, mac, IEEE80211_MAC_ADDR_LEN);
378 if (ret != HDF_SUCCESS && ret != HDF_ERR_NOT_SUPPORT) {
379 HDF_LOGE("%s: fail to do set scanning mac addr!ret=%d", __func__, ret);
380 return ret;
381 }
382 isFuncValid = (ret == HDF_ERR_NOT_SUPPORT) ? false : true;
383 if (!HdfSbufWriteUint8(rspData, isFuncValid)) {
384 HDF_LOGE("%s: %s!", __func__, ERROR_DESC_WRITE_RSP_FAILED);
385 return HDF_FAILURE;
386 }
387 return HDF_SUCCESS;
388 }
389
390 static struct MessageDef g_wifiStaFeatureCmds[] = {
391 DUEMessage(CMD_STA_CONNECT, WifiCmdAssoc, 0),
392 DUEMessage(CMD_STA_DISCONNECT, WifiCmdDisconnect, 0),
393 DUEMessage(CMD_STA_SCAN, WifiCmdScan, 0),
394 DUEMessage(CMD_STA_ABORT_SCAN, WifiCmdAbortScan, 0),
395 DUEMessage(CMD_STA_SET_SCAN_MAC_ADDR, WifiCmdSetScanningMacAddress, 0)
396 };
397 ServiceDefine(STAService, STA_SERVICE_ID, g_wifiStaFeatureCmds);
398
399 Service *g_staService = NULL;
400
StaInit(struct WifiFeature * feature)401 int32_t StaInit(struct WifiFeature *feature)
402 {
403 (void)feature;
404 if (g_staService == NULL) {
405 ServiceCfg cfg = {
406 .dispatcherId = DEFAULT_DISPATCHER_ID
407 };
408 g_staService = CreateService(STAService, &cfg);
409 if (g_staService == NULL) {
410 return HDF_FAILURE;
411 }
412 }
413 return HDF_SUCCESS;
414 }
415
StaDeinit(struct WifiFeature * feature)416 int32_t StaDeinit(struct WifiFeature *feature)
417 {
418 (void)feature;
419 if (g_staService != NULL && g_staService->Destroy != NULL) {
420 g_staService->Destroy(g_staService);
421 g_staService = NULL;
422 }
423 return HDF_SUCCESS;
424 }
425
426 struct WifiFeature g_staFeature = {
427 .name = "sta",
428 .init = StaInit,
429 .deInit = StaDeinit
430 };
431
GetWifiStaFeature(void)432 struct WifiFeature *GetWifiStaFeature(void)
433 {
434 return &g_staFeature;
435 }
436
437 #ifdef __cplusplus
438 }
439 #endif
440