diff options
Diffstat (limited to 'qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c')
-rw-r--r-- | qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c b/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c index 8f83562..537d323 100644 --- a/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c @@ -61,6 +61,11 @@ (DOT11F_FF_CATEGORY_LEN + DOT11F_FF_ACTION_LEN + DOT11F_FF_TRANSACTIONID_LEN) #define SA_QUERY_IE_OFFSET (4) +#define MIN_OCI_IE_LEN 6 +#define OCI_IE_OUI_SIZE 1 +#define OCI_IE_OP_CLS_OFFSET 3 +#define ELE_ID_EXT_LEN 1 + static last_processed_msg rrm_link_action_frm; /**----------------------------------------------------------------- @@ -1213,13 +1218,19 @@ static bool lim_check_oci_match(struct mac_context *mac, struct pe_session *pe_session, uint8_t *ie, uint8_t *peer, uint32_t ie_len) { - const uint8_t *oci_ie; - tDot11fIEoci self_oci, *peer_oci; + const uint8_t *oci_ie, ext_id_param = WLAN_EXTN_ELEMID_OCI; + tDot11fIEoci self_oci, peer_oci = {0}; + uint32_t status = DOT11F_PARSE_SUCCESS; if (!lim_is_self_and_peer_ocv_capable(mac, peer, pe_session)) return true; - oci_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_OCI, ie, ie_len); + if (ie_len < MIN_OCI_IE_LEN) + return false; + + oci_ie = wlan_get_ext_ie_ptr_from_ext_id(&ext_id_param, + OCI_IE_OUI_SIZE, + ie, ie_len); if (!oci_ie) { pe_err("OCV not found OCI in SA Query frame!"); return false; @@ -1233,19 +1244,25 @@ lim_check_oci_match(struct mac_context *mac, struct pe_session *pe_session, * Primary channel : 1 byte * Freq_seg_1_ch_num : 1 byte */ - peer_oci = (tDot11fIEoci *)&oci_ie[2]; + status = dot11f_unpack_ie_oci(mac, + (uint8_t *)&oci_ie[OCI_IE_OP_CLS_OFFSET], + oci_ie[SIR_MAC_IE_LEN_OFFSET] - + ELE_ID_EXT_LEN, + &peer_oci, false); + if (!DOT11F_SUCCEEDED(status) || !peer_oci.present) + return false; lim_fill_oci_params(mac, pe_session, &self_oci); - if ((self_oci.op_class != peer_oci->op_class) || - (self_oci.prim_ch_num != peer_oci->prim_ch_num) || - (self_oci.freq_seg_1_ch_num != peer_oci->freq_seg_1_ch_num)) { + if ((self_oci.op_class != peer_oci.op_class) || + (self_oci.prim_ch_num != peer_oci.prim_ch_num) || + (self_oci.freq_seg_1_ch_num != peer_oci.freq_seg_1_ch_num)) { pe_err("OCI mismatch,self %d %d %d, peer %d %d %d", self_oci.op_class, self_oci.prim_ch_num, self_oci.freq_seg_1_ch_num, - peer_oci->op_class, - peer_oci->prim_ch_num, - peer_oci->freq_seg_1_ch_num); + peer_oci.op_class, + peer_oci.prim_ch_num, + peer_oci.freq_seg_1_ch_num); return false; } |