• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 **)&params->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 **)&params->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 **)&params->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 **)&params->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(&params->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, &params) != 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, &params);
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(&params, reqData);
308     if (ret != HDF_SUCCESS) {
309         return ret;
310     }
311     ret = ScanAll(netdev, &params);
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