qcacmn: Add basic infra for connection manager UTF
Add basic infra for connection manager UTF Change-Id: Id111a4bcda970e927b73441be55de4d33a694796
This commit is contained in:
@@ -44,6 +44,11 @@
|
||||
#else
|
||||
#define CFG_CFR_ALL
|
||||
#endif
|
||||
#ifdef FEATURE_CM_UTF_ENABLE
|
||||
#include <wlan_cm_utf.h>
|
||||
#else
|
||||
#define CFG_WLAN_CM_UTF_PARAM
|
||||
#endif
|
||||
|
||||
#define CFG_CONVERGED_ALL \
|
||||
CFG_SCAN_ALL \
|
||||
@@ -54,7 +59,8 @@
|
||||
CFG_HIF \
|
||||
CFG_DCS_ALL \
|
||||
CFG_CFR_ALL \
|
||||
CFG_MLME_SCORE_ALL
|
||||
CFG_MLME_SCORE_ALL \
|
||||
CFG_WLAN_CM_UTF_PARAM
|
||||
|
||||
#endif /* __CFG_CONVERGED_H */
|
||||
|
||||
|
@@ -37,6 +37,7 @@ INCS += -I$(obj)/$(DEPTH)/pld/inc
|
||||
INCS += -I$(obj)/$(DEPTH)/component_dev/dp/inc
|
||||
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/mlme/connection_mgr/dispatcher/inc
|
||||
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/thermal/dispatcher/inc
|
||||
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/mlme/connection_mgr/utf/inc
|
||||
|
||||
ifeq ($(WLAN_CONV_CRYPTO_SUPPORTED), 1)
|
||||
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/crypto/inc
|
||||
|
277
umac/mlme/connection_mgr/utf/inc/wlan_cm_utf.h
Normal file
277
umac/mlme/connection_mgr/utf/inc/wlan_cm_utf.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOC: Implements CM UTF
|
||||
*/
|
||||
|
||||
#ifndef WLAN_CM_UTF_H
|
||||
#define WLAN_CM_UTF_H
|
||||
|
||||
#include <qdf_debugfs.h>
|
||||
#include <qdf_mem.h>
|
||||
#include <qdf_trace.h>
|
||||
#include <qdf_module.h>
|
||||
#include <qdf_event.h>
|
||||
#include <qdf_defer.h>
|
||||
#include <wlan_cm_public_struct.h>
|
||||
#include <wlan_mgmt_txrx_utils_api.h>
|
||||
#include <wlan_reg_services_api.h>
|
||||
#include <wlan_scan_tgt_api.h>
|
||||
#include <wlan_cfg80211.h>
|
||||
|
||||
#define NUM_UTF_DEBUGFS_INFOS 2
|
||||
|
||||
/*
|
||||
* <ini>
|
||||
* wlan_cm_utf - WLAN CM UTF Configuration
|
||||
* @Min: 0
|
||||
* @Max: 1
|
||||
* @Default: 0
|
||||
*
|
||||
* This ini is used to config wlan cm utf
|
||||
*
|
||||
* Related: None
|
||||
*
|
||||
* Usage: External
|
||||
*
|
||||
* </ini>
|
||||
*/
|
||||
#define CFG_WLAN_CM_UTF CFG_INI_UINT( \
|
||||
"wlan_cm_utf", \
|
||||
0, \
|
||||
1, \
|
||||
0, \
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"WLAN CM UTF Configuration")
|
||||
|
||||
#define CFG_WLAN_CM_UTF_PARAM CFG(CFG_WLAN_CM_UTF)
|
||||
/**
|
||||
* enum wlan_cm_utf_test - CM UTF Test ID
|
||||
* @CM_UTF_ID_CONNECT_SUCCESS: Connect Succes
|
||||
* @CM_UTF_ID_DISCONNECT_SUCCESS: Disconnect Success
|
||||
* @CM_UTF_ID_PEER_CREATE_FAILURE: Peer Create Failure
|
||||
* @CM_UTF_ID_PEER_CREATE_TIMEOUT: No Peer Create Response
|
||||
* @CM_UTF_ID_PEER_DELETE_TIMEOUT: No Peer Delete Response
|
||||
* @CM_UTF_ID_AUTH_FAILURE: Auth Req Failure
|
||||
* @CM_UTF_ID_AUTH_TIMEOUT: No Auth Response
|
||||
* @CM_UTF_ID_ASSOC_FAILURE: Assoc Req Failure
|
||||
* @CM_UTF_ID_ASSOC_TIMEOUT: No Assoc Response
|
||||
* @CM_UTF_ID_CONNECT_SCAN_FAILURE: SSID Not Found
|
||||
* @CM_UTF_ID_CONNECT_SER_TIMEOUT: Serialization Active Cmd Timeout for Connect
|
||||
* @CM_UTF_ID_DISCONNECT_SER_TIMEOUT: Ser Active Cmd Timeout for Disconnect
|
||||
* @CM_UTF_ID_CONNECT_SER_FAILED: Serialization Cmd Queue Failure for Connect
|
||||
* @CM_UTF_ID_DISCONNECT_SER_FAILED: Ser Cmd Queue Failure for Disconnect
|
||||
*/
|
||||
enum wlan_cm_utf_test {
|
||||
CM_UTF_ID_CONNECT_SUCCESS,
|
||||
CM_UTF_ID_DISCONNECT_SUCCESS,
|
||||
CM_UTF_ID_PEER_CREATE_FAILURE,
|
||||
CM_UTF_ID_PEER_CREATE_TIMEOUT,
|
||||
CM_UTF_ID_PEER_DELETE_TIMEOUT,
|
||||
CM_UTF_ID_AUTH_FAILURE,
|
||||
CM_UTF_ID_AUTH_TIMEOUT,
|
||||
CM_UTF_ID_ASSOC_FAILURE,
|
||||
CM_UTF_ID_ASSOC_TIMEOUT,
|
||||
CM_UTF_ID_CONNECT_SCAN_FAILURE,
|
||||
CM_UTF_ID_CONNECT_SER_TIMEOUT,
|
||||
CM_UTF_ID_DISCONNECT_SER_TIMEOUT,
|
||||
CM_UTF_ID_CONNECT_SER_FAILED,//Need ser utf
|
||||
CM_UTF_ID_DISCONNECT_SER_FAILED,//Need ser utf
|
||||
CM_UTF_ID_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum wlan_cm_utf_evt - CM UTF Resp event
|
||||
* @CM_UTF_BSS_PEER_CREATE_RESP: Peer Create Response
|
||||
* @CM_UTF_BSS_PEER_DELETE_RESP: Peer Delete Response
|
||||
* @CM_UTF_CONNECT_RESP: Connect Response
|
||||
* @CM_UTF_DISCONNECT_RESP: Disconnect Response
|
||||
* @CM_UTF_PEER_DELETE_IND: Peer Delete Indication
|
||||
*/
|
||||
enum wlan_cm_utf_evt {
|
||||
CM_UTF_BSS_PEER_CREATE_RESP,
|
||||
CM_UTF_BSS_PEER_DELETE_RESP,
|
||||
CM_UTF_CONNECT_RESP,
|
||||
CM_UTF_DISCONNECT_RESP,
|
||||
CM_UTF_PEER_DELETE_IND,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_cm_utf_node- CM UTF node to hold CM req info
|
||||
* @wlan_cm_utf_evt: CM UTF Resp event
|
||||
* @peer_mac: Peer Mac
|
||||
* @conn_req: Connect Request
|
||||
* @disconn_req: Disconnect Request
|
||||
*/
|
||||
struct wlan_cm_utf_node {
|
||||
enum wlan_cm_utf_evt evt_id;
|
||||
struct qdf_mac_addr *peer_mac;
|
||||
struct wlan_cm_vdev_connect_req conn_req;
|
||||
struct wlan_cm_vdev_discon_req disconn_req;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_cm_utf- CM UTF handle
|
||||
* @vdev: Vdev object
|
||||
* @debugfs_de: debugfs entry
|
||||
* @test_id: Test case Id
|
||||
* @req: cfg80211 connect request params
|
||||
* @cm_utf_timer: CM UTF timer
|
||||
* @cm_utf_test_timer: CM UTF timer for each test
|
||||
* @utf_node: CM UTF node to hold CM req info
|
||||
* @cm_utf_work: CM UTF work queue for processing events
|
||||
*/
|
||||
struct wlan_cm_utf {
|
||||
qdf_list_node_t cm_utf_node;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct dentry *debugfs_de[NUM_UTF_DEBUGFS_INFOS];
|
||||
enum wlan_cm_utf_test test_id;
|
||||
struct wlan_cm_connect_req req;
|
||||
qdf_timer_t cm_utf_timer;
|
||||
qdf_timer_t cm_utf_test_timer;
|
||||
struct wlan_cm_utf_node utf_node;
|
||||
uint32_t last_cmd_id;
|
||||
enum wlan_cm_source last_cmd_source;
|
||||
qdf_work_t cm_utf_work;
|
||||
};
|
||||
|
||||
/*
|
||||
* Debugfs read/write functions
|
||||
*/
|
||||
/**
|
||||
* wlan_cm_utf_cm_test_id_show() - debugfs function to display CM test case name
|
||||
* @m: seq_file handle
|
||||
* @v: not used, offset of read
|
||||
*/
|
||||
int wlan_cm_utf_cm_test_id_show(qdf_debugfs_file_t m, void *v);
|
||||
|
||||
int wlan_cm_utf_scan_db_update_show(qdf_debugfs_file_t m, void *v);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_cm_test_id_write() - debugfs write to start CM UTF test
|
||||
*
|
||||
* @file: file handler to access cm utf handle
|
||||
* @buf: received data buffer
|
||||
* @count: length of received buffer
|
||||
* @ppos: Not used
|
||||
*
|
||||
* Return: count
|
||||
*/
|
||||
ssize_t wlan_cm_utf_cm_test_id_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_scan_db_update_write() - debugfs write to add manual scan entry
|
||||
*
|
||||
* @file: file handler to access cm utf handle
|
||||
* @buf: received data buffer
|
||||
* @count: length of received buffer
|
||||
* @ppos: Not used
|
||||
*
|
||||
* Return: count
|
||||
*/
|
||||
ssize_t wlan_cm_utf_scan_db_update_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_attach: Connection manager UTF init API
|
||||
* @vdev: Vdev object
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_attach(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_detach: Connection manager UTF deinit API
|
||||
* @vdev: Vdev object
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
void wlan_cm_utf_detach(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_bss_peer_create_req: Connection manager UTF bss peer
|
||||
* create request handler
|
||||
* @vdev: VDEV object
|
||||
* @peer_mac: Peer mac address
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_bss_peer_create_req(struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr *peer_mac);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_connect_req_active: Connection manager UTF handler when connect
|
||||
* request is activated
|
||||
* @vdev: VDEV object
|
||||
* @vdev_connect_req: Vdev connect request
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_connect_req_active(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_vdev_connect_req *vdev_connect_req);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_connect_req: Connection manager UTF connect request handler
|
||||
* @vdev: VDEV object
|
||||
* @vdev_connect_req: Vdev connect request
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_connect_req(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_vdev_connect_req *vdev_connect_req);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_disconnect_req: Connection manager UTF disconnect
|
||||
* request handler
|
||||
* @vdev: VDEV object
|
||||
* @vdev_connect_req: Vdev connect request
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_disconnect_req(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_vdev_discon_req *vdev_disconnect_req);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_bss_peer_delete_req: Connection manager UTF bss peer
|
||||
* delete request handler
|
||||
* @vdev: VDEV object
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_bss_peer_delete_req(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_cm_utf_vdev_down: Connection manager UTF vdev down request handler
|
||||
* @vdev: VDEV object
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_utf_vdev_down(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* osif_cm_utf_register_cb() - API to register connection manager callbacks
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS osif_cm_utf_register_cb(void);
|
||||
#endif //WLAN_CM_UTF_H
|
1032
umac/mlme/connection_mgr/utf/src/wlan_cm_utf_main.c
Normal file
1032
umac/mlme/connection_mgr/utf/src/wlan_cm_utf_main.c
Normal file
File diff suppressed because it is too large
Load Diff
166
umac/mlme/connection_mgr/utf/src/wlan_cm_utf_scan.c
Normal file
166
umac/mlme/connection_mgr/utf/src/wlan_cm_utf_scan.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOC: Implements scan functinality for CM UTF
|
||||
*/
|
||||
|
||||
#ifdef FEATURE_CM_UTF_ENABLE
|
||||
#include <wlan_cm_utf.h>
|
||||
#include <qdf_str.h>
|
||||
|
||||
struct wlan_cm_utf_raw_bcn {
|
||||
uint32_t channel_number;
|
||||
int32_t rssi;
|
||||
uint8_t band;
|
||||
uint8_t bssid[QDF_MAC_ADDR_SIZE];
|
||||
uint8_t ssid[WLAN_SSID_MAX_LEN];
|
||||
};
|
||||
|
||||
static void wlan_cm_utf_scan_db_update(struct wlan_objmgr_vdev *vdev,
|
||||
void *buffer)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct wlan_cm_utf_raw_bcn *event = NULL;
|
||||
struct mgmt_rx_event_params *rx_param = NULL;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
char *buff = (char *)buffer;
|
||||
char *token;
|
||||
uint32_t frame_len = 0;
|
||||
qdf_nbuf_t buf;
|
||||
struct ie_ssid ssid;
|
||||
struct ie_header *ie;
|
||||
struct wlan_frame_hdr *hdr;
|
||||
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
if (!pdev) {
|
||||
mlme_err("Pdev is Null");
|
||||
return;
|
||||
}
|
||||
|
||||
psoc = wlan_pdev_get_psoc(pdev);
|
||||
if (!psoc) {
|
||||
mlme_err("Psoc is Null");
|
||||
return;
|
||||
}
|
||||
|
||||
while ((token = qdf_str_sep(&buff, "\n")) != NULL) {
|
||||
mlme_err("%s", token);
|
||||
event = qdf_mem_malloc(sizeof(struct wlan_cm_utf_raw_bcn));
|
||||
if (!event) {
|
||||
mlme_err("Failed to allocate event memory");
|
||||
return;
|
||||
}
|
||||
if (sscanf(token,
|
||||
"%2x:%2x:%2x:%2x:%2x:%2x ,%u ,%u ,%u ,%s",
|
||||
(unsigned int *)&event->bssid[0],
|
||||
(unsigned int *)&event->bssid[1],
|
||||
(unsigned int *)&event->bssid[2],
|
||||
(unsigned int *)&event->bssid[3],
|
||||
(unsigned int *)&event->bssid[4],
|
||||
(unsigned int *)&event->bssid[5],
|
||||
&event->channel_number,
|
||||
(unsigned int *)&event->band,
|
||||
&event->rssi,
|
||||
event->ssid) != 10) {
|
||||
goto free_buf;
|
||||
}
|
||||
ssid.ssid_id = 0; //Element id for ssid
|
||||
ssid.ssid_len = strlen(event->ssid);
|
||||
qdf_mem_copy(ssid.ssid, event->ssid, strlen(event->ssid));
|
||||
|
||||
rx_param = qdf_mem_malloc(sizeof(struct mgmt_rx_event_params));
|
||||
if (!rx_param) {
|
||||
mlme_err("Failed to allocate memory");
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
qdf_mem_zero(rx_param, sizeof(struct mgmt_rx_event_params));
|
||||
rx_param->snr = event->rssi;
|
||||
rx_param->channel = event->channel_number;
|
||||
rx_param->chan_freq = wlan_reg_chan_band_to_freq(
|
||||
pdev,
|
||||
event->channel_number,
|
||||
BIT(event->band));
|
||||
|
||||
rx_param->pdev_id = 0;
|
||||
frame_len = sizeof(struct wlan_frame_hdr) +
|
||||
sizeof(struct wlan_bcn_frame) -
|
||||
sizeof(struct ie_header) +
|
||||
sizeof(struct ie_header) + ssid.ssid_len;
|
||||
|
||||
buf = qdf_nbuf_alloc(NULL, frame_len, 0, 0, FALSE);
|
||||
if (!buf) {
|
||||
mlme_err("Failed to allocate buffer");
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
qdf_nbuf_set_pktlen(buf, frame_len);
|
||||
qdf_mem_zero((uint8_t *)qdf_nbuf_data(buf), frame_len);
|
||||
|
||||
hdr = (struct wlan_frame_hdr *)qdf_nbuf_data(buf);
|
||||
qdf_mem_copy(hdr->i_addr3, event->bssid, QDF_MAC_ADDR_SIZE);
|
||||
qdf_mem_copy(hdr->i_addr2, event->bssid, QDF_MAC_ADDR_SIZE);
|
||||
ie = (struct ie_header *)(((uint8_t *)qdf_nbuf_data(buf))
|
||||
+ sizeof(struct wlan_frame_hdr)
|
||||
+ offsetof(struct wlan_bcn_frame, ie));
|
||||
|
||||
qdf_mem_copy(ie, &ssid, sizeof(struct ie_ssid));
|
||||
tgt_scan_bcn_probe_rx_callback(psoc, NULL, buf,
|
||||
rx_param, MGMT_BEACON);
|
||||
free_buf:
|
||||
if (event) {
|
||||
qdf_mem_free(event);
|
||||
event = NULL;
|
||||
}
|
||||
if (rx_param) {
|
||||
qdf_mem_free(rx_param);
|
||||
rx_param = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int wlan_cm_utf_scan_db_update_show(qdf_debugfs_file_t m, void *v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t wlan_cm_utf_scan_db_update_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct wlan_cm_utf *cm_utf =
|
||||
((struct seq_file *)file->private_data)->private;
|
||||
char *locbuf;
|
||||
|
||||
if ((!buf) || (count <= 0))
|
||||
return -EFAULT;
|
||||
|
||||
locbuf = (char *)qdf_mem_malloc(count);
|
||||
|
||||
if (!locbuf)
|
||||
return -EFAULT;
|
||||
|
||||
qdf_mem_zero(locbuf, count);
|
||||
|
||||
if (copy_from_user(locbuf, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
wlan_cm_utf_scan_db_update(cm_utf->vdev, locbuf);
|
||||
qdf_mem_free(locbuf);
|
||||
return count;
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user