From 37c53bb0d83abf692fa57ef56b4f06573c5b0cbb Mon Sep 17 00:00:00 2001 From: RichardHuang9527 Date: Mon, 20 Jun 2022 07:25:55 -0700 Subject: [PATCH] feat: Add new hdi interfaces for hml. Signed-off-by: RichardHuang9527 --- wlan/client/include/wifi_driver_client.h | 40 +++ wlan/client/src/netlink/netlink_cmd_adapter.c | 218 +++++++++++++- wlan/client/src/sbuf/sbuf_cmd_adapter.c | 109 +++++++ wlan/client/src/wifi_common_cmd.h | 15 +- wlan/client/src/wifi_driver_client.c | 71 +++++ wlan/hal/src/wifi_hal.c | 95 ++++++ .../service_common/wlan_common_cmd.c | 123 ++++++-- .../service_common/wlan_common_cmd.h | 1 + .../service_extend/wlan_extend_cmd.c | 62 ++++ .../service_extend/wlan_extend_cmd.h | 4 + wlan/hdi_service/wlan_interface_drivers.c | 1 + wlan/hdi_service/wlan_interface_service.c | 0 wlan/interfaces/include/wifi_hal.h | 80 +++++ wlan/test/hdi_service/wlan_callback_impl.c | 17 +- wlan/test/unittest/hal/wifi_hal_test.cpp | 285 ++++++++++++++++++ 15 files changed, 1076 insertions(+), 45 deletions(-) mode change 100644 => 100755 wlan/hdi_service/wlan_interface_service.c diff --git a/wlan/client/include/wifi_driver_client.h b/wlan/client/include/wifi_driver_client.h index 993f0c83b8..4b59b913b9 100644 --- a/wlan/client/include/wifi_driver_client.h +++ b/wlan/client/include/wifi_driver_client.h @@ -42,6 +42,14 @@ extern "C" { #define WIFI_POWER_MODE_THROUGH_WALL 2 #define WIFI_POWER_MODE_NUM 3 +#define HML_PARAM_BUF_SIZE 1024 + +#define CMD_CLOSE_GO_CAC 133 +#define CMD_SET_GO_CSA_CHANNEL 161 +#define CMD_SET_GO_RADAR_DETECT 163 +#define CMD_ID_MCC_STA_P2P_QUOTA_TIME 167 +#define CMD_ID_CTRL_ROAM_CHANNEL 169 + /* common related interface */ enum WifiDriverClientResultCode { RET_CODE_SUCCESS = 0, @@ -152,11 +160,40 @@ enum WifiClientType { WIFI_CLIENT_BUTT }; +#ifndef WLANTYPES_H +struct HdfWifiInfo { + int32_t band; + uint32_t size; +}; + +struct CmdData { + int32_t cmdId; + int8_t* buf; + uint32_t bufLen; +}; + +struct HmlEventData { + uint32_t eventId; + uint8_t* buf; + uint32_t bufLen; +}; + +struct CoexChannelList { + uint8_t* buf; + uint32_t bufLen; +}; +#endif + typedef int32_t (*OnReceiveFunc)(uint32_t event, void *data, const char *ifName); int32_t WifiRegisterEventCallback(OnReceiveFunc onRecFunc, uint32_t eventType, const char *ifName); void WifiUnregisterEventCallback(OnReceiveFunc onRecFunc, uint32_t eventType, const char *ifName); +typedef int32_t (*NotifyMessage)(const char* ifName, struct HmlEventData *data); + +int32_t WifiRegisterHmlCallback(NotifyMessage func, const char *ifName); +int32_t WifiUnregisterHmlCallback(NotifyMessage func, const char *ifName); + /* hal related interface */ #define MAX_WLAN_DEVICE 3 #define MAX_CHANNEL_NUM 14 @@ -234,6 +271,9 @@ int32_t GetCurrentPowerMode(const char *ifName, uint8_t *mode); int32_t SetPowerMode(const char *ifName, uint8_t mode); int32_t StartChannelMeas(const char *ifName, int32_t commandId, const int32_t *paramBuf, uint32_t paramBufLen); int32_t GetChannelMeasResult(const char *ifName, int32_t commandId, uint32_t *paramBuf, uint32_t *paramBufLen); +int32_t GetCoexChannelList(const char *ifName, struct CoexChannelList *list); +int32_t SendHmlCmd(const char *ifName, const struct CmdData* data); +int32_t SendP2pCmd(const char *ifName, const struct CmdData* data); /* wpa related interface */ #define MAX_SSID_LEN 32 diff --git a/wlan/client/src/netlink/netlink_cmd_adapter.c b/wlan/client/src/netlink/netlink_cmd_adapter.c index 77ccde9d39..161ceae66a 100644 --- a/wlan/client/src/netlink/netlink_cmd_adapter.c +++ b/wlan/client/src/netlink/netlink_cmd_adapter.c @@ -47,17 +47,25 @@ #define WAITFORTHREAD 100000 #define RETRIES 30 -#define STR_WLAN0 "wlan0" -#define STR_WLAN1 "wlan1" -#define STR_P2P0 "p2p0" -#define STR_P2P0_X "p2p0-" +#define STR_WLAN0 "wlan0" +#define STR_WLAN1 "wlan1" +#define STR_P2P0 "p2p0" +#define STR_P2P0_X "p2p0-" -#define PRIMARY_ID_POWER_MODE 0x8bfd +#define PRIMARY_ID_POWER_MODE 0x8bfd #define SECONDARY_ID_POWER_MODE 0x101 -#define SET_POWER_MODE_SLEEP "pow_mode sleep" -#define SET_POWER_MODE_INIT "pow_mode init" -#define SET_POWER_MODE_THIRD "pow_mode third" -#define GET_POWER_MODE "get_pow_mode" +#define SET_POWER_MODE_SLEEP "pow_mode sleep" +#define SET_POWER_MODE_INIT "pow_mode init" +#define SET_POWER_MODE_THIRD "pow_mode third" +#define GET_POWER_MODE "get_pow_mode" + +#define CMD_SET_CLOSE_GO_CAC "SET_CLOSE_GO_CAC" +#define CMD_SET_CHANGE_GO_CHANNEL "CMD_SET_CHANGE_GO_CHANNEL" +#define CMD_SET_GO_DETECT_RADAR "CMD_SET_GO_DETECT_RADAR" +#define CMD_SET_DYNAMIC_DBAC_MODE "SET_DYNAMIC_DBAC_MODE" +#define CMD_SET_P2P_SCENES "CMD_SET_P2P_SCENES" +#define P2P_BUF_SIZE 64 +#define MAX_PRIV_CMD_SIZE 4096 // vendor attr enum AndrWifiAttr { @@ -101,6 +109,12 @@ typedef struct { union HwprivReqData data; } HwprivIoctlData; +typedef struct { + char *buf; + int size; + int len; +}WifiPrivCmd; + static struct WifiHalInfo g_wifiHalInfo = {0}; static struct nl_sock *OpenNetlinkSocket(void) @@ -1403,3 +1417,189 @@ int32_t GetChannelMeasResult(const char *ifName, int32_t commandId, uint32_t *pa (void)paramBufLen; return RET_CODE_NOT_SUPPORT; } + +int32_t GetCoexChannelList(const char *ifName, struct CoexChannelList *list) +{ + (void)ifName; + (void)list; + return RET_CODE_NOT_SUPPORT; +} + +int32_t SendHmlCmd(const char *ifName, const struct CmdData *data) +{ + (void)ifName; + (void)data; + return RET_CODE_NOT_SUPPORT; +} + +static int32_t SendCommandToDriver(const char *cmd, uint32_t len, const char *ifName) +{ + struct ifreq ifr = {0}; + int ret = RET_CODE_FAILURE; + WifiPrivCmd privCmd = {0}; + char buf[MAX_PRIV_CMD_SIZE] = {0}; + uint32_t bufSize = MAX_PRIV_CMD_SIZE; + + if (cmd == NULL) { + HILOG_ERROR(LOG_DOMAIN, "%s: cmd is null\n", __FUNCTION__); + return RET_CODE_INVALID_PARAM; + } + if (len > MAX_PRIV_CMD_SIZE) { + HILOG_ERROR(LOG_DOMAIN, "%s: Size of command is too large\n", __FUNCTION__); + return RET_CODE_INVALID_PARAM; + } + + if (memcpy_s(buf, bufSize, cmd, len) != EOK) { + HILOG_ERROR(LOG_DOMAIN, "%s: memcpy_s error\n", __FUNCTION__); + return RET_CODE_FAILURE; + } + privCmd.buf = buf; + privCmd.size = sizeof(buf); + privCmd.len = size; + ifr.ifr_data = &privCmd; + if (strcpy_s(ifr.ifr_name, IFNAMSIZ, ifName) != EOK) { + HILOG_ERROR(LOG_DOMAIN, "%s: strcpy_s error\n", __FUNCTION__); + return RET_CODE_FAILURE; + } + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + HILOG_ERROR(LOG_DOMAIN, "%s: socket failed, errno = %d, (%s)\n", __FUNCTION__, errno, strerror(errno)); + return ret; + } + do { + ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr); + if (ret < 0) { + HILOG_ERROR(LOG_DOMAIN, "%s: ioctl failed, errno = %d, (%s)\n", __FUNCTION__, errno, strerror(errno)); + ret = (errno == EOPNOTSUPP) ? RET_CODE_NOT_SUPPORT : RET_CODE_FAILURE; + break; + } + (void)memset_s((void *)cmd, len, 0, len); + if (memcpy_s((void *)cmd, len, privCmd.buf, len - 1) != EOK) { + HILOG_ERROR(LOG_DOMAIN, "%s: memcpy_s error\n", __FUNCTION__); + ret = RET_CODE_FAILURE; + } + } while (0); + + close(sock); + return RET_CODE_SUCCESS; +} + +static int32_t DisableNextCacOnce(const char *ifName) +{ + char cmdBuf[P2P_BUF_SIZE] = {CMD_SET_CLOSE_GO_CAC}; + + return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName); +} + +static int32_t SetGoChannel(const char *ifName, const int8_t *data, uint32_t len) +{ + int ret = RET_CODE_FAILURE; + char cmdBuf[P2P_BUF_SIZE] = {0}; + uint32_t cmdLen = strlen(CMD_SET_CHANGE_GO_CHANNEL); + + if ((cmdLen + len) > P2P_BUF_SIZE) { + HILOG_ERROR(LOG_DOMAIN, "%s: the length of input data is too large\n", __FUNCTION__); + return ret; + } + ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_CHANGE_GO_CHANNEL, *data); + if (ret != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: ifName: %s, len = %u, value: %d, cmdBuf: %s\n", __FUNCTION__, ifName, len, *data, + cmdBuf); + return RET_CODE_FAILURE; + } + + return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName); +} + +static int32_t SetGoDetectRadar(const char *ifName, const int8_t *data, uint32_t len) +{ + int ret = RET_CODE_FAILURE; + char cmdBuf[P2P_BUF_SIZE] = {0}; + uint32_t cmdLen = strlen(CMD_SET_GO_DETECT_RADAR); + + if ((cmdLen + len) > P2P_BUF_SIZE) { + HILOG_ERROR(LOG_DOMAIN, "%s: the length of input data is too large\n", __FUNCTION__); + return ret; + } + ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_GO_DETECT_RADAR, *data); + if (ret != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: ifName: %s, len = %u, value: %d, cmdBuf: %s\n", __FUNCTION__, ifName, len, *data, + cmdBuf); + return RET_CODE_FAILURE; + } + return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName); +} + +static int32_t SetP2pScenes(const char *ifName, const int8_t *data, uint32_t len) +{ + int ret = RET_CODE_FAILURE; + char cmdBuf[P2P_BUF_SIZE] = {0}; + uint32_t cmdLen = strlen(CMD_SET_P2P_SCENES); + + if ((cmdLen + len) > P2P_BUF_SIZE) { + HILOG_ERROR(LOG_DOMAIN, "%s: the length of input data is too large\n", __FUNCTION__); + return ret; + } + ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_P2P_SCENES, *data); + if (ret != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: ifName: %s, len = %u, value: %d, cmdBuf: %s\n", __FUNCTION__, ifName, len, *data, + cmdBuf); + return RET_CODE_FAILURE; + } + return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName); +} + +static int32_t SetDynamicDbacMode(const char *ifName, int8_t *data, uint32_t len) +{ + int ret = RET_CODE_FAILURE; + char cmdBuf[P2P_BUF_SIZE] = {0}; + uint32_t cmdLen = strlen(CMD_SET_DYNAMIC_DBAC_MODE); + + if ((cmdLen + len) > P2P_BUF_SIZE) { + HILOG_ERROR(LOG_DOMAIN, "%s: the length of input data is too large\n", __FUNCTION__); + return ret; + } + ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_DYNAMIC_DBAC_MODE, *data); + if (ret != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: ifName: %s, len = %u, value: %d, cmdBuf: %s\n", __FUNCTION__, ifName, len, *data, + cmdBuf); + return RET_CODE_FAILURE; + } + return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName); +} + +int32_t SendP2pCmd(const char *ifName, const struct CmdData *data) +{ + int32_t ret; + + if (strcmp(ifName, STR_WLAN0) != EOK) { + HILOG_ERROR(LOG_DOMAIN, "%s: %s is not supported\n", __FUNCTION__, ifName); + return RET_CODE_NOT_SUPPORT; + } + switch (data->cmdId) { + case CMD_CLOSE_GO_CAC: + ret = DisableNextCacOnce(ifName); + break; + case CMD_SET_GO_CHANNEL: + ret = SetGoChannel(ifName, data->buf, data->bufLen); + break; + case CMD_SET_GO_RADAR_DETECT: + ret = SetGoDetectRadar(ifName, data->buf, data->bufLen); + break; + case CMD_ID_MCC_STA_P2P_QUOTA_TIME: + ret = SetDynamicDbacMode(data->buf, data->bufLen); + break; + case CMD_ID_CTRL_ROAM_CHANNEL: + ret = SetP2pScenes(ifName, data->buf, data->bufLen); + break; + default: + HILOG_ERROR(LOG_DOMAIN, "%s: Invalid command id", __FUNCTION__); + return RET_CODE_NOT_SUPPORT; + } + + if (ret != HDF_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: Send p2p command fail, ret = %d\n", __FUNCTION__, ret); + ret = RET_CODE_FAILURE; + } + return ret; +} \ No newline at end of file diff --git a/wlan/client/src/sbuf/sbuf_cmd_adapter.c b/wlan/client/src/sbuf/sbuf_cmd_adapter.c index 83886efe15..7d3296e7f3 100644 --- a/wlan/client/src/sbuf/sbuf_cmd_adapter.c +++ b/wlan/client/src/sbuf/sbuf_cmd_adapter.c @@ -909,6 +909,115 @@ int32_t GetChannelMeasResult(const char *ifName, int32_t commandId, uint32_t *pa return ret; } +int32_t GetCoexChannelList(const char *ifName, struct CoexChannelList *list) +{ + int32_t ret = RET_CODE_FAILURE; + struct HdfSBuf *data = NULL; + struct HdfSBuf *reply = NULL; + + if (HdfSbufObtainDefault(&data, &reply) != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: HdfSbufObtainDefault fail", __FUNCTION__); + return RET_CODE_FAILURE; + } + + do { + if (!HdfSbufWriteString(data, ifName)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write ifName fail!", __FUNCTION__); + break; + } + if (!HdfSbufWriteUint32(data, list->bufLen)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write paramBufLen fail!", __FUNCTION__); + break; + } + ret = SendCmdSync(WIFI_HAL_CMD_GET_COEX_CHANNEL_LIST, data, reply); + if (ret != RET_CODE_SUCCESS) { + break; + } + if (!HdfSbufReadBuffer(reply, (const void **)(&(list->buf)), &(list->bufLen))) { + HILOG_ERROR(LOG_DOMAIN, "%s: read paramBuf fail!", __FUNCTION__); + ret = RET_CODE_FAILURE; + } + } while (0); + + if (data != NULL) { + HdfSbufRecycle(data); + data = NULL; + } + if (reply != NULL) { + HdfSbufRecycle(reply); + reply = NULL; + } + return ret; +} + +int32_t SendHmlCmd(const char *ifName, const struct CmdData* data) +{ + int32_t ret = RET_CODE_FAILURE; + struct HdfSBuf *req = NULL; + + req = HdfSbufObtainDefaultSize(); + if (req == NULL) { + HILOG_ERROR(LOG_DOMAIN, "%s: HdfSbufObtainDefaultSize fail!", __FUNCTION__); + return ret; + } + + do { + if (!HdfSbufWriteString(req, ifName)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write ifName fail!", __FUNCTION__); + break; + } + if (!HdfSbufWriteInt32(req, data->cmdId)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write cmd fail!", __FUNCTION__); + break; + } + if (!HdfSbufWriteBuffer(req, data->buf, data->bufLen)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write data fail!", __FUNCTION__); + break; + } + ret = SendCmdSync(WIFI_HAL_CMD_SEND_HML_CMD, req, NULL); + if (ret != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: SendCmdSync fail, ret = %{public}d!", __FUNCTION__, ret); + } + } while (0); + + HdfSbufRecycle(req); + return ret; +} + +int32_t SendP2pCmd(const char *ifName, const struct CmdData* data) +{ + int32_t ret = RET_CODE_FAILURE; + struct HdfSBuf *req = NULL; + + req = HdfSbufObtainDefaultSize(); + if (req == NULL) { + HILOG_ERROR(LOG_DOMAIN, "%s: HdfSbufObtainDefaultSize fail!", __FUNCTION__); + return ret; + } + + do { + if (!HdfSbufWriteString(req, ifName)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write ifName fail!", __FUNCTION__); + break; + } + if (!HdfSbufWriteInt32(req, data->cmdId)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write cmd fail!", __FUNCTION__); + break; + } + if (!HdfSbufWriteBuffer(req, data->buf, data->bufLen)) { + HILOG_ERROR(LOG_DOMAIN, "%s: write data fail!", __FUNCTION__); + break; + } + ret = SendCmdSync(WIFI_HAL_CMD_SEND_P2P_CMD, req, NULL); + if (ret != RET_CODE_SUCCESS) { + HILOG_ERROR(LOG_DOMAIN, "%s: SendCmdSync fail, ret = %{public}d!", __FUNCTION__, ret); + } + } while (0); + + HdfSbufRecycle(req); + return ret; +} + #ifdef __cplusplus #if __cplusplus } diff --git a/wlan/client/src/wifi_common_cmd.h b/wlan/client/src/wifi_common_cmd.h index 60f139d153..1172aa9cba 100644 --- a/wlan/client/src/wifi_common_cmd.h +++ b/wlan/client/src/wifi_common_cmd.h @@ -57,7 +57,10 @@ enum BaseCommands { CMD_BASE_GET_POWER_MODE, CMD_BASE_SET_POWER_MODE, CMD_BASE_START_CHANNEL_MEAS, - CMD_BASE_GET_CHANNEL_MEAS_RESULT + CMD_BASE_GET_CHANNEL_MEAS_RESULT, + CMD_BASE_GET_COEX_CHANNEL_LIST, + CMD_BASE_SEND_HML_CMD, + CMD_BASE_SEND_P2P_CMD }; enum APCommands { @@ -108,7 +111,10 @@ typedef enum { WIFI_HAL_CMD_GET_POWER_MODE = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_GET_POWER_MODE), WIFI_HAL_CMD_SET_POWER_MODE = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_SET_POWER_MODE), WIFI_HAL_CMD_START_CHANNEL_MEAS = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_START_CHANNEL_MEAS), - WIFI_HAL_CMD_GET_CHANNEL_MEAS_RESULT = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_GET_CHANNEL_MEAS_RESULT) + WIFI_HAL_CMD_GET_CHANNEL_MEAS_RESULT = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_GET_CHANNEL_MEAS_RESULT), + WIFI_HAL_CMD_GET_COEX_CHANNEL_LIST = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_GET_COEX_CHANNEL_LIST), + WIFI_HAL_CMD_SEND_HML_CMD = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_SEND_HML_CMD), + WIFI_HAL_CMD_SEND_P2P_CMD = HDF_WIFI_CMD(BASE_SERVICE_ID, CMD_BASE_SEND_P2P_CMD), } WifiHalCmd; typedef enum { @@ -149,6 +155,11 @@ struct CallbackEvent { OnReceiveFunc onRecFunc; }; +struct HmlCallbackEvent { + char ifName[IFNAMSIZ + 1]; + NotifyMessage func; +}; + void WifiEventReport(const char *ifName, uint32_t event, void *data); #endif /* end of wifi_common_cmd.h */ diff --git a/wlan/client/src/wifi_driver_client.c b/wlan/client/src/wifi_driver_client.c index 067ffe8af8..55456f0e82 100644 --- a/wlan/client/src/wifi_driver_client.c +++ b/wlan/client/src/wifi_driver_client.c @@ -15,6 +15,7 @@ #include #include +#include #include "wifi_common_cmd.h" #include "hilog/log.h" #include "securec.h" @@ -31,6 +32,7 @@ extern "C" { #define MAX_CALL_BACK_COUNT 10 static struct CallbackEvent *g_callbackEventMap[MAX_CALL_BACK_COUNT] = {NULL}; +static struct HmlCallbackEvent *g_hmlCallbackMap[MAX_CALL_BACK_COUNT] = {NULL}; void WifiEventReport(const char *ifName, uint32_t event, void *data) { @@ -103,6 +105,75 @@ void WifiUnregisterEventCallback(OnReceiveFunc onRecFunc, uint32_t eventType, co } } +void WifiHmlReport(const char *ifName, struct HmlEventData *data) +{ + uint32_t i; + + for (i = 0; i < MAX_CALL_BACK_COUNT; i++) { + if (g_hmlCallbackMap[i] != NULL && (strcmp(g_hmlCallbackMap[i]->ifName, ifName) == 0)) { + HILOG_INFO(LOG_DOMAIN, "%s: WifiHmlReport send event, ifName = %s", __FUNCTION__, ifName); + g_hmlCallbackMap[i]->func(ifName, data); + } + } +} + +int32_t WifiRegisterHmlCallback(NotifyMessage func, const char *ifName) +{ + uint32_t i; + struct HmlCallbackEvent *hmlCallbackEvent = NULL; + + if (func == NULL || ifName == NULL) { + HILOG_ERROR(LOG_DOMAIN, "%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__); + return RET_CODE_INVALID_PARAM; + } + for (i = 0; i < MAX_CALL_BACK_COUNT; i++) { + if (g_hmlCallbackMap[i] != NULL && (strcmp(g_hmlCallbackMap[i]->ifName, ifName) == 0) && + g_hmlCallbackMap[i]->func == func) { + HILOG_INFO(LOG_DOMAIN, "%s the func has been registered!", __FUNCTION__); + return RET_CODE_SUCCESS; + } + } + hmlCallbackEvent = (struct HmlCallbackEvent *)OsalMemCalloc(sizeof(struct HmlCallbackEvent)); + if (hmlCallbackEvent == NULL) { + HILOG_ERROR(LOG_DOMAIN, "%s fail: malloc fail!", __FUNCTION__); + return RET_CODE_FAILURE; + } + if (strcpy_s(hmlCallbackEvent->ifName, IFNAMSIZ, ifName) != RET_CODE_SUCCESS) { + OsalMemFree(hmlCallbackEvent); + return RET_CODE_FAILURE; + } + hmlCallbackEvent->func = func; + for (i = 0; i < MAX_CALL_BACK_COUNT; i++) { + if (g_hmlCallbackMap[i] == NULL) { + g_hmlCallbackMap[i] = hmlCallbackEvent; + return RET_CODE_SUCCESS; + } + } + OsalMemFree(hmlCallbackEvent); + HILOG_ERROR(LOG_DOMAIN, "%s fail: register onRecFunc num more than %d!", __FUNCTION__, MAX_CALL_BACK_COUNT); + return RET_CODE_FAILURE; +} + +int32_t WifiUnregisterHmlCallback(NotifyMessage func, const char *ifName) +{ + uint32_t i; + + if (func == NULL || ifName == NULL) { + HILOG_ERROR(LOG_DOMAIN, "%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__); + return RET_CODE_FAILURE; + } + for (i = 0; i < MAX_CALL_BACK_COUNT; i++) { + if (g_hmlCallbackMap[i] != NULL && (strcmp(g_hmlCallbackMap[i]->ifName, ifName) == 0) && + g_hmlCallbackMap[i]->func == func) { + g_hmlCallbackMap[i]->func = NULL; + OsalMemFree(g_hmlCallbackMap[i]); + g_hmlCallbackMap[i] = NULL; + return RET_CODE_SUCCESS; + } + } + return RET_CODE_FAILURE; +} + #ifdef __cplusplus #if __cplusplus } diff --git a/wlan/hal/src/wifi_hal.c b/wlan/hal/src/wifi_hal.c index 0e1e0309bd..66abefd7ed 100644 --- a/wlan/hal/src/wifi_hal.c +++ b/wlan/hal/src/wifi_hal.c @@ -293,6 +293,56 @@ static int32_t GetChannelMeasResultInner(const char *ifName, int32_t commandId, return GetChannelMeasResult(ifName, commandId, paramBuf, paramBufLen); } +static int32_t HalRegisterHmlCallbackInner(NotifyMessage func, const char *ifName) +{ + if (func == NULL || ifName == NULL) { + HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__); + return HDF_ERR_INVALID_PARAM; + } + if (WifiRegisterHmlCallback(func, ifName) != HDF_SUCCESS) { + HDF_LOGE("%s: hml callback function has been registered, line: %d", __FUNCTION__, __LINE__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t HalUnregisterHmlCallbackInner(NotifyMessage func, const char *ifName) +{ + if (func == NULL || ifName == NULL) { + HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__); + return HDF_ERR_INVALID_PARAM; + } + WifiUnregisterHmlCallback(func, ifName); + return HDF_SUCCESS; +} + +static int32_t GetCoexChannelListInner(const char *ifName, struct CoexChannelList *list) +{ + if (ifName == NULL || list == NULL) { + HDF_LOGE("%{public}s: input parameter invalid, line: %{public}d", __FUNCTION__, __LINE__); + return HDF_ERR_INVALID_PARAM; + } + return GetCoexChannelList(ifName, list); +} + +static int32_t SendHmlCmdInner(const char *ifName, const struct CmdData* data) +{ + if (ifName == NULL || data == NULL) { + HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__); + return HDF_ERR_INVALID_PARAM; + } + return SendHmlCmd(ifName, data); +} + +static int32_t SendP2pCmdInner(const char *ifName, const struct CmdData* data) +{ + if (ifName == NULL || data == NULL) { + HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__); + return HDF_ERR_INVALID_PARAM; + } + return SendP2pCmd(ifName, data); +} + static int32_t Start(struct IWiFi *iwifi) { HalMutexLock(); @@ -415,6 +465,46 @@ static int32_t WifiGetChannelMeasResult(const char *ifName, int32_t commandId, u return ret; } +static int32_t HalRegisterHmlCallback(NotifyMessage func, const char *ifName) +{ + HalMutexLock(); + int32_t ret = HalRegisterHmlCallbackInner(func, ifName); + HalMutexUnlock(); + return ret; +} + +static int32_t HalUnregisterHmlCallback(NotifyMessage func, const char *ifName) +{ + HalMutexLock(); + int32_t ret = HalUnregisterHmlCallbackInner(func, ifName); + HalMutexUnlock(); + return ret; +} + +static int32_t WifiGetCoexChannelList(const char *ifName, struct CoexChannelList *list) +{ + HalMutexLock(); + int32_t ret = GetCoexChannelListInner(ifName, list); + HalMutexUnlock(); + return ret; +} + +static int32_t WifiSendHmlCmd(const char *ifName, const struct CmdData* data) +{ + HalMutexLock(); + int32_t ret = SendHmlCmdInner(ifName, data); + HalMutexUnlock(); + return ret; +} + +static int32_t WifiSendP2pCmd(const char *ifName, const struct CmdData* data) +{ + HalMutexLock(); + int32_t ret = SendP2pCmdInner(ifName, data); + HalMutexUnlock(); + return ret; +} + int32_t WifiConstruct(struct IWiFi **wifiInstance) { static bool isInited = false; @@ -441,6 +531,11 @@ int32_t WifiConstruct(struct IWiFi **wifiInstance) singleWifiInstance.setPowerMode = WifiSetPowerMode; singleWifiInstance.startChannelMeas = WifiStartChannelMeas; singleWifiInstance.getChannelMeasResult = WifiGetChannelMeasResult; + singleWifiInstance.registerHmlCallback = HalRegisterHmlCallback; + singleWifiInstance.unregisterHmlCallback = HalUnregisterHmlCallback; + singleWifiInstance.getCoexChannelList = WifiGetCoexChannelList; + singleWifiInstance.sendHmlCmd = WifiSendHmlCmd; + singleWifiInstance.sendP2pCmd = WifiSendP2pCmd; InitIWiFiList(); isInited = true; } diff --git a/wlan/hdi_service/service_common/wlan_common_cmd.c b/wlan/hdi_service/service_common/wlan_common_cmd.c index 0113902015..97fd1d5be5 100644 --- a/wlan/hdi_service/service_common/wlan_common_cmd.c +++ b/wlan/hdi_service/service_common/wlan_common_cmd.c @@ -18,6 +18,7 @@ #include #include #include +#include "wlan_extend_cmd.h" #include "v1_0/iwlan_callback.h" #include "v1_0/iwlan_interface.h" #include "v1_0/wlan_interface_service.h" @@ -181,7 +182,7 @@ int32_t WlanInterfaceGetAsscociatedStas(struct IWlanInterface *self, const struc OsalMemFree(wifiStaInfo); return ret; } - for (int i = 0; i < *staInfoLen; i++) { + for (uint32_t i = 0; i < *staInfoLen; i++) { staInfo[i].mac = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * ETH_ADDR_LEN); if (staInfo[i].mac != NULL) { if (memcpy_s(staInfo[i].mac, WIFI_MAC_ADDR_LENGTH, wifiStaInfo[i].mac, WIFI_MAC_ADDR_LENGTH) != EOK) { @@ -576,6 +577,47 @@ static int32_t HdfWLanCallbackFun(uint32_t event, void *data, const char *ifName return ret; } +static void HdfWlanDelRemoteObj(struct IWlanCallback *self) +{ + struct HdfWlanRemoteNode *pos = NULL; + struct HdfWlanRemoteNode *tmp = NULL; + struct DListHead *head = &HdfStubDriver()->remoteListHead; + + (void)self; + DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct HdfWlanRemoteNode, node) { + if (pos->service->index == self->AsObject(self)->index) { + DListRemove(&(pos->node)); + WlanCallbackRelease(pos->callbackObj); + OsalMemFree(pos); + break; + } + } + WlanCallbackRelease(self); +} + +int32_t HdfWLanHmlCallbackFun(const char* ifName, struct HmlEventData *data) +{ + struct HdfWlanRemoteNode *pos = NULL; + struct DListHead *head = &HdfStubDriver()->remoteListHead; + int32_t ret = HDF_FAILURE; + + if (data == NULL || ifName == NULL) { + HDF_LOGE("%{public}s: data or ifName is NULL!", __func__); + return HDF_ERR_INVALID_PARAM; + } + DLIST_FOR_EACH_ENTRY(pos, head, struct HdfWlanRemoteNode, node) { + if (pos->service == NULL || pos->callbackObj == NULL) { + HDF_LOGW("%{public}s: pos->service or pos->callbackObj NULL", __func__); + continue; + } + ret = pos->callbackObj->NotifyMessage(pos->callbackObj, ifName, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: dispatch code fialed, error code: %{public}d", __func__, ret); + } + } + return ret; +} + int32_t WlanInterfaceRegisterEventCallback(struct IWlanInterface *self, struct IWlanCallback *cbFunc, const char *ifName) { @@ -586,6 +628,10 @@ int32_t WlanInterfaceRegisterEventCallback(struct IWlanInterface *self, struct I HDF_LOGE("%{public}s: input parameter invalid!", __func__); return HDF_ERR_INVALID_PARAM; } + if (g_wifi == NULL) { + HDF_LOGE("%{public}s g_wifi is NULL!", __func__); + return HDF_FAILURE; + } (void)OsalMutexLock(&HdfStubDriver()->mutex); ret = HdfWlanAddRemoteObj(cbFunc); if (ret != HDF_SUCCESS) { @@ -593,35 +639,23 @@ int32_t WlanInterfaceRegisterEventCallback(struct IWlanInterface *self, struct I HDF_LOGE("%{public}s: HdfSensorAddRemoteObj false", __func__); return ret; } - if (g_wifi == NULL) { - HDF_LOGE("%{public}s g_wifi is NULL!", __func__); - (void)OsalMutexUnlock(&HdfStubDriver()->mutex); - return HDF_FAILURE; - } - ret = g_wifi->registerEventCallback(HdfWLanCallbackFun, ifName); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%{public}s: Register failed!, error code: %{public}d", __func__, ret); - } - (void)OsalMutexUnlock(&HdfStubDriver()->mutex); - return ret; -} - -static void HdfWlanDelRemoteObj(struct IWlanCallback *self) -{ - struct HdfWlanRemoteNode *pos = NULL; - struct HdfWlanRemoteNode *tmp = NULL; - struct DListHead *head = &HdfStubDriver()->remoteListHead; - - (void)self; - DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct HdfWlanRemoteNode, node) { - if (pos->service->index == self->AsObject(self)->index) { - DListRemove(&(pos->node)); - WlanCallbackRelease(pos->callbackObj); - OsalMemFree(pos); + do { + ret = g_wifi->registerEventCallback(HdfWLanCallbackFun, ifName); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: Register failed!, error code: %{public}d", __func__, ret); + HdfWlanDelRemoteObj(cbFunc); break; } - } - WlanCallbackRelease(self); + ret = WlanInterfaceRegisterHmlCallback(HdfWLanHmlCallbackFun, ifName); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: Register hml callback failed!, error code: %{public}d", __func__, ret); + HdfWlanDelRemoteObj(cbFunc); + g_wifi->unregisterEventCallback(HdfWLanCallbackFun, ifName); + } + } while (0); + + (void)OsalMutexUnlock(&HdfStubDriver()->mutex); + return ret; } int32_t WlanInterfaceUnregisterEventCallback(struct IWlanInterface *self, struct IWlanCallback *cbFunc, @@ -634,13 +668,12 @@ int32_t WlanInterfaceUnregisterEventCallback(struct IWlanInterface *self, struct HDF_LOGE("%{public}s: input parameter invalid!", __func__); return HDF_ERR_INVALID_PARAM; } - (void)OsalMutexLock(&HdfStubDriver()->mutex); - HdfWlanDelRemoteObj(cbFunc); if (g_wifi == NULL) { HDF_LOGE("%{public}s g_wifi is NULL!", __func__); - (void)OsalMutexUnlock(&HdfStubDriver()->mutex); return HDF_FAILURE; } + (void)OsalMutexLock(&HdfStubDriver()->mutex); + HdfWlanDelRemoteObj(cbFunc); if (DListIsEmpty(&HdfStubDriver()->remoteListHead)) { ret = g_wifi->unregisterEventCallback(HdfWLanCallbackFun, ifName); if (ret != HDF_SUCCESS) { @@ -648,6 +681,12 @@ int32_t WlanInterfaceUnregisterEventCallback(struct IWlanInterface *self, struct HDF_LOGE("%{public}s: Unregister failed!, error code: %{public}d", __func__, ret); return ret; } + ret = WlanInterfaceUnregisterHmlCallback(HdfWLanHmlCallbackFun, ifName); + if (ret != HDF_SUCCESS) { + (void)OsalMutexUnlock(&HdfStubDriver()->mutex); + HDF_LOGE("%{public}s: Unregister hml callback failed!, error code: %{public}d", __func__, ret); + return ret; + } } (void)OsalMutexUnlock(&HdfStubDriver()->mutex); return HDF_SUCCESS; @@ -820,7 +859,7 @@ int32_t WlanInterfaceGetNetDevInfo(struct IWlanInterface *self, struct HdfNetDev return HDF_FAILURE; } netDeviceInfoResult->deviceInfosLen = MAX_NETDEVICE_COUNT; - for (int i = 0; i < netDeviceInfoResult->deviceInfosLen; i++) { + for (uint32_t i = 0; i < netDeviceInfoResult->deviceInfosLen; i++) { netDeviceInfoResult->deviceInfos[i].index = netDeviceInfo->deviceInfos[i].index; netDeviceInfoResult->deviceInfos[i].iftype = netDeviceInfo->deviceInfos[i].iftype; netDeviceInfoResult->deviceInfos[i].ifName = (char *)OsalMemCalloc(sizeof(char) * IFNAMSIZ); @@ -1001,6 +1040,26 @@ int32_t WlanInterfaceSetPowerMode(struct IWlanInterface *self, const struct HdfF return ret; } +int32_t WlanInterfaceSendP2pCmd(struct IWlanInterface *self, const char* ifName, const struct CmdData* data) +{ + int32_t ret; + + (void)self; + if (ifName == NULL || data == NULL) { + HDF_LOGE("%{public}s input parameter invalid!", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (g_wifi == NULL) { + HDF_LOGE("%{public}s g_wifi is NULL!", __func__); + return HDF_FAILURE; + } + ret = g_wifi->sendP2pCmd(ifName, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: get channel meas result failed!, error code: %{public}d", __func__, ret); + } + return ret; +} + int32_t WlanInterfaceWifiConstruct(void) { int32_t ret; diff --git a/wlan/hdi_service/service_common/wlan_common_cmd.h b/wlan/hdi_service/service_common/wlan_common_cmd.h index 5c56d6ceab..b602f9b04b 100644 --- a/wlan/hdi_service/service_common/wlan_common_cmd.h +++ b/wlan/hdi_service/service_common/wlan_common_cmd.h @@ -55,6 +55,7 @@ int32_t WlanInterfaceStartScan(struct IWlanInterface *self, const struct HdfFeat const struct HdfWifiScan *scan); int32_t WlanInterfaceGetPowerMode(struct IWlanInterface *self, const struct HdfFeatureInfo *ifeature, uint8_t *mode); int32_t WlanInterfaceSetPowerMode(struct IWlanInterface *self, const struct HdfFeatureInfo *ifeature, uint8_t mode); +int32_t WlanInterfaceSendP2pCmd(struct IWlanInterface *self, const char* ifName, const struct CmdData* data); int32_t WlanInterfaceWifiConstruct(void); int32_t WlanInterfaceWifiDestruct(void); #endif diff --git a/wlan/hdi_service/service_extend/wlan_extend_cmd.c b/wlan/hdi_service/service_extend/wlan_extend_cmd.c index 0f1a3cd9d8..e4eff45e67 100644 --- a/wlan/hdi_service/service_extend/wlan_extend_cmd.c +++ b/wlan/hdi_service/service_extend/wlan_extend_cmd.c @@ -65,6 +65,68 @@ int32_t WlanInterfaceGetChannelMeasResult(struct IWlanInterface *self, const cha return ret; } +int32_t WlanInterfaceRegisterHmlCallback(NotifyMessage func, const char *ifName) +{ + int32_t ret; + + ret = g_wifi->registerHmlCallback(func, ifName); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: Register hml callback failed!, error code: %{public}d", __func__, ret); + } + return ret; +} + +int32_t WlanInterfaceUnregisterHmlCallback(NotifyMessage func, const char *ifName) +{ + int32_t ret; + + ret = g_wifi->unregisterHmlCallback(func, ifName); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: Register hml callback failed!, error code: %{public}d", __func__, ret); + } + return ret; +} + +int32_t WlanInterfaceGetCoexChannelList(struct IWlanInterface *self, const char* ifName, struct CoexChannelList *data) +{ + int32_t ret; + + (void)self; + if (ifName == NULL || data == NULL) { + HDF_LOGE("%{public}s input parameter invalid!", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (g_wifi == NULL) { + HDF_LOGE("%{public}s g_wifi is NULL!", __func__); + return HDF_FAILURE; + } + ret = g_wifi->getCoexChannelList(ifName, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: get coex channel list failed!, error code: %{public}d", __func__, ret); + } + return ret; +} + +int32_t WlanInterfaceSendHmlCmd(struct IWlanInterface *self, const char* ifName, const struct CmdData* data) +{ + int32_t ret; + + (void)self; + if (ifName == NULL || data == NULL) { + HDF_LOGE("%{public}s input parameter invalid!", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (g_wifi == NULL) { + HDF_LOGE("%{public}s g_wifi is NULL!", __func__); + return HDF_FAILURE; + } + ret = g_wifi->sendHmlCmd(ifName, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: get channel meas result failed!, error code: %{public}d", __func__, ret); + } + return ret; +} + int32_t WlanExtendInterfaceWifiConstruct(void) { int32_t ret; diff --git a/wlan/hdi_service/service_extend/wlan_extend_cmd.h b/wlan/hdi_service/service_extend/wlan_extend_cmd.h index c86cbb5844..7f615db758 100644 --- a/wlan/hdi_service/service_extend/wlan_extend_cmd.h +++ b/wlan/hdi_service/service_extend/wlan_extend_cmd.h @@ -20,6 +20,10 @@ int32_t WlanInterfaceStartChannelMeas(struct IWlanInterface *self, const char* i const int32_t* paramBuf, uint32_t paramBufLen); int32_t WlanInterfaceGetChannelMeasResult(struct IWlanInterface *self, const char* ifName, int32_t commandId, uint32_t* paramBuf, uint32_t* paramBufLen); +int32_t WlanInterfaceRegisterHmlCallback(NotifyMessage func, const char *ifName); +int32_t WlanInterfaceUnregisterHmlCallback(NotifyMessage func, const char *ifName); +int32_t WlanInterfaceGetCoexChannelList(struct IWlanInterface *self, const char* ifName, struct CoexChannelList *data); +int32_t WlanInterfaceSendHmlCmd(struct IWlanInterface *self, const char* ifName, const struct CmdData* data); int32_t WlanExtendInterfaceWifiConstruct(void); int32_t WlanExtendInterfaceWifiDestruct(void); #endif diff --git a/wlan/hdi_service/wlan_interface_drivers.c b/wlan/hdi_service/wlan_interface_drivers.c index 634927e739..7fb0cbc2e7 100644 --- a/wlan/hdi_service/wlan_interface_drivers.c +++ b/wlan/hdi_service/wlan_interface_drivers.c @@ -60,6 +60,7 @@ int HdfWlanInterfaceDriverInit(struct HdfDeviceObject *deviceObject) } if (WlanInterfaceServiceInit() != HDF_SUCCESS) { HDF_LOGE("%{public}s: wlan interface service init failed!", __func__); + OsalMutexDestroy(&stubData->mutex); return HDF_FAILURE; } return HDF_SUCCESS; diff --git a/wlan/hdi_service/wlan_interface_service.c b/wlan/hdi_service/wlan_interface_service.c old mode 100644 new mode 100755 diff --git a/wlan/interfaces/include/wifi_hal.h b/wlan/interfaces/include/wifi_hal.h index 9d5a18f1d8..cd142ee87c 100644 --- a/wlan/interfaces/include/wifi_hal.h +++ b/wlan/interfaces/include/wifi_hal.h @@ -62,6 +62,20 @@ extern "C" { */ typedef int32_t (*CallbackFunc)(uint32_t event, void *data, const char *ifName); +/** + * @brief Defines a callback to listen for IWiFi asynchronous hml events. + * + * @param ifName The interface name. + * @param buf Indicates the pointer to the data passed to the callback. + * @param size Indicates the size of buf; + * + * @return Returns 0 if the IWiFi callback is defined; returns a negative value otherwise. + * + * @since 1.0 + * @version 1.0 + */ +typedef int32_t (*HmlCallbackFunc)(const char* ifName, int32_t cmd, const int8_t *buf, uint32_t bufLen); + /** * @brief Defines the basic WLAN features provided by the hardware abstraction layer (HAL). * @@ -268,6 +282,72 @@ struct IWiFi { * @version 1.0 */ int32_t (*getChannelMeasResult)(const char *ifName, int32_t commandId, uint32_t *paramBuf, uint32_t *paramBufLen); + + /** + * @brief Registers a callback to listen for IWiFi asynchronous hml events. + * + * @param func Indicates the callback to register. + * @param ifName Indicates the pointer to the network interface name. + * + * @return Returns 0 if the callback is registered; returns a negative value otherwise. + * + * @since 3.2 + * @version 1.0 + */ + int32_t (*registerHmlCallback)(NotifyMessage func, const char *ifName); + + /** + * @brief Unregisters an IWiFi hml callback. + + * @param func Indicates the callback to register. + * @param ifName Indicates the pointer to the network interface name. + * + * @return Returns 0 if the IWiFi callback is deregistered; returns a negative value otherwise. + * + * @since 3.2 + * @version 1.0 + */ + int32_t (*unregisterHmlCallback)(NotifyMessage func, const char *ifName); + + /** + * @brief Obtaining Coex Channel List. + * + * @param ifName Indicates the pointer to the network interface name. + * @param data Coex channel list result data. + * @param paramBufLen Buffer size of coex channel list result data. + * + * @return Returns 0 if get infos successful; returns a negative value otherwise. + * + * @since 3.2 + * @version 1.0 + */ + int32_t (*getCoexChannelList)(const char* ifName, struct CoexChannelList *data); + + /** + * @brief Send hml command to driver. + * + * @param ifName Indicates the pointer to the network interface name. + * @param data Struct whose member including command id, buffer and length of buffer. + * + * @return Returns 0 if send command successful; returns a negative value otherwise. + * + * @since 3.2 + * @version 1.0 + */ + int32_t (*sendHmlCmd)(const char *ifName, const struct CmdData* data); + + /** + * @brief Send p2p command to driver. + * + * @param ifName Indicates the pointer to the network interface name. + * @param data Struct whose member including command id, buffer and length of buffer. + * + * @return Returns 0 if send command successful; returns a negative value otherwise. + * + * @since 3.2 + * @version 1.0 + */ + int32_t (*sendP2pCmd)(const char *ifName, const struct CmdData* data); }; /** diff --git a/wlan/test/hdi_service/wlan_callback_impl.c b/wlan/test/hdi_service/wlan_callback_impl.c index 7d517523fd..918482d95d 100644 --- a/wlan/test/hdi_service/wlan_callback_impl.c +++ b/wlan/test/hdi_service/wlan_callback_impl.c @@ -30,8 +30,8 @@ int32_t WlanCallbackResetDriver(struct IWlanCallback *self, uint32_t event, int3 return HDF_SUCCESS; } -int32_t WlanCallbackScanResult( - struct IWlanCallback *self, uint32_t event, const struct HdfWifiScanResult *scanResult, const char *ifName) +int32_t WlanCallbackScanResult(struct IWlanCallback *self, uint32_t event, const struct HdfWifiScanResult *scanResult, + const char *ifName) { (void)self; if (scanResult == NULL || ifName == NULL) { @@ -46,6 +46,18 @@ int32_t WlanCallbackScanResult( return HDF_SUCCESS; } +int32_t WlanCallbackHmlNotifyMessage(struct IWlanCallback *self, const char *ifName, + const struct HmlEventData *data) +{ + (void)self; + if (ifName == NULL || data == NULL) { + HDF_LOGE("%{public}s: input parameter invalid!", __func__); + return HDF_ERR_INVALID_PARAM; + } + HDF_LOGE("WlanCallbackResetDriver: receive hml notify message\n"); + return HDF_SUCCESS; +} + struct IWlanCallback *WlanCallbackServiceGet(void) { struct WlanCallbackService *service = @@ -63,6 +75,7 @@ struct IWlanCallback *WlanCallbackServiceGet(void) service->stub.interface.ResetDriverResult = WlanCallbackResetDriver; service->stub.interface.ScanResult = WlanCallbackScanResult; + service->stub.interface.NotifyMessage = WlanCallbackHmlNotifyMessage; return &service->stub.interface; } diff --git a/wlan/test/unittest/hal/wifi_hal_test.cpp b/wlan/test/unittest/hal/wifi_hal_test.cpp index 7f2cfec9f2..5e73e08ddd 100644 --- a/wlan/test/unittest/hal/wifi_hal_test.cpp +++ b/wlan/test/unittest/hal/wifi_hal_test.cpp @@ -31,6 +31,7 @@ const uint32_t IFNAME_MIN_NUM = 0; const uint32_t IFNAME_MAX_NUM = 32; const uint32_t MAX_IF_NAME_LENGTH = 16; const uint32_t SIZE = 4; +const int32_t TEST_CMD = 123; class WifiHalTest : public testing::Test { public: @@ -174,6 +175,16 @@ static int32_t HalCallbackEvent(uint32_t event, void *respData, const char *ifNa return HDF_SUCCESS; } +static int32_t HmlCallbackEvent(const char *ifName, struct HmlEventData *data) +{ + if (ifName == NULL || data == NULL) { + return HDF_FAILURE; + } + + printf("Receive hml callback event\n"); + return HDF_SUCCESS; +} + /** * @tc.name: WifiHalRegisterEventCallback001 * @tc.desc: Wifi hal register callback function test @@ -1229,6 +1240,280 @@ HWTEST_F(WifiHalTest, SetScanningMacAddress001, TestSize.Level1) EXPECT_EQ(ret, HDF_SUCCESS); } +/** + * @tc.name: WifiHalRegisterHmlCallback001 + * @tc.desc: Wifi hal register callback function test + * @tc.type: FUNC + * @tc.require: AR000F869G + */ +HWTEST_F(WifiHalTest, WifiHalRegisterHmlCallback001, TestSize.Level1) +{ + int ret; + + ret = g_wifi->registerHmlCallback(HmlCallbackEvent, "wlan0"); + EXPECT_EQ(HDF_SUCCESS, ret); +} + +/** + * @tc.name: WifiHalUnregisterHmlCallback001 + * @tc.desc: Wifi hal unregister callback function test + * @tc.type: FUNC + * @tc.require: AR000F869G + */ +HWTEST_F(WifiHalTest, WifiHalUnregisterHmlCallback001, TestSize.Level1) +{ + int ret; + + ret = g_wifi->unregisterHmlCallback(HmlCallbackEvent, "wlan0"); + EXPECT_EQ(HDF_SUCCESS, ret); +} + +/** + * @tc.name: GetCoexChannelList001 + * @tc.desc: wifi hal get coex channel list function test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WifiHalTest, GetCoexChannelList001, TestSize.Level1) +{ + int32_t ret; + struct IWiFiAp *apFeature = nullptr; + uint32_t bufLen = HML_PARAM_BUF_SIZE; + uint8_t buf[HML_PARAM_BUF_SIZE] = {0}; + struct CoexChannelList list = {0}; + list.buf = buf; + list.bufLen = bufLen; + + ret = g_wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature); + EXPECT_EQ(ret, HDF_SUCCESS); + EXPECT_NE(apFeature, nullptr); + ret = g_wifi->getCoexChannelList(nullptr, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->getCoexChannelList(apFeature->baseFeature.ifName, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->getCoexChannelList(nullptr, &list); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->getCoexChannelList(apFeature->baseFeature.ifName, &list); + printf("GetCoexChannelList001_%d: ret = %d\n", __LINE__, ret); + bool flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + ret = g_wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature); + EXPECT_EQ(ret, HDF_SUCCESS); +} + +/** + * @tc.name: GetCoexChannelList002 + * @tc.desc: wifi hal get coex channel list function test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WifiHalTest, GetCoexChannelList002, TestSize.Level1) +{ + int32_t ret; + struct IWiFiSta *staFeature = nullptr; + uint32_t bufLen = HML_PARAM_BUF_SIZE; + uint8_t buf[HML_PARAM_BUF_SIZE] = {0}; + struct CoexChannelList list = {0}; + list.buf = buf; + list.bufLen = bufLen; + + ret = g_wifi->createFeature(PROTOCOL_80211_IFTYPE_STATION, (struct IWiFiBaseFeature **)&staFeature); + EXPECT_EQ(ret, HDF_SUCCESS); + EXPECT_NE(staFeature, nullptr); + ret = g_wifi->getCoexChannelList(nullptr, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->getCoexChannelList(staFeature->baseFeature.ifName, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->getCoexChannelList(nullptr, &list); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->getCoexChannelList(staFeature->baseFeature.ifName, &list); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + bool flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + ret = g_wifi->destroyFeature((struct IWiFiBaseFeature *)staFeature); + EXPECT_EQ(ret, HDF_SUCCESS); +} + +/** + * @tc.name: SendHmlCmd001 + * @tc.desc: wifi hal send hml command function test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WifiHalTest, SendHmlCmd001, TestSize.Level1) +{ + int32_t ret; + struct IWiFiAp *apFeature = nullptr; + uint32_t bufLen = HML_PARAM_BUF_SIZE; + int8_t buf[HML_PARAM_BUF_SIZE] = {0}; + struct CmdData data = {0}; + data.cmdId = TEST_CMD; + data.buf = buf; + data.bufLen = bufLen; + + ret = g_wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature); + EXPECT_EQ(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(nullptr, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(apFeature->baseFeature.ifName, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(nullptr, &data); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(apFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + bool flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + ret = g_wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature); + EXPECT_EQ(ret, HDF_SUCCESS); +} + +/** + * @tc.name: SendHmlCmd002 + * @tc.desc: wifi hal send hml command function test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WifiHalTest, SendHmlCmd002, TestSize.Level1) +{ + int32_t ret; + struct IWiFiSta *staFeature = nullptr; + uint32_t bufLen = HML_PARAM_BUF_SIZE; + int8_t buf[HML_PARAM_BUF_SIZE] = {0}; + struct CmdData data = {0}; + data.cmdId = TEST_CMD; + data.buf = buf; + data.bufLen = bufLen; + + ret = g_wifi->createFeature(PROTOCOL_80211_IFTYPE_STATION, (struct IWiFiBaseFeature **)&staFeature); + EXPECT_EQ(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(nullptr, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(staFeature->baseFeature.ifName, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(nullptr, &data); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendHmlCmd(staFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + bool flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + ret = g_wifi->destroyFeature((struct IWiFiBaseFeature *)staFeature); + EXPECT_EQ(ret, HDF_SUCCESS); +} + +/** + * @tc.name: SendP2pCmd001 + * @tc.desc: wifi hal send p2p command function test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WifiHalTest, SendP2pCmd001, TestSize.Level1) +{ + int32_t ret; + bool flag; + struct IWiFiAp *apFeature = nullptr; + uint32_t bufLen = HML_PARAM_BUF_SIZE; + int8_t buf[HML_PARAM_BUF_SIZE] = {0}; + struct CmdData data = {0}; + data.cmdId = TEST_CMD; + data.buf = buf; + data.bufLen = bufLen; + + ret = g_wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature); + EXPECT_EQ(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(nullptr, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(nullptr, &data); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, &data); + EXPECT_NE(ret, HDF_SUCCESS); + data.cmdId = CMD_CLOSE_GO_CAC; + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_SET_GO_CSA_CHANNEL; + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_SET_RADAR_DETECT; + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_ID_MCC_STA_P2P_QUOTA_TIME; + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_ID_CTRL_ROAM_CHANNEL; + ret = g_wifi->sendP2pCmd(apFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + ret = g_wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature); + EXPECT_EQ(ret, HDF_SUCCESS); +} + +/** + * @tc.name: SendP2pCmd002 + * @tc.desc: wifi hal send p2p command function test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WifiHalTest, SendP2pCmd002, TestSize.Level1) +{ + int32_t ret; + bool flag; + struct IWiFiSta *staFeature = nullptr; + uint32_t bufLen = HML_PARAM_BUF_SIZE; + int8_t buf[HML_PARAM_BUF_SIZE] = {0}; + struct CmdData data = {0}; + data.cmdId = TEST_CMD; + data.buf = buf; + data.bufLen = bufLen; + + ret = g_wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&staFeature); + EXPECT_EQ(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(nullptr, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, nullptr); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(nullptr, &data); + EXPECT_NE(ret, HDF_SUCCESS); + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, &data); + EXPECT_NE(ret, HDF_SUCCESS); + data.cmdId = CMD_CLOSE_GO_CAC; + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_SET_GO_CSA_CHANNEL; + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_SET_RADAR_DETECT; + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_ID_MCC_STA_P2P_QUOTA_TIME; + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + data.cmdId = CMD_ID_CTRL_ROAM_CHANNEL; + ret = g_wifi->sendP2pCmd(staFeature->baseFeature.ifName, &data); + printf("GetCoexChannelList002_%d: ret = %d\n", __LINE__, ret); + flag = (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT); + ASSERT_TRUE(flag); + ret = g_wifi->destroyFeature((struct IWiFiBaseFeature *)staFeature); + EXPECT_EQ(ret, HDF_SUCCESS); +} + /** * @tc.name: ResetDriver001 * @tc.desc: wifi hal reset driver function test -- Gitee