qcacmn: iot_sim beacon content change update

Adding support for beacon content change.

Change-Id: I8f804dd7d2cbbe7d3b7dea58841d7321f28101c7
CRs-Fixed: 2694454
This commit is contained in:
nakul kachhwaha
2020-06-02 12:45:10 +05:30
committed by nshrivas
parent c5cdd1eaaf
commit 89a67f807e
10 changed files with 232 additions and 24 deletions

View File

@@ -89,7 +89,7 @@ QDF_STATUS iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat,
* iot_sim_frame_update() - Management frame update
* @pdev: reference to global pdev object
* @nbuf: frame buffer
* @direction: direction tx or rx
* @tx: TRUE in case of tx
*
* This function updates the outgoing management frame with
* the content stored in iot_sim_context.
@@ -98,7 +98,9 @@ QDF_STATUS iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat,
* QDF_STATUS_E_FAILURE on failure
*/
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev,
qdf_nbuf_t nbuf, bool direction);
qdf_nbuf_t nbuf,
struct beacon_tmpl_params *param,
bool tx);
/*
* iot_sim_get_ctx_from_pdev() - API to get iot_sim context object

View File

@@ -22,6 +22,7 @@
#include <qdf_util.h>
#include <qdf_str.h>
#include <wmi_unified_param.h>
#include <wlan_iot_sim_utils_api.h>
/*
* iot_sim_oper_to_str - function to return iot sim operation string
@@ -580,6 +581,11 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
{
struct simulation_test_params param;
if (FRAME_TYPE_IS_BEACON(type, subtype) && offset) {
iot_sim_info("Beacon update from offset:%d", offset);
return QDF_STATUS_E_NOSUPPORT;
}
if (iot_sim_frame_supported_by_fw(type, subtype, action)) {
qdf_mem_zero(&param, sizeof(struct simulation_test_params));
param.pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj);
@@ -608,8 +614,10 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
&param)))
iot_sim_err("Sending del rule to fw failed!");
if (!FRAME_TYPE_IS_BEACON(type, subtype))
return QDF_STATUS_SUCCESS;
if (FRAME_TYPE_IS_BEACON(type, subtype) && clear)
return QDF_STATUS_E_NOSUPPORT;
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_E_NOSUPPORT;
@@ -889,6 +897,7 @@ iot_sim_debug_content_change_write(struct file *file,
((struct seq_file *)file->private_data)->private;
uint8_t action = 0, category = 0;
bool is_action = 0, clear = false;
mlme_pdev_ext_t *ext = NULL;
if ((!buf) || (count > USER_BUF_LEN) || (count < 7))
return -EFAULT;
@@ -947,11 +956,24 @@ iot_sim_debug_content_change_write(struct file *file,
content, length, 0,
is_action);
}
if (QDF_IS_STATUS_SUCCESS(status))
if (QDF_IS_STATUS_SUCCESS(status)) {
iot_sim_err("iot_sim: Content Change Operation - success");
else
if (FRAME_TYPE_IS_BEACON(type, subtype)) {
if (isc->bcn_buf && (!length || !content)) {
qdf_nbuf_free(isc->bcn_buf);
isc->bcn_buf = NULL;
}
ext = wlan_pdev_mlme_get_ext_hdl(isc->pdev_obj);
if (ext) {
isc->iot_sim_update_beacon_trigger(ext);
iot_sim_info("Beacon update triggered");
} else {
iot_sim_err("mlme_pdev_ext is null");
}
}
} else {
iot_sim_err("iot_sim: Content Change Operation - Fail");
}
free:
qdf_mem_free(content);
qdf_mem_free(locbuf);
@@ -1366,6 +1388,7 @@ wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
qdf_set_macaddr_broadcast(&isc->bcast_peer.addr);
qdf_spinlock_create(&isc->bcast_peer.iot_sim_lock);
qdf_list_create(&isc->bcast_peer.list, 0);
isc->bcn_buf = NULL;
wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_IOT_SIM_COMP,
(void *)isc, QDF_STATUS_SUCCESS);
@@ -1396,11 +1419,14 @@ wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
/* Deinitilise function pointers from iot_sim context */
iot_sim_debugfs_deinit(isc);
iot_sim_remove_all_rules(isc);
if (isc->bcn_buf)
qdf_nbuf_free(isc->bcn_buf);
qdf_spinlock_destroy(&isc->bcast_peer.iot_sim_lock);
qdf_mem_free(isc);
}
iot_sim_debug("iot_sim component pdev%u object created",
iot_sim_debug("iot_sim component pdev%u object destroyed",
wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj));
return QDF_STATUS_SUCCESS;
}

View File

@@ -153,6 +153,8 @@ struct iot_sim_context {
/* IOT_SIM Peer list & Bcast Peer */
struct iot_sim_rule_per_peer *iot_sim_peer_list, bcast_peer;
struct iot_sim_debugfs iot_sim_dbgfs_ctx;
void (*iot_sim_update_beacon_trigger)(mlme_pdev_ext_t *);
qdf_nbuf_t bcn_buf;
};
/* enum iot_sim_operations - iot sim operations

View File

@@ -21,6 +21,7 @@
#include <wlan_objmgr_vdev_obj.h>
#define IEEE80211_FRAME_BODY_OFFSET 0x18
#define IEEE80211_TSF_LEN (8)
/*
* iot_sim_apply_content_change_rule - function to apply content change rule
@@ -34,13 +35,125 @@
* QDF_STATUS_E_NOSUPPORT, no content change rule found for this frame
*/
QDF_STATUS
iot_sim_apply_content_change_rule(struct iot_sim_rule *piot_sim_rule,
iot_sim_update_beacon_template_struct(qdf_nbuf_t nbuf,
struct beacon_tmpl_params *param)
{
struct ie_header *ie = NULL;
uint16_t offset = 0, ie_len = 0;
struct ieee80211_ath_channelswitch_ie *csa = NULL;
struct ieee80211_extendedchannelswitch_ie *ecsa = NULL;
struct extn_ie_header *extn_ie = NULL;
if (!param)
return QDF_STATUS_E_NULL_VALUE;
/**
* Skip fixed field
*/
offset += IEEE80211_TSF_LEN; /* TSF field */
offset += 2; /* Beacon interval */
offset += 2; /* Capability Information */
ie_len = wbuf_get_pktlen(nbuf) -
sizeof(struct ieee80211_frame) - offset;
ie = (struct ie_header *)((uint8_t *)qdf_nbuf_data(nbuf) +
sizeof(struct ieee80211_frame) + offset);
while (ie_len >= sizeof(struct ie_header)) {
ie_len -= sizeof(struct ie_header);
if (!ie->ie_len) {
ie += 1;
continue;
}
if (ie_len < ie->ie_len) {
iot_sim_err("Incomplete corrupted IE:%x", ie->ie_id);
return QDF_STATUS_E_INVAL;
}
switch (ie->ie_id) {
case WLAN_ELEMID_TIM:
if (ie->ie_len < WLAN_TIM_IE_MIN_LENGTH) {
iot_sim_err("Invalid TIM IE Length");
goto err;
}
param->tim_ie_offset = ((uint8_t *)ie -
(uint8_t *)qdf_nbuf_data(nbuf));
break;
case WLAN_ELEMID_CHANSWITCHANN:
if (ie->ie_len != WLAN_CSA_IE_MAX_LEN) {
iot_sim_err("Invalid CSA IE Length");
goto err;
}
csa =
(struct ieee80211_ath_channelswitch_ie *)ie;
param->csa_switch_count_offset =
(((uint8_t *)&csa->tbttcount) -
(uint8_t *)qdf_nbuf_data(nbuf));
break;
case WLAN_ELEMID_EXTCHANSWITCHANN:
if (ie->ie_len != WLAN_XCSA_IE_MAX_LEN) {
iot_sim_err("Invalid ECSA IE Length");
goto err;
}
ecsa =
(struct ieee80211_extendedchannelswitch_ie *)ie;
param->ext_csa_switch_count_offset =
(((uint8_t *)&ecsa->tbttcount) -
(uint8_t *)qdf_nbuf_data(nbuf));
break;
case WLAN_ELEMID_EXTN_ELEM:
extn_ie = (struct extn_ie_header *)ie;
switch (extn_ie->ie_extn_id) {
case WLAN_EXTN_ELEMID_ESP:
param->esp_ie_offset =
((uint8_t *)ie -
(uint8_t *)qdf_nbuf_data(nbuf));
break;
case WLAN_EXTN_ELEMID_MUEDCA:
param->mu_edca_ie_offset =
((uint8_t *)ie -
(uint8_t *)qdf_nbuf_data(nbuf));
break;
default:
break;
}
break;
case WLAN_ELEMID_MULTIPLE_BSSID:
offset = ((uint8_t *)ie -
(uint8_t *)qdf_nbuf_data(nbuf));
param->mbssid_ie_offset = offset;
break;
default:
break;
}
/* Consume info element */
ie_len -= ie->ie_len;
/* Go to next IE */
ie = (struct ie_header *)((uint8_t *)ie +
sizeof(struct ie_header) +
ie->ie_len);
}
param->tmpl_len = wbuf_get_pktlen(nbuf);
param->tmpl_len_aligned = roundup(param->tmpl_len,
sizeof(uint32_t));
param->frm = (uint8_t *)qdf_nbuf_data(nbuf);
return QDF_STATUS_SUCCESS;
err:
return QDF_STATUS_E_INVAL;
}
QDF_STATUS
iot_sim_apply_content_change_rule(struct wlan_objmgr_pdev *pdev,
struct iot_sim_rule *piot_sim_rule,
qdf_nbuf_t nbuf,
int fixed_param_length)
int fixed_param_length,
struct beacon_tmpl_params *param)
{
uint8_t *buf = NULL;
qdf_size_t buf_len = 0;
int offset = 0;
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!piot_sim_rule->frm_content || !piot_sim_rule->len)
return QDF_STATUS_E_NOSUPPORT;
@@ -76,6 +189,11 @@ iot_sim_apply_content_change_rule(struct iot_sim_rule *piot_sim_rule,
iot_sim_err("Failed to modify content");
}
if (IEEE80211_IS_BEACON((struct ieee80211_frame *)qdf_nbuf_data(nbuf)))
status = iot_sim_update_beacon_template_struct(nbuf, param);
if (QDF_IS_STATUS_ERROR(status))
iot_sim_err("Failed to update beacon param");
return QDF_STATUS_SUCCESS;
}
@@ -113,18 +231,20 @@ iot_sim_apply_drop_rule(struct iot_sim_rule *piot_sim_rule,
*
* @pdev: pdev object
* @nbuf: input packet
* @direction: direction to specify from where this packet is arrived
* @param: beacon template cmd parameter
* @tx: tx or not
*
* Return: QDF_STATUS_SUCCESS in general
* QDF_STATUS_E_NOSUPPORT, no content change rule found for this frame
*/
QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
struct beacon_tmpl_params *param,
bool tx)
{
uint8_t type, subtype, seq = 0;
struct iot_sim_context *isc;
uint8_t *buf = qdf_nbuf_data(nbuf), *frm = NULL;
int fixed_param_length = 0;
int fixed_param_len = 0;
bool is_action_frm = false;
uint8_t cat, cat_index;
int auth_seq_index = 0;
@@ -146,14 +266,15 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
auth_seq_index = IEEE80211_FRAME_BODY_OFFSET + 2;
seq = le16toh(*(u_int16_t *)(buf + auth_seq_index));
} else if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
(subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP ||
subtype == IEEE80211_FC0_SUBTYPE_BEACON))
/* Probe response frame */
fixed_param_length = 12;
fixed_param_len = 12;
else if (type == IEEE80211_FC0_TYPE_MGT &&
(subtype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP ||
subtype == IEEE80211_FC0_SUBTYPE_REASSOC_RESP))
/* Assoc/Reassoc response frame */
fixed_param_length = 6;
fixed_param_len = 6;
else if (type == IEEE80211_FC0_TYPE_MGT &&
subtype == IEEE80211_FC0_SUBTYPE_ACTION) {
/* Action frame */
@@ -171,10 +292,12 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
type, subtype, seq, is_action_frm,
tx ? "TX" : "RX");
/* Only broadcast peer is getting handled right now.
/**
* Only broadcast peer is getting handled right now.
* Need to add support for peer based content modification
*/
qdf_spin_lock(&isc->bcast_peer.iot_sim_lock);
if (!isc->bcast_peer.rule_per_seq[seq])
goto norule;
@@ -189,9 +312,26 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
goto norule;
if (tx) {
status = iot_sim_apply_content_change_rule(piot_sim_rule,
nbuf,
fixed_param_length);
if (IEEE80211_IS_BEACON((struct ieee80211_frame *)
qdf_nbuf_data(nbuf))) {
if (isc->bcn_buf)
qdf_nbuf_free(isc->bcn_buf);
isc->bcn_buf = qdf_nbuf_copy(nbuf);
status =
iot_sim_apply_content_change_rule(pdev,
piot_sim_rule,
isc->bcn_buf,
fixed_param_len,
param);
} else {
status =
iot_sim_apply_content_change_rule(pdev,
piot_sim_rule,
nbuf,
fixed_param_len,
param);
}
if (status == QDF_STATUS_E_NOSUPPORT)
goto norule;
} else {

View File

@@ -20,10 +20,20 @@
#include <wlan_objmgr_cmn.h>
#include <wlan_lmac_if_def.h>
#include <wmi_unified_param.h>
#include "include/wlan_pdev_mlme.h"
#include "wlan_pdev_mlme_api.h"
/* Forward Declarations */
struct wmi_iot_sim_cmd_ops;
/**
* struct iot_sim_cbacks - IOT Sim callbacks
* @reg_beacon_trigger_handler: reg_beacon_trigger_handler
*/
struct iot_sim_cbacks {
void (*update_beacon_trigger)(mlme_pdev_ext_t *);
};
/**
* iot_sim_cmd_handler() - IOT SIM frame handler function
* @vdev - vdev object.
@@ -33,7 +43,7 @@ struct wmi_iot_sim_cmd_ops;
* Return : QDF_STATUS_E_SUCCESS/QDF_STATUS_E_FAILURE.
*/
QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t buf,
bool tx);
struct beacon_tmpl_params *param, bool tx);
/**
* wlan_iot_sim_init() - API to init iot_sim component

View File

@@ -24,11 +24,25 @@
#define IEEE80211_FRAME_BODY_OFFSET 0x18
QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t nbuf,
bool tx)
struct beacon_tmpl_params *param, bool tx)
{
struct wlan_objmgr_pdev *pdev = vdev->vdev_objmgr.wlan_pdev;
return iot_sim_frame_update(pdev, nbuf, tx);
return iot_sim_frame_update(pdev, nbuf, param, tx);
}
QDF_STATUS iot_sim_register_callbacks(struct wlan_objmgr_pdev *pdev,
struct iot_sim_cbacks *cb)
{
struct iot_sim_context *isc = NULL;
isc = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_IOT_SIM_COMP);
if (!isc)
return QDF_STATUS_E_NULL_VALUE;
isc->iot_sim_update_beacon_trigger = cb->update_beacon_trigger;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
@@ -79,4 +93,6 @@ void wlan_lmac_if_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
&rx_ops->iot_sim_rx_ops;
iot_sim_ops->iot_sim_cmd_handler = iot_sim_cmd_handler;
iot_sim_ops->iot_sim_register_cb = iot_sim_register_callbacks;
}

View File

@@ -193,6 +193,7 @@ QDF_STATUS iot_sim_mgmt_tx_update(struct wlan_objmgr_psoc *psoc,
if (rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler) {
status = rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler(vdev,
buf,
NULL,
true);
if (QDF_IS_STATUS_ERROR(status))
mgmt_txrx_err("iot_sim_cmd_handler returned failure");

View File

@@ -945,7 +945,8 @@ static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
dbgid);
if (vdev) {
status = rx_ops->iot_sim_rx_ops.
iot_sim_cmd_handler(vdev, buf, false);
iot_sim_cmd_handler(vdev, buf,
NULL, false);
if (status == QDF_STATUS_E_NULL_VALUE) {
wlan_objmgr_vdev_release_ref(vdev, dbgid);
mgmt_txrx_debug("iot_sim:Pkt processed at RX");

View File

@@ -428,6 +428,7 @@ QDF_STATUS wlan_objmgr_register_vdev_create_handler(
qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(wlan_objmgr_register_vdev_create_handler);
QDF_STATUS wlan_objmgr_unregister_vdev_create_handler(
enum wlan_umac_comp_id id,
@@ -454,6 +455,7 @@ QDF_STATUS wlan_objmgr_unregister_vdev_create_handler(
qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(wlan_objmgr_unregister_vdev_create_handler);
QDF_STATUS wlan_objmgr_register_vdev_destroy_handler(
enum wlan_umac_comp_id id,
@@ -480,6 +482,7 @@ QDF_STATUS wlan_objmgr_register_vdev_destroy_handler(
qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(wlan_objmgr_register_vdev_destroy_handler);
QDF_STATUS wlan_objmgr_unregister_vdev_destroy_handler(
enum wlan_umac_comp_id id,
@@ -506,6 +509,7 @@ QDF_STATUS wlan_objmgr_unregister_vdev_destroy_handler(
qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(wlan_objmgr_unregister_vdev_destroy_handler);
QDF_STATUS wlan_objmgr_register_vdev_status_handler(
enum wlan_umac_comp_id id,

View File

@@ -1418,13 +1418,19 @@ struct wlan_lmac_if_sptrl_rx_ops {
#endif /* WLAN_CONV_SPECTRAL_ENABLE */
#ifdef WLAN_IOT_SIM_SUPPORT
struct iot_sim_cbacks;
/**
* wlan_lmac_if_iot_sim_rx_ops: iot_sim rx operations
* iot_sim_cmd_handler: Applies iot_sim rule in outgoing and incoming frames
* iot_sim_register_cb: callback registration with iot_sim
**/
struct wlan_lmac_if_iot_sim_rx_ops {
QDF_STATUS (*iot_sim_cmd_handler)(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t n_buf, bool tx);
qdf_nbuf_t n_buf,
struct beacon_tmpl_params *param,
bool tx);
QDF_STATUS (*iot_sim_register_cb)(struct wlan_objmgr_pdev *pdev,
struct iot_sim_cbacks *cb);
};
#endif