void p2p_sd_response(struct p2p_data *p2p, int freq, const u8 *dst, u8 dialog_token, const struct wpabuf *resp_tlvs) { struct wpabuf *resp; size_t max_len; /* * In the 60 GHz, we have a smaller maximum frame length for management * frames. */ max_len = (freq > 56160) ? 928 : 1400; /* TODO: fix the length limit to match with the maximum frame length */ if (wpabuf_len(resp_tlvs) > max_len) { p2p_dbg(p2p, "SD response long enough to require fragmentation"); if (p2p->sd_resp) { /* * TODO: Could consider storing the fragmented response * separately for each peer to avoid having to drop old * one if there is more than one pending SD query. * Though, that would eat more memory, so there are * also benefits to just using a single buffer. */ p2p_dbg(p2p, "Drop previous SD response"); wpabuf_free(p2p->sd_resp); } p2p->sd_resp = wpabuf_dup(resp_tlvs); if (p2p->sd_resp == NULL) { p2p_err(p2p, "Failed to allocate SD response fragmentation area"); return; } os_memcpy(p2p->sd_resp_addr, dst, ETH_ALEN); p2p->sd_resp_dialog_token = dialog_token; p2p->sd_resp_pos = 0; p2p->sd_frag_id = 0; resp = p2p_build_sd_response(dialog_token, WLAN_STATUS_SUCCESS, 1, p2p->srv_update_indic, NULL); } else { p2p_dbg(p2p, "SD response fits in initial response"); resp = p2p_build_sd_response(dialog_token, WLAN_STATUS_SUCCESS, 0, p2p->srv_update_indic, resp_tlvs); } if (resp == NULL) return; p2p->pending_action_state = P2P_NO_PENDING_ACTION; if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, p2p->cfg->dev_addr, wpabuf_head(resp), wpabuf_len(resp), 200) < 0) p2p_dbg(p2p, "Failed to send Action frame"); wpabuf_free(resp); }
void p2p_sd_response(struct p2p_data *p2p, int freq, const u8 *dst, u8 dialog_token, const struct wpabuf *resp_tlvs) { struct wpabuf *resp; /* TODO: fix the length limit to match with the maximum frame length */ if (wpabuf_len(resp_tlvs) > 1400) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: SD response long " "enough to require fragmentation"); if (p2p->sd_resp) { /* * TODO: Could consider storing the fragmented response * separately for each peer to avoid having to drop old * one if there is more than one pending SD query. * Though, that would eat more memory, so there are * also benefits to just using a single buffer. */ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Drop " "previous SD response"); wpabuf_free(p2p->sd_resp); } p2p->sd_resp = wpabuf_dup(resp_tlvs); if (p2p->sd_resp == NULL) { wpa_msg(p2p->cfg->msg_ctx, MSG_ERROR, "P2P: Failed to " "allocate SD response fragmentation area"); return; } os_memcpy(p2p->sd_resp_addr, dst, ETH_ALEN); p2p->sd_resp_dialog_token = dialog_token; p2p->sd_resp_pos = 0; p2p->sd_frag_id = 0; resp = p2p_build_sd_response(dialog_token, WLAN_STATUS_SUCCESS, 1, p2p->srv_update_indic, NULL); } else { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: SD response fits " "in initial response"); resp = p2p_build_sd_response(dialog_token, WLAN_STATUS_SUCCESS, 0, p2p->srv_update_indic, resp_tlvs); } if (resp == NULL) return; p2p->pending_action_state = P2P_NO_PENDING_ACTION; if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, p2p->cfg->dev_addr, wpabuf_head(resp), wpabuf_len(resp), 200) < 0) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to send Action frame"); wpabuf_free(resp); }