static void gas_server_handle_rx_comeback_req(struct gas_server_response *response) { struct gas_server_handler *handler = response->handler; struct gas_server *gas = handler->gas; size_t max_len = (response->freq > 56160) ? 928 : 1400; size_t hdr_len = 24 + 2 + 6 + 3 + handler->adv_proto_id_len + 2; size_t remaining, resp_frag_len; struct wpabuf *resp; remaining = wpabuf_len(response->resp) - response->offset; if (hdr_len + remaining > max_len) resp_frag_len = max_len - hdr_len; else resp_frag_len = remaining; wpa_printf(MSG_DEBUG, "GAS: Sending out %u/%u remaining Query Response octets", (unsigned int) resp_frag_len, (unsigned int) remaining); resp = gas_build_comeback_resp(response->dialog_token, WLAN_STATUS_SUCCESS, response->frag_id++, resp_frag_len < remaining, 0, handler->adv_proto_id_len + resp_frag_len); if (!resp) { gas_server_free_response(response); return; } /* Advertisement Protocol element */ wpabuf_put_u8(resp, WLAN_EID_ADV_PROTO); wpabuf_put_u8(resp, 1 + handler->adv_proto_id_len); /* Length */ wpabuf_put_u8(resp, 0x7f); /* Advertisement Protocol ID */ wpabuf_put_data(resp, handler->adv_proto_id, handler->adv_proto_id_len); /* Query Response Length */ wpabuf_put_le16(resp, resp_frag_len); wpabuf_put_data(resp, wpabuf_head_u8(response->resp) + response->offset, resp_frag_len); response->offset += resp_frag_len; gas->tx(gas->ctx, response->freq, response->dst, resp, remaining > resp_frag_len ? 2000 : 0); wpabuf_free(resp); }
struct wpabuf * gas_anqp_build_comeback_resp(u8 dialog_token, u16 status_code, u8 frag_id, u8 more, u16 comeback_delay, size_t size) { struct wpabuf *buf; buf = gas_build_comeback_resp(dialog_token, status_code, frag_id, more, comeback_delay, 4 + size); if (buf == NULL) return NULL; gas_add_adv_proto_anqp(buf, 0x7f, 0); wpabuf_put(buf, 2); /* Query Response Length to be filled */ return buf; }