mirror of
https://github.com/cilynx/rtl88x2bu
synced 2025-09-05 00:35:14 +00:00
5.6.1.6_35492.20191025_COEX20180928-6a6a
This commit is contained in:
@@ -2461,8 +2461,6 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
|
||||
u16 capability;
|
||||
unsigned char *pos;
|
||||
struct rtw_ieee802_11_elems elems;
|
||||
struct rtw_ieee80211_ht_cap *pht_cap = NULL;
|
||||
struct HT_info_element *pht_info = NULL;
|
||||
|
||||
_rtw_memset(recv_beacon, 0, sizeof(*recv_beacon));
|
||||
|
||||
@@ -2475,34 +2473,48 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
|
||||
if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed)
|
||||
return _FALSE;
|
||||
|
||||
/* check bw and channel offset */
|
||||
if (elems.ht_capabilities) {
|
||||
if (elems.ht_capabilities_len != sizeof(*pht_cap))
|
||||
if (elems.ht_capabilities_len != 26)
|
||||
return _FALSE;
|
||||
|
||||
pht_cap = (struct rtw_ieee80211_ht_cap *) elems.ht_capabilities;
|
||||
recv_beacon->ht_cap_info = pht_cap->cap_info;
|
||||
}
|
||||
|
||||
if (elems.ht_operation) {
|
||||
if (elems.ht_operation_len != sizeof(*pht_info))
|
||||
if (elems.ht_operation_len != 22)
|
||||
return _FALSE;
|
||||
|
||||
pht_info = (struct HT_info_element *) elems.ht_operation;
|
||||
recv_beacon->ht_info_infos_0_sco = pht_info->infos[0] & 0x03;
|
||||
}
|
||||
|
||||
/* Checking for channel */
|
||||
if (elems.ds_params && elems.ds_params_len == sizeof(recv_beacon->bcn_channel))
|
||||
_rtw_memcpy(&recv_beacon->bcn_channel, elems.ds_params,
|
||||
sizeof(recv_beacon->bcn_channel));
|
||||
else if (pht_info)
|
||||
/* In 5G, some ap do not have DSSET IE checking HT info for channel */
|
||||
recv_beacon->bcn_channel = pht_info->primary_channel;
|
||||
else {
|
||||
if (elems.vht_capabilities) {
|
||||
if (elems.vht_capabilities_len != 12)
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
if (elems.vht_operation) {
|
||||
if (elems.vht_operation_len != 5)
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
if (rtw_ies_get_supported_rate(pos, left, recv_beacon->rate_set, &recv_beacon->rate_num) == _FAIL)
|
||||
return _FALSE;
|
||||
|
||||
if (cckratesonly_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
|
||||
recv_beacon->proto_cap |= PROTO_CAP_11B;
|
||||
else if (cckrates_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
|
||||
recv_beacon->proto_cap |= PROTO_CAP_11B | PROTO_CAP_11G;
|
||||
else
|
||||
recv_beacon->proto_cap |= PROTO_CAP_11G;
|
||||
|
||||
if (elems.ht_capabilities && elems.ht_operation)
|
||||
recv_beacon->proto_cap |= PROTO_CAP_11N;
|
||||
|
||||
if (elems.vht_capabilities && elems.vht_operation)
|
||||
recv_beacon->proto_cap |= PROTO_CAP_11AC;
|
||||
|
||||
/* check bw and channel offset */
|
||||
rtw_ies_get_chbw(pos, left, &recv_beacon->ch, &recv_beacon->bw, &recv_beacon->offset, 1, 1);
|
||||
if (!recv_beacon->ch) {
|
||||
/* we don't find channel IE, so don't check it */
|
||||
/* RTW_INFO("Oops: %s we don't find channel IE, so don't check it\n", __func__); */
|
||||
recv_beacon->bcn_channel = Adapter->mlmeextpriv.cur_channel;
|
||||
recv_beacon->ch = Adapter->mlmeextpriv.cur_channel;
|
||||
}
|
||||
|
||||
/* checking SSID */
|
||||
@@ -2512,22 +2524,21 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
|
||||
|
||||
_rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len);
|
||||
recv_beacon->ssid_len = elems.ssid_len;
|
||||
} else
|
||||
; /* means hidden ssid */
|
||||
}
|
||||
|
||||
/* checking RSN first */
|
||||
if (elems.rsn_ie && elems.rsn_ie_len) {
|
||||
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2;
|
||||
rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
|
||||
&recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
|
||||
&recv_beacon->is_8021x, NULL);
|
||||
&recv_beacon->akm, NULL);
|
||||
}
|
||||
/* checking WPA secon */
|
||||
else if (elems.wpa_ie && elems.wpa_ie_len) {
|
||||
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA;
|
||||
rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2,
|
||||
&recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
|
||||
&recv_beacon->is_8021x);
|
||||
&recv_beacon->akm);
|
||||
} else if (capability & BIT(4))
|
||||
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP;
|
||||
|
||||
@@ -2543,61 +2554,48 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon)
|
||||
void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon)
|
||||
{
|
||||
u8 ssid[IW_ESSID_MAX_SIZE + 1];
|
||||
|
||||
_rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len);
|
||||
ssid[recv_beacon->ssid_len] = '\0';
|
||||
|
||||
RTW_INFO("%s: ssid = %s\n", __func__, ssid);
|
||||
RTW_INFO("%s: channel = %d\n", __func__, recv_beacon->bcn_channel);
|
||||
RTW_INFO("%s: ht_cap = 0x%04x\n", __func__, recv_beacon->ht_cap_info);
|
||||
RTW_INFO("%s: ht_info_infos_0_sco = 0x%02x\n", __func__, recv_beacon->ht_info_infos_0_sco);
|
||||
RTW_INFO("%s: sec=%d, group = %x, pair = %x, 8021X = %x\n", __func__,
|
||||
recv_beacon->encryp_protocol, recv_beacon->group_cipher,
|
||||
recv_beacon->pairwise_cipher, recv_beacon->is_8021x);
|
||||
RTW_PRINT_SEL(sel, "ssid = %s (len = %u)\n", ssid, recv_beacon->ssid_len);
|
||||
RTW_PRINT_SEL(sel, "ch = %u,%u,%u\n"
|
||||
, recv_beacon->ch, recv_beacon->bw, recv_beacon->offset);
|
||||
RTW_PRINT_SEL(sel, "proto_cap = 0x%02x\n", recv_beacon->proto_cap);
|
||||
RTW_MAP_DUMP_SEL(sel, "rate_set = "
|
||||
, recv_beacon->rate_set, recv_beacon->rate_num);
|
||||
RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n"
|
||||
, recv_beacon->encryp_protocol, recv_beacon->group_cipher
|
||||
, recv_beacon->pairwise_cipher, recv_beacon->akm);
|
||||
}
|
||||
#define DBG_BCN_CNT
|
||||
|
||||
int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
|
||||
{
|
||||
unsigned int len;
|
||||
#define BCNKEY_VERIFY_PROTO_CAP 0
|
||||
#define BCNKEY_VERIFY_WHOLE_RATE_SET 0
|
||||
|
||||
u8 *pbssid = GetAddr3Ptr(pframe);
|
||||
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
|
||||
struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
|
||||
struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys;
|
||||
struct beacon_keys recv_beacon;
|
||||
int ret = 0;
|
||||
|
||||
if (is_client_associated_to_ap(Adapter) == _FALSE)
|
||||
return _TRUE;
|
||||
|
||||
len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
|
||||
|
||||
if (len > MAX_IE_SZ) {
|
||||
RTW_WARN("%s IE too long for survey event\n", __func__);
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
if (_rtw_memcmp(cur_network->network.MacAddress, pbssid, 6) == _FALSE) {
|
||||
RTW_WARN("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT,
|
||||
MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress));
|
||||
return _TRUE;
|
||||
}
|
||||
goto exit_success;
|
||||
|
||||
if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE)
|
||||
return _TRUE; /* parsing failed => broken IE */
|
||||
goto exit_success; /* parsing failed => broken IE */
|
||||
|
||||
#ifdef DBG_RX_BCN
|
||||
rtw_debug_bcn(Adapter, pframe, packet_len);
|
||||
#endif
|
||||
|
||||
/* don't care hidden ssid, use current beacon ssid directly */
|
||||
if (recv_beacon.ssid_len == 0) {
|
||||
_rtw_memcpy(recv_beacon.ssid, pmlmepriv->cur_beacon_keys.ssid,
|
||||
pmlmepriv->cur_beacon_keys.ssid_len);
|
||||
recv_beacon.ssid_len = pmlmepriv->cur_beacon_keys.ssid_len;
|
||||
}
|
||||
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
|
||||
if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _TRUE)
|
||||
if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE)
|
||||
pmlmepriv->new_beacon_cnts = 0;
|
||||
else if ((pmlmepriv->new_beacon_cnts == 0) ||
|
||||
_rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) {
|
||||
@@ -2605,11 +2603,11 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
|
||||
|
||||
if (pmlmepriv->new_beacon_cnts == 0) {
|
||||
RTW_ERR("%s: cur beacon key\n", __func__);
|
||||
RTW_DBG_EXPR(rtw_dump_bcn_keys(&pmlmepriv->cur_beacon_keys));
|
||||
RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon));
|
||||
}
|
||||
|
||||
RTW_DBG("%s: new beacon key\n", __func__);
|
||||
RTW_DBG_EXPR(rtw_dump_bcn_keys(&recv_beacon));
|
||||
RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon));
|
||||
|
||||
_rtw_memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon));
|
||||
pmlmepriv->new_beacon_cnts = 1;
|
||||
@@ -2621,45 +2619,47 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
|
||||
/* if counter >= max, it means beacon is changed really */
|
||||
if (pmlmepriv->new_beacon_cnts >= new_bcn_max)
|
||||
#else
|
||||
if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _FALSE)
|
||||
if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _FALSE)
|
||||
#endif
|
||||
{
|
||||
/* check bw mode change only? */
|
||||
pmlmepriv->cur_beacon_keys.ht_cap_info = recv_beacon.ht_cap_info;
|
||||
pmlmepriv->cur_beacon_keys.ht_info_infos_0_sco = recv_beacon.ht_info_infos_0_sco;
|
||||
if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys,
|
||||
sizeof(recv_beacon)) == _FALSE) {
|
||||
/* beacon is changed, have to do disconnect/connect */
|
||||
RTW_WARN("%s: new beacon occur!!\n", __func__);
|
||||
#ifdef DBG_BCN_CNT
|
||||
rtw_dump_bcn_keys(&recv_beacon);
|
||||
#endif
|
||||
return _FAIL;
|
||||
struct beacon_keys tmp_beacon;
|
||||
|
||||
RTW_INFO(FUNC_ADPT_FMT" new beacon occur!!\n", FUNC_ADPT_ARG(Adapter));
|
||||
RTW_INFO(FUNC_ADPT_FMT" cur beacon key:\n", FUNC_ADPT_ARG(Adapter));
|
||||
rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon);
|
||||
RTW_INFO(FUNC_ADPT_FMT" new beacon key:\n", FUNC_ADPT_ARG(Adapter));
|
||||
rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon);
|
||||
|
||||
if (!rtw_is_chbw_grouped(cur_beacon->ch, cur_beacon->bw, cur_beacon->offset
|
||||
, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset))
|
||||
goto exit;
|
||||
|
||||
_rtw_memcpy(&tmp_beacon, cur_beacon, sizeof(tmp_beacon));
|
||||
|
||||
/* check fields excluding below */
|
||||
tmp_beacon.ch = recv_beacon.ch;
|
||||
tmp_beacon.bw = recv_beacon.bw;
|
||||
tmp_beacon.offset = recv_beacon.offset;
|
||||
if (!BCNKEY_VERIFY_PROTO_CAP)
|
||||
tmp_beacon.proto_cap = recv_beacon.proto_cap;
|
||||
if (!BCNKEY_VERIFY_WHOLE_RATE_SET) {
|
||||
tmp_beacon.rate_num = recv_beacon.rate_num;
|
||||
_rtw_memcpy(tmp_beacon.rate_set, recv_beacon.rate_set, 12);
|
||||
}
|
||||
#ifdef DBG_BCN_CNT
|
||||
RTW_INFO("%s bw mode change\n", __func__);
|
||||
RTW_INFO("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
|
||||
cur_network->BcnInfo.ht_cap_info,
|
||||
cur_network->BcnInfo.ht_info_infos_0);
|
||||
#endif
|
||||
if (_rtw_memcmp(&tmp_beacon, &recv_beacon, sizeof(recv_beacon)) == _FALSE)
|
||||
goto exit;
|
||||
|
||||
cur_network->BcnInfo.ht_cap_info = recv_beacon.ht_cap_info;
|
||||
cur_network->BcnInfo.ht_info_infos_0 =
|
||||
(cur_network->BcnInfo.ht_info_infos_0 & (~0x03)) |
|
||||
recv_beacon.ht_info_infos_0_sco;
|
||||
|
||||
#ifdef DBG_BCN_CNT
|
||||
RTW_INFO("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
|
||||
cur_network->BcnInfo.ht_cap_info,
|
||||
cur_network->BcnInfo.ht_info_infos_0);
|
||||
#endif
|
||||
_rtw_memcpy(&pmlmepriv->cur_beacon_keys, &recv_beacon, sizeof(recv_beacon));
|
||||
_rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon));
|
||||
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
|
||||
pmlmepriv->new_beacon_cnts = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
return _SUCCESS;
|
||||
exit_success:
|
||||
ret = 1;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
|
||||
|
Reference in New Issue
Block a user