diff --git a/src/wsc.c b/src/wsc.c index 7ed35a27..d705407c 100644 --- a/src/wsc.c +++ b/src/wsc.c @@ -591,6 +591,59 @@ static bool wfa_extract_registrar_configuration_methods( return true; } +int wsc_parse_beacon(const unsigned char *pdu, unsigned int len, + struct wsc_beacon *out) +{ + int r; + struct wsc_wfa_ext_iter iter; + uint8_t version; + + memset(out, 0, sizeof(struct wsc_beacon)); + + r = wsc_parse_attrs(pdu, len, &out->version2, &iter, + WSC_ATTR_VERSION, ATTR_FLAG_REQUIRED, &version, + WSC_ATTR_WSC_STATE, ATTR_FLAG_REQUIRED, &out->config_state, + WSC_ATTR_AP_SETUP_LOCKED, 0, &out->ap_setup_locked, + WSC_ATTR_SELECTED_REGISTRAR, 0, &out->selected_registrar, + WSC_ATTR_DEVICE_PASSWORD_ID, + ATTR_FLAG_REGISTRAR, &out->device_password_id, + WSC_ATTR_SELECTED_REGISTRAR_CONFIGURATION_METHODS, + ATTR_FLAG_REGISTRAR, &out->selected_reg_config_methods, + WSC_ATTR_UUID_E, ATTR_FLAG_REQUIRED, &out->uuid_e, + WSC_ATTR_RF_BANDS, 0, &out->rf_bands, + WSC_ATTR_INVALID); + + if (r < 0) + return r; + + if (!wsc_wfa_ext_iter_next(&iter)) + goto done; + + if (wsc_wfa_ext_iter_get_type(&iter) == + WSC_WFA_EXTENSION_AUTHORIZED_MACS) { + if (!wfa_extract_authorized_macs(&iter, &out->authorized_macs)) + return -EBADMSG; + + if (!wsc_wfa_ext_iter_next(&iter)) + goto done; + } + + if (wsc_wfa_ext_iter_get_type(&iter) == + WSC_WFA_EXTENSION_REGISTRAR_CONFIGRATION_METHODS) { + if (!wfa_extract_registrar_configuration_methods(&iter, + &out->reg_config_methods)) + return -EBADMSG; + + if (!wsc_wfa_ext_iter_next(&iter)) + goto done; + } + + return -EINVAL; + +done: + return 0; +} + int wsc_parse_probe_response(const unsigned char *pdu, unsigned int len, struct wsc_probe_response *out) { diff --git a/src/wsc.h b/src/wsc.h index e0a3da3a..44d29888 100644 --- a/src/wsc.h +++ b/src/wsc.h @@ -327,6 +327,19 @@ struct wsc_primary_device_type { uint16_t subcategory; }; +struct wsc_beacon { + bool version2; + enum wsc_config_state config_state; + bool ap_setup_locked; + bool selected_registrar; + enum wsc_device_password_id device_password_id; + uint16_t selected_reg_config_methods; + uint8_t uuid_e[16]; + uint8_t rf_bands; + uint8_t authorized_macs[30]; + uint16_t reg_config_methods; +}; + struct wsc_probe_response { bool version2; enum wsc_config_state config_state; @@ -348,5 +361,7 @@ struct wsc_probe_response { uint16_t reg_config_methods; }; +int wsc_parse_beacon(const unsigned char *pdu, unsigned int len, + struct wsc_beacon *out); int wsc_parse_probe_response(const unsigned char *pdu, unsigned int len, struct wsc_probe_response *out);