00001
00020
00021
00022
00023
00024
00025 #include "mac_ie.h"
00026
00027 #include <string.h>
00028
00029 #include "dbg_assert.h"
00030
00031
00032
00033
00034
00035
00052 static uint32_t mac_ie_find(uint32_t addr,
00053 uint16_t buflen,
00054 uint8_t ie_id,
00055 uint16_t *len)
00056 {
00057 uint32_t end = addr + buflen;
00058
00059 while ((addr + MAC_INFOELT_LEN_OFT) < end)
00060 {
00061 uint16_t ie_len = mac_ie_len(addr);
00062 uint32_t ie_end = addr + ie_len;
00063
00064
00065 if (ie_id == co_read8p(addr))
00066 {
00067
00068 if (ie_end > end)
00069 return 0;
00070
00071 *len = ie_len;
00072
00073
00074 return addr;
00075 }
00076
00077 addr = ie_end;
00078 }
00079
00080 return 0;
00081 }
00082
00098 static uint32_t mac_ext_ie_find(uint32_t addr,
00099 uint16_t buflen,
00100 uint8_t ext_ie_id,
00101 uint16_t *len)
00102 {
00103 uint32_t end = addr + buflen;
00104
00105 while (addr < end)
00106 {
00107
00108 addr = mac_ie_find(addr, buflen, MAC_ELTID_EXT, len);
00109
00110
00111
00112 if ((addr == 0) || ((addr + MAC_INFOELT_EXT_INFO_OFT) > end))
00113 return 0;
00114
00115
00116 if (ext_ie_id == co_read8p(addr + MAC_INFOELT_EXT_ID_OFT))
00117 {
00118
00119 return addr;
00120 }
00121
00122 addr += *len;
00123 buflen -= *len;
00124 }
00125
00126
00127 ASSERT_ERR(addr == end);
00128
00129 return 0;
00130 }
00131
00148 static uint32_t mac_vsie_find(uint32_t addr,
00149 uint16_t buflen,
00150 uint8_t const *oui,
00151 uint8_t ouilen,
00152 uint16_t *len)
00153 {
00154 uint32_t end = addr + buflen;
00155
00156
00157 while (addr < end)
00158 {
00159
00160 addr = mac_ie_find(addr, buflen, MAC_ELTID_OUI, len);
00161
00162
00163
00164 if ((addr == 0) || ((addr + MAC_INFOELT_INFO_OFT + ouilen) > end))
00165 return 0;
00166
00167
00168 if (co_cmp8p(addr + MAC_INFOELT_INFO_OFT, oui, ouilen))
00169 {
00170
00171 return addr;
00172 }
00173
00174
00175 addr += *len;
00176 buflen -= *len;
00177 }
00178
00179
00180 ASSERT_ERR(addr == end);
00181
00182 return 0;
00183 }
00184
00185 uint32_t mac_ie_rates_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00186 {
00187 uint16_t len;
00188 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_RATES, &len);
00189
00190 if ((addr == 0) || (len > MAC_RATES_MAX_LEN) ||
00191 (len < MAC_RATES_MIN_LEN))
00192 return 0;
00193
00194 *ie_len = len - MAC_INFOELT_INFO_OFT;
00195
00196 return addr;
00197 }
00198
00199 uint32_t mac_ie_ext_rates_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00200 {
00201 uint16_t len;
00202 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_EXT_RATES, &len);
00203
00204 if ((addr == 0) || (len < MAC_RATES_MIN_LEN))
00205 return 0;
00206
00207 *ie_len = len - MAC_INFOELT_INFO_OFT;
00208
00209 return addr;
00210 }
00211
00212 uint32_t mac_ie_ssid_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00213 {
00214 uint16_t len;
00215 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_SSID, &len);
00216
00217 if ((addr == 0) || (len > MAC_SSID_MAX_LEN))
00218 return 0;
00219
00220 *ie_len = len - MAC_INFOELT_INFO_OFT;
00221
00222 return addr;
00223 }
00224
00225 uint32_t mac_ie_country_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00226 {
00227 uint16_t len;
00228 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_COUNTRY, &len);
00229
00230 if ((addr == 0) || (len < MAC_COUNTRY_MIN_LEN))
00231 return 0;
00232
00233 *ie_len = len - MAC_INFOELT_INFO_OFT;
00234
00235 return addr;
00236 }
00237
00238 uint32_t mac_ie_rsn_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00239 {
00240 uint16_t len;
00241 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_RSN_IEEE, &len);
00242
00243 if ((addr == 0) || (len < MAC_RSNIE_MIN_LEN))
00244 return 0;
00245
00246 *ie_len = len - MAC_INFOELT_INFO_OFT;
00247
00248 return addr;
00249 }
00250
00251 uint32_t mac_ie_wpa_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00252 {
00253 uint16_t len;
00254 uint32_t addr = mac_vsie_find(buffer, buflen,
00255 (uint8_t const *)"\x00\x50\xF2\x01\x01", 5, &len);
00256
00257 if ((addr == 0) || (len < MAC_WPA_MIN_LEN))
00258 return 0;
00259
00260 *ie_len = len - MAC_INFOELT_INFO_OFT;
00261
00262 return addr;
00263 }
00264
00265 uint32_t mac_ie_wapi_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00266 {
00267 uint16_t len;
00268 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_WAPI, &len);
00269
00270 if ((addr == 0) || (len < MAC_WAPI_MIN_LEN))
00271 return 0;
00272
00273 *ie_len = len - MAC_INFOELT_INFO_OFT;
00274
00275 return addr;
00276 }
00277
00278 uint32_t mac_ie_mesh_id_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00279 {
00280 uint16_t len;
00281 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MESH_ID, &len);
00282
00283 if ((addr == 0) || (len > MAC_MESHID_MAX_LEN))
00284 return 0;
00285
00286 *ie_len = len - MAC_INFOELT_INFO_OFT;
00287
00288 return addr;
00289 }
00290
00291 uint32_t mac_ie_mesh_peer_mgmt_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00292 {
00293 uint16_t len;
00294 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MESH_PEER_MGMT, &len);
00295
00296 if ((addr == 0) || (len > MAC_MPM_MAX_LEN) ||
00297 (len < MAC_MPM_MIN_LEN))
00298 return 0;
00299
00300 *ie_len = len - MAC_INFOELT_INFO_OFT;
00301
00302 return addr;
00303 }
00304
00305 uint32_t mac_ie_mesh_awake_win_find(uint32_t buffer, uint16_t buflen)
00306 {
00307 uint16_t len;
00308 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MESH_AWAKE_WINDOW, &len);
00309
00310 if ((addr == 0) || (len != MAC_MAW_LEN))
00311 return 0;
00312
00313 return addr;
00314 }
00315
00316 uint32_t mac_ie_mesh_conf_find(uint32_t buffer, uint16_t buflen)
00317 {
00318 uint16_t len;
00319 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MESH_CONF, &len);
00320
00321 if ((addr == 0) || (len != MAC_MCFG_LEN))
00322 return 0;
00323
00324 return addr;
00325 }
00326
00327 uint32_t mac_ie_tim_find(uint32_t buffer, uint16_t buflen)
00328 {
00329 uint16_t len;
00330 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_TIM, &len);
00331
00332 if ((addr == 0) || (len > MAC_TIM_MAX_LEN) ||
00333 (len < MAC_TIM_MIN_LEN))
00334 return 0;
00335
00336 return addr;
00337 }
00338
00339 uint32_t mac_ie_csa_find(uint32_t buffer, uint16_t buflen)
00340 {
00341 uint16_t len;
00342 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_CHANNEL_SWITCH, &len);
00343
00344 if ((addr == 0) || (len != MAC_CHANNEL_SWITCH_ELT_LEN))
00345 return 0;
00346
00347 return addr;
00348 }
00349
00350 uint32_t mac_ie_ecsa_find(uint32_t buffer, uint16_t buflen)
00351 {
00352 uint16_t len;
00353 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_EXT_CHANNEL_SWITCH, &len);
00354
00355 if ((addr == 0) || (len != MAC_EXT_CHANNEL_SWITCH_ELT_LEN))
00356 return 0;
00357
00358 return addr;
00359 }
00360
00361 uint32_t mac_ie_sec_chnl_offset_find(uint32_t buffer, uint16_t buflen, bool *valid_len)
00362 {
00363 uint16_t len;
00364 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_SEC_CH_OFFSET, &len);
00365
00366 if (addr == 0)
00367 return 0;
00368
00369 *valid_len = (len == MAC_INFOELT_SEC_CH_OFFSET_ELT_LEN);
00370
00371 return addr;
00372 }
00373
00374 uint32_t mac_ie_wide_bw_chnl_find(uint32_t buffer, uint16_t buflen, bool *valid_len)
00375 {
00376 uint16_t len;
00377 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_CHAN_SWITCH_WRP, &len);
00378
00379 if (addr == 0)
00380 return 0;
00381
00382 addr = mac_ie_find(addr + MAC_INFOELT_INFO_OFT, len - MAC_INFOELT_INFO_OFT,
00383 MAC_ELTID_WIDE_BANDWIDTH_CHAN_SWITCH, &len);
00384
00385 if (addr == 0)
00386 return 0;
00387
00388 *valid_len = (len == MAC_INFOELT_WIDE_BW_CHAN_SWITCH_ELT_LEN);
00389
00390 return addr;
00391 }
00392
00393 uint32_t mac_ie_ds_find(uint32_t buffer, uint16_t buflen)
00394 {
00395 uint16_t len;
00396 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_DS, &len);
00397
00398 if ((addr == 0) || (len != MAC_DS_PARAM_LEN))
00399 return 0;
00400
00401 return addr;
00402 }
00403
00404 uint32_t mac_ie_mgmt_mic_find(uint32_t buffer, uint16_t buflen)
00405 {
00406 uint16_t len;
00407 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MGMT_MIC, &len);
00408
00409 if ((addr == 0) || (len != MAC_MGMT_MIC_LEN))
00410 return 0;
00411
00412 return addr;
00413 }
00414
00415 uint32_t mac_ie_qos_capa_find(uint32_t buffer, uint16_t buflen)
00416 {
00417 uint16_t len;
00418 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_QOS_CAPA, &len);
00419
00420 if ((addr == 0) || (len != MAC_QOS_CAPA_LEN))
00421 return 0;
00422
00423 return addr;
00424 }
00425
00426 uint32_t mac_ie_erp_find(uint32_t buffer, uint16_t buflen)
00427 {
00428 uint16_t len;
00429 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_ERP, &len);
00430
00431 if ((addr == 0) || (len != MAC_ERP_LEN))
00432 return 0;
00433
00434 return addr;
00435 }
00436
00437 uint32_t mac_ie_op_mode_notif_find(uint32_t buffer, uint16_t buflen)
00438 {
00439 uint16_t len;
00440 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_OP_MODE_NOTIF, &len);
00441
00442 if ((addr == 0) || (len != MAC_OP_MODE_NOTIF_LEN))
00443 return 0;
00444
00445 return addr;
00446 }
00447
00448 uint32_t mac_ie_power_constraint_find(uint32_t buffer, uint16_t buflen)
00449 {
00450 uint16_t len;
00451 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_POWER_CONSTRAINT, &len);
00452
00453 if ((addr == 0) || (len != MAC_POWER_CONSTRAINT_ELT_LEN))
00454 return 0;
00455
00456 return addr;
00457 }
00458
00459 uint32_t mac_ie_mde_find(uint32_t buffer, uint16_t buflen)
00460 {
00461 uint16_t len;
00462 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MDE, &len);
00463
00464 if ((addr == 0) || (len != MAC_INFOELT_MDE_LEN))
00465 return 0;
00466
00467 return addr;
00468 }
00469
00470 uint32_t mac_ie_wmm_param_find(uint32_t buffer, uint16_t buflen)
00471 {
00472 uint16_t len;
00473 uint32_t addr = mac_vsie_find(buffer, buflen,
00474 (uint8_t const *)"\x00\x50\xF2\x02\x01", 5, &len);
00475
00476 if ((addr == 0) || (len != MAC_WMM_PARAM_LEN))
00477 return 0;
00478
00479 return addr;
00480 }
00481
00482 uint32_t mac_ie_ht_capa_find(uint32_t buffer, uint16_t buflen)
00483 {
00484 uint16_t len;
00485 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_HT_CAPA, &len);
00486
00487 if ((addr == 0) || (len != MAC_HT_CAPA_LEN))
00488 return 0;
00489
00490 return addr;
00491 }
00492
00493 uint32_t mac_ie_multi_bssid_find(uint32_t buffer, uint16_t buflen)
00494 {
00495 uint16_t len;
00496 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MULTIPLE_BSSID, &len);
00497
00498 if ((addr == 0) || (len < MAC_MULTI_BSSID_MIN_LEN))
00499 return 0;
00500
00501 return addr;
00502 }
00503
00504 uint32_t mac_ie_sub_non_txed_bssid_find(uint32_t buffer, uint16_t buflen)
00505 {
00506 uint16_t len;
00507 uint32_t addr = mac_ie_find(buffer, buflen, MAC_SUBID_MBSSID_NON_TXED_PROF, &len);
00508
00509 if ((addr == 0) || (len < MAC_MBSSID_NON_TXED_PROF_MIN_LEN))
00510 return 0;
00511
00512 return addr;
00513 }
00514
00515 uint32_t mac_ie_non_txed_bssid_capa_find(uint32_t buffer, uint16_t buflen)
00516 {
00517 uint16_t len;
00518 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_NON_TXED_BSSID_CAPA, &len);
00519
00520 if ((addr == 0) || (len != MAC_NON_TXED_BSSID_CAPA_LEN))
00521 return 0;
00522
00523 return addr;
00524 }
00525
00526 uint32_t mac_ie_multi_bssid_index_find(uint32_t buffer, uint16_t buflen)
00527 {
00528 uint16_t len;
00529 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_MULTI_BSSID_INDEX, &len);
00530
00531 if ((addr == 0) || (len < MAC_MULTI_BSSID_INDEX_MIN_LEN))
00532 return 0;
00533
00534 return addr;
00535 }
00536
00537 uint32_t mac_ie_vht_capa_find(uint32_t buffer, uint16_t buflen)
00538 {
00539 uint16_t len;
00540 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_VHT_CAPA, &len);
00541
00542 if ((addr == 0) || (len != MAC_VHT_CAPA_LEN))
00543 return 0;
00544
00545 return addr;
00546 }
00547
00548 uint32_t mac_ie_he_capa_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00549 {
00550 uint16_t len;
00551 uint32_t addr = mac_ext_ie_find(buffer, buflen, MAC_ELTID_EXT_HE_CAPA, &len);
00552
00553 if ((addr == 0) || (len > MAC_HE_CAPA_MAX_LEN) ||
00554 (len < MAC_HE_CAPA_MIN_LEN))
00555 return 0;
00556
00557 *ie_len = len - MAC_INFOELT_EXT_INFO_OFT;
00558
00559 return addr;
00560 }
00561
00562 uint32_t mac_ie_ht_oper_find(uint32_t buffer, uint16_t buflen)
00563 {
00564 uint16_t len;
00565 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_HT_OPERATION, &len);
00566
00567 if ((addr == 0) || (len != MAC_HT_OPER_LEN))
00568 return 0;
00569
00570 return addr;
00571 }
00572
00573 uint32_t mac_ie_vht_oper_find(uint32_t buffer, uint16_t buflen)
00574 {
00575 uint16_t len;
00576 uint32_t addr = mac_ie_find(buffer, buflen, MAC_ELTID_VHT_OPERATION, &len);
00577
00578 if ((addr == 0) || (len != MAC_VHT_OPER_LEN))
00579 return 0;
00580
00581 return addr;
00582 }
00583
00584 uint32_t mac_ie_he_oper_find(uint32_t buffer, uint16_t buflen, uint8_t *ie_len)
00585 {
00586 uint16_t len;
00587 uint32_t addr = mac_ext_ie_find(buffer, buflen, MAC_ELTID_EXT_HE_OPERATION, &len);
00588
00589 if ((addr == 0) || (len > MAC_HE_OPER_MAX_LEN) ||
00590 (len < MAC_HE_OPER_MIN_LEN))
00591 return 0;
00592
00593 *ie_len = len - MAC_INFOELT_EXT_INFO_OFT;
00594
00595 return addr;
00596 }
00597
00598 uint32_t mac_ie_mu_edca_find(uint32_t buffer, uint16_t buflen)
00599 {
00600 uint16_t len;
00601 uint32_t addr = mac_ext_ie_find(buffer, buflen, MAC_ELTID_EXT_MU_EDCA, &len);
00602
00603 if ((addr == 0) || (len != MAC_MU_EDCA_LEN))
00604 return 0;
00605
00606 return addr;
00607 }
00608
00609 uint32_t mac_ie_uora_find(uint32_t buffer, uint16_t buflen)
00610 {
00611 uint16_t len;
00612 uint32_t addr = mac_ext_ie_find(buffer, buflen, MAC_ELTID_EXT_UORA, &len);
00613
00614 if ((addr == 0) || (len != MAC_UORA_LEN))
00615 return 0;
00616
00617 return addr;
00618 }
00619