1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 #include "wifi_provision_internal.h"
5 
6 #ifdef AWSS_SUPPORT_AHA
7 
8 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
9 extern "C" {
10 #endif
11 
12 #define AHA_SA_OFFSET     (10)
13 #define AHA_PROBE_PKT_LEN (49)
14 
15 const char *zc_default_ssid = "aha";
16 const char *zc_default_passwd = "12345678";
17 
18 static const uint8_t aha_probe_req_frame[AHA_PROBE_PKT_LEN] = {
19     0x40, 0x00,                         /* mgnt type, frame control */
20     0x00, 0x00,                         /* duration */
21     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* DA */
22     0x28, 0xC2, 0xDD, 0x61, 0x68, 0x83, /* SA, to be replaced with wifi mac */
23     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* BSSID */
24     0xC0, 0x79,                         /* seq */
25     0x00, 0x03, 0x61, 0x68, 0x61,       /* ssid, aha */
26     0x01, 0x08, 0x82, 0x84, 0x8B, 0x96,
27     0x8C, 0x92, 0x98, 0xA4,             /* supported rates */
28     0x32, 0x04, 0xB0, 0x48, 0x60, 0x6C, /* extended supported rates */
29     0x3F, 0x84, 0x10, 0x9E              /* FCS */
30 };
31 
awss_recv_callback_aha_ssid(struct parser_res * res)32 int awss_recv_callback_aha_ssid(struct parser_res *res)
33 {
34     uint8_t tods = res->tods;
35     uint8_t channel = res->channel;
36 
37     awss_debug("found default ssid: %s\r\n", zc_default_ssid);
38     AWSS_UPDATE_STATIS(AWSS_STATIS_PAP_IDX, AWSS_STATIS_TYPE_TIME_START);
39 
40     strncpy((char *)zc_ssid, zc_default_ssid, ZC_MAX_SSID_LEN - 1);
41     strncpy((char *)zc_passwd, zc_default_passwd, ZC_MAX_PASSWD_LEN - 1);
42 
43     zconfig_set_state(STATE_RCV_DONE, tods, channel);
44     return PKG_END;
45 }
46 
aws_send_aha_probe_req(void)47 int aws_send_aha_probe_req(void)
48 {
49     uint8_t probe[AHA_PROBE_PKT_LEN];
50     memcpy(probe, aha_probe_req_frame, sizeof(probe));
51     os_wifi_get_mac(&probe[AHA_SA_OFFSET]);
52     HAL_Wifi_Send_80211_Raw_Frame(FRAME_PROBE_REQ, probe, sizeof(probe));
53     return 0;
54 }
55 
awss_ieee80211_aha_process(uint8_t * mgmt_header,int len,int link_type,struct parser_res * res,signed char rssi)56 int awss_ieee80211_aha_process(uint8_t *mgmt_header, int len, int link_type,
57                                struct parser_res *res, signed char rssi)
58 {
59     uint8_t ssid[ZC_MAX_SSID_LEN] = { 0 }, bssid[ETH_ALEN] = { 0 };
60     uint8_t auth, pairwise_cipher, group_cipher;
61     struct ieee80211_hdr *hdr;
62     int fc, ret, channel;
63 
64     /*
65      * when device try to connect current router (include aha)
66      * skip the new aha and process the new aha in the next scope.
67      */
68     if (mgmt_header == NULL || zconfig_finished)
69         return ALINK_INVALID;
70 
71     /*
72      * we don't process aha until user press configure button
73      */
74     if (awss_get_config_press() == 0)
75         return ALINK_INVALID;
76 
77     hdr = (struct ieee80211_hdr *)mgmt_header;
78     fc = hdr->frame_control;
79 
80     if (!ieee80211_is_beacon(fc) && !ieee80211_is_probe_resp(fc))
81         return ALINK_INVALID;
82     ret = ieee80211_get_bssid_2(mgmt_header, bssid);
83     if (ret < 0)
84         return ALINK_INVALID;
85 
86     ret = ieee80211_get_ssid(mgmt_header, len, ssid);
87     if (ret < 0)
88         return ALINK_INVALID;
89 
90     /*
91      * skip ap which is not aha
92      */
93     if (strcmp((const char *)ssid, zc_default_ssid))
94         return ALINK_INVALID;
95     channel = cfg80211_get_bss_channel(mgmt_header, len);
96     rssi = rssi > 0 ? rssi - 256 : rssi;
97 
98     cfg80211_get_cipher_info(mgmt_header, len, &auth, &pairwise_cipher,
99                              &group_cipher);
100     awss_save_apinfo(ssid, bssid, channel, auth, pairwise_cipher, group_cipher,
101                      rssi);
102     return ALINK_DEFAULT_SSID;
103 }
104 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
105 }
106 #endif
107 #endif
108