diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms index 01568e4777..2038ba7d6b 100644 --- a/core/mac/src/cfg/cfgUtil/dot11f.frms +++ b/core/mac/src/cfg/cfgUtil/dot11f.frms @@ -302,6 +302,16 @@ FF StatusCode (1) // WMM Spec 2.2.10 statusCode, 1; } +FF p2p_action_oui (4) +{ + oui_data[4]; +} + +FF p2p_action_subtype (1) +{ + subtype, 1; +} + FF OperatingMode (1) { { @@ -3737,6 +3747,17 @@ FRAME ext_channel_switch_action_frame FF ext_chan_switch_ann_action; } +FRAME p2p_oper_chan_change_confirm +{ + FF Category; + FF p2p_action_oui; + FF p2p_action_subtype; + FF DialogToken; + OPTIE HTCaps; + OPTIE VHTCaps; + OPTIE OperatingMode; +} + // Local Variables: // mode: c++ // fill-column: 77 diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h index d9f9b36ab5..1264274973 100644 --- a/core/mac/src/include/dot11f.h +++ b/core/mac/src/include/dot11f.h @@ -35,7 +35,7 @@ * * * This file was automatically generated by 'framesc' - * Thu Oct 6 17:32:00 2016 from the following file(s): + * Thu Nov 3 15:54:51 2016 from the following file(s): * * dot11f.frms * @@ -570,6 +570,32 @@ void dot11f_pack_ff_ext_chan_switch_ann_action(tpAniSirGlobal, #define EXT_CHAN_SWITCH_ANN_ACTION_SWITCH_COUNT_OFFSET 24 #define EXT_CHAN_SWITCH_ANN_ACTION_SWITCH_COUNT_WIDTH 8 +typedef struct sDot11fFfp2p_action_oui { + uint8_t oui_data[4]; +} tDot11fFfp2p_action_oui; + +#define DOT11F_FF_P2P_ACTION_OUI_LEN (4) + +void dot11f_unpack_ff_p2p_action_oui(tpAniSirGlobal, uint8_t *, + tDot11fFfp2p_action_oui *); + +void dot11f_pack_ff_p2p_action_oui(tpAniSirGlobal, tDot11fFfp2p_action_oui *, + uint8_t *); + +typedef struct sDot11fFfp2p_action_subtype { + uint8_t subtype; +} tDot11fFfp2p_action_subtype; + +#define DOT11F_FF_P2P_ACTION_SUBTYPE_LEN (1) + +void dot11f_unpack_ff_p2p_action_subtype(tpAniSirGlobal, uint8_t *, + tDot11fFfp2p_action_subtype *); + +void dot11f_pack_ff_p2p_action_subtype(tpAniSirGlobal, + tDot11fFfp2p_action_subtype *, + uint8_t *); + + /********************************************************************* * TLVs * ********************************************************************/ @@ -9334,4 +9360,34 @@ uint32_t dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize(tpAniSir } /* End extern "C". */ #endif /* C++ */ +typedef struct sDot11fp2p_oper_chan_change_confirm{ + tDot11fFfCategory Category; + tDot11fFfp2p_action_oui p2p_action_oui; + tDot11fFfp2p_action_subtype p2p_action_subtype; + tDot11fFfDialogToken DialogToken; + tDot11fIEHTCaps HTCaps; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEOperatingMode OperatingMode; +} tDot11fp2p_oper_chan_change_confirm; + +#define DOT11F_P2P_OPER_CHAN_CHANGE_CONFIRM (48) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +uint32_t dot11f_unpack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx, + uint8_t *pBuf, uint32_t nBuf, + tDot11fp2p_oper_chan_change_confirm * pFrm); +uint32_t dot11f_pack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx, + tDot11fp2p_oper_chan_change_confirm *pFrm, uint8_t *pBuf, + uint32_t nBuf, uint32_t *pnConsumed); +uint32_t dot11f_get_packed_p2p_oper_chan_change_confirmSize(tpAniSirGlobal pCtx, + tDot11fp2p_oper_chan_change_confirm *pFrm, + uint32_t *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + #endif /* DOT11F_H */ diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 4a3b40add9..7b76ba563e 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -485,6 +485,7 @@ typedef struct sPESession /* Added to Support BT-AMP */ uint8_t *access_policy_vendor_ie; uint8_t access_policy; bool ignore_assoc_disallowed; + bool send_p2p_conf_frame; bool process_ho_fail; } tPESession, *tpPESession; diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index a1162ec979..ba383a8bbf 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -3175,6 +3175,11 @@ void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *body) * the policy manager connection table needs to be updated. */ cds_update_connection_info(psessionEntry->smeSessionId); + if (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) { + lim_log(pMac, LOG1, + FL("Send p2p operating channel change conf action frame once first beacon is received on new channel")); + psessionEntry->send_p2p_conf_frame = true; + } break; case LIM_SWITCH_CHANNEL_SAP_DFS: { diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 2cd0f854db..9e4ba6c8cc 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -3548,6 +3548,162 @@ lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx, return eSIR_SUCCESS; } /* End lim_send_extended_chan_switch_action_frame */ + +/** + * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm + * sent over the air + * + * @mac_ctx: pointer to global mac + * @tx_complete : Sent status + * + * Return: This returns QDF_STATUS + */ + +static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf( + tpAniSirGlobal mac_ctx, + uint32_t tx_complete) +{ + lim_log(mac_ctx, LOG1, + FL(" tx_complete= %d"), tx_complete); + return QDF_STATUS_SUCCESS; +} + +/** + * lim_p2p_oper_chan_change_confirm_action_frame()- function to send + * p2p oper chan change confirm action frame + * @mac_ctx: pointer to global mac structure + * @peer: Destination mac. + * @session_entry: session entry + * + * This function is called to send p2p oper chan change confirm action frame. + * + * Return: success if frame is sent else return failure + */ + +tSirRetStatus +lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx, + tSirMacAddr peer, tpPESession session_entry) +{ + tDot11fp2p_oper_chan_change_confirm frm; + uint8_t *frame; + tpSirMacMgmtHdr mac_hdr; + uint32_t num_bytes, n_payload, status; + void *packet; + QDF_STATUS qdf_status; + uint8_t tx_flag = 0; + uint8_t sme_session_id = 0; + + if (session_entry == NULL) { + lim_log(mac_ctx, LOGE, FL("Session entry is NULL!!!")); + return eSIR_FAILURE; + } + + sme_session_id = session_entry->smeSessionId; + + qdf_mem_set(&frm, sizeof(frm), 0); + + frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY; + + qdf_mem_copy(frm.p2p_action_oui.oui_data, + SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE); + frm.p2p_action_subtype.subtype = 0x04; + frm.DialogToken.token = 0x0; + + if (session_entry->htCapability) { + lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request")); + populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps); + } + + if (session_entry->vhtCapability) { + lim_log(mac_ctx, LOG1, FL("Populate VHT Caps in Assoc Request")); + populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps); + populate_dot11f_operating_mode(mac_ctx, + &frm.OperatingMode, session_entry); + } + + status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx, + &frm, &n_payload); + if (DOT11F_FAILED(status)) { + lim_log(mac_ctx, LOGP, + FL("Failed to get packed size 0x%08x."), + status); + /* We'll fall back on the worst case scenario*/ + n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm); + } else if (DOT11F_WARNED(status)) { + lim_log(mac_ctx, LOGW, + FL("There were warnings while calculating the packed size (0x%08x)."), + status); + } + + num_bytes = n_payload + sizeof(tSirMacMgmtHdr); + + qdf_status = cds_packet_alloc((uint16_t)num_bytes, + (void **) &frame, (void **) &packet); + + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + lim_log(mac_ctx, LOGP, + FL("Failed to allocate %d bytes."), + num_bytes); + return eSIR_FAILURE; + } + + qdf_mem_set(frame, num_bytes, 0); + + /* Next, fill out the buffer descriptor */ + lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr); + mac_hdr = (tpSirMacMgmtHdr) frame; + qdf_mem_copy((uint8_t *) mac_hdr->bssId, + (uint8_t *) session_entry->bssId, + sizeof(tSirMacAddr)); + + status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm, + frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload); + if (DOT11F_FAILED(status)) { + lim_log(mac_ctx, LOGE, + FL("Failed to pack 0x%08x."), + status); + cds_packet_free((void *)packet); + return eSIR_FAILURE; + } else if (DOT11F_WARNED(status)) { + lim_log(mac_ctx, LOGW, + FL("There were warnings while packing 0x%08x."), + status); + } + + if ((SIR_BAND_5_GHZ == + lim_get_rf_band(session_entry->currentOperChannel)) || + (session_entry->pePersona == QDF_P2P_CLIENT_MODE) || + (session_entry->pePersona == QDF_P2P_GO_MODE)) { + tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + lim_log(mac_ctx, LOG1, FL("Send frame on channel %d to mac " + MAC_ADDRESS_STR), session_entry->currentOperChannel, + MAC_ADDR_ARRAY(peer)); + + MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + session_entry->peSessionId, mac_hdr->fc.subType)); + + qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet, + (uint16_t)num_bytes, + TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7, lim_tx_complete, frame, + lim_oper_chan_change_confirm_tx_complete_cnf, + tx_flag, sme_session_id, false, 0); + + MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + session_entry->peSessionId, qdf_status)); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + lim_log(mac_ctx, LOGE, + FL("Failed to send status %X!"), + qdf_status); + /* Pkt will be freed up by the callback */ + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + + tSirRetStatus lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac, tSirMacAddr peer, diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 533beda41c..71cd587ad1 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -509,6 +509,9 @@ tSirRetStatus lim_send_channel_switch_mgmt_frame(tpAniSirGlobal, tSirMacAddr, tSirRetStatus lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx, tSirMacAddr peer, uint8_t mode, uint8_t new_op_class, uint8_t new_channel, uint8_t count, tpPESession session_entry); +tSirRetStatus lim_p2p_oper_chan_change_confirm_action_frame( + tpAniSirGlobal mac_ctx, tSirMacAddr peer, + tpPESession session_entry); tSirRetStatus lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac, tSirMacAddr peer, uint8_t nMode, diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c index dee95530d8..111db50d97 100644 --- a/core/mac/src/pe/sch/sch_beacon_process.c +++ b/core/mac/src/pe/sch/sch_beacon_process.c @@ -856,6 +856,13 @@ static void __sch_beacon_process_for_session(tpAniSirGlobal mac_ctx, beaconParams.paramChangeBitmap);) lim_send_beacon_params(mac_ctx, &beaconParams, session); } + + if ((session->pePersona == QDF_P2P_CLIENT_MODE) && + session->send_p2p_conf_frame) { + lim_p2p_oper_chan_change_confirm_action_frame(mac_ctx, + session->bssId, session); + session->send_p2p_conf_frame = false; + } } /** diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c index 5461e6b4df..a6cefb74d0 100644 --- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c +++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c @@ -33,7 +33,7 @@ * * * This file was automatically generated by 'framesc' - * Thu Oct 6 17:32:00 2016 from the following file(s): + * Thu Nov 3 15:54:51 2016 from the following file(s): * * dot11f.frms * @@ -782,6 +782,26 @@ void dot11f_unpack_ff_ext_chan_switch_ann_action(tpAniSirGlobal pCtx, #define SigFfext_chan_switch_ann_action (0x001f) +void dot11f_unpack_ff_p2p_action_oui(tpAniSirGlobal pCtx, + uint8_t *pBuf, + tDot11fFfp2p_action_oui *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->oui_data, pBuf, 4); + (void)pCtx; +} /* End dot11f_unpack_ff_p2p_action_oui. */ + +#define SigFfp2p_action_oui (0x0020) + +void dot11f_unpack_ff_p2p_action_subtype(tpAniSirGlobal pCtx, + uint8_t *pBuf, + tDot11fFfp2p_action_subtype *pDst) +{ + pDst->subtype = *pBuf; + (void)pCtx; +} /* End dot11f_unpack_ff_p2p_action_subtype. */ + +#define SigFfp2p_action_subtype (0x0021) + uint32_t dot11f_unpack_tlv_authorized_ma_cs(tpAniSirGlobal pCtx, uint8_t *pBuf, uint16_t tlvlen, @@ -8845,6 +8865,47 @@ uint32_t dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal p } /* End dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame. */ +static const tFFDefn FFS_p2p_oper_chan_change_confirm[] = { + { "Category", offsetof(tDot11fp2p_oper_chan_change_confirm, Category), + SigFfCategory, DOT11F_FF_CATEGORY_LEN, }, + { "p2p_action_oui", offsetof(tDot11fp2p_oper_chan_change_confirm, + p2p_action_oui), SigFfp2p_action_oui, DOT11F_FF_P2P_ACTION_OUI_LEN, }, + { "p2p_action_subtype", offsetof(tDot11fp2p_oper_chan_change_confirm, + p2p_action_subtype), SigFfp2p_action_subtype, + DOT11F_FF_P2P_ACTION_SUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fp2p_oper_chan_change_confirm, + DialogToken), SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, +}; + +static const tIEDefn IES_p2p_oper_chan_change_confirm[] = { + { offsetof(tDot11fp2p_oper_chan_change_confirm, HTCaps), + offsetof(tDot11fIEHTCaps, present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + { offsetof(tDot11fp2p_oper_chan_change_confirm, VHTCaps), + offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + { offsetof(tDot11fp2p_oper_chan_change_confirm, OperatingMode), + offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode", + 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_OPERATINGMODE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; + +uint32_t dot11f_unpack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx, + uint8_t *pBuf, uint32_t nBuf, + tDot11fp2p_oper_chan_change_confirm *pFrm) +{ + uint32_t i = 0; + uint32_t status = 0; + status = unpack_core(pCtx, pBuf, nBuf, + FFS_p2p_oper_chan_change_confirm, IES_p2p_oper_chan_change_confirm, + (uint8_t *)pFrm, sizeof(*pFrm)); + + (void)i; + return status; + +} /* End dot11f_unpack_p2p_oper_chan_change_confirm. */ + static uint32_t unpack_core(tpAniSirGlobal pCtx, uint8_t *pBuf, uint32_t nBuf, @@ -9047,6 +9108,16 @@ static uint32_t unpack_core(tpAniSirGlobal pCtx, pBufRemaining, (tDot11fFfext_chan_switch_ann_action *) (pFrm + pFf->offset)); break; + case SigFfp2p_action_oui: + dot11f_unpack_ff_p2p_action_oui(pCtx, + pBufRemaining, (tDot11fFfp2p_action_oui *) + (pFrm + pFf->offset)); + break; + case SigFfp2p_action_subtype: + dot11f_unpack_ff_p2p_action_subtype(pCtx, + pBufRemaining, (tDot11fFfp2p_action_subtype *) + (pFrm + pFf->offset)); + break; default: FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I don'" "t know about the FF signature %d-- this is most " @@ -11941,6 +12012,16 @@ uint32_t dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize(tpAniSir return status; } /* End dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize. */ +uint32_t dot11f_get_packed_p2p_oper_chan_change_confirmSize(tpAniSirGlobal pCtx, + tDot11fp2p_oper_chan_change_confirm *pFrm, uint32_t *pnNeeded) +{ + uint32_t status = 0; + *pnNeeded = 7; + status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded, + IES_p2p_oper_chan_change_confirm); + return status; +} /* End dot11f_get_packed_p2p_oper_chan_change_confirmSize. */ + static uint32_t get_packed_size_core(tpAniSirGlobal pCtx, uint8_t *pFrm, uint32_t *pnNeeded, @@ -13495,6 +13576,22 @@ void dot11f_pack_ff_ext_chan_switch_ann_action(tpAniSirGlobal pCtx, (void)pCtx; } /* End dot11f_pack_ff_ext_chan_switch_ann_action. */ +void dot11f_pack_ff_p2p_action_oui(tpAniSirGlobal pCtx, + tDot11fFfp2p_action_oui *pSrc, + uint8_t *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui_data, 4); + (void)pCtx; +} /* End dot11f_pack_ff_p2p_action_oui. */ + +void dot11f_pack_ff_p2p_action_subtype(tpAniSirGlobal pCtx, + tDot11fFfp2p_action_subtype *pSrc, + uint8_t *pBuf) +{ + *pBuf = pSrc->subtype; + (void)pCtx; +} /* End dot11f_pack_ff_p2p_action_subtype. */ + uint32_t dot11f_pack_tlv_authorized_ma_cs(tpAniSirGlobal pCtx, tDot11fTLVAuthorizedMACs *pSrc, uint8_t *pBuf, @@ -21169,6 +21266,21 @@ uint32_t dot11f_pack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCt } /* End dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame. */ +uint32_t dot11f_pack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx, + tDot11fp2p_oper_chan_change_confirm *pFrm, + uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed) +{ + uint32_t i = 0; + uint32_t status = 0; + (void)i; + *pnConsumed = 0U; + status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed, + FFS_p2p_oper_chan_change_confirm, IES_p2p_oper_chan_change_confirm); + + return status; + +} /* End dot11f_unpack_p2p_oper_chan_change_confirm. */ + static uint32_t pack_core(tpAniSirGlobal pCtx, uint8_t *pSrc, uint8_t *pBuf, @@ -21359,6 +21471,16 @@ static uint32_t pack_core(tpAniSirGlobal pCtx, pCtx, (tDot11fFfext_chan_switch_ann_action *) (pSrc + pFf->offset), pBufRemaining); break; + case SigFfp2p_action_oui: + dot11f_pack_ff_p2p_action_oui( + pCtx, (tDot11fFfp2p_action_oui *) + (pSrc + pFf->offset), pBufRemaining); + break; + case SigFfp2p_action_subtype: + dot11f_pack_ff_p2p_action_subtype( + pCtx, (tDot11fFfp2p_action_subtype *) + (pSrc + pFf->offset), pBufRemaining); + break; default: FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" "'t know about the Fixed Field %d; this is most l"