3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-25 17:59:25 +01:00

ie: Implement ie_parse_neighbor_report

This commit is contained in:
Andrew Zaborowski 2016-11-02 23:46:10 +01:00 committed by Denis Kenzior
parent bc2396b4f7
commit 1b99521e98
2 changed files with 82 additions and 0 deletions

View File

@ -1564,3 +1564,62 @@ bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to)
return true;
}
enum nr_subelem_id {
NR_SUBELEM_ID_TSF_INFO = 1,
NR_SUBELEM_ID_CONDENSED_COUNTRY_STR = 2,
NR_SUBELEM_ID_BSS_TRANSITION_PREF = 3,
NR_SUBELEM_ID_BSS_TERMINATION_DURATION = 4,
NR_SUBELEM_ID_BEARING = 5,
NR_SUBELEM_ID_WIDE_BW_CHANNEL = 6,
/* Remaining defined subelements use the IE_TYPE_* ID values */
};
int ie_parse_neighbor_report(struct ie_tlv_iter *iter,
struct ie_neighbor_report_info *info)
{
unsigned int len = ie_tlv_iter_get_length(iter);
const uint8_t *data = ie_tlv_iter_get_data(iter);
struct ie_tlv_iter opt_iter;
if (len < 13)
return -EINVAL;
memset(info, 0, sizeof(*info));
memcpy(info->addr, data + 0, 6);
info->ht = util_is_bit_set(data[8], 3);
info->md = util_is_bit_set(data[8], 2);
info->immediate_block_ack = util_is_bit_set(data[8], 1);
info->delayed_block_ack = util_is_bit_set(data[8], 0);
info->rm = util_is_bit_set(data[9], 7);
info->apsd = util_is_bit_set(data[9], 6);
info->qos = util_is_bit_set(data[9], 5);
info->spectrum_mgmt = util_is_bit_set(data[9], 4);
info->key_scope = util_is_bit_set(data[9], 3);
info->security = util_is_bit_set(data[9], 2);
info->reachable = util_bit_field(data[9], 0, 2);
info->oper_class = data[10];
info->channel_num = data[11];
info->phy_type = data[12];
ie_tlv_iter_init(&opt_iter, data + 13, len - 13);
while (ie_tlv_iter_next(&opt_iter)) {
if (ie_tlv_iter_get_tag(&opt_iter) !=
NR_SUBELEM_ID_BSS_TRANSITION_PREF)
continue;
if (ie_tlv_iter_get_length(&opt_iter) != 1)
continue;
info->bss_transition_pref = ie_tlv_iter_get_data(&opt_iter)[0];
info->bss_transition_pref_present = true;
}
return 0;
}

View File

@ -249,6 +249,26 @@ enum ie_rm_capability {
IE_RM_CAP_NEIGHBOR_REPORT = 0x0002,
};
struct ie_neighbor_report_info {
uint8_t addr[6];
uint8_t reachable;
bool spectrum_mgmt : 1;
bool qos : 1;
bool apsd : 1;
bool rm : 1;
bool delayed_block_ack : 1;
bool immediate_block_ack : 1;
bool security : 1;
bool key_scope : 1;
bool md : 1;
bool ht : 1;
uint8_t oper_class;
uint8_t channel_num;
uint8_t phy_type;
uint8_t bss_transition_pref;
bool bss_transition_pref_present : 1;
};
void ie_tlv_iter_init(struct ie_tlv_iter *iter, const unsigned char *tlv,
unsigned int len);
void ie_tlv_iter_recurse(struct ie_tlv_iter *iter,
@ -325,3 +345,6 @@ int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter,
int ie_parse_fast_bss_transition_from_data(const uint8_t *data, uint8_t len,
struct ie_ft_info *info);
bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to);
int ie_parse_neighbor_report(struct ie_tlv_iter *iter,
struct ie_neighbor_report_info *info);