diff options
| author | Naveen Rawat <nrawat@qca.qualcomm.com> | 2016-02-04 13:47:57 -0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-13 10:11:30 +0530 |
| commit | b02cb8d0ddbc86c3c69b755919c617f2c1f118a9 (patch) | |
| tree | f15e2bc0a5849ff23594956b6b9ed5fb8aa73a1f | |
| parent | e740ca8e9b1171bcbe6a240f1a4baf10da0d3ddf (diff) | |
qcacld-2.0: Add support for get and set OEM capability
Add support for get and set OEM capability over private netlink
socket.
Change-Id: I8c4a8c19633845750ec9d2492632471c68ba410d
CRs-Fixed: 949469
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_oemdata.h | 22 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_oemdata.c | 541 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 20 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 54 | ||||
| -rw-r--r-- | CORE/SVC/inc/wlan_ptt_sock_svc.h | 6 |
5 files changed, 508 insertions, 135 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_oemdata.h b/CORE/HDD/inc/wlan_hdd_oemdata.h index 1d4ba472473c..8822ccebbff4 100644 --- a/CORE/HDD/inc/wlan_hdd_oemdata.h +++ b/CORE/HDD/inc/wlan_hdd_oemdata.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -158,6 +158,26 @@ typedef PACKED_PRE struct PACKED_POST tHddChannelInfo peer_chan_info; } tPeerStatusInfo; +/** + * enum oem_capability_mask - mask field for userspace client capabilities + * @OEM_CAP_RM_FTMRR: FTM range report mask bit + * @OEM_CAP_RM_LCI: LCI capability mask bit + */ +enum oem_capability_mask { + OEM_CAP_RM_FTMRR = (1 << (0)), + OEM_CAP_RM_LCI = (1 << (1)), +}; + +/** + * struct oem_get_capability_rsp - capabilites set by userspace and target. + * @target_cap: target capabilities + * @client_capabilities: capabilities set by userspace via set request + */ +struct oem_get_capability_rsp { + t_iw_oem_data_cap target_cap; + struct sme_oem_capability cap; +}; + #endif //__WLAN_HDD_OEM_DATA_H__ #endif //FEATURE_OEM_DATA_SUPPORT diff --git a/CORE/HDD/src/wlan_hdd_oemdata.c b/CORE/HDD/src/wlan_hdd_oemdata.c index 3ea48119d52b..91cffba1ba6a 100644 --- a/CORE/HDD/src/wlan_hdd_oemdata.c +++ b/CORE/HDD/src/wlan_hdd_oemdata.c @@ -49,6 +49,77 @@ #include "wma.h" static struct hdd_context_s *pHddCtx; +/** + * populate_oem_data_cap() - populate oem capabilities + * @adapter: device adapter + * @data_cap: pointer to populate the capabilities + * + * Return: error code + */ +static int populate_oem_data_cap(hdd_adapter_t *adapter, + t_iw_oem_data_cap *data_cap) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_config_t *config; + uint32_t num_chan; + uint8_t *chan_list; + hdd_context_t *hdd_ctx = adapter->pHddCtx; + + config = hdd_ctx->cfg_ini; + if (!config) { + hddLog(LOGE, FL("HDD configuration is null")); + return -EINVAL; + } + chan_list = vos_mem_malloc(sizeof(uint8_t) * OEM_CAP_MAX_NUM_CHANNELS); + if (NULL == chan_list) { + hddLog(LOGE, FL("Memory allocation failed")); + return -ENOMEM; + } + + strlcpy(data_cap->oem_target_signature, OEM_TARGET_SIGNATURE, + OEM_TARGET_SIGNATURE_LEN); + data_cap->oem_target_type = hdd_ctx->target_type; + data_cap->oem_fw_version = hdd_ctx->target_fw_version; + data_cap->driver_version.major = QWLAN_VERSION_MAJOR; + data_cap->driver_version.minor = QWLAN_VERSION_MINOR; + data_cap->driver_version.patch = QWLAN_VERSION_PATCH; + data_cap->driver_version.build = QWLAN_VERSION_BUILD; + data_cap->allowed_dwell_time_min = config->nNeighborScanMinChanTime; + data_cap->allowed_dwell_time_max = config->nNeighborScanMaxChanTime; + data_cap->curr_dwell_time_min = + sme_getNeighborScanMinChanTime(hdd_ctx->hHal, + adapter->sessionId); + data_cap->curr_dwell_time_max = + sme_getNeighborScanMaxChanTime(hdd_ctx->hHal, + adapter->sessionId); + data_cap->supported_bands = config->nBandCapability; + + /* request for max num of channels */ + num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN; + status = sme_GetCfgValidChannels(hdd_ctx->hHal, &chan_list[0], + &num_chan); + if (VOS_STATUS_SUCCESS != status) { + hddLog(LOGE, FL("failed to get valid channel list, status: %d"), + status); + vos_mem_free(chan_list); + return -EINVAL; + } + + /* make sure num channels is not more than chan list array */ + if (num_chan > OEM_CAP_MAX_NUM_CHANNELS) { + hddLog(LOGE, FL("Num of channels-%d > length-%d of chan_list"), + num_chan, OEM_CAP_MAX_NUM_CHANNELS); + vos_mem_free(chan_list); + return -EINVAL; + } + + data_cap->num_channels = num_chan; + vos_mem_copy(data_cap->channel_list, chan_list, + sizeof(uint8_t) * num_chan); + + vos_mem_free(chan_list); + return 0; +} /**--------------------------------------------------------------------------- @@ -71,15 +142,11 @@ int iw_get_oem_data_cap( union iwreq_data *wrqu, char *extra) { - eHalStatus status; - t_iw_oem_data_cap oemDataCap; + int status; + t_iw_oem_data_cap oemDataCap = { {0} }; t_iw_oem_data_cap *pHddOemDataCap; hdd_adapter_t *pAdapter = netdev_priv(dev); hdd_context_t *pHddContext; - hdd_config_t *pConfig; - tANI_U32 numChannels; - tANI_U8 chanList[OEM_CAP_MAX_NUM_CHANNELS]; - tANI_U32 i; int ret; ENTER(); @@ -96,61 +163,14 @@ int iw_get_oem_data_cap( if (0 != ret) return ret; - pConfig = pHddContext->cfg_ini; + status = populate_oem_data_cap(pAdapter, &oemDataCap); + if (0 != status) { + hddLog(LOGE, FL("Failed to populate oem data capabilities")); + return status; + } - do - { - vos_mem_zero(&oemDataCap, sizeof(oemDataCap)); - strlcpy(oemDataCap.oem_target_signature, OEM_TARGET_SIGNATURE, - OEM_TARGET_SIGNATURE_LEN); - oemDataCap.oem_target_type = pHddContext->target_type; - oemDataCap.oem_fw_version = pHddContext->target_fw_version; - oemDataCap.driver_version.major = QWLAN_VERSION_MAJOR; - oemDataCap.driver_version.minor = QWLAN_VERSION_MINOR; - oemDataCap.driver_version.patch = QWLAN_VERSION_PATCH; - oemDataCap.driver_version.build = QWLAN_VERSION_BUILD; - oemDataCap.allowed_dwell_time_min = pConfig->nNeighborScanMinChanTime; - oemDataCap.allowed_dwell_time_max = pConfig->nNeighborScanMaxChanTime; - oemDataCap.curr_dwell_time_min = - sme_getNeighborScanMinChanTime(pHddContext->hHal, - pAdapter->sessionId); - oemDataCap.curr_dwell_time_max = - sme_getNeighborScanMaxChanTime(pHddContext->hHal, - pAdapter->sessionId); - oemDataCap.supported_bands = pConfig->nBandCapability; - - /* request for max num of channels */ - numChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; - status = sme_GetCfgValidChannels(pHddContext->hHal, - &chanList[0], - &numChannels); - if (eHAL_STATUS_SUCCESS != status) - { - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s:failed to get valid channel list", __func__); - return -ENOENT; - } - else - { - /* make sure num channels is not more than chan list array */ - if (numChannels > OEM_CAP_MAX_NUM_CHANNELS) - { - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s:Num of channels(%d) more than length(%d) of chanlist", - __func__, numChannels, OEM_CAP_MAX_NUM_CHANNELS); - return -ENOMEM; - } - - oemDataCap.num_channels = numChannels; - for (i = 0; i < numChannels; i++) - { - oemDataCap.channel_list[i] = chanList[i]; - } - } - - pHddOemDataCap = (t_iw_oem_data_cap *)(extra); - vos_mem_copy(pHddOemDataCap, &oemDataCap, sizeof(*pHddOemDataCap)); - } while (0); + pHddOemDataCap = (t_iw_oem_data_cap *) (extra); + *pHddOemDataCap = oemDataCap; EXIT(); return 0; @@ -553,6 +573,133 @@ static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList) return 0; } +/** + * oem_process_set_cap_req_msg() - process oem set capability request + * @oem_cap_len: Length of OEM capability + * @oem_cap: Pointer to OEM capability buffer + * @app_pid: process ID, to which rsp message is to be sent + * + * This function sends oem message to SME + * + * Return: error code + */ +static int oem_process_set_cap_req_msg(int oem_cap_len, + char *oem_cap, int32_t app_pid) +{ + VOS_STATUS status; + int error_code; + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *ani_hdr; + uint8_t *buf; + + if (!oem_cap) { + hddLog(LOGE, FL("oem_cap is null")); + return -EINVAL; + } + + status = sme_oem_update_capability(pHddCtx->hHal, + (struct sme_oem_capability *)oem_cap); + if (!VOS_IS_STATUS_SUCCESS(status)) + hddLog(LOGE, FL("error updating rm capability, status: %d"), + status); + error_code = vos_status_to_os_return(status); + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if (skb == NULL) { + hddLog(LOGE, FL("alloc_skb failed")); + return -ENOMEM; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + ani_hdr = NLMSG_DATA(nlh); + ani_hdr->type = ANI_MSG_SET_OEM_CAP_RSP; + /* 64 bit alignment */ + ani_hdr->length = sizeof(error_code); + nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + ani_hdr->length); + + /* message body will contain only status code */ + buf = (char *)((char *)ani_hdr + sizeof(tAniMsgHdr)); + vos_mem_copy(buf, &error_code, ani_hdr->length); + + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + ani_hdr->length)); + + hddLog(LOG1, FL("sending oem response to process pid %d"), app_pid); + + (void)nl_srv_ucast(skb, app_pid, MSG_DONTWAIT); + + return error_code; +} + +/** + * oem_process_get_cap_req_msg() - process oem get capability request + * + * This function process the get capability request from OEM and responds + * with the capability. + * + * Return: error code + */ +static int oem_process_get_cap_req_msg(void) +{ + int error_code; + struct oem_get_capability_rsp *cap_rsp; + t_iw_oem_data_cap data_cap = { {0} }; + struct sme_oem_capability oem_cap; + hdd_adapter_t *adapter; + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *ani_hdr; + uint8_t *buf; + + /* for now, STA interface only */ + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (!adapter) { + hddLog(LOGE, FL("No adapter for STA mode")); + return -EINVAL; + } + + error_code = populate_oem_data_cap(adapter, &data_cap); + if (0 != error_code) + return error_code; + + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(*cap_rsp)), + GFP_KERNEL); + if (skb == NULL) { + hddLog(LOGE, FL("alloc_skb failed")); + return -ENOMEM; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + ani_hdr = NLMSG_DATA(nlh); + ani_hdr->type = ANI_MSG_GET_OEM_CAP_RSP; + + ani_hdr->length = sizeof(*cap_rsp); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + ani_hdr->length)); + + buf = (char *)((char *)ani_hdr + sizeof(tAniMsgHdr)); + vos_mem_copy(buf, &data_cap, sizeof(data_cap)); + + buf = (char *) buf + sizeof(data_cap); + vos_mem_zero(&oem_cap, sizeof(oem_cap)); + sme_oem_get_capability(pHddCtx->hHal, &oem_cap); + vos_mem_copy(buf, &oem_cap, sizeof(oem_cap)); + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + ani_hdr->length))); + hddLog(LOG1, FL("send rsp to oem-pid:%d for get_capability"), + pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + return 0; +} + /**--------------------------------------------------------------------------- \brief hdd_SendPeerStatusIndToOemApp() @@ -670,6 +817,196 @@ void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac, return; } +/** + * oem_app_reg_req_handler() - function to handle APP registration request + * from userspace + * @hdd_ctx: handle to HDD context + * @msg_hdr: pointer to ANI message header + * @nlh: pointer to NL message header + * + * Return: 0 if success, error code otherwise + */ +static int oem_app_reg_req_handler(struct hdd_context_s *hdd_ctx, + tAniMsgHdr *msg_hdr, struct nlmsghdr *nlh) +{ + char *sign_str = NULL; + + /* Registration request is only allowed for Qualcomm Application */ + hddLog(LOG1, + FL("Received App Reg Req from App process pid(%d), len(%d)"), + nlh->nlmsg_pid, msg_hdr->length); + + sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr)); + if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) && + (0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR, + OEM_APP_SIGNATURE_LEN))) { + hddLog(LOG1, + FL("Valid App Reg Req from oem app process pid(%d)"), + nlh->nlmsg_pid); + + hdd_ctx->oem_app_registered = TRUE; + hdd_ctx->oem_pid = nlh->nlmsg_pid; + send_oem_reg_rsp_nlink_msg(); + } else { + hddLog(LOGE, + FL("Invalid signature in App Reg Req from pid(%d)"), + nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_SIGNATURE); + return -EPERM; + } + + return 0; +} + +/** + * oem_data_req_handler() - function to handle data_req from userspace + * @hdd_ctx: handle to HDD context + * @msg_hdr: pointer to ANI message header + * @nlh: pointer to NL message header + * + * Return: 0 if success, error code otherwise + */ +static int oem_data_req_handler(struct hdd_context_s *hdd_ctx, + tAniMsgHdr *msg_hdr, struct nlmsghdr *nlh) +{ + hddLog(LOG1, FL("Received Oem Data Request length(%d) from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!hdd_ctx->oem_app_registered) || + (nlh->nlmsg_pid != hdd_ctx->oem_pid)) { + /* either oem app is not registered yet or pid is different */ + hddLog(LOGE, FL("OEM DataReq: app not registered(%d) or incorrect pid(%d)"), + hdd_ctx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + if ((!msg_hdr->length) || (OEM_DATA_REQ_SIZE < msg_hdr->length)) { + hddLog(LOGE, FL("Invalid length (%d) in Oem Data Request"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + + oem_process_data_req_msg(msg_hdr->length, + (char *) ((char *)msg_hdr + + sizeof(tAniMsgHdr))); + + return 0; +} + +/** + * oem_chan_info_req_handler() - function to handle chan_info_req from userspace + * @hdd_ctx: handle to HDD context + * @msg_hdr: pointer to ANI message header + * @nlh: pointer to NL message header + * + * Return: 0 if success, error code otherwise + */ +static int oem_chan_info_req_handler(struct hdd_context_s *hdd_ctx, + tAniMsgHdr *msg_hdr, struct nlmsghdr *nlh) +{ + hddLog(LOG1, + FL("Received channel info request, num channel(%d) from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!hdd_ctx->oem_app_registered) || + (nlh->nlmsg_pid != hdd_ctx->oem_pid)) { + /* either oem app is not registered yet or pid is different */ + hddLog(LOGE, + FL("Chan InfoReq: app not registered(%d) or incorrect pid(%d)"), + hdd_ctx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + /* message length contains list of channel ids */ + if ((!msg_hdr->length) || + (WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length)) { + hddLog(LOGE, + FL("Invalid length (%d) in channel info request"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + oem_process_channel_info_req_msg(msg_hdr->length, + (char *)((char *)msg_hdr + sizeof(tAniMsgHdr))); + + return 0; +} + +/** + * oem_set_cap_req_handler() - function to handle set_cap_req from userspace + * @hdd_ctx: handle to HDD context + * @msg_hdr: pointer to ANI message header + * @nlh: pointer to NL message header + * + * Return: 0 if success, error code otherwise + */ +static int oem_set_cap_req_handler(struct hdd_context_s *hdd_ctx, + tAniMsgHdr *msg_hdr, struct nlmsghdr *nlh) +{ + hddLog(LOG1, FL("Received set oem cap req of length:%d from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!hdd_ctx->oem_app_registered) || + (nlh->nlmsg_pid != hdd_ctx->oem_pid)) { + /* oem app is not registered yet or pid is different */ + hddLog(LOGE, FL("set_oem_capability : app not registered(%d) or incorrect pid(%d)"), + hdd_ctx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + if ((!msg_hdr->length) || + (sizeof(struct sme_oem_capability) < msg_hdr->length)) { + hddLog(LOGE, FL("Invalid length (%d) in set_oem_capability"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + + oem_process_set_cap_req_msg(msg_hdr->length, (char *) + ((char *)msg_hdr + sizeof(tAniMsgHdr)), + nlh->nlmsg_pid); + return 0; +} + +/** + * oem_get_cap_req_handler() - function to handle get_cap_req from userspace + * @hdd_ctx: handle to HDD context + * @msg_hdr: pointer to ANI message header + * @nlh: pointer to NL message header + * + * Return: 0 if success, error code otherwise + */ +static int oem_get_cap_req_handler(struct hdd_context_s *hdd_ctx, + tAniMsgHdr *msg_hdr, struct nlmsghdr *nlh) +{ + hddLog(LOG1, FL("Rcvd get oem capability req - length:%d from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!hdd_ctx->oem_app_registered) || + (nlh->nlmsg_pid != hdd_ctx->oem_pid)) { + /* oem app is not registered yet or pid is different */ + hddLog(LOGE, FL("get_oem_capability : app not registered(%d) or incorrect pid(%d)"), + hdd_ctx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + oem_process_get_cap_req_msg(); + return 0; +} + /* * Callback function invoked by Netlink service for all netlink * messages (from user space) addressed to WLAN_NL_MSG_OEM @@ -690,7 +1027,7 @@ static int oem_msg_callback(struct sk_buff *skb) struct nlmsghdr *nlh; tAniMsgHdr *msg_hdr; int ret; - char *sign_str = NULL; + nlh = (struct nlmsghdr *)skb->data; if (!nlh) { @@ -720,83 +1057,23 @@ static int oem_msg_callback(struct sk_buff *skb) switch (msg_hdr->type) { case ANI_MSG_APP_REG_REQ: - /* Registration request is only allowed for Qualcomm Application */ - hddLog(LOG1, FL("Received App Req Req from App process pid(%d), len(%d)"), - nlh->nlmsg_pid, msg_hdr->length); - - sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr)); - if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) && - (0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR, - OEM_APP_SIGNATURE_LEN))) { - hddLog(LOG1, FL("Valid App Req Req from oem app process pid(%d)"), - nlh->nlmsg_pid); - - pHddCtx->oem_app_registered = TRUE; - pHddCtx->oem_pid = nlh->nlmsg_pid; - send_oem_reg_rsp_nlink_msg(); - } else { - hddLog(LOGE, FL("Invalid signature in App Reg Request from pid(%d)"), - nlh->nlmsg_pid); - send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, - OEM_ERR_INVALID_SIGNATURE); - return -EPERM; - } + ret = oem_app_reg_req_handler(pHddCtx, msg_hdr, nlh); break; case ANI_MSG_OEM_DATA_REQ: - hddLog(LOG1, FL("Received Oem Data Request length(%d) from pid: %d"), - msg_hdr->length, nlh->nlmsg_pid); - - if ((!pHddCtx->oem_app_registered) || - (nlh->nlmsg_pid != pHddCtx->oem_pid)) { - /* either oem app is not registered yet or pid is different */ - hddLog(LOGE, FL("OEM DataReq: app not registered(%d) or incorrect pid(%d)"), - pHddCtx->oem_app_registered, nlh->nlmsg_pid); - send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, - OEM_ERR_APP_NOT_REGISTERED); - return -EPERM; - } - - if ((!msg_hdr->length) || (OEM_DATA_REQ_SIZE < msg_hdr->length)) { - hddLog(LOGE, FL("Invalid length (%d) in Oem Data Request"), - msg_hdr->length); - send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, - OEM_ERR_INVALID_MESSAGE_LENGTH); - return -EPERM; - } - oem_process_data_req_msg(msg_hdr->length, - (char *) ((char *)msg_hdr + - sizeof(tAniMsgHdr))); + ret = oem_data_req_handler(pHddCtx, msg_hdr, nlh); break; case ANI_MSG_CHANNEL_INFO_REQ: - hddLog(LOG1, - FL("Received channel info request, num channel(%d) from pid: %d"), - msg_hdr->length, nlh->nlmsg_pid); - - if ((!pHddCtx->oem_app_registered) || - (nlh->nlmsg_pid != pHddCtx->oem_pid)) { - /* either oem app is not registered yet or pid is different */ - hddLog(LOGE, - FL("Chan InfoReq: app not registered(%d) or incorrect pid(%d)"), - pHddCtx->oem_app_registered, nlh->nlmsg_pid); - send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, - OEM_ERR_APP_NOT_REGISTERED); - return -EPERM; - } + ret = oem_chan_info_req_handler(pHddCtx, msg_hdr, nlh); + break; - /* message length contains list of channel ids */ - if ((!msg_hdr->length) || - (WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length)) { - hddLog(LOGE, - FL("Invalid length (%d) in channel info request"), - msg_hdr->length); - send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, - OEM_ERR_INVALID_MESSAGE_LENGTH); - return -EPERM; - } - oem_process_channel_info_req_msg(msg_hdr->length, - (char *)((char*)msg_hdr + sizeof(tAniMsgHdr))); + case ANI_MSG_SET_OEM_CAP_REQ: + ret = oem_set_cap_req_handler(pHddCtx, msg_hdr, nlh); + break; + + case ANI_MSG_GET_OEM_CAP_REQ: + ret = oem_get_cap_req_handler(pHddCtx, msg_hdr, nlh); break; default: @@ -807,7 +1084,7 @@ static int oem_msg_callback(struct sk_buff *skb) OEM_ERR_INVALID_MESSAGE_TYPE); return -EPERM; } - return 0; + return ret; } static int __oem_msg_callback(struct sk_buff *skb) diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 93488174c453..e7d356e49bc4 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -250,6 +250,21 @@ struct sme_ap_find_request_req{ }; #endif /* WLAN_FEATURE_APFIND */ +/** + * struct sme_oem_capability - OEM capability to be exchanged between host + * and userspace + * @ftm_rr: FTM range report capability bit + * @lci_capability: LCI capability bit + * @reserved1: reserved + * @reserved2: reserved + */ +struct sme_oem_capability { + uint32_t ftm_rr:1; + uint32_t lci_capability:1; + uint32_t reserved1:30; + uint32_t reserved2; +}; + /*------------------------------------------------------------------------- Function declarations and documentation ------------------------------------------------------------------------*/ @@ -1953,6 +1968,11 @@ eHalStatus sme_OemDataReq(tHalHandle hHal, tOemDataReqConfig *, tANI_U32 *pOemDataReqID); +VOS_STATUS sme_oem_update_capability(tHalHandle hHal, + struct sme_oem_capability *cap); +VOS_STATUS sme_oem_get_capability(tHalHandle hHal, + struct sme_oem_capability *cap); + #endif /*FEATURE_OEM_DATA_SUPPORT*/ diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index a5a56c8eaee3..044ac94fecde 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -18677,7 +18677,6 @@ VOS_STATUS sme_set_btc_bt_wlan_interval_page_sap(uint32_t bt_interval, return vos_status; } - /** * sme_send_disassoc_req_frame - send disassoc req * @hal: handler to hal @@ -18800,3 +18799,56 @@ eHalStatus sme_enable_disable_chanavoidind_event(tHalHandle hal, return eHAL_STATUS_FAILURE; } +/** + * sme_oem_update_capability() - update UMAC's oem related capability. + * @hal: Handle returned by mac_open + * @oem_cap: pointer to oem_capability + * + * This function updates OEM capability to UMAC. Currently RTT + * related capabilities are updated. More capabilities can be + * added in future. + * + * Return: VOS_STATUS + */ +VOS_STATUS sme_oem_update_capability(tHalHandle hal, + struct sme_oem_capability *cap) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pmac = PMAC_STRUCT(hal); + uint8_t *bytes; + + bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability; + + if (cap->ftm_rr) + bytes[4] |= RM_CAP_FTM_RANGE_REPORT; + if (cap->lci_capability) + bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT; + + return status; +} + +/** + * sme_oem_get_capability() - get oem capability + * @hal: Handle returned by mac_open + * @oem_cap: pointer to oem_capability + * + * This function is used to get the OEM capability from UMAC. + * Currently RTT related capabilities are received. More + * capabilities can be added in future. + * + * Return: VOS_STATUS + */ +VOS_STATUS sme_oem_get_capability(tHalHandle hal, + struct sme_oem_capability *cap) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pmac = PMAC_STRUCT(hal); + uint8_t *bytes; + + bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability; + + cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT; + cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT; + + return status; +} diff --git a/CORE/SVC/inc/wlan_ptt_sock_svc.h b/CORE/SVC/inc/wlan_ptt_sock_svc.h index 9a2c71884b9b..a662d95255f3 100644 --- a/CORE/SVC/inc/wlan_ptt_sock_svc.h +++ b/CORE/SVC/inc/wlan_ptt_sock_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -67,6 +67,10 @@ #define ANI_MSG_CHANNEL_INFO_RSP (ANI_DRIVER_MSG_START + 5) #define ANI_MSG_OEM_ERROR (ANI_DRIVER_MSG_START + 6) #define ANI_MSG_PEER_STATUS_IND (ANI_DRIVER_MSG_START + 7) +#define ANI_MSG_SET_OEM_CAP_REQ (ANI_DRIVER_MSG_START + 8) +#define ANI_MSG_SET_OEM_CAP_RSP (ANI_DRIVER_MSG_START + 9) +#define ANI_MSG_GET_OEM_CAP_REQ (ANI_DRIVER_MSG_START + 10) +#define ANI_MSG_GET_OEM_CAP_RSP (ANI_DRIVER_MSG_START + 11) #define ANI_MAX_RADIOS 3 #define ANI_NL_MSG_OK 0 |
