qcacmn: Add get candidates logic in connection manager

Adds get candidates logic in Connection manager.

Change-Id: I852b0bfab51f9914734181e4f748ef962d63b8b7
CRs-Fixed: 2749185
This commit is contained in:
gaurank kathpalia 2020-08-04 21:28:04 +05:30 • committed by snandini
commit 6a2f984c06
7 changed files with 315 additions and 68 deletions

View file

@ -19,18 +19,198 @@
*/
#include "wlan_cm_main_api.h"
#include "wlan_cm_bss_score_param.h"
#include "wlan_scan_api.h"
#include "wlan_cm_sm.h"
#ifdef WLAN_POLICY_MGR_ENABLE
#include "wlan_policy_mgr_api.h"
#endif
QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx, struct cm_connect_req *req)
#ifdef WLAN_POLICY_MGR_ENABLE
static void
cm_get_pcl_chan_weigtage_for_sta(struct wlan_objmgr_pdev *pdev,
struct pcl_freq_weight_list *pcl_lst)
{
/*
* TODO: Interface event, get candidate list, do hw mode change and
* serialize. Also move to scan state from here if required.
* If candidate found and all are blacklisted or serialization fails
* post WLAN_CM_SM_EV_CONNECT_REQ_FAIL.
*/
enum QDF_OPMODE opmode = QDF_STA_MODE;
enum policy_mgr_con_mode pm_mode;
uint32_t num_entries = 0;
QDF_STATUS status;
if (!pcl_lst)
return;
if (policy_mgr_map_concurrency_mode(&opmode, &pm_mode)) {
status = policy_mgr_get_pcl(wlan_pdev_get_psoc(pdev), pm_mode,
pcl_lst->pcl_freq_list,
&num_entries,
pcl_lst->pcl_weight_list,
NUM_CHANNELS);
if (QDF_IS_STATUS_ERROR(status))
return;
pcl_lst->num_of_pcl_channels = num_entries;
}
}
static void cm_calculate_scores(struct wlan_objmgr_pdev *pdev,
struct scan_filter *filter, qdf_list_t *list)
{
struct pcl_freq_weight_list *pcl_lst = NULL;
if (!filter->num_of_bssid) {
pcl_lst = qdf_mem_malloc(sizeof(*pcl_lst));
cm_get_pcl_chan_weigtage_for_sta(pdev, pcl_lst);
if (pcl_lst && !pcl_lst->num_of_pcl_channels) {
qdf_mem_free(pcl_lst);
pcl_lst = NULL;
}
}
wlan_cm_calculate_bss_score(pdev, pcl_lst, list, &filter->bssid_hint);
if (pcl_lst)
qdf_mem_free(pcl_lst);
}
#else
static inline
void cm_calculate_scores(struct wlan_objmgr_pdev *pdev,
struct scan_filter *filter, qdf_list_t *list)
{
wlan_cm_calculate_bss_score(pdev, NULL, list, &filter->bssid_hint);
}
#endif
#ifdef WLAN_FEATURE_11W
static inline void
cm_set_pmf_caps(struct cm_connect_req *cm_req, struct scan_filter *filter)
{
filter->pmf_cap = cm_req->req.crypto.pmf_cap;
}
#else
static inline void
cm_set_pmf_caps(struct cm_connect_req *cm_req, struct scan_filter *filter)
{}
#endif
static void cm_connect_prepare_scan_fliter(struct cnx_mgr *cm_ctx,
struct cm_connect_req *cm_req,
struct scan_filter *filter)
{
if (!qdf_is_macaddr_zero(&cm_req->req.bssid)) {
filter->num_of_bssid = 1;
qdf_copy_macaddr(&filter->bssid_list[0], &cm_req->req.bssid);
}
qdf_copy_macaddr(&filter->bssid_hint, &cm_req->req.bssid_hint);
filter->num_of_ssid = 1;
qdf_mem_copy(&filter->ssid_list[0], &cm_req->req.ssid,
sizeof(struct wlan_ssid));
if (cm_req->req.chan_freq) {
filter->num_of_channels = 1;
filter->chan_freq_list[0] = cm_req->req.chan_freq;
}
/* TODO: Fill band (STA+STA) */
/* TODO: RSN OVERRIDE */
filter->authmodeset = cm_req->req.crypto.auth_type;
filter->ucastcipherset = cm_req->req.crypto.ciphers_pairwise;
filter->key_mgmt = cm_req->req.crypto.akm_suites;
filter->mcastcipherset = cm_req->req.crypto.group_cipher;
filter->mgmtcipherset = cm_req->req.crypto.mgmt_ciphers;
cm_set_pmf_caps(cm_req, filter);
/* TODO: FOR WPS/OSEN set ignore auth */
/* TODO: SET mobility domain */
/* TODO: fill fils info */
}
static QDF_STATUS
cm_send_connect_start_fail(struct cnx_mgr *cm_ctx,
struct cm_connect_req *cm_req,
enum wlan_cm_connect_fail_reason reason)
{
struct wlan_cm_connect_rsp *resp;
resp = qdf_mem_malloc(sizeof(*resp));
if (!resp)
return QDF_STATUS_E_NOMEM;
return cm_sm_deliver_event(cm_ctx, WLAN_CM_SM_EV_CONNECT_FAILURE,
sizeof(*resp), resp);
qdf_mem_free(resp);
}
static QDF_STATUS cm_connect_get_candidates(struct wlan_objmgr_pdev *pdev,
struct cnx_mgr *cm_ctx,
struct cm_connect_req *cm_req)
{
struct scan_filter *filter;
uint32_t num_bss = 0;
enum QDF_OPMODE op_mode;
qdf_list_t *candidate_list;
filter = qdf_mem_malloc(sizeof(*filter));
if (!filter)
return QDF_STATUS_E_NOMEM;
cm_connect_prepare_scan_fliter(cm_ctx, cm_req, filter);
candidate_list = wlan_scan_get_result(pdev, filter);
if (candidate_list) {
num_bss = qdf_list_size(candidate_list);
mlme_debug("num_entries found %d", num_bss);
}
op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev);
if (num_bss && op_mode == QDF_STA_MODE)
cm_calculate_scores(pdev, filter, candidate_list);
qdf_mem_free(filter);
if (!candidate_list ||
(candidate_list && !qdf_list_size(candidate_list))) {
if (candidate_list)
wlan_scan_purge_results(candidate_list);
mlme_info("No valid candidate found num_bss %d", num_bss);
/*
* Do connect scan only of no candidates were found
* if candidates were found and were removed due to invalid
* return failure
*/
if (!num_bss)
return cm_sm_deliver_event(cm_ctx, WLAN_CM_SM_EV_SCAN,
sizeof(*cm_req), cm_req);
return QDF_STATUS_E_EMPTY;
}
cm_req->candidate_list = candidate_list;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx,
struct cm_connect_req *cm_req)
{
struct wlan_objmgr_pdev *pdev;
enum wlan_cm_connect_fail_reason reason = CM_GENERIC_FAILURE;
QDF_STATUS status;
/* TODO: Interface event */
pdev = wlan_vdev_get_pdev(cm_ctx->vdev);
if (!pdev)
return QDF_STATUS_E_INVAL;
status = cm_connect_get_candidates(pdev, cm_ctx, cm_req);
if (QDF_IS_STATUS_ERROR(status)) {
reason = CM_NO_CANDIDATE_FOUND;
goto connect_err;
}
/* TODO: Do HW mode change */
/* TODO: serialize */
return QDF_STATUS_SUCCESS;
connect_err:
return cm_send_connect_start_fail(cm_ctx, cm_req, reason);
}
QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
{
/*
@ -72,3 +252,19 @@ QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx,
*/
return QDF_STATUS_SUCCESS;
}
QDF_STATUS cm_connect_start_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_req *req)
{
struct cnx_mgr *cm_ctx = NULL;
struct cm_connect_req *cm_req = NULL;
/*
* TODO: Get WAPI/WPA/RSN IE and refill crypto params of req.
* Prepare cm_connect_req cm_req, get cm id and inform it to OSIF.
* store connect req to the cm ctx req_list
*/
return cm_sm_deliver_event(cm_ctx, WLAN_CM_SM_EV_CONNECT_REQ,
sizeof(*cm_req), cm_req);
}

View file

@ -18,6 +18,7 @@
* DOC: Implements disconnect specific apis of connection manager
*/
#include "wlan_cm_main_api.h"
#include "wlan_cm_sm.h"
QDF_STATUS cm_disconnect_start(struct cnx_mgr *cm_ctx,
struct cm_disconnect_req *req)
@ -48,3 +49,17 @@ QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req)
{
struct cnx_mgr *cm_ctx = NULL;
struct cm_disconnect_req *cm_req = NULL;
/*
* TODO: Prepare cm_disconnect_req cm_req, get cm id and inform it to
* OSIF. store disconnect req to the cm ctx req_list
*/
return cm_sm_deliver_event(cm_ctx, WLAN_CM_SM_EV_DISCONNECT_REQ,
sizeof(*cm_req), cm_req);
}

View file

@ -71,63 +71,6 @@ enum wlan_cm_sm_state {
WLAN_CM_SS_MAX = 14,
};
/**
* enum wlan_cm_sm_evt - connection manager related events
* @WLAN_CM_SM_EV_CONNECT_REQ: Connect request event from requester
* @WLAN_CM_SM_EV_SCAN: Event to start connect scan
* @WLAN_CM_SM_EV_SCAN_SUCCESS: Connect scan success event
* @WLAN_CM_SM_EV_SCAN_FAILURE: Connect scan fail event
* @WLAN_CM_SM_EV_CONNECT_START: Connect start process initiate
* @WLAN_CM_SM_EV_CONNECT_ACTIVE: Connect request is activated
* @WLAN_CM_SM_EV_CONNECT_SUCCESS: Connect success
* @WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE: Get next candidate for connection
* @WLAN_CM_SM_EV_CONNECT_FAILURE: Connect failed for all candidate
* @WLAN_CM_SM_EV_DISCONNECT_REQ: Disconnect request event from
* requester
* @WLAN_CM_SM_EV_DISCONNECT_START: Start disconnect sequence
* @WLAN_CM_SM_EV_DISCONNECT_ACTIVE: Process disconnect after in active cmd
* @WLAN_CM_SM_EV_DISCONNECT_DONE: Disconnect done event
* @WLAN_CM_SM_EV_ROAM_START: Roam start event
* @WLAN_CM_SM_EV_ROAM_SYNC: Roam sync event
* @WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: Roam invoke fail event
* @WLAN_CM_SM_EV_ROAM_HO_FAIL: Hand off failed event
* @WLAN_CM_SM_EV_PREAUTH_DONE: Preauth is completed
* @WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP: Get next candidate as preauth failed
* @WLAN_CM_SM_EV_PREAUTH_FAIL: Preauth failed for all candidate
* @WLAN_CM_SM_EV_START_REASSOC: Start reassoc after preauth done
* @WLAN_CM_SM_EV_REASSOC_DONE: Reassoc completed
* @WLAN_CM_SM_EV_REASSOC_FAILURE: Reassoc failed
* @WLAN_CM_SM_EV_ROAM_COMPLETE: Roaming completed
* @WLAN_CM_SM_EV_MAX: Max event
*/
enum wlan_cm_sm_evt {
WLAN_CM_SM_EV_CONNECT_REQ = 0,
WLAN_CM_SM_EV_SCAN = 1,
WLAN_CM_SM_EV_SCAN_SUCCESS = 2,
WLAN_CM_SM_EV_SCAN_FAILURE = 3,
WLAN_CM_SM_EV_CONNECT_START = 4,
WLAN_CM_SM_EV_CONNECT_ACTIVE = 5,
WLAN_CM_SM_EV_CONNECT_SUCCESS = 6,
WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE = 7,
WLAN_CM_SM_EV_CONNECT_FAILURE = 8,
WLAN_CM_SM_EV_DISCONNECT_REQ = 9,
WLAN_CM_SM_EV_DISCONNECT_START = 10,
WLAN_CM_SM_EV_DISCONNECT_ACTIVE = 11,
WLAN_CM_SM_EV_DISCONNECT_DONE = 12,
WLAN_CM_SM_EV_ROAM_START = 13,
WLAN_CM_SM_EV_ROAM_SYNC = 14,
WLAN_CM_SM_EV_ROAM_INVOKE_FAIL = 15,
WLAN_CM_SM_EV_ROAM_HO_FAIL = 16,
WLAN_CM_SM_EV_PREAUTH_DONE = 17,
WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP = 18,
WLAN_CM_SM_EV_PREAUTH_FAIL = 19,
WLAN_CM_SM_EV_START_REASSOC = 20,
WLAN_CM_SM_EV_REASSOC_DONE = 21,
WLAN_CM_SM_EV_REASSOC_FAILURE = 22,
WLAN_CM_SM_EV_ROAM_COMPLETE = 23,
WLAN_CM_SM_EV_MAX,
};
/**
* struct cm_state_sm - connection manager sm
* @cm_sm_lock: sm lock
@ -164,7 +107,7 @@ struct cm_connect_req {
qdf_timer_t hw_mode_timer;
struct wlan_cm_connect_req req;
struct element_info rsn_ie;
qdf_list_t candidate_list;
qdf_list_t *candidate_list;
struct scan_cache_node *cur_candidate;
};

View file

@ -102,6 +102,16 @@ QDF_STATUS cm_connect_cmd_timeout(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id);
QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx,
struct wlan_cm_connect_rsp *resp);
/**
* cm_connect_start_req() - Connect start req from the requester
* @vdev: vdev on which connect is received
* @req: Connection req provided
*
* Return: QDF status
*/
QDF_STATUS cm_connect_start_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_req *req);
/*************** DISCONNECT APIs ****************/
/**
@ -125,7 +135,7 @@ QDF_STATUS cm_disconnect_start(struct cnx_mgr *cm_ctx,
QDF_STATUS cm_disconnect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id);
/**
* cm_connect_complete() - This API would be called after connect complete
* cm_disconnect_complete() - This API would be called after disconnect complete
* request from the serialization.
* @cm_ctx: connection manager context
* @resp: disconnection complete resp.
@ -137,4 +147,14 @@ QDF_STATUS cm_disconnect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id);
QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx,
struct wlan_cm_discon_rsp *resp);
/**
* cm_disconnect_start_req() - Disconnect start req from the requester
* @vdev: vdev on which connect is received
* @req: disconnection req provided
*
* Return: QDF status
*/
QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req);
#endif /* __WLAN_CM_MAIN_API_H__ */

View file

@ -26,6 +26,63 @@
#ifdef FEATURE_CM_ENABLE
#include <wlan_sm_engine.h>
/**
* enum wlan_cm_sm_evt - connection manager related events
* @WLAN_CM_SM_EV_CONNECT_REQ: Connect request event from requester
* @WLAN_CM_SM_EV_SCAN: Event to start connect scan
* @WLAN_CM_SM_EV_SCAN_SUCCESS: Connect scan success event
* @WLAN_CM_SM_EV_SCAN_FAILURE: Connect scan fail event
* @WLAN_CM_SM_EV_CONNECT_START: Connect start process initiate
* @WLAN_CM_SM_EV_CONNECT_ACTIVE: Connect request is activated
* @WLAN_CM_SM_EV_CONNECT_SUCCESS: Connect success
* @WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE: Get next candidate for connection
* @WLAN_CM_SM_EV_CONNECT_FAILURE: Connect failed for all candidate
* @WLAN_CM_SM_EV_DISCONNECT_REQ: Disconnect request event from
* requester
* @WLAN_CM_SM_EV_DISCONNECT_START: Start disconnect sequence
* @WLAN_CM_SM_EV_DISCONNECT_ACTIVE: Process disconnect after in active cmd
* @WLAN_CM_SM_EV_DISCONNECT_DONE: Disconnect done event
* @WLAN_CM_SM_EV_ROAM_START: Roam start event
* @WLAN_CM_SM_EV_ROAM_SYNC: Roam sync event
* @WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: Roam invoke fail event
* @WLAN_CM_SM_EV_ROAM_HO_FAIL: Hand off failed event
* @WLAN_CM_SM_EV_PREAUTH_DONE: Preauth is completed
* @WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP: Get next candidate as preauth failed
* @WLAN_CM_SM_EV_PREAUTH_FAIL: Preauth failed for all candidate
* @WLAN_CM_SM_EV_START_REASSOC: Start reassoc after preauth done
* @WLAN_CM_SM_EV_REASSOC_DONE: Reassoc completed
* @WLAN_CM_SM_EV_REASSOC_FAILURE: Reassoc failed
* @WLAN_CM_SM_EV_ROAM_COMPLETE: Roaming completed
* @WLAN_CM_SM_EV_MAX: Max event
*/
enum wlan_cm_sm_evt {
WLAN_CM_SM_EV_CONNECT_REQ = 0,
WLAN_CM_SM_EV_SCAN = 1,
WLAN_CM_SM_EV_SCAN_SUCCESS = 2,
WLAN_CM_SM_EV_SCAN_FAILURE = 3,
WLAN_CM_SM_EV_CONNECT_START = 4,
WLAN_CM_SM_EV_CONNECT_ACTIVE = 5,
WLAN_CM_SM_EV_CONNECT_SUCCESS = 6,
WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE = 7,
WLAN_CM_SM_EV_CONNECT_FAILURE = 8,
WLAN_CM_SM_EV_DISCONNECT_REQ = 9,
WLAN_CM_SM_EV_DISCONNECT_START = 10,
WLAN_CM_SM_EV_DISCONNECT_ACTIVE = 11,
WLAN_CM_SM_EV_DISCONNECT_DONE = 12,
WLAN_CM_SM_EV_ROAM_START = 13,
WLAN_CM_SM_EV_ROAM_SYNC = 14,
WLAN_CM_SM_EV_ROAM_INVOKE_FAIL = 15,
WLAN_CM_SM_EV_ROAM_HO_FAIL = 16,
WLAN_CM_SM_EV_PREAUTH_DONE = 17,
WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP = 18,
WLAN_CM_SM_EV_PREAUTH_FAIL = 19,
WLAN_CM_SM_EV_START_REASSOC = 20,
WLAN_CM_SM_EV_REASSOC_DONE = 21,
WLAN_CM_SM_EV_REASSOC_FAILURE = 22,
WLAN_CM_SM_EV_ROAM_COMPLETE = 23,
WLAN_CM_SM_EV_MAX,
};
/**
* cm_sm_create() - Invoke SM creation for connection manager
* @cm_ctx: connection manager ctx

View file

@ -21,16 +21,17 @@
*/
#include <wlan_cm_api.h>
#include "connection_mgr/core/src/wlan_cm_main_api.h"
QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_req *req)
{
return QDF_STATUS_SUCCESS;
return cm_connect_start_req(vdev, req);
}
QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req)
{
return QDF_STATUS_SUCCESS;
return cm_disconnect_start_req(vdev, req);
}

View file

@ -223,4 +223,19 @@ static inline QDF_STATUS wlan_scan_purge_results(qdf_list_t *scan_list)
return scm_purge_scan_results(scan_list);
}
/**
* wlan_scan_get_result() - The Public API to get scan results
* @pdev: pdev info
* @filter: Filters
*
* This function fetches scan result
*
* Return: scan list pointer
*/
static inline qdf_list_t *wlan_scan_get_result(struct wlan_objmgr_pdev *pdev,
struct scan_filter *filter)
{
return scm_get_scan_result(pdev, filter);
}
#endif