static void gas_serv_req_local_processing(struct hostapd_data *hapd, const u8 *sa, u8 dialog_token, struct anqp_query_info *qi) { struct wpabuf *buf, *tx_buf; buf = gas_serv_build_gas_resp_payload(hapd, qi->request, NULL, qi->home_realm_query, qi->home_realm_query_len); wpa_hexdump_buf(MSG_MSGDUMP, "ANQP: Locally generated ANQP responses", buf); if (!buf) return; if (wpabuf_len(buf) > hapd->gas_frag_limit || hapd->conf->gas_comeback_delay) { struct gas_dialog_info *di; u16 comeback_delay = 1; if (hapd->conf->gas_comeback_delay) { /* Testing - allow overriding of the delay value */ comeback_delay = hapd->conf->gas_comeback_delay; } wpa_printf(MSG_DEBUG, "ANQP: Too long response to fit in " "initial response - use GAS comeback"); di = gas_dialog_create(hapd, sa, dialog_token); if (!di) { wpa_printf(MSG_INFO, "ANQP: Could not create dialog " "for " MACSTR " (dialog token %u)", MAC2STR(sa), dialog_token); wpabuf_free(buf); return; } di->sd_resp = buf; di->sd_resp_pos = 0; tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_SUCCESS, comeback_delay, NULL); } else { wpa_printf(MSG_DEBUG, "ANQP: Initial response (no comeback)"); tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_SUCCESS, 0, buf); wpabuf_free(buf); } if (!tx_buf) return; hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, wpabuf_head(tx_buf), wpabuf_len(tx_buf)); wpabuf_free(tx_buf); }
static void gas_serv_req_remote_processing(struct hostapd_data *hapd, const u8 *sa, u8 dialog_token, struct anqp_query_info *qi) { struct gas_dialog_info *di; struct wpabuf *tx_buf = NULL; di = gas_dialog_create(hapd, sa, dialog_token); if (!di) { wpa_msg(hapd->msg_ctx, MSG_ERROR, "GAS: Could not create dialog for " MACSTR " (dialog token %u) ", MAC2STR(sa), dialog_token); return; } di->requested = qi->remote_request; di->received = 0; di->all_requested = qi->request; /* send the request to external agent */ if (gas_serv_get_info(hapd, qi->remote_request, qi->param, qi->param_arg, sa, dialog_token) < 0) { gas_serv_dialog_clear(di); tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_ADV_SRV_UNREACHABLE, 0, NULL); } else if (qi->remote_delay >= GAS_SERV_MIN_COMEBACK_DELAY) { di->comeback_delay = qi->remote_delay; wpa_printf(MSG_DEBUG, "GAS: Tx GAS Initial Resp (comeback = " "%d TU)", qi->remote_delay + GAS_SERV_COMEBACK_DELAY_FUDGE); tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_SUCCESS, qi->remote_delay + GAS_SERV_COMEBACK_DELAY_FUDGE, NULL); } if (!tx_buf) return; hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, wpabuf_head(tx_buf), wpabuf_len(tx_buf)); wpabuf_free(tx_buf); }
static void gas_serv_req_local_processing(struct hostapd_data *hapd, const u8 *sa, u8 dialog_token, struct anqp_query_info *qi, int prot, int std_addr3) { struct wpabuf *buf, *tx_buf; buf = gas_serv_build_gas_resp_payload(hapd, qi->request, qi->home_realm_query, qi->home_realm_query_len, qi->icon_name, qi->icon_name_len, qi->extra_req, qi->num_extra_req); wpa_hexdump_buf(MSG_MSGDUMP, "ANQP: Locally generated ANQP responses", buf); if (!buf) return; #ifdef CONFIG_P2P if (wpabuf_len(buf) == 0 && qi->p2p_sd) { wpa_printf(MSG_DEBUG, "ANQP: Do not send response to P2P SD from generic GAS service (P2P SD implementation will process this)"); wpabuf_free(buf); return; } #endif /* CONFIG_P2P */ if (wpabuf_len(buf) > hapd->gas_frag_limit || hapd->conf->gas_comeback_delay) { struct gas_dialog_info *di; u16 comeback_delay = 1; if (hapd->conf->gas_comeback_delay) { /* Testing - allow overriding of the delay value */ comeback_delay = hapd->conf->gas_comeback_delay; } wpa_printf(MSG_DEBUG, "ANQP: Too long response to fit in " "initial response - use GAS comeback"); di = gas_dialog_create(hapd, sa, dialog_token); if (!di) { wpa_printf(MSG_INFO, "ANQP: Could not create dialog " "for " MACSTR " (dialog token %u)", MAC2STR(sa), dialog_token); wpabuf_free(buf); tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_UNSPECIFIED_FAILURE, 0, NULL); } else { di->prot = prot; di->sd_resp = buf; di->sd_resp_pos = 0; tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_SUCCESS, comeback_delay, NULL); } } else { wpa_printf(MSG_DEBUG, "ANQP: Initial response (no comeback)"); tx_buf = gas_anqp_build_initial_resp_buf( dialog_token, WLAN_STATUS_SUCCESS, 0, buf); wpabuf_free(buf); } if (!tx_buf) return; if (prot) convert_to_protected_dual(tx_buf); if (std_addr3) hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, wpabuf_head(tx_buf), wpabuf_len(tx_buf)); else hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa, wpabuf_head(tx_buf), wpabuf_len(tx_buf)); wpabuf_free(tx_buf); }