Path: blob/next/external/packages/extras-buildpkgs/hostapd-realtek/debian/patches/realtek.patch
8686 views
diff --git a/hostapd/main.c b/hostapd/main.c1index 6c7406a..07dda78 1006442--- a/hostapd/main.c3+++ b/hostapd/main.c4@@ -422,7 +422,7 @@ static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,5static void show_version(void)6{7fprintf(stderr,8- "hostapd v" VERSION_STR "\n"9+ "hostapd v" VERSION_STR " for Realtek rtl871xdrv\n"10"User space daemon for IEEE 802.11 AP management,\n"11"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"12"Copyright (c) 2002-2015, Jouni Malinen <[email protected]> "13diff --git a/src/ap/beacon.c b/src/ap/beacon.c14index 5fe8fd5..5f7c077 10064415--- a/src/ap/beacon.c16+++ b/src/ap/beacon.c17@@ -1007,6 +1007,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,18#ifdef CONFIG_IEEE80211N19tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);20tailpos = hostapd_eid_ht_operation(hapd, tailpos);21+22+ //DRIVER_RTW ADD23+ if(hapd->iconf->ieee80211n)24+ hapd->conf->wmm_enabled = 1;25+26#endif /* CONFIG_IEEE80211N */2728tailpos = hostapd_eid_ext_capab(hapd, tailpos);29diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c30index fc8786d..efd3841 10064431--- a/src/ap/hw_features.c32+++ b/src/ap/hw_features.c33@@ -494,7 +494,10 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)34iface->num_ht40_scan_tries = 1;35eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);36eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);37- return 1;38+39+ //DRIVER_RTW Modify40+ //return -1;41+ return 0;//ignore this error42}4344if (ret < 0) {45diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c46index bab1f03..555d0d8 10064447--- a/src/drivers/driver_bsd.c48+++ b/src/drivers/driver_bsd.c49@@ -47,6 +47,12 @@5051#include "l2_packet/l2_packet.h"5253+#ifdef HOSTAPD54+#ifdef CONFIG_SUPPORT_RTW_DRIVER55+#define RTW_BSD_HOSTAPD_SET_BEACON (1100)56+#endif57+#endif58+59struct bsd_driver_data {60struct hostapd_data *hapd; /* back pointer */6162@@ -800,6 +806,296 @@ handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)63drv_event_eapol_rx(drv->hapd, src_addr, buf, len);64}6566+#ifdef CONFIG_SUPPORT_RTW_DRIVER67+static int rtw_set_beacon_ops(void *priv, const u8 *head, size_t head_len,68+ const u8 *tail, size_t tail_len, int dtim_period,69+ int beacon_int)70+{71+ int ret=0;72+ u8 *pbuf;73+ size_t sz;74+ struct bsd_driver_data *drv = priv;75+76+ if((head_len<24) ||(!head))77+ return -1;78+79+ sz = head_len+tail_len - 24; // 24 = wlan hdr80+81+ printf("%s, beacon_sz=%d\n", __func__, sz);82+83+ pbuf = os_zalloc(sz);84+ if (pbuf == NULL) {85+ return -ENOMEM;86+ }87+88+ os_memcpy(pbuf, (head+24), (head_len-24));// 24=beacon header len.89+90+ os_memcpy(&pbuf[head_len-24], tail, tail_len);91+92+ ret = set80211var(drv, RTW_BSD_HOSTAPD_SET_BEACON, pbuf, sz);93+94+ os_free(pbuf);95+96+ return ret;97+98+}99+100+static struct hostapd_hw_modes *rtw_get_hw_feature_data_ops(101+ void *priv, u16 *num_modes, u16 *flags)102+{103+104+#define MAX_NUM_CHANNEL (14)105+#define MAX_NUM_CHANNEL_5G (24)106+107+ struct hostapd_hw_modes *modes;108+ size_t i;109+ int k;110+111+ printf("%s\n", __func__);112+113+ *num_modes = 3;114+ *flags = 0;115+116+ modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));117+ if (modes == NULL)118+ return NULL;119+120+ //.1121+ modes[0].mode = HOSTAPD_MODE_IEEE80211G;122+ modes[0].num_channels = MAX_NUM_CHANNEL;123+ modes[0].num_rates = 12;124+ modes[0].channels =125+ os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data));126+ modes[0].rates = os_zalloc(modes[0].num_rates * sizeof(int));127+ if (modes[0].channels == NULL || modes[0].rates == NULL)128+ goto fail;129+ for (i = 0; i < MAX_NUM_CHANNEL; i++) {130+ modes[0].channels[i].chan = i + 1;131+ modes[0].channels[i].freq = 2412 + 5 * i;132+ modes[0].channels[i].flag = 0;133+ if (i >= 13)134+ modes[0].channels[i].flag = HOSTAPD_CHAN_DISABLED;135+ }136+ modes[0].rates[0] = 10;137+ modes[0].rates[1] = 20;138+ modes[0].rates[2] = 55;139+ modes[0].rates[3] = 110;140+ modes[0].rates[4] = 60;141+ modes[0].rates[5] = 90;142+ modes[0].rates[6] = 120;143+ modes[0].rates[7] = 180;144+ modes[0].rates[8] = 240;145+ modes[0].rates[9] = 360;146+ modes[0].rates[10] = 480;147+ modes[0].rates[11] = 540;148+149+150+ //.2151+ modes[1].mode = HOSTAPD_MODE_IEEE80211B;152+ modes[1].num_channels = MAX_NUM_CHANNEL;153+ modes[1].num_rates = 4;154+ modes[1].channels =155+ os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data));156+ modes[1].rates = os_zalloc(modes[1].num_rates * sizeof(int));157+ if (modes[1].channels == NULL || modes[1].rates == NULL)158+ goto fail;159+ for (i = 0; i < MAX_NUM_CHANNEL; i++) {160+ modes[1].channels[i].chan = i + 1;161+ modes[1].channels[i].freq = 2412 + 5 * i;162+ modes[1].channels[i].flag = 0;163+ if (i >= 11)164+ modes[1].channels[i].flag = HOSTAPD_CHAN_DISABLED;165+ }166+ modes[1].rates[0] = 10;167+ modes[1].rates[1] = 20;168+ modes[1].rates[2] = 55;169+ modes[1].rates[3] = 110;170+171+172+ //.3173+ modes[2].mode = HOSTAPD_MODE_IEEE80211A;174+#ifdef CONFIG_DRIVER_RTL_DFS175+ modes[2].num_channels = MAX_NUM_CHANNEL_5G;176+#else /* CONFIG_DRIVER_RTL_DFS */177+ modes[2].num_channels = 9;178+#endif /* CONFIG_DRIVER_RTL_DFS */179+180+ modes[2].num_rates = 8;181+ modes[2].channels = os_zalloc(modes[2].num_channels * sizeof(struct hostapd_channel_data));182+ modes[2].rates = os_zalloc(modes[2].num_rates * sizeof(int));183+ if (modes[2].channels == NULL || modes[2].rates == NULL)184+ goto fail;185+186+187+ k = 0;188+ // 5G band1 Channel: 36, 40, 44, 48189+ for (i=0; i < 4; i++) {190+ modes[2].channels[k].chan = 36+(i*4);191+ modes[2].channels[k].freq = 5180+(i*20);192+ modes[2].channels[k].flag = 0;193+ k++;194+ }195+196+#ifdef CONFIG_DRIVER_RTL_DFS197+ // 5G band2 Channel: 52, 56, 60, 64198+ for (i=0; i < 4; i++) {199+ modes[2].channels[k].chan = 52+(i*4);200+ modes[2].channels[k].freq = 5260+(i*20);201+ modes[2].channels[k].flag = 0;202+ k++;203+ }204+205+ // 5G band3 Channel: 100, 104, 108. 112, 116, 120, 124, 128, 132, 136, 140206+ for (i=0; i < 11; i++) {207+ modes[2].channels[k].chan = 100+(i*4);208+ modes[2].channels[k].freq = 5500+(i*20);209+ modes[2].channels[k].flag = 0;210+ k++;211+ }212+#endif /* CONFIG_DRIVER_RTL_DFS */213+214+ // 5G band4 Channel: 149, 153, 157, 161, 165215+ for (i=0; i < 5; i++) {216+ modes[2].channels[k].chan = 149+(i*4);217+ modes[2].channels[k].freq = 5745+(i*20);218+ modes[2].channels[k].flag = 0;219+ k++;220+ }221+222+ modes[2].rates[0] = 60;223+ modes[2].rates[1] = 90;224+ modes[2].rates[2] = 120;225+ modes[2].rates[3] = 180;226+ modes[2].rates[4] = 240;227+ modes[2].rates[5] = 360;228+ modes[2].rates[6] = 480;229+ modes[2].rates[7] = 540;230+231+232+ //233+#if 0234+#define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0))235+#define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1))236+#define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3)))237+#define HT_CAP_INFO_SMPS_STATIC ((u16) 0)238+#define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2))239+#define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3)))240+#define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4))241+#define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5))242+#define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6))243+#define HT_CAP_INFO_TX_STBC ((u16) BIT(7))244+#define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9)))245+#define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8))246+#define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9))247+#define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9)))248+#define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10))249+#define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11))250+#define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12))251+#define HT_CAP_INFO_PSMP_SUPP ((u16) BIT(13))252+#define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14))253+#define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15))254+#endif255+256+ //HOSTAPD_MODE_IEEE80211G257+ modes[0].ht_capab = HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET|HT_CAP_INFO_SHORT_GI20MHZ|258+ HT_CAP_INFO_SHORT_GI40MHZ|HT_CAP_INFO_MAX_AMSDU_SIZE|HT_CAP_INFO_DSSS_CCK40MHZ;259+260+ modes[0].mcs_set[0]= 0xff;261+ modes[0].mcs_set[1]= 0xff;262+263+ //HOSTAPD_MODE_IEEE80211B264+ modes[1].ht_capab = 0;265+266+ //HOSTAPD_MODE_IEEE80211A267+ modes[2].ht_capab = modes[0].ht_capab;268+269+ modes[2].mcs_set[0]= 0xff;270+ modes[2].mcs_set[1]= 0xff;271+272+ return modes;273+274+fail:275+ if (modes) {276+ for (i = 0; i < *num_modes; i++) {277+ os_free(modes[i].channels);278+ os_free(modes[i].rates);279+ }280+ os_free(modes);281+ }282+283+ return NULL;284+285+}286+287+#if 0288+#define IEEE80211_FC0_TYPE_MASK 0x0c289+#define IEEE80211_FC0_TYPE_SHIFT 2290+#define IEEE80211_FC0_TYPE_MGT 0x00291+#define IEEE80211_FC0_TYPE_CTL 0x04292+#define IEEE80211_FC0_TYPE_DATA 0x08293+#define IEEE80211_FC0_SUBTYPE_MASK 0xf0294+#define IEEE80211_FC0_SUBTYPE_SHIFT 4295+#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00296+#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10297+#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20298+#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30299+#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40300+#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50301+#define IEEE80211_FC0_SUBTYPE_BEACON 0x80302+#define IEEE80211_FC0_SUBTYPE_ATIM 0x90303+#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0304+#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0305+#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0306+#define IEEE80211_FC0_SUBTYPE_ACTION 0xd0307+#define IEEE80211_FC0_SUBTYPE_ACTION_NOACK 0xe0308+309+#define IEEE80211_APPIE_WPA (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON | \310+ IEEE80211_FC0_SUBTYPE_PROBE_RESP)311+312+#endif313+314+#define RTW_IEEE80211_APPIE_BEACON (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)315+#define RTW_IEEE80211_APPIE_PROBE_RESP (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_PROBE_RESP)316+#define RTW_IEEE80211_APPIE_ASSOC_RESP (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_ASSOC_RESP)317+318+319+static int rtw_set_wps_assoc_resp_ie(void *priv, const void *ie, size_t len)320+{321+ return bsd_set80211(priv, IEEE80211_IOC_APPIE, RTW_IEEE80211_APPIE_ASSOC_RESP,322+ ie, len);323+}324+325+static int rtw_set_wps_beacon_ie(void *priv, const void *ie, size_t len)326+{327+ return bsd_set80211(priv, IEEE80211_IOC_APPIE, RTW_IEEE80211_APPIE_BEACON,328+ ie, len);329+}330+331+static int rtw_set_wps_probe_resp_ie(void *priv, const void *ie, size_t len)332+{333+ return bsd_set80211(priv, IEEE80211_IOC_APPIE, RTW_IEEE80211_APPIE_PROBE_RESP,334+ ie, len);335+}336+337+static int rtw_set_ap_wps_ie_ops(void *priv, const struct wpabuf *beacon,338+ const struct wpabuf *proberesp, const struct wpabuf *assocresp)339+{340+ if (rtw_set_wps_assoc_resp_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL,341+ assocresp ? wpabuf_len(assocresp) : 0))342+ return -1;343+344+ if (rtw_set_wps_beacon_ie(priv, beacon ? wpabuf_head(beacon) : NULL,345+ beacon ? wpabuf_len(beacon) : 0))346+ return -1;347+348+ return rtw_set_wps_probe_resp_ie(priv,349+ proberesp ? wpabuf_head(proberesp) : NULL,350+ proberesp ? wpabuf_len(proberesp): 0);351+352+}353+#endif354+355+356static void *357bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)358{359@@ -854,6 +1150,12 @@ bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)360goto bad;361}362363+#ifdef CONFIG_SUPPORT_RTW_DRIVER364+ /* mark up after init */365+ if (bsd_ctrl_iface(drv, 1) < 0)366+ goto bad;367+#endif368+369return drv;370bad:371if (drv->sock_xmit != NULL)372@@ -1292,6 +1594,15 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)373event.interface_status.ifname);374wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);375}376+ else{377+ os_strlcpy(event.interface_status.ifname, drv->ifname,378+ sizeof(event.interface_status.ifname));379+ event.interface_status.ievent = EVENT_INTERFACE_ADDED;380+ wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",381+ event.interface_status.ifname);382+ wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);383+ }384+385break;386}387}388@@ -1609,7 +1920,52 @@ wpa_driver_bsd_get_capa(void *priv, struct wpa_driver_capa *capa)389}390#endif /* HOSTAPD */391392-393+#ifdef CONFIG_SUPPORT_RTW_DRIVER394+const struct wpa_driver_ops wpa_driver_bsd_ops = {395+ .name = "bsd",396+ .desc = "BSD 802.11 support",397+#ifdef HOSTAPD398+ .hapd_init = bsd_init,399+ .hapd_deinit = bsd_deinit,400+ .set_privacy = bsd_set_privacy,//del ?401+ .get_seqnum = bsd_get_seqnum,//del ?402+ .flush = bsd_flush,403+ .read_sta_data = bsd_read_sta_driver_data,//del ?404+ .sta_disassoc = bsd_sta_disassoc,405+ .sta_deauth = bsd_sta_deauth,406+ .get_hw_feature_data = rtw_get_hw_feature_data_ops,//add407+ //.sta_remove = rtl871x_sta_remove_ops,//add408+ .set_beacon = rtw_set_beacon_ops, //add409+ .set_ap_wps_ie = rtw_set_ap_wps_ie_ops,//add410+#else /* HOSTAPD */411+ .init = wpa_driver_bsd_init,412+ .deinit = wpa_driver_bsd_deinit,413+ .get_bssid = wpa_driver_bsd_get_bssid,414+ .get_ssid = wpa_driver_bsd_get_ssid,415+ .set_countermeasures = wpa_driver_bsd_set_countermeasures,416+ .scan2 = wpa_driver_bsd_scan,417+ .get_scan_results2 = wpa_driver_bsd_get_scan_results2,418+ .deauthenticate = wpa_driver_bsd_deauthenticate,419+ .disassociate = wpa_driver_bsd_disassociate,420+ .associate = wpa_driver_bsd_associate,421+ .get_capa = wpa_driver_bsd_get_capa,422+ .set_freq = bsd_set_freq, //only for wpa_supplicant423+ .set_ieee8021x = bsd_set_ieee8021x,//only for wpa_supplicant424+ .hapd_set_ssid = bsd_set_ssid,//only for wpa_supplicant425+ .hapd_get_ssid = bsd_get_ssid,//only for wpa_supplicant426+ .sta_set_flags = bsd_set_sta_authorized, //only for wpa_supplicant427+ .set_generic_elem = bsd_set_opt_ie, //only for wpa_supplicant428+#endif /* HOSTAPD */429+ //.set_freq = bsd_set_freq, //only for wpa_supplicant430+ .set_key = bsd_set_key,431+ //.set_ieee8021x = bsd_set_ieee8021x, //only for wpa_supplicant432+ //.hapd_set_ssid = bsd_set_ssid, //only for wpa_supplicant433+ //.hapd_get_ssid = bsd_get_ssid, //only for wpa_supplicant434+ .hapd_send_eapol = bsd_send_eapol, //only for wpa_supplicant435+ //.sta_set_flags = bsd_set_sta_authorized, //only for wpa_supplicant436+ //.set_generic_elem = bsd_set_opt_ie, //only for wpa_supplicant437+};438+#else439const struct wpa_driver_ops wpa_driver_bsd_ops = {440.name = "bsd",441.desc = "BSD 802.11 support",442@@ -1644,3 +2000,4 @@ const struct wpa_driver_ops wpa_driver_bsd_ops = {443.hapd_send_eapol = bsd_send_eapol,444.set_generic_elem = bsd_set_opt_ie,445};446+#endif447diff --git a/src/drivers/driver_rtl.h b/src/drivers/driver_rtl.h448new file mode 100644449index 0000000..2200e18450--- /dev/null451+++ b/src/drivers/driver_rtl.h452@@ -0,0 +1,114 @@453+454+#ifndef _DRIVER_RTL_H_455+#define _DRIVER_RTL_H_456+457+458+#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28)459+460+#define IEEE_CRYPT_ALG_NAME_LEN (16)461+462+/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */463+enum {464+ RTL871X_HOSTAPD_FLUSH = 1,465+ RTL871X_HOSTAPD_ADD_STA = 2,466+ RTL871X_HOSTAPD_REMOVE_STA = 3,467+ RTL871X_HOSTAPD_GET_INFO_STA = 4,468+ /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */469+ RTL871X_HOSTAPD_GET_WPAIE_STA = 5,470+ RTL871X_SET_ENCRYPTION = 6,471+ RTL871X_GET_ENCRYPTION = 7,472+ RTL871X_HOSTAPD_SET_FLAGS_STA = 8,473+ RTL871X_HOSTAPD_GET_RID = 9,474+ RTL871X_HOSTAPD_SET_RID = 10,475+ RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11,476+ RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12,477+ RTL871X_HOSTAPD_MLME = 13,478+ RTL871X_HOSTAPD_SCAN_REQ = 14,479+ RTL871X_HOSTAPD_STA_CLEAR_STATS = 15,480+ RTL871X_HOSTAPD_SET_BEACON = 16,481+ RTL871X_HOSTAPD_SET_WPS_BEACON = 17,482+ RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18,483+ RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19,484+ RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20,485+};486+487+typedef struct ieee_param {488+ u32 cmd;489+ u8 sta_addr[ETH_ALEN];490+ union {491+ struct {492+ u8 name;493+ u32 value;494+ } wpa_param;495+ struct {496+ u32 len;497+ u8 reserved[32];498+ u8 data[0];499+ } wpa_ie;500+ struct{501+ int command;502+ int reason_code;503+ } mlme;504+ struct {505+ u8 alg[IEEE_CRYPT_ALG_NAME_LEN];506+ u8 set_tx;507+ u32 err;508+ u8 idx;509+ u8 seq[8]; /* sequence counter (set: RX, get: TX) */510+ u16 key_len;511+ u8 key[0];512+ } crypt;513+ struct {514+ u16 aid;515+ u16 capability;516+ int flags;517+ u8 tx_supp_rates[16];518+ //struct ieee80211_ht_capability ht_cap;519+ struct ieee80211_ht_capabilities ht_cap;520+ } add_sta;521+ struct {522+ u8 reserved[2];//for set max_num_sta523+ u8 buf[0];524+ } bcn_ie;525+526+ } u;527+528+} ieee_param;529+530+531+532+#define IEEE80211_CCK_RATE_LEN 4533+#define IEEE80211_OFDM_RATE_LEN 8534+535+#define IEEE80211_CCK_RATE_1MB 0x02536+#define IEEE80211_CCK_RATE_2MB 0x04537+#define IEEE80211_CCK_RATE_5MB 0x0B538+#define IEEE80211_CCK_RATE_11MB 0x16539+#define IEEE80211_OFDM_RATE_6MB 0x0C540+#define IEEE80211_OFDM_RATE_9MB 0x12541+#define IEEE80211_OFDM_RATE_12MB 0x18542+#define IEEE80211_OFDM_RATE_18MB 0x24543+#define IEEE80211_OFDM_RATE_24MB 0x30544+#define IEEE80211_OFDM_RATE_36MB 0x48545+#define IEEE80211_OFDM_RATE_48MB 0x60546+#define IEEE80211_OFDM_RATE_54MB 0x6C547+#define IEEE80211_BASIC_RATE_MASK 0x80548+549+#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)550+#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)551+#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)552+#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)553+#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)554+#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)555+#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)556+#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)557+#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)558+#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)559+#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)560+#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)561+562+#define IEEE80211_CCK_RATES_MASK 0x0000000F563+#define IEEE80211_OFDM_RATES_MASK 0x00000FF0564+565+#endif566+567diff --git a/src/drivers/driver_rtw.c b/src/drivers/driver_rtw.c568new file mode 100644569index 0000000..436dd14570--- /dev/null571+++ b/src/drivers/driver_rtw.c572@@ -0,0 +1,1993 @@573+/*574+ * hostapd / Driver interface for rtl871x driver575+ * Copyright (c) 2010,576+ *577+ * This program is free software; you can redistribute it and/or modify578+ * it under the terms of the GNU General Public License version 2 as579+ * published by the Free Software Foundation.580+ *581+ * Alternatively, this software may be distributed under the terms of BSD582+ * license.583+ *584+ * See README and COPYING for more details.585+ */586+587+//#define CONFIG_MGNT_L2SOCK 1588+#define CONFIG_MLME_OFFLOAD 1589+590+591+#include "includes.h"592+#include <net/if.h>593+#include <sys/ioctl.h>594+595+#include "common.h"596+597+/*#include "wireless_copy.h"*/598+#include "linux_wext.h"599+600+#include "driver.h"601+#include "eloop.h"602+#include "priv_netlink.h"603+#include "l2_packet/l2_packet.h"604+#include "common/ieee802_11_defs.h"605+#include "netlink.h"606+#include "linux_ioctl.h"607+608+//#include "../src/ap/hostapd.h"609+//#include "../src/ap/ap_config.h"610+#include "ap/hostapd.h"611+#include "ap/ap_config.h"612+613+#ifdef USE_KERNEL_HEADERS614+/* compat-wireless does not include linux/compiler.h to define __user, so615+ * define it here */616+#ifndef __user617+#define __user618+#endif /* __user */619+#include <asm/types.h>620+#include <linux/if_packet.h>621+#include <linux/if_ether.h> /* The L2 protocols */622+#include <linux/if_arp.h>623+#include <linux/wireless.h>624+#else /* USE_KERNEL_HEADERS */625+#include <net/if_arp.h>626+#include <netpacket/packet.h>627+//#include "wireless_copy.h"628+#endif /* USE_KERNEL_HEADERS */629+630+//#include <net/if.h>631+632+633+#ifndef ETH_P_80211_RAW634+#define ETH_P_80211_RAW 0x0019635+#endif636+637+#if 0638+#include "hostapd.h"639+#include "driver.h"640+#include "ieee802_1x.h"641+#include "eloop.h"642+#include "priv_netlink.h"643+#include "sta_info.h"644+#include "l2_packet/l2_packet.h"645+646+#include "wpa.h"647+#include "accounting.h"648+#include "ieee802_11.h"649+#include "hw_features.h"650+#include "radius/radius.h"651+#endif652+653+#include "driver_rtl.h"654+655+656+//static int rtl871x_sta_remove_ops(void *priv, const u8 *addr);657+658+struct rtl871x_driver_data {659+ struct hostapd_data *hapd;660+661+ char iface[IFNAMSIZ + 1];662+ int ifindex;663+ struct l2_packet_data *l2_sock;/* socket for sending eapol frames*/664+ struct l2_packet_data *l2_sock_recv;/* raw packet recv socket from bridge interface*/665+#ifdef CONFIG_MGNT_L2SOCK666+ struct l2_packet_data *mgnt_l2_sock; /* socket for tx/rx management frames*/667+#else668+ int mgnt_sock;/* socket for tx/rx management frames*/669+#endif670+ int ioctl_sock; /* socket for ioctl() use */671+ int wext_sock; /* socket for wireless events */672+673+ struct netlink_data *netlink;674+675+ int we_version;676+677+ u8 hw_mac[ETH_ALEN];678+679+ u8 acct_mac[ETH_ALEN];680+681+ struct hostap_sta_driver_data acct_data;682+683+};684+685+/*686+static const char *ether_sprintf(const u8 *addr)687+{688+ static char buf[sizeof(MACSTR)];689+690+ if (addr != NULL)691+ snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));692+ else693+ snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);694+695+ return buf;696+}697+*/698+699+#ifndef CONFIG_MLME_OFFLOAD700+static int rtl871x_set_iface_flags(void *priv, int dev_up)701+{702+ struct rtl871x_driver_data *drv = priv;703+ struct ifreq ifr;704+705+ wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);706+707+ if (drv->mgnt_sock < 0)708+ return -1;709+710+ memset(&ifr, 0, sizeof(ifr));711+ //os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);712+ //os_strlcpy(ifr.ifr_name, "mgnt.wlan", IFNAMSIZ);713+ snprintf(ifr.ifr_name, IFNAMSIZ, "mgnt.%s", "wlan0");714+715+ if (ioctl(drv->mgnt_sock, SIOCGIFFLAGS, &ifr) != 0) {716+ perror("ioctl[SIOCGIFFLAGS]");717+ return -1;718+ }719+720+ if (dev_up)721+ ifr.ifr_flags |= IFF_UP;722+ else723+ ifr.ifr_flags &= ~IFF_UP;724+725+ if (ioctl(drv->mgnt_sock, SIOCSIFFLAGS, &ifr) != 0) {726+ perror("ioctl[SIOCSIFFLAGS]");727+ return -1;728+ }729+730+#if 0731+ if (dev_up) {732+ memset(&ifr, 0, sizeof(ifr));733+ os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);734+ ifr.ifr_mtu = HOSTAPD_MTU;735+ if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) {736+ perror("ioctl[SIOCSIFMTU]");737+ printf("Setting MTU failed - trying to survive with "738+ "current value\n");739+ }740+ }741+#endif742+743+ return 0;744+}745+#endif746+747+static int rtl871x_hostapd_ioctl(struct rtl871x_driver_data *drv, ieee_param *param, int len)748+{749+ struct iwreq iwr;750+751+ memset(&iwr, 0, sizeof(iwr));752+ os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);753+ iwr.u.data.pointer = (caddr_t) param;754+ iwr.u.data.length = len;755+756+ if (ioctl(drv->ioctl_sock, RTL_IOCTL_HOSTAPD, &iwr) < 0) {757+ perror("ioctl[RTL_IOCTL_HOSTAPD]");758+ return -1;759+ }760+761+ return 0;762+}763+764+static int rtl871x_set_mode(struct rtl871x_driver_data *drv, u32 mode)765+{766+ struct iwreq iwr;767+768+ if (drv->ioctl_sock < 0)769+ return -1;770+771+ memset(&iwr, 0, sizeof(iwr));772+773+ os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);774+775+ //iwr.u.mode = IW_MODE_MASTER;776+ iwr.u.mode = mode;777+778+ if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {779+ perror("ioctl[SIOCSIWMODE]");780+ printf("Could not set interface to mode(%d)!\n", mode);781+ return -1;782+ }783+784+ return 0;785+786+}787+788+/*789+static int rtl871x_notif_assoc(struct hostapd_data *hapd, const u8 *addr,790+ const u8 *ie, size_t ielen)791+{792+ struct sta_info *sta;793+ int new_assoc, res;794+795+ //hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,796+ // HOSTAPD_LEVEL_INFO, "associated");797+798+ sta = ap_get_sta(hapd, addr);799+ if (sta) {800+ accounting_sta_stop(hapd, sta);801+ } else {802+ sta = ap_sta_add(hapd, addr);803+ if (sta == NULL)804+ {805+ rtl871x_sta_remove_ops(hapd->drv_priv, addr);806+ return -1;807+ }808+ }809+ sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);810+811+ if (hapd->conf->wpa) {812+ if (ie == NULL || ielen == 0) {813+ if (hapd->conf->wps_state) {814+ wpa_printf(MSG_DEBUG, "STA did not include "815+ "WPA/RSN IE in (Re)Association "816+ "Request - possible WPS use");817+ sta->flags |= WLAN_STA_MAYBE_WPS;818+ goto skip_wpa_check;819+ }820+821+ wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");822+ return -1;823+ }824+ if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&825+ os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {826+ sta->flags |= WLAN_STA_WPS;827+ goto skip_wpa_check;828+ }829+830+ if (sta->wpa_sm == NULL)831+ sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,832+ sta->addr);833+ if (sta->wpa_sm == NULL) {834+ wpa_printf(MSG_ERROR, "Failed to initialize WPA state "835+ "machine");836+ return -1;837+ }838+ res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,839+ ie, ielen, NULL, 0);840+ if (res != WPA_IE_OK) {841+ wpa_printf(MSG_DEBUG, "WPA/RSN information element "842+ "rejected? (res %u)", res);843+ wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);844+ return -1;845+ }846+ } else if (hapd->conf->wps_state) {847+ if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 &&848+ os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {849+ sta->flags |= WLAN_STA_WPS;850+ } else851+ sta->flags |= WLAN_STA_MAYBE_WPS;852+ }853+skip_wpa_check:854+855+ new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;856+ sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;857+ wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);858+859+ hostapd_new_assoc_sta(hapd, sta, !new_assoc);860+861+ ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);862+863+ return 0;864+}865+*/866+867+static int rtl871x_get_sta_wpaie(struct rtl871x_driver_data *drv, u8 *iebuf, u8 *addr)868+{869+ struct ieee_param param;870+871+ printf("+%s, " MACSTR " is sta's address\n", __func__, MAC2STR(addr));872+873+ memset(¶m, 0, sizeof(param));874+875+ param.cmd = RTL871X_HOSTAPD_GET_WPAIE_STA;876+877+ memcpy(param.sta_addr, addr, ETH_ALEN);878+879+ if (rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param))) {880+ printf("Could not get sta wpaie from kernel driver.\n");881+ return -1;882+ }883+884+885+ if(param.u.wpa_ie.len > 32)886+ return -1;887+888+ memcpy(iebuf, param.u.wpa_ie.reserved, param.u.wpa_ie.len);889+890+ return 0;891+892+}893+894+static int rtl871x_del_sta(struct rtl871x_driver_data *drv, u8 *addr)895+{896+ struct hostapd_data *hapd = drv->hapd;897+898+#if 1899+900+ //union wpa_event_data event;901+ //os_memset(&event, 0, sizeof(event));902+ //event.disassoc_info.addr = addr;903+ //wpa_supplicant_event(hapd, EVENT_DISASSOC, &event);904+905+ drv_event_disassoc(hapd, addr);906+907+#else908+909+ struct sta_info *sta;910+911+ //hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,912+ // HOSTAPD_LEVEL_INFO, "disassociated");913+914+ sta = ap_get_sta(hapd, addr);915+ if (sta != NULL)916+ {917+ sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);918+ wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);919+ sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;920+ ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);921+ ap_free_sta(hapd, sta);922+ }923+ else924+ {925+ wpa_printf(MSG_DEBUG, "Disassociation notification for "926+ "unknown STA " MACSTR, MAC2STR(addr));927+ }928+#endif929+930+ return 0;931+932+}933+934+static int rtl871x_new_sta(struct rtl871x_driver_data *drv, u8 *addr)935+{936+ struct hostapd_data *hapd = drv->hapd;937+ //struct ieee80211req_wpaie ie;938+ int ielen = 0, res=0;939+ //u8 *iebuf = NULL;940+ u8 iebuf[32], *piebuf=NULL;941+942+ /*943+ * Fetch negotiated WPA/RSN parameters from the driver.944+ */945+ //memset(&ie, 0, sizeof(ie));946+ //memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);947+ memset(iebuf, 0 , sizeof(iebuf));948+ if (rtl871x_get_sta_wpaie(drv, iebuf, addr)) {949+ //if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {950+951+ wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s",952+ __func__, strerror(errno));953+ goto no_ie;954+ }955+956+ //wpa_hexdump(MSG_MSGDUMP, "req WPA IE",957+ // ie.wpa_ie, IEEE80211_MAX_OPT_IE);958+959+ //wpa_hexdump(MSG_MSGDUMP, "req RSN IE",960+ // ie.rsn_ie, IEEE80211_MAX_OPT_IE);961+962+ //iebuf = ie.wpa_ie;963+964+/*965+ if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)966+ iebuf[1] = 0;967+ if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {968+ iebuf = ie.rsn_ie;969+ if (iebuf[0] != WLAN_EID_RSN)970+ iebuf[1] = 0;971+ }972+*/973+974+ if ((iebuf[0] == WLAN_EID_VENDOR_SPECIFIC) || (iebuf[0] == WLAN_EID_RSN) )975+ {976+ piebuf = iebuf;977+ ielen = iebuf[1];978+979+ if (ielen == 0)980+ piebuf = NULL;981+ else982+ ielen += 2;983+ }984+985+no_ie:986+987+ //res = rtl871x_notif_assoc(hapd, addr, piebuf, ielen);988+ //drv_event_assoc(hapd, addr, piebuf, ielen);989+ drv_event_assoc(hapd, addr, piebuf, ielen, 0);990+991+ if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {992+ /* Cached accounting data is not valid anymore. */993+ memset(drv->acct_mac, 0, ETH_ALEN);994+ memset(&drv->acct_data, 0, sizeof(drv->acct_data));995+ }996+997+ return res;998+999+}1000+1001+static void rtl871x_wireless_event_wireless(struct rtl871x_driver_data *drv,1002+ char *data, int len)1003+{1004+ struct iw_event iwe_buf, *iwe = &iwe_buf;1005+ char *pos, *end, *custom, *buf;1006+1007+ pos = data;1008+ end = data + len;1009+1010+ while (pos + IW_EV_LCP_LEN <= end) {1011+ /* Event data may be unaligned, so make a local, aligned copy1012+ * before processing. */1013+ memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);1014+ wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",1015+ iwe->cmd, iwe->len);1016+ if (iwe->len <= IW_EV_LCP_LEN)1017+ return;1018+1019+ custom = pos + IW_EV_POINT_LEN;1020+ if (drv->we_version > 18 &&1021+ (iwe->cmd == IWEVMICHAELMICFAILURE ||1022+ iwe->cmd == IWEVCUSTOM)) {1023+ /* WE-19 removed the pointer from struct iw_point */1024+ char *dpos = (char *) &iwe_buf.u.data.length;1025+ int dlen = dpos - (char *) &iwe_buf;1026+ memcpy(dpos, pos + IW_EV_LCP_LEN,1027+ sizeof(struct iw_event) - dlen);1028+ } else {1029+ memcpy(&iwe_buf, pos, sizeof(struct iw_event));1030+ custom += IW_EV_POINT_OFF;1031+ }1032+1033+ //printf("got wireless event, iwe->cmd=%d\n", iwe->cmd);1034+1035+ switch (iwe->cmd) {1036+ case IWEVEXPIRED:1037+ rtl871x_del_sta(drv, (u8 *)iwe->u.addr.sa_data);1038+ break;1039+ case IWEVREGISTERED:1040+ if(rtl871x_new_sta(drv, (u8 *)iwe->u.addr.sa_data))1041+ {1042+ printf("Failed to add new sta: "MACSTR" \n", MAC2STR((u8 *)iwe->u.addr.sa_data));1043+ }1044+ break;1045+ case IWEVCUSTOM:1046+ if (custom + iwe->u.data.length > end)1047+ return;1048+ buf = malloc(iwe->u.data.length + 1);1049+ if (buf == NULL)1050+ return; /* XXX */1051+ memcpy(buf, custom, iwe->u.data.length);1052+ buf[iwe->u.data.length] = '\0';1053+ //madwifi_wireless_event_wireless_custom(drv, buf);1054+ free(buf);1055+ break;1056+ }1057+1058+ pos += iwe->len;1059+ }1060+1061+}1062+1063+#if 11064+static void rtl871x_wireless_event_rtm_newlink(void *ctx,1065+ struct ifinfomsg *ifi, u8 *buf, size_t len)1066+{1067+ struct rtl871x_driver_data *drv = ctx;1068+ int attrlen, rta_len;1069+ struct rtattr *attr;1070+1071+ if (ifi->ifi_index != drv->ifindex)1072+ return;1073+1074+ attrlen = len;1075+ attr = (struct rtattr *) buf;1076+1077+ rta_len = RTA_ALIGN(sizeof(struct rtattr));1078+ while (RTA_OK(attr, attrlen)) {1079+ if (attr->rta_type == IFLA_WIRELESS) {1080+ rtl871x_wireless_event_wireless(1081+ drv, ((char *) attr) + rta_len,1082+ attr->rta_len - rta_len);1083+ }1084+ attr = RTA_NEXT(attr, attrlen);1085+ }1086+}1087+1088+#else1089+static void rtl871x_wireless_event_rtm_newlink(struct rtl871x_driver_data *drv,1090+ struct nlmsghdr *h, int len)1091+{1092+ struct ifinfomsg *ifi;1093+ int attrlen, nlmsg_len, rta_len;1094+ struct rtattr * attr;1095+1096+ if (len < (int) sizeof(*ifi))1097+ return;1098+1099+ ifi = NLMSG_DATA(h);1100+1101+ if (ifi->ifi_index != drv->ifindex)1102+ return;1103+1104+ nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));1105+1106+ attrlen = h->nlmsg_len - nlmsg_len;1107+ if (attrlen < 0)1108+ return;1109+1110+ attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);1111+1112+ rta_len = RTA_ALIGN(sizeof(struct rtattr));1113+ while (RTA_OK(attr, attrlen)) {1114+ if (attr->rta_type == IFLA_WIRELESS) {1115+ rtl871x_wireless_event_wireless(1116+ drv, ((char *) attr) + rta_len,1117+ attr->rta_len - rta_len);1118+ }1119+ attr = RTA_NEXT(attr, attrlen);1120+ }1121+}1122+#endif1123+1124+/*1125+static void rtl871x_wireless_event_receive(int sock, void *eloop_ctx, void *sock_ctx)1126+{1127+ char buf[256];//!!!1128+ int left;1129+ struct sockaddr_nl from;1130+ socklen_t fromlen;1131+ struct nlmsghdr *h;1132+ struct rtl871x_driver_data *drv = eloop_ctx;1133+1134+ //printf("+rtl871x_wireless_event_receive\n");1135+1136+ fromlen = sizeof(from);1137+ left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,1138+ (struct sockaddr *) &from, &fromlen);1139+ if (left < 0) {1140+ if (errno != EINTR && errno != EAGAIN)1141+ perror("recvfrom(netlink)");1142+ return;1143+ }1144+1145+ h = (struct nlmsghdr *)buf;1146+ while (left >= (int) sizeof(*h)) {1147+ int len, plen;1148+1149+ len = h->nlmsg_len;1150+ plen = len - sizeof(*h);//payload len1151+ if (len > left || plen < 0) {1152+ printf("Malformed netlink message: "1153+ "len=%d left=%d plen=%d\n",1154+ len, left, plen);1155+ break;1156+ }1157+1158+ switch (h->nlmsg_type) {1159+ case RTM_NEWLINK:1160+ rtl871x_wireless_event_rtm_newlink(drv, h, plen);1161+ break;1162+ }1163+1164+ len = NLMSG_ALIGN(len);1165+ left -= len;1166+ h = (struct nlmsghdr *) ((char *) h + len);1167+ }1168+1169+ if (left > 0) {1170+ printf("%d extra bytes in the end of netlink message\n", left);1171+ }1172+1173+}1174+*/1175+1176+static int rtl871x_wireless_event_init(struct rtl871x_driver_data *drv)1177+{1178+ struct netlink_config *cfg;1179+1180+ //madwifi_get_we_version(drv);1181+1182+ cfg = os_zalloc(sizeof(*cfg));1183+ if (cfg == NULL)1184+ return -1;1185+ cfg->ctx = drv;1186+ cfg->newlink_cb = rtl871x_wireless_event_rtm_newlink;1187+ drv->netlink = netlink_init(cfg);1188+ if (drv->netlink == NULL) {1189+ os_free(cfg);1190+ return -1;1191+ }1192+1193+ return 0;1194+}1195+1196+/*1197+static int rtl871x_wireless_event_init_ops(void *priv)1198+{1199+ int s;1200+ struct sockaddr_nl local;1201+ struct rtl871x_driver_data *drv = priv;1202+1203+ //madwifi_get_we_version(drv);1204+1205+ drv->wext_sock = -1;1206+1207+ s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);1208+ if (s < 0) {1209+ perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");1210+ return -1;1211+ }1212+1213+ memset(&local, 0, sizeof(local));1214+ local.nl_family = AF_NETLINK;1215+ local.nl_groups = RTMGRP_LINK;1216+ if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {1217+ perror("bind(netlink)");1218+ close(s);1219+ return -1;1220+ }1221+1222+ eloop_register_read_sock(s, rtl871x_wireless_event_receive, drv, NULL);1223+ drv->wext_sock = s;1224+1225+ return 0;1226+1227+}1228+1229+static void rtl871x_wireless_event_deinit_ops(void *priv)1230+{1231+ struct rtl871x_driver_data *drv = priv;1232+1233+ if (drv != NULL) {1234+ if (drv->wext_sock < 0)1235+ return;1236+ eloop_unregister_read_sock(drv->wext_sock);1237+ close(drv->wext_sock);1238+ }1239+}1240+*/1241+1242+#if 11243+static void rtl871x_handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)1244+{1245+ struct rtl871x_driver_data *drv = ctx;1246+ drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),1247+ len - sizeof(struct l2_ethhdr));1248+}1249+#else1250+static void rtl871x_handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)1251+{1252+ struct rtl871x_driver_data *drv = ctx;1253+ struct hostapd_data *hapd = drv->hapd;1254+ struct sta_info *sta;1255+1256+ sta = ap_get_sta(hapd, src_addr);1257+ if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {1258+ printf("Data frame from not associated STA %s\n",1259+ ether_sprintf(src_addr));1260+ /* XXX cannot happen */1261+ return;1262+ }1263+ ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),1264+ len - sizeof(struct l2_ethhdr));1265+}1266+#endif1267+1268+static int rtl871x_send_eapol_ops(void *priv, const u8 *addr, const u8 *data, size_t data_len,1269+ int encrypt, const u8 *own_addr, u32 flags)1270+{1271+ struct rtl871x_driver_data *drv = priv;1272+ unsigned char buf[3000];1273+ unsigned char *bp = buf;1274+ struct l2_ethhdr *eth;1275+ size_t len;1276+ int status;1277+1278+ printf("+rtl871x_send_eapol\n");1279+1280+ /*1281+ * Prepend the Ethernet header. If the caller left us1282+ * space at the front we could just insert it but since1283+ * we don't know we copy to a local buffer. Given the frequency1284+ * and size of frames this probably doesn't matter.1285+ */1286+ len = data_len + sizeof(struct l2_ethhdr);1287+ if (len > sizeof(buf)) {1288+ bp = malloc(len);1289+ if (bp == NULL) {1290+ printf("EAPOL frame discarded, cannot malloc temp "1291+ "buffer of size %lu!\n", (unsigned long) len);1292+ return -1;1293+ }1294+ }1295+1296+ eth = (struct l2_ethhdr *) bp;1297+ memcpy(eth->h_dest, addr, ETH_ALEN);1298+ memcpy(eth->h_source, own_addr, ETH_ALEN);1299+ eth->h_proto = htons(ETH_P_EAPOL);1300+ memcpy(eth+1, data, data_len);1301+1302+ wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);1303+1304+ status = l2_packet_send(drv->l2_sock, addr, ETH_P_EAPOL, bp, len);1305+1306+ if (bp != buf)1307+ free(bp);1308+1309+ return status;1310+1311+}1312+1313+#ifndef CONFIG_MLME_OFFLOAD1314+static void rtl871x_receive_mgnt(struct rtl871x_driver_data *drv , const u8 *buf, size_t len)1315+{1316+ const struct ieee80211_mgmt *mgmt;1317+ //const u8 *end, *ie;1318+ u16 fc, type, stype;1319+ //size_t ie_len;1320+ struct hostapd_data *hapd = drv->hapd;1321+1322+ //printf("+rtl871x_receive_mgnt, " MACSTR " is our address\n", MAC2STR(hapd->own_addr));1323+1324+1325+#if 01326+ {1327+ int i;1328+ for(i=0; i<len; i+=8)1329+ {1330+ printf("%x:%x:%x:%x:%x:%x:%x:%x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);1331+ }1332+1333+ }1334+#endif1335+1336+ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))1337+ return;1338+1339+ mgmt = (const struct ieee80211_mgmt *)buf;1340+1341+ fc = le_to_host16(mgmt->frame_control);1342+ type = WLAN_FC_GET_TYPE(fc);1343+ stype = WLAN_FC_GET_STYPE(fc);1344+1345+#if 11346+ if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&1347+ WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP)1348+ {1349+ //printf("MGNT Frame - PROBE_RESP Frame\n");1350+ }1351+#endif1352+1353+ //end = buf + len;1354+ //ie = mgmt->u.probe_req.variable;1355+ //ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));1356+ //hostapd_wps_probe_req_rx(drv->hapd, mgmt->sa, ie, ie_len);1357+1358+ switch (type) {1359+ case WLAN_FC_TYPE_MGMT:1360+ if (stype != WLAN_FC_STYPE_BEACON)1361+ wpa_printf(MSG_MSGDUMP, "MGMT");1362+1363+1364+1365+ if (stype == WLAN_FC_STYPE_PROBE_REQ)1366+ {1367+1368+ }1369+ else1370+ {1371+ //printf("rtl871x_receive_mgnt, type=0x%x, stype=0x%x\n", type, stype);1372+ }1373+1374+1375+ //ieee802_11_mgmt(hapd, (u8 *)buf, len, stype, NULL);1376+1377+ break;1378+ case WLAN_FC_TYPE_CTRL:1379+ printf("rtl871x_receive_mgnt, CTRL\n");1380+ break;1381+ case WLAN_FC_TYPE_DATA:1382+ printf("rtl871x_receive_mgnt, DATA\n");1383+ //handle_data(hapd, buf, data_len, stype);1384+ break;1385+ default:1386+ printf("unknown frame type %d\n", type);1387+ break;1388+ }1389+1390+1391+}1392+1393+#ifdef CONFIG_MGNT_L2SOCK1394+static void rtl871x_recvive_mgmt_frame(void *ctx, const u8 *src_addr, const u8 *buf,1395+ size_t len)1396+{1397+ struct rtl871x_driver_data *drv = ctx;1398+1399+ rtl871x_receive_mgnt(drv, buf, len);1400+}1401+#else1402+static void rtl871x_recvive_mgmt_frame(int sock, void *eloop_ctx, void *sock_ctx)1403+{1404+#if 01405+ int len;1406+ unsigned char buf[1024];1407+ struct hostapd_data *hapd = (struct hostapd_data *)eloop_ctx;1408+ struct rtl871x_driver_data *drv = (struct rtl871x_driver_data *)hapd->drv_priv;1409+1410+ len = recv(sock, buf, sizeof(buf), 0);1411+ if (len < 0) {1412+ perror("recv");1413+ return;1414+ }1415+1416+ rtl871x_receive_mgnt(drv, buf, len);1417+#endif1418+}1419+1420+static int rtl871x_mgnt_sock_init(struct rtl871x_driver_data *drv, const char *name)1421+{1422+ int sock;1423+ struct ifreq ifr;1424+ struct sockaddr_ll addr;1425+1426+ sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));1427+ if (sock < 0) {1428+ perror("socket[PF_PACKET,SOCK_RAW]");1429+ return -1;1430+ }1431+1432+ if (eloop_register_read_sock(sock, rtl871x_recvive_mgmt_frame, drv->hapd, NULL))1433+ {1434+ printf("Could not register read socket\n");1435+ return -1;1436+ }1437+1438+ memset(&ifr, 0, sizeof(ifr));1439+ //snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%sap", drv->iface);1440+ os_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));1441+ if (ioctl(sock, SIOCGIFINDEX, &ifr) != 0) {1442+ perror("ioctl(SIOCGIFINDEX)");1443+ return -1;1444+ }1445+1446+ //if (rtl871x_set_iface_flags(drv, 1)) {1447+ // return -1;1448+ //}1449+1450+ memset(&addr, 0, sizeof(addr));1451+ addr.sll_family = AF_PACKET;1452+ addr.sll_ifindex = ifr.ifr_ifindex;1453+ wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",1454+ addr.sll_ifindex);1455+1456+ if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {1457+ perror("bind");1458+ return -1;1459+ }1460+1461+ memset(&ifr, 0, sizeof(ifr));1462+ os_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));1463+ if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {1464+ perror("ioctl(SIOCGIFHWADDR)");1465+ return -1;1466+ }1467+1468+1469+ if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {1470+ printf("Invalid HW-addr family 0x%04x\n",1471+ ifr.ifr_hwaddr.sa_family);1472+ return -1;1473+ }1474+1475+ //memcpy(drv->hapd->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);1476+1477+ return sock;1478+1479+}1480+#endif1481+#endif1482+1483+static void rtl871x_handle_tx_callback(struct hostapd_data *hapd, u8 *buf, size_t len,1484+ int ok)1485+{1486+#if 01487+ struct ieee80211_hdr *hdr;1488+ u16 fc, type, stype;1489+ struct sta_info *sta;1490+1491+ //printf("%s\n", __func__);1492+1493+ hdr = (struct ieee80211_hdr *) buf;1494+ fc = le_to_host16(hdr->frame_control);1495+1496+ type = WLAN_FC_GET_TYPE(fc);1497+ stype = WLAN_FC_GET_STYPE(fc);1498+1499+ switch (type) {1500+ case WLAN_FC_TYPE_MGMT:1501+ //printf("MGMT (TX callback) %s\n",1502+ // ok ? "ACK" : "fail");1503+ ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);1504+ break;1505+ case WLAN_FC_TYPE_CTRL:1506+ printf("CTRL (TX callback) %s\n",1507+ ok ? "ACK" : "fail");1508+ break;1509+ case WLAN_FC_TYPE_DATA:1510+ printf("DATA (TX callback) %s\n",1511+ ok ? "ACK" : "fail");1512+ sta = ap_get_sta(hapd, hdr->addr1);1513+ if (sta && sta->flags & WLAN_STA_PENDING_POLL) {1514+ wpa_printf(MSG_DEBUG, "STA " MACSTR1515+ " %s pending activity poll",1516+ MAC2STR(sta->addr),1517+ ok ? "ACKed" : "did not ACK");1518+ if (ok)1519+ sta->flags &= ~WLAN_STA_PENDING_POLL;1520+ }1521+ if (sta)1522+ ieee802_1x_tx_status(hapd, sta, buf, len, ok);1523+ break;1524+ default:1525+ printf("unknown TX callback frame type %d\n", type);1526+ break;1527+ }1528+#endif1529+}1530+1531+static int rtl871x_send_mgnt(struct rtl871x_driver_data *drv, const void *msg, size_t len)1532+{1533+ int res=0;1534+1535+ return res;1536+}1537+1538+static int rtl871x_send_mgmt_frame_ops(void *priv, const void *msg, size_t len,1539+ int flags)1540+{1541+ struct rtl871x_driver_data *drv = priv;1542+ //struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msg;1543+ int res=0;1544+1545+ //printf("%s\n", __func__);1546+1547+1548+ //hdr->frame_control |= host_to_le16(BIT(1));/* Request TX callback */1549+#ifdef CONFIG_MGNT_L2SOCK1550+ //res = send(drv->mgnt_l2_sock, msg, len, flags);1551+ //res = l2_packet_send(drv->mgnt_l2_sock, addr, ETH_P_EAPOL, msg, len);1552+ if(drv->mgnt_l2_sock == NULL)1553+ return res;1554+1555+ res = l2_packet_send(drv->mgnt_l2_sock, NULL, ETH_P_80211_RAW, msg, len);1556+#else1557+1558+ if(drv->mgnt_sock < 0)1559+ return res;1560+1561+ res = send(drv->mgnt_sock, msg, len, flags);1562+#endif1563+ //hdr->frame_control &= ~host_to_le16(BIT(1));1564+1565+1566+ rtl871x_send_mgnt(drv, msg, len);1567+1568+ rtl871x_handle_tx_callback(drv->hapd, (u8*)msg, len, 1);1569+1570+ return res;1571+1572+}1573+1574+/*1575+static int rtl871x_driver_send_ether_ops(void *priv, const u8 *dst, const u8 *src,1576+ u16 proto, const u8 *data, size_t data_len)1577+{1578+ return 0;1579+}1580+*/1581+1582+static struct hostapd_hw_modes *rtl871x_get_hw_feature_data_ops(void *priv,1583+ u16 *num_modes,1584+ u16 *flags)1585+{1586+1587+#define MAX_NUM_CHANNEL (14)1588+#define MAX_NUM_CHANNEL_5G (24)1589+1590+ struct hostapd_hw_modes *modes;1591+ size_t i;1592+ int k;1593+1594+ *num_modes = 3;1595+ *flags = 0;1596+1597+ modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));1598+ if (modes == NULL)1599+ return NULL;1600+1601+ //.11602+ modes[0].mode = HOSTAPD_MODE_IEEE80211G;1603+ modes[0].num_channels = MAX_NUM_CHANNEL;1604+ modes[0].num_rates = 12;1605+ modes[0].channels =1606+ os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data));1607+ modes[0].rates = os_zalloc(modes[0].num_rates * sizeof(int));1608+ if (modes[0].channels == NULL || modes[0].rates == NULL)1609+ goto fail;1610+ for (i = 0; i < MAX_NUM_CHANNEL; i++) {1611+ modes[0].channels[i].chan = i + 1;1612+ modes[0].channels[i].freq = 2412 + 5 * i;1613+ modes[0].channels[i].flag = 0;1614+ if (i >= 13)1615+ modes[0].channels[i].flag = HOSTAPD_CHAN_DISABLED;1616+ }1617+ modes[0].rates[0] = 10;1618+ modes[0].rates[1] = 20;1619+ modes[0].rates[2] = 55;1620+ modes[0].rates[3] = 110;1621+ modes[0].rates[4] = 60;1622+ modes[0].rates[5] = 90;1623+ modes[0].rates[6] = 120;1624+ modes[0].rates[7] = 180;1625+ modes[0].rates[8] = 240;1626+ modes[0].rates[9] = 360;1627+ modes[0].rates[10] = 480;1628+ modes[0].rates[11] = 540;1629+1630+1631+ //.21632+ modes[1].mode = HOSTAPD_MODE_IEEE80211B;1633+ modes[1].num_channels = MAX_NUM_CHANNEL;1634+ modes[1].num_rates = 4;1635+ modes[1].channels =1636+ os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data));1637+ modes[1].rates = os_zalloc(modes[1].num_rates * sizeof(int));1638+ if (modes[1].channels == NULL || modes[1].rates == NULL)1639+ goto fail;1640+ for (i = 0; i < MAX_NUM_CHANNEL; i++) {1641+ modes[1].channels[i].chan = i + 1;1642+ modes[1].channels[i].freq = 2412 + 5 * i;1643+ modes[1].channels[i].flag = 0;1644+ if (i >= 11)1645+ modes[1].channels[i].flag = HOSTAPD_CHAN_DISABLED;1646+ }1647+ modes[1].rates[0] = 10;1648+ modes[1].rates[1] = 20;1649+ modes[1].rates[2] = 55;1650+ modes[1].rates[3] = 110;1651+1652+1653+ //.31654+ modes[2].mode = HOSTAPD_MODE_IEEE80211A;1655+#ifdef CONFIG_DRIVER_RTL_DFS1656+ modes[2].num_channels = MAX_NUM_CHANNEL_5G;1657+#else /* CONFIG_DRIVER_RTL_DFS */1658+ modes[2].num_channels = 9;1659+#endif /* CONFIG_DRIVER_RTL_DFS */1660+1661+ modes[2].num_rates = 8;1662+ modes[2].channels = os_zalloc(modes[2].num_channels * sizeof(struct hostapd_channel_data));1663+ modes[2].rates = os_zalloc(modes[2].num_rates * sizeof(int));1664+ if (modes[2].channels == NULL || modes[2].rates == NULL)1665+ goto fail;1666+1667+1668+ k = 0;1669+ // 5G band1 Channel: 36, 40, 44, 481670+ for (i=0; i < 4; i++) {1671+ modes[2].channels[k].chan = 36+(i*4);1672+ modes[2].channels[k].freq = 5180+(i*20);1673+ modes[2].channels[k].flag = 0;1674+ k++;1675+ }1676+1677+#ifdef CONFIG_DRIVER_RTL_DFS1678+ // 5G band2 Channel: 52, 56, 60, 641679+ for (i=0; i < 4; i++) {1680+ modes[2].channels[k].chan = 52+(i*4);1681+ modes[2].channels[k].freq = 5260+(i*20);1682+ modes[2].channels[k].flag = 0;1683+ k++;1684+ }1685+1686+ // 5G band3 Channel: 100, 104, 108. 112, 116, 120, 124, 128, 132, 136, 1401687+ for (i=0; i < 11; i++) {1688+ modes[2].channels[k].chan = 100+(i*4);1689+ modes[2].channels[k].freq = 5500+(i*20);1690+ modes[2].channels[k].flag = 0;1691+ k++;1692+ }1693+#endif /* CONFIG_DRIVER_RTL_DFS */1694+1695+ // 5G band4 Channel: 149, 153, 157, 161, 1651696+ for (i=0; i < 5; i++) {1697+ modes[2].channels[k].chan = 149+(i*4);1698+ modes[2].channels[k].freq = 5745+(i*20);1699+ modes[2].channels[k].flag = 0;1700+ k++;1701+ }1702+1703+ modes[2].rates[0] = 60;1704+ modes[2].rates[1] = 90;1705+ modes[2].rates[2] = 120;1706+ modes[2].rates[3] = 180;1707+ modes[2].rates[4] = 240;1708+ modes[2].rates[5] = 360;1709+ modes[2].rates[6] = 480;1710+ modes[2].rates[7] = 540;1711+1712+1713+ //1714+#if 01715+#define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0))1716+#define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1))1717+#define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3)))1718+#define HT_CAP_INFO_SMPS_STATIC ((u16) 0)1719+#define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2))1720+#define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3)))1721+#define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4))1722+#define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5))1723+#define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6))1724+#define HT_CAP_INFO_TX_STBC ((u16) BIT(7))1725+#define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9)))1726+#define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8))1727+#define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9))1728+#define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9)))1729+#define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10))1730+#define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11))1731+#define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12))1732+#define HT_CAP_INFO_PSMP_SUPP ((u16) BIT(13))1733+#define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14))1734+#define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15))1735+#endif1736+1737+ //HOSTAPD_MODE_IEEE80211G1738+ modes[0].ht_capab = HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET|HT_CAP_INFO_SHORT_GI20MHZ|1739+ HT_CAP_INFO_SHORT_GI40MHZ|HT_CAP_INFO_MAX_AMSDU_SIZE|HT_CAP_INFO_DSSS_CCK40MHZ;1740+1741+ modes[0].mcs_set[0]= 0xff;1742+ modes[0].mcs_set[1]= 0xff;1743+1744+ //HOSTAPD_MODE_IEEE80211B1745+ modes[1].ht_capab = 0;1746+1747+ //HOSTAPD_MODE_IEEE80211A1748+ modes[2].ht_capab = modes[0].ht_capab;1749+1750+ modes[2].mcs_set[0]= 0xff;1751+ modes[2].mcs_set[1]= 0xff;1752+1753+ return modes;1754+1755+fail:1756+ if (modes) {1757+ for (i = 0; i < *num_modes; i++) {1758+ os_free(modes[i].channels);1759+ os_free(modes[i].rates);1760+ }1761+ os_free(modes);1762+ }1763+1764+ return NULL;1765+1766+}1767+1768+#if 01769+static int rtl871x_sta_add_ops(const char *ifname, void *priv, const u8 *addr,1770+ u16 aid, u16 capability, u8 *supp_rates,1771+ size_t supp_rates_len, int flags,1772+ u16 listen_interval)1773+{1774+1775+#if 11776+ printf("+%s, " MACSTR " is new sta address added\n", __func__, MAC2STR(addr));1777+ return 0;1778+#else1779+ struct hostap_driver_data *drv = priv;1780+ struct prism2_hostapd_param param;1781+ int tx_supp_rates = 0;1782+ size_t i;1783+1784+#define WLAN_RATE_1M BIT(0)1785+#define WLAN_RATE_2M BIT(1)1786+#define WLAN_RATE_5M5 BIT(2)1787+#define WLAN_RATE_11M BIT(3)1788+1789+ for (i = 0; i < supp_rates_len; i++) {1790+ if ((supp_rates[i] & 0x7f) == 2)1791+ tx_supp_rates |= WLAN_RATE_1M;1792+ if ((supp_rates[i] & 0x7f) == 4)1793+ tx_supp_rates |= WLAN_RATE_2M;1794+ if ((supp_rates[i] & 0x7f) == 11)1795+ tx_supp_rates |= WLAN_RATE_5M5;1796+ if ((supp_rates[i] & 0x7f) == 22)1797+ tx_supp_rates |= WLAN_RATE_11M;1798+ }1799+1800+ memset(¶m, 0, sizeof(param));1801+ param.cmd = PRISM2_HOSTAPD_ADD_STA;1802+ memcpy(param.sta_addr, addr, ETH_ALEN);1803+ param.u.add_sta.aid = aid;1804+ param.u.add_sta.capability = capability;1805+ param.u.add_sta.tx_supp_rates = tx_supp_rates;1806+ return hostapd_ioctl(drv, ¶m, sizeof(param));1807+#endif1808+}1809+1810+static int rtl871x_sta_add2_ops(const char *ifname, void *priv,1811+ struct hostapd_sta_add_params *params)1812+{1813+#if 01814+ ieee_param param;1815+ //int i, tx_supp_rates = 0;1816+ struct rtl871x_driver_data *drv = priv;1817+1818+ printf("%s\n", __func__);1819+1820+ memset(¶m, 0, sizeof(param));1821+ param.cmd = RTL871X_HOSTAPD_ADD_STA;1822+ memcpy(param.sta_addr, params->addr, ETH_ALEN);1823+ param.u.add_sta.aid = params->aid;1824+ param.u.add_sta.capability = params->capability;1825+ param.u.add_sta.flags = params->flags;1826+1827+ memcpy(param.u.add_sta.tx_supp_rates, params->supp_rates, params->supp_rates_len);1828+1829+/*1830+ for (i = 0; i < params->supp_rates_len; i++)1831+ {1832+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_1MB)1833+ tx_supp_rates |= IEEE80211_CCK_RATE_1MB_MASK;1834+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_2MB)1835+ tx_supp_rates |= IEEE80211_CCK_RATE_2MB_MASK;1836+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_5MB)1837+ tx_supp_rates |= IEEE80211_CCK_RATE_5MB_MASK;1838+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_11MB)1839+ tx_supp_rates |= IEEE80211_CCK_RATE_11MB_MASK;1840+1841+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_6MB)1842+ tx_supp_rates |= IEEE80211_OFDM_RATE_6MB_MASK;1843+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_9MB)1844+ tx_supp_rates |= IEEE80211_OFDM_RATE_9MB_MASK;1845+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_12MB)1846+ tx_supp_rates |= IEEE80211_OFDM_RATE_12MB_MASK;1847+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_18MB)1848+ tx_supp_rates |= IEEE80211_OFDM_RATE_18MB_MASK;1849+1850+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_24MB)1851+ tx_supp_rates |= IEEE80211_OFDM_RATE_24MB_MASK;1852+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_36MB)1853+ tx_supp_rates |= IEEE80211_OFDM_RATE_36MB_MASK;1854+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_48MB)1855+ tx_supp_rates |= IEEE80211_OFDM_RATE_48MB_MASK;1856+ if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_54MB)1857+ tx_supp_rates |= IEEE80211_OFDM_RATE_54MB_MASK;1858+1859+ }1860+1861+ param.u.add_sta.tx_supp_rates = tx_supp_rates;1862+*/1863+1864+#ifdef CONFIG_IEEE80211N1865+ if (params->ht_capabilities && params->ht_capabilities->length>0)1866+ {1867+ struct ieee80211_ht_capability *pht_cap = (struct ieee80211_ht_capability *)¶ms->ht_capabilities->data;1868+ memcpy((u8*)¶m.u.add_sta.ht_cap, (u8*)pht_cap, sizeof(struct ieee80211_ht_capability));1869+1870+ }1871+#endif /* CONFIG_IEEE80211N */1872+1873+ return rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param));1874+#else1875+ return 0;1876+#endif1877+}1878+#endif1879+1880+static int rtl871x_sta_remove_ops(void *priv, const u8 *addr)1881+{1882+ struct rtl871x_driver_data *drv = priv;1883+ struct ieee_param param;1884+1885+ printf("+%s, " MACSTR " is sta address removed\n", __func__, MAC2STR(addr));1886+1887+ //hostap_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);1888+1889+ memset(¶m, 0, sizeof(param));1890+ param.cmd = RTL871X_HOSTAPD_REMOVE_STA;1891+ memcpy(param.sta_addr, addr, ETH_ALEN);1892+ if (rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param))) {1893+ printf("Could not remove station from kernel driver.\n");1894+ return -1;1895+ }1896+1897+ return 0;1898+1899+}1900+1901+#define RTL871X_HIDDEN_SSID_SUPPORT1902+#ifdef RTL871X_HIDDEN_SSID_SUPPORT1903+static int rtl871x_set_hidden_ssid_ops(const char *iface, void *priv, u8 value)1904+{1905+ int ret;1906+ ieee_param pparam;1907+ struct rtl871x_driver_data *drv = priv;1908+ struct hostapd_data *hapd = drv->hapd;1909+1910+ printf("%s\n", __func__);1911+1912+ pparam.cmd = RTL871X_HOSTAPD_SET_HIDDEN_SSID;1913+ pparam.u.wpa_param.name = 0;1914+ pparam.u.wpa_param.value = value;1915+1916+ ret = rtl871x_hostapd_ioctl(drv, &pparam, sizeof(ieee_param));1917+1918+ return ret;1919+}1920+1921+static const u8 * get_ie(u8 *ies, size_t ies_len, u8 id)1922+{1923+ const u8 *end, *pos;1924+1925+ pos = ies;1926+ end = pos + ies_len;1927+1928+ while (pos + 1 < end) {1929+ if (pos + 2 + pos[1] > end)1930+ break;1931+1932+ //printf("id:%u, clen:%u\n", pos[0], pos[1]);1933+1934+ if (pos[0] == id)1935+ return pos;1936+ pos += 2 + pos[1];1937+ }1938+1939+ return NULL;1940+}1941+#endif //RTL871X_HIDDEN_SSID_SUPPORT1942+1943+static int rtl871x_set_beacon_ops(void *priv, struct wpa_driver_ap_params *params)1944+{1945+ int ret;1946+ size_t sz;1947+ ieee_param *pparam;1948+ struct rtl871x_driver_data *drv = priv;1949+ struct hostapd_data *hapd = drv->hapd;1950+1951+ u8 *ssid_ie;1952+ u8 ssid_len;1953+ u8 expend_len = 0;1954+1955+ if((params->head_len<24) ||(!params->head))1956+ return -1;1957+1958+ printf("%s\n", __func__);1959+1960+1961+#ifdef RTL871X_HIDDEN_SSID_SUPPORT1962+ rtl871x_set_hidden_ssid_ops(drv->iface, priv, hapd->conf->ignore_broadcast_ssid);1963+1964+ ssid_ie = get_ie((params->head+24+12), (params->head_len-24-12), WLAN_EID_SSID);1965+1966+ if(hapd->conf->ignore_broadcast_ssid == 2)1967+ {1968+ ssid_len = ssid_ie[1];1969+1970+ //confirm the ssid_len1971+ if(ssid_len != hapd->conf->ssid.ssid_len)1972+ {1973+ printf("%s ssid_len(%u) != hapd->conf->ssid.ssid_len(%u)!!\n", __func__1974+ , ssid_len, hapd->conf->ssid.ssid_len1975+ );1976+ }1977+1978+ memcpy(ssid_ie+2, hapd->conf->ssid.ssid, ssid_len);1979+ }1980+ else if(hapd->conf->ignore_broadcast_ssid == 1)1981+ {1982+ expend_len = hapd->conf->ssid.ssid_len;1983+ printf("%s ignore_broadcast_ssid:%d, %s,%d, expend_len:%u\n", __func__1984+ , hapd->conf->ignore_broadcast_ssid1985+ , hapd->conf->ssid.ssid1986+ , hapd->conf->ssid.ssid_len1987+ , expend_len1988+ );1989+ }1990+#endif //RTL871X_HIDDEN_SSID_SUPPORT1991+1992+ sz = params->head_len+params->tail_len+12-24 + 2 + expend_len;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed1993+ pparam = os_zalloc(sz);1994+ if (pparam == NULL) {1995+ return -ENOMEM;1996+ }1997+1998+ pparam->cmd = RTL871X_HOSTAPD_SET_BEACON;1999+2000+ memcpy(pparam->u.bcn_ie.reserved, &hapd->conf->max_num_sta, 2);//for set max_num_sta2001+2002+#ifdef RTL871X_HIDDEN_SSID_SUPPORT2003+ if(hapd->conf->ignore_broadcast_ssid == 1)2004+ {2005+ u8 *ssid_ie_next = params->head+24+12+2;2006+ size_t head_remain_len = params->head_len-24-12-2;2007+2008+ memcpy(pparam->u.bcn_ie.buf, (params->head+24), 12);2009+2010+ pparam->u.bcn_ie.buf[12] = WLAN_EID_SSID;2011+ pparam->u.bcn_ie.buf[13] = expend_len;2012+ memcpy(pparam->u.bcn_ie.buf+12+2, hapd->conf->ssid.ssid, expend_len);2013+2014+ memcpy(pparam->u.bcn_ie.buf+12+2+expend_len, ssid_ie_next, head_remain_len);// 24=beacon header len.2015+ memcpy(&pparam->u.bcn_ie.buf[params->head_len-24+expend_len], params->tail, params->tail_len);2016+ }2017+ else2018+#endif //RTL871X_HIDDEN_SSID_SUPPORT2019+ {2020+ memcpy(pparam->u.bcn_ie.buf, (params->head+24), (params->head_len-24));// 24=beacon header len.2021+ memcpy(&pparam->u.bcn_ie.buf[params->head_len-24], params->tail, params->tail_len);2022+ }2023+2024+ ret = rtl871x_hostapd_ioctl(drv, pparam, sz);2025+2026+ os_free(pparam);2027+2028+ //rtl871x_set_max_num_sta(drv);2029+2030+ return ret;2031+2032+}2033+2034+/*2035+enum wpa_alg {2036+ WPA_ALG_NONE,2037+ WPA_ALG_WEP,2038+ WPA_ALG_TKIP,2039+ WPA_ALG_CCMP,2040+ WPA_ALG_IGTK,2041+ WPA_ALG_PMK2042+};2043+*/2044+static int rtl871x_set_key_ops(const char *ifname, void *priv, enum wpa_alg alg,2045+ const u8 *addr, int idx, int txkey, const u8 *seq,2046+ size_t seq_len, const u8 *key, size_t key_len)2047+{2048+ ieee_param *param;2049+ u8 *buf;2050+ char *alg_str;2051+ size_t blen;2052+ int ret = 0;2053+ struct rtl871x_driver_data *drv = priv;2054+2055+ printf("%s\n", __func__);2056+2057+ blen = sizeof(*param) + key_len;2058+ buf = os_zalloc(blen);2059+ if (buf == NULL)2060+ return -1;2061+2062+ param = (ieee_param *)buf;2063+ param->cmd = RTL871X_SET_ENCRYPTION;2064+ if (addr == NULL)2065+ memset(param->sta_addr, 0xff, ETH_ALEN);2066+ else2067+ memcpy(param->sta_addr, addr, ETH_ALEN);2068+2069+2070+ switch (alg) {2071+ case WPA_ALG_NONE:2072+ alg_str = "none";2073+ break;2074+ case WPA_ALG_WEP:2075+ //cipher = IEEE80211_CIPHER_WEP;2076+ alg_str = "WEP";2077+ break;2078+ case WPA_ALG_TKIP:2079+ //cipher = IEEE80211_CIPHER_TKIP;2080+ alg_str = "TKIP";2081+ break;2082+ case WPA_ALG_CCMP:2083+ //cipher = IEEE80211_CIPHER_AES_CCM;2084+ alg_str = "CCMP";2085+ break;2086+ default:2087+ printf("%s: unknown/unsupported algorithm %d\n",2088+ __func__, alg);2089+ return -1;2090+ }2091+2092+ os_strlcpy((char *) param->u.crypt.alg, alg_str,2093+ IEEE_CRYPT_ALG_NAME_LEN);2094+2095+ //param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;2096+ param->u.crypt.set_tx = txkey ? 1 : 0;2097+ param->u.crypt.idx = idx;2098+ param->u.crypt.key_len = key_len;2099+2100+ //memcpy((u8 *) (param + 1), key, key_len);2101+ memcpy(param->u.crypt.key, key, key_len);2102+2103+ if (rtl871x_hostapd_ioctl(drv, param, blen)) {2104+ printf("Failed to set encryption.\n");2105+ ret = -1;2106+ }2107+2108+ os_free(buf);2109+2110+ return ret;2111+2112+}2113+2114+/*2115+static int rtl871x_set_encryption_ops(const char *ifname, void *priv,2116+ const char *alg, const u8 *addr,2117+ int idx, const u8 *key, size_t key_len,2118+ int txkey)2119+{2120+ ieee_param *param;2121+ u8 *buf;2122+ size_t blen;2123+ int ret = 0;2124+ struct rtl871x_driver_data *drv = priv;2125+2126+ printf("%s\n", __func__);2127+#if 02128+ blen = sizeof(*param) + key_len;2129+ buf = os_zalloc(blen);2130+ if (buf == NULL)2131+ return -1;2132+2133+ param = (ieee_param *)buf;2134+ param->cmd = RTL871X_SET_ENCRYPTION;2135+ if (addr == NULL)2136+ memset(param->sta_addr, 0xff, ETH_ALEN);2137+ else2138+ memcpy(param->sta_addr, addr, ETH_ALEN);2139+2140+ os_strlcpy((char *) param->u.crypt.alg, alg,2141+ IEEE_CRYPT_ALG_NAME_LEN);2142+2143+ //param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;2144+ param->u.crypt.set_tx = txkey ? 1 : 0;2145+ param->u.crypt.idx = idx;2146+ param->u.crypt.key_len = key_len;2147+2148+ //memcpy((u8 *) (param + 1), key, key_len);2149+ memcpy(param->u.crypt.key, key, key_len);2150+2151+ if (rtl871x_hostapd_ioctl(drv, param, blen)) {2152+ printf("Failed to set encryption.\n");2153+ ret = -1;2154+ }2155+2156+ os_free(buf);2157+#endif2158+ return ret;2159+2160+}2161+*/2162+2163+//static int rtl871x_sta_deauth_ops(void *priv, const u8 *addr, int reason)2164+static int rtl871x_sta_deauth_ops(void *priv, const u8 *own_addr, const u8 *addr,2165+ int reason)2166+{2167+ printf("+%s, " MACSTR " is deauth, reason=%d\n", __func__, MAC2STR(addr), reason);2168+2169+ //struct hostap_driver_data *drv = priv;2170+ struct rtl871x_driver_data *drv = priv;2171+ struct ieee80211_mgmt mgmt;2172+2173+ memset(&mgmt, 0, sizeof(mgmt));2174+ mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,2175+ WLAN_FC_STYPE_DEAUTH);2176+2177+ memcpy(mgmt.da, addr, ETH_ALEN);2178+ //memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);2179+ //memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);2180+ memcpy(mgmt.sa, own_addr, ETH_ALEN);2181+ memcpy(mgmt.bssid, own_addr, ETH_ALEN);2182+ mgmt.u.deauth.reason_code = host_to_le16(reason);2183+2184+ return rtl871x_send_mgmt_frame_ops(drv, &mgmt, IEEE80211_HDRLEN +2185+ sizeof(mgmt.u.deauth), 0);2186+2187+}2188+2189+2190+//static int rtl871x_sta_disassoc_ops(void *priv, const u8 *addr, int reason)2191+static int rtl871x_sta_disassoc_ops(void *priv, const u8 *own_addr, const u8 *addr,2192+ int reason)2193+{2194+ printf("+%s, " MACSTR " is disassoc, reason=%d\n", __func__, MAC2STR(addr), reason);2195+2196+ struct rtl871x_driver_data *drv = priv;2197+ struct ieee80211_mgmt mgmt;2198+2199+ memset(&mgmt, 0, sizeof(mgmt));2200+ mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,2201+ WLAN_FC_STYPE_DISASSOC);2202+2203+ memcpy(mgmt.da, addr, ETH_ALEN);2204+ //memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);2205+ //memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);2206+ memcpy(mgmt.sa, own_addr, ETH_ALEN);2207+ memcpy(mgmt.bssid, own_addr, ETH_ALEN);2208+2209+ mgmt.u.disassoc.reason_code = host_to_le16(reason);2210+2211+ return rtl871x_send_mgmt_frame_ops(drv, &mgmt, IEEE80211_HDRLEN +2212+ sizeof(mgmt.u.disassoc), 0);2213+2214+}2215+2216+static int rtl871x_set_wps_assoc_resp_ie(struct rtl871x_driver_data *drv, const void *ie, size_t len)2217+{2218+ int ret;2219+ size_t sz;2220+ ieee_param *pparam;2221+2222+2223+ printf("%s\n", __func__);2224+2225+ sz = len + 12 + 2;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed2226+ pparam = os_zalloc(sz);2227+ if (pparam == NULL) {2228+ return -ENOMEM;2229+ }2230+2231+ pparam->cmd = RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP;2232+2233+ if(ie && len>0)2234+ {2235+ memcpy(pparam->u.bcn_ie.buf, ie, len);2236+ }2237+2238+ ret = rtl871x_hostapd_ioctl(drv, pparam, sz);2239+2240+ os_free(pparam);2241+2242+ return ret;2243+2244+}2245+2246+static int rtl871x_set_wps_beacon_ie(struct rtl871x_driver_data *drv, const void *ie, size_t len)2247+{2248+ int ret;2249+ size_t sz;2250+ ieee_param *pparam;2251+2252+2253+ printf("%s\n", __func__);2254+2255+ sz = len + 12 + 2;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed2256+ pparam = os_zalloc(sz);2257+ if (pparam == NULL) {2258+ return -ENOMEM;2259+ }2260+2261+ pparam->cmd = RTL871X_HOSTAPD_SET_WPS_BEACON;2262+2263+ if(ie && len>0)2264+ {2265+ memcpy(pparam->u.bcn_ie.buf, ie, len);2266+ }2267+2268+ ret = rtl871x_hostapd_ioctl(drv, pparam, sz);2269+2270+ os_free(pparam);2271+2272+ return ret;2273+2274+}2275+2276+static int rtl871x_set_wps_probe_resp_ie(struct rtl871x_driver_data *drv, const void *ie, size_t len)2277+{2278+ int ret;2279+ size_t sz;2280+ ieee_param *pparam;2281+2282+2283+ printf("%s\n", __func__);2284+2285+ sz = len + 12 + 2;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed2286+ pparam = os_zalloc(sz);2287+ if (pparam == NULL) {2288+ return -ENOMEM;2289+ }2290+2291+ pparam->cmd = RTL871X_HOSTAPD_SET_WPS_PROBE_RESP;2292+2293+ if(ie && len>0)2294+ {2295+ memcpy(pparam->u.bcn_ie.buf, ie, len);2296+ }2297+2298+ ret = rtl871x_hostapd_ioctl(drv, pparam, sz);2299+2300+ os_free(pparam);2301+2302+ return ret;2303+2304+}2305+2306+static int rtl871x_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,2307+ const struct wpabuf *proberesp, const struct wpabuf *assocresp)2308+{2309+ struct rtl871x_driver_data *drv = priv;2310+2311+ if (rtl871x_set_wps_assoc_resp_ie(drv, assocresp ? wpabuf_head(assocresp) : NULL,2312+ assocresp ? wpabuf_len(assocresp) : 0))2313+ return -1;2314+2315+ if (rtl871x_set_wps_beacon_ie(drv, beacon ? wpabuf_head(beacon) : NULL,2316+ beacon ? wpabuf_len(beacon) : 0))2317+ return -1;2318+2319+ return rtl871x_set_wps_probe_resp_ie(drv,2320+ proberesp ? wpabuf_head(proberesp) : NULL,2321+ proberesp ? wpabuf_len(proberesp): 0);2322+2323+}2324+2325+static int rtl871x_sta_flush_ops(void *priv)2326+{2327+ ieee_param param;2328+ struct rtl871x_driver_data *drv = priv;2329+2330+ memset(¶m, 0, sizeof(param));2331+2332+ param.cmd = RTL871X_HOSTAPD_FLUSH;2333+2334+ return rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param));2335+}2336+2337+static void *rtl871x_driver_init_ops(struct hostapd_data *hapd, struct wpa_init_params *params)2338+{2339+ struct rtl871x_driver_data *drv;2340+ struct ifreq ifr;2341+ //struct iwreq iwr;2342+ char ifrn_name[IFNAMSIZ + 1];//for mgnt_l2_sock/mgnt_sock2343+ char brname[IFNAMSIZ];2344+2345+ drv = os_zalloc(sizeof(struct rtl871x_driver_data));2346+ if (drv == NULL) {2347+ printf("Could not allocate memory for rtl871x driver data\n");2348+ return NULL;2349+ }2350+2351+ drv->hapd = hapd;2352+ drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);2353+ if (drv->ioctl_sock < 0) {2354+ perror("socket[PF_INET,SOCK_DGRAM]");2355+ goto bad;2356+ }2357+ os_memcpy(drv->iface, params->ifname, sizeof(drv->iface));2358+2359+ linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);/*set interface up*/2360+2361+ os_memset(&ifr, 0, sizeof(ifr));2362+ os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));2363+ if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {2364+ perror("ioctl(SIOCGIFINDEX)");2365+ goto bad;2366+ }2367+ drv->ifindex = ifr.ifr_ifindex;2368+ printf("drv->ifindex=%d\n", drv->ifindex);2369+2370+ drv->l2_sock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,2371+ rtl871x_handle_read, drv, 1);2372+2373+ if (drv->l2_sock == NULL)2374+ goto bad;2375+2376+ if (l2_packet_get_own_addr(drv->l2_sock, params->own_addr))2377+ goto bad;2378+2379+2380+ if (params->bridge[0]) {2381+ wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",2382+ params->bridge[0]);2383+ drv->l2_sock_recv = l2_packet_init(params->bridge[0], NULL,2384+ ETH_P_EAPOL, rtl871x_handle_read, drv,2385+ 1);2386+ if (drv->l2_sock_recv == NULL)2387+ {2388+ //goto bad;2389+ drv->l2_sock_recv = drv->l2_sock;2390+ printf("no br0 interface , let l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock);2391+ }2392+2393+ } else if (linux_br_get(brname, drv->iface) == 0) {2394+ wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "2395+ "EAPOL receive", brname);2396+ drv->l2_sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,2397+ rtl871x_handle_read, drv, 1);2398+ if (drv->l2_sock_recv == NULL)2399+ goto bad;2400+ }2401+ else2402+ {2403+ drv->l2_sock_recv = drv->l2_sock;2404+ printf("l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock);2405+ }2406+2407+2408+ os_memset(ifrn_name, 0, sizeof(ifrn_name));2409+ //snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s_rena", drv->iface);2410+ snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s", "wlan0"/*drv->iface*/);2411+#ifdef CONFIG_MGNT_L2SOCK2412+ drv->mgnt_l2_sock = NULL;2413+ drv->mgnt_l2_sock = l2_packet_init(ifrn_name, NULL, ETH_P_80211_RAW,2414+ rtl871x_recvive_mgmt_frame, drv, 1);2415+ if (drv->mgnt_l2_sock == NULL)2416+ goto bad;2417+2418+#else2419+2420+#ifdef CONFIG_MLME_OFFLOAD2421+ drv->mgnt_sock = -1;2422+#else2423+ drv->mgnt_sock = rtl871x_mgnt_sock_init(drv, ifrn_name);2424+ if (drv->mgnt_sock < 0) {2425+ goto bad;2426+ }2427+#endif2428+2429+#endif2430+2431+2432+ //madwifi_set_iface_flags(drv, 0); /* mark down during setup */2433+ //madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */2434+2435+2436+ //linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);/*set interface up*/2437+2438+2439+ //enter MASTER MODE when init.2440+ if(rtl871x_set_mode(drv, IW_MODE_MASTER)<0)2441+ {2442+ printf("Could not set interface to master mode!\n");2443+ goto bad;2444+ }2445+2446+/*2447+ memset(&iwr, 0, sizeof(iwr));2448+ os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);2449+ iwr.u.mode = IW_MODE_MASTER;2450+ if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {2451+ perror("ioctl[SIOCSIWMODE]");2452+ printf("Could not set interface to master mode!\n");2453+ goto bad;2454+ }2455+*/2456+2457+#ifndef CONFIG_MLME_OFFLOAD2458+ rtl871x_set_iface_flags(drv, 1); /*set mgnt interface up*/2459+#endif2460+2461+2462+ if (rtl871x_wireless_event_init(drv))2463+ goto bad;2464+2465+2466+ os_memcpy(drv->hw_mac, params->own_addr, ETH_ALEN);2467+2468+ return drv;2469+2470+bad:2471+2472+ if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock)2473+ l2_packet_deinit(drv->l2_sock_recv);2474+2475+ if (drv->l2_sock != NULL)2476+ l2_packet_deinit(drv->l2_sock);2477+2478+ if (drv->ioctl_sock >= 0)2479+ close(drv->ioctl_sock);2480+2481+#ifdef CONFIG_MGNT_L2SOCK2482+ if ( drv->mgnt_l2_sock != NULL)2483+ l2_packet_deinit(drv->mgnt_l2_sock);2484+#else2485+ if (drv->mgnt_sock >= 0)2486+ close(drv->mgnt_sock);2487+#endif2488+2489+ if (drv != NULL)2490+ free(drv);2491+2492+ return NULL;2493+2494+}2495+2496+static void rtl871x_driver_deinit_ops(void *priv)2497+{2498+ //struct iwreq iwr;2499+ struct rtl871x_driver_data *drv = priv;2500+2501+ //back to INFRA MODE when exit.2502+/*2503+ memset(&iwr, 0, sizeof(iwr));2504+ os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);2505+ iwr.u.mode = IW_MODE_INFRA;2506+ if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {2507+ perror("ioctl[SIOCSIWMODE]");2508+ }2509+*/2510+ rtl871x_set_mode(drv, IW_MODE_INFRA);2511+2512+2513+ if (drv->ioctl_sock >= 0)2514+ close(drv->ioctl_sock);2515+2516+2517+ if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock)2518+ l2_packet_deinit(drv->l2_sock_recv);2519+2520+ if(drv->l2_sock)2521+ l2_packet_deinit(drv->l2_sock);2522+2523+ //if (drv->sock_xmit != NULL)2524+ // l2_packet_deinit(drv->sock_xmit);2525+2526+#ifdef CONFIG_MGNT_L2SOCK2527+ if (drv->mgnt_l2_sock)2528+ l2_packet_deinit(drv->mgnt_l2_sock);2529+#else2530+ if (drv->mgnt_sock >= 0)2531+ close(drv->mgnt_sock);2532+#endif2533+2534+ os_free(drv);2535+2536+}2537+2538+2539+const struct wpa_driver_ops wpa_driver_rtw_ops = {2540+ .name = "rtl871xdrv",2541+ //.init = rtl871x_driver_init_ops,2542+ //.deinit = rtl871x_driver_deinit_ops,2543+ .hapd_init = rtl871x_driver_init_ops,2544+ .hapd_deinit = rtl871x_driver_deinit_ops,2545+ //.wireless_event_init = rtl871x_wireless_event_init_ops,2546+ //.wireless_event_deinit = rtl871x_wireless_event_deinit_ops,2547+ //.send_eapol = rtl871x_send_eapol_ops,2548+ .hapd_send_eapol = rtl871x_send_eapol_ops,2549+ //.send_ether = rtl871x_driver_send_ether_ops,2550+ //.send_mgmt_frame = rtl871x_send_mgmt_frame_ops,2551+ .get_hw_feature_data = rtl871x_get_hw_feature_data_ops,2552+ //.sta_add = rtl871x_sta_add_ops,2553+ //.sta_add2 = rtl871x_sta_add2_ops,2554+ .sta_remove = rtl871x_sta_remove_ops,2555+ .set_ap = rtl871x_set_beacon_ops,2556+ //.set_encryption = rtl871x_set_encryption_ops,2557+ .set_key = rtl871x_set_key_ops,2558+ .sta_deauth = rtl871x_sta_deauth_ops,2559+ .sta_disassoc = rtl871x_sta_disassoc_ops,2560+ //.set_wps_beacon_ie = rtl871x_set_wps_beacon_ie_ops,2561+ //.set_wps_probe_resp_ie = rtl871x_set_wps_probe_resp_ie_ops,2562+ .set_ap_wps_ie = rtl871x_set_ap_wps_ie,2563+ .flush = rtl871x_sta_flush_ops,2564+};2565+2566diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c2567index 01defdf..1de29c8 1006442568--- a/src/drivers/driver_wext.c2569+++ b/src/drivers/driver_wext.c2570@@ -1081,6 +1081,38 @@ void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx)2571wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);2572}25732574+//added for wps2.0 @201105192575+static int wpa_driver_wext_set_probe_req_ie(struct wpa_driver_wext_data *drv, const u8 *extra_ies,2576+ size_t extra_ies_len)2577+{2578+ unsigned char *pbuf;2579+ struct iwreq iwr;2580+ int ret = 0;2581+2582+ pbuf = os_malloc(extra_ies_len);2583+ os_memset(pbuf, 0, extra_ies_len);2584+2585+ os_memset(&iwr, 0, sizeof(iwr));2586+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);2587+2588+ os_memcpy(pbuf, extra_ies, extra_ies_len);2589+2590+ iwr.u.data.pointer = (caddr_t)pbuf;2591+ iwr.u.data.length = extra_ies_len;2592+ iwr.u.data.flags = 0x8766;//magic number2593+2594+ if (ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr) < 0) {2595+ perror("ioctl[SIOCSIWMLME]");2596+ ret = -1;2597+ }2598+2599+ if(pbuf)2600+ os_free(pbuf);2601+2602+ return ret;2603+2604+}2605+26062607/**2608* wpa_driver_wext_scan - Request the driver to initiate scan2609@@ -1103,6 +1135,10 @@ int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params)2610return -1;2611}26122613+ //added for wps2.0 @201105192614+ wpa_driver_wext_set_probe_req_ie(drv, params->extra_ies,2615+ params->extra_ies_len);2616+2617os_memset(&iwr, 0, sizeof(iwr));2618os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);26192620@@ -2403,6 +2439,28 @@ int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv,2621return 0;2622}26232624+// Aries 20120120, append rssi information at the end of "status" command2625+int wext_signal_poll(void *priv, struct wpa_signal_info *signal_info)2626+{2627+ struct wpa_driver_wext_data *drv = priv;2628+ struct iwreq iwr;2629+ struct iw_statistics stat;2630+ int ret = 0;2631+2632+ os_memset(&iwr, 0, sizeof(iwr));2633+ os_memset(&stat, 0, sizeof(stat));2634+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);2635+ iwr.u.data.pointer = (caddr_t) &stat;2636+ iwr.u.data.length = sizeof(struct iw_statistics);2637+ iwr.u.data.flags = 1;2638+ if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) {2639+ perror("ioctl[SIOCGIWSTATS] fail\n");2640+ ret = -1;2641+ }2642+ signal_info->current_signal = stat.qual.level;2643+ signal_info->current_noise = stat.qual.noise;2644+ return ret;2645+}26462647int wpa_driver_wext_set_operstate(void *priv, int state)2648{2649diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c2650index a98af9a..d7d9c5b 1006442651--- a/src/drivers/drivers.c2652+++ b/src/drivers/drivers.c2653@@ -45,6 +45,9 @@ extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */2654#ifdef CONFIG_DRIVER_NONE2655extern struct wpa_driver_ops wpa_driver_none_ops; /* driver_none.c */2656#endif /* CONFIG_DRIVER_NONE */2657+#ifdef CONFIG_DRIVER_RTW2658+extern struct wpa_driver_ops wpa_driver_rtw_ops; /* driver_rtw.c */2659+#endif /* CONFIG_DRIVER_RTW */266026612662const struct wpa_driver_ops *const wpa_drivers[] =2663@@ -82,5 +85,8 @@ const struct wpa_driver_ops *const wpa_drivers[] =2664#ifdef CONFIG_DRIVER_NONE2665&wpa_driver_none_ops,2666#endif /* CONFIG_DRIVER_NONE */2667+#ifdef CONFIG_DRIVER_RTW2668+ &wpa_driver_rtw_ops,2669+#endif /* CONFIG_DRIVER_RTW */2670NULL2671};2672diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak2673index 3dd43c7..3e44fcb 1006442674--- a/src/drivers/drivers.mak2675+++ b/src/drivers/drivers.mak2676@@ -74,6 +74,10 @@ DRV_CFLAGS += -DCONFIG_DRIVER_BSD2677DRV_OBJS += ../src/drivers/driver_bsd.o2678CONFIG_L2_FREEBSD=y2679CONFIG_DNET_PCAP=y2680+ifdef CONFIG_SUPPORT_RTW_DRIVER2681+DRV_CFLAGS += -DCONFIG_SUPPORT_RTW_DRIVER -DCONFIG_DRIVER_RTL_DFS2682+NEED_AP_MLME=y2683+endif2684endif26852686ifdef CONFIG_DRIVER_OPENBSD2687@@ -84,6 +88,17 @@ DRV_CFLAGS += -DCONFIG_DRIVER_OPENBSD2688DRV_OBJS += ../src/drivers/driver_openbsd.o2689endif26902691+ifdef CONFIG_DRIVER_RTW2692+#CFLAGS += -DCONFIG_DRIVER_RTL2693+#OBJS += driver_rtl.o2694+DRV_AP_CFLAGS += -DCONFIG_DRIVER_RTW -DCONFIG_DRIVER_RTL_DFS2695+DRV_AP_OBJS += ../src/drivers/driver_rtw.o2696+CONFIG_L2_PACKET=linux2697+NEED_NETLINK=y2698+NEED_LINUX_IOCTL=y2699+NEED_AP_MLME=y2700+endif2701+2702ifdef CONFIG_DRIVER_NONE2703DRV_CFLAGS += -DCONFIG_DRIVER_NONE2704DRV_OBJS += ../src/drivers/driver_none.o2705diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c2706index 7ac99c7..1f7697c 1006442707--- a/src/eap_peer/eap_wsc.c2708+++ b/src/eap_peer/eap_wsc.c2709@@ -569,8 +569,13 @@ send_msg:2710r = eap_wsc_build_msg(data, ret, id);2711if (data->state == FAIL && ret->methodState == METHOD_DONE) {2712/* Use reduced client timeout for WPS to avoid long wait */2713+#if 0 /* Aries add, 2012/06/12, extend timeout for AP IOT */2714+ if (sm->ClientTimeout > 4)2715+ sm->ClientTimeout = 4;2716+#else2717if (sm->ClientTimeout > 2)2718sm->ClientTimeout = 2;2719+#endif2720}2721return r;2722}2723diff --git a/src/wps/wps.c b/src/wps/wps.c2724index fbaf85a..10a82e1 1006442725--- a/src/wps/wps.c2726+++ b/src/wps/wps.c2727@@ -321,11 +321,15 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,2728if (wps_parse_msg(msg, &attr) < 0)2729return 0;27302731+ return is_selected_pin_registrar(&attr);2732+// Marked by Albert 2011/11/172733+// Some APs won't carry the AuthorizedMACs in the probe response.2734+// So, skip this check will speed up the process to find the current AP out for WPS handshake.2735+/*2736if (!attr.version2 && ver1_compat) {2737/*2738* Version 1.0 AP - AuthorizedMACs not used, so revert back to2739* old mechanism of using SelectedRegistrar.2740- */2741return is_selected_pin_registrar(&attr);2742}27432744@@ -342,6 +346,7 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,2745}27462747return 0;2748+*/2749}275027512752diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c2753index 4ca3a42..f74b036 1006442754--- a/src/wps/wps_registrar.c2755+++ b/src/wps/wps_registrar.c2756@@ -589,9 +589,10 @@ static int wps_build_probe_config_methods(struct wps_registrar *reg,2757* These are the methods that the AP supports as an Enrollee for adding2758* external Registrars.2759*/2760- methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;2761- methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |2762- WPS_CONFIG_PHY_PUSHBUTTON);2763+ methods = reg->wps->config_methods;2764+ //methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;2765+ //methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |2766+ // WPS_CONFIG_PHY_PUSHBUTTON);2767wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);2768wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);2769wpabuf_put_be16(msg, 2);277027712772