/** @file ql_wifi_net.c @brief Quectel wifi net api. */ /*============================================================================ Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. =============================================================================*/ /*=========================================================================== EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. WHEN WHO WHAT, WHERE, WHY ---------- ------------ ---------------------------------------------------- =============================================================================*/ /*=========================================================================== * include files ===========================================================================*/ #include #include #include #include "ql_api_osi.h" #include "ql_osi_def.h" #include "ql_log.h" #include "ql_api_wifi.h" #include "quec_common.h" #include "ql_wifi_msg.h" #include "ql_wifi_net.h" /*======================================================================== * Macro Definition *========================================================================*/ #define QL_WIFI_LOG_LEVEL QL_LOG_LEVEL_INFO #define QL_WIFI_NET_LOG(msg, ...) QL_LOG(QL_WIFI_LOG_LEVEL, "wifi_net", msg, ##__VA_ARGS__) #define QL_WIFI_NET_TASK_EVENT_CNT 5 #define QL_WIFI_NET_MSG_QUEUE_CNT 100 /*======================================================================== * Enumeration Definition *========================================================================*/ /*======================================================================== * Type Definition *=========================================================================*/ typedef struct { ql_queue_t msg_queue; ql_task_t task; ql_wifi_net_app_notify_cb app_notify_cb; } ql_wifi_net_manager_s; /*======================================================================== * Global Variable *========================================================================*/ ql_wifi_net_manager_s ql_wifi_net_manager = {0}; ql_mutex_t ql_wifi_net_mutex = NULL; /*======================================================================== * function Definition *========================================================================*/ void ql_wifi_net_recv(void *ctx) { // Message from MSG engine.It needs to be registered to MSG engine. // Once we get data from MSG engine,it will be passed to NET engine. ql_wifi_msg_cmd_info_s *info = (ql_wifi_msg_cmd_info_s *)ctx; QuecOSStatus err; ql_wifi_msg_cmd_info_s msg_cmd_info = {0}; ql_wifi_net_manager_s *manager = &ql_wifi_net_manager; msg_cmd_info.msg_id = info->msg_id; msg_cmd_info.msg_info = info->msg_info; QL_WIFI_NET_LOG("net msg %x/%p", info->msg_id, info->msg_info); ql_rtos_mutex_try_lock(ql_wifi_net_mutex); err = ql_rtos_queue_release(manager->msg_queue, sizeof(ql_wifi_msg_cmd_info_s), (uint8 *)&msg_cmd_info, QL_NO_WAIT); if (err) { QL_WIFI_NET_LOG("net msg rel failed"); } ql_rtos_mutex_unlock(ql_wifi_net_mutex); return; } static void ql_wifi_net_state_notify(void *ctx) { ql_wifi_state_e state = *((ql_wifi_state_e*)ctx); char *p = NULL; ql_wifi_net_manager_s *manager = &ql_wifi_net_manager; p = malloc(2); if (p == NULL) { return; } p[0] = (char)state; p[1] = '\0'; // Nofity Wi-Fi connect status to APP engine. ql_rtos_mutex_try_lock(ql_wifi_net_mutex); if (manager->app_notify_cb) { ql_wifi_msg_cmd_info_s info = {.msg_id = QL_WIFI_APP_STA_STATUS_CMD,.msg_info = p}; manager->app_notify_cb(&info); } ql_rtos_mutex_unlock(ql_wifi_net_mutex); } ql_wifi_net_errcode_e ql_wifi_net_app_notify_cb_register(ql_wifi_net_app_notify_cb cb) { // APP engine notification cb for notifying app status. // Use ql_wifi_net_state_notify to calling this callback. ql_wifi_net_manager_s *manager = &ql_wifi_net_manager; ql_rtos_mutex_try_lock(ql_wifi_net_mutex); manager->app_notify_cb = cb; ql_rtos_mutex_unlock(ql_wifi_net_mutex); return QL_WIFI_NET_SUCCESS; } void ql_wifi_net_thread(void *argv) { QuecOSStatus err; ql_wifi_msg_cmd_info_s cmd_info = {0}; ql_wifi_net_manager_s *manager = &ql_wifi_net_manager; QL_WIFI_NET_LOG("wifi net init"); err = ql_rtos_queue_create(&(manager->msg_queue), sizeof(ql_wifi_msg_cmd_info_s), QL_WIFI_NET_MSG_QUEUE_CNT); if (err) { QL_WIFI_NET_LOG("create queue faild!"); goto exit; } if (QL_WIFI_MSG_SUCCESS != ql_wifi_msg_net_notify_cb_register(ql_wifi_net_recv)) { QL_WIFI_NET_LOG("msg net cb reg err"); goto exit; } // from net to app if (QL_WIFI_SUCCESS != ql_wifi_status_notify_cb_register(ql_wifi_net_state_notify)) { QL_WIFI_NET_LOG("wifi status notify cb reg err"); goto exit; } while (1) { memset(&cmd_info, 0, sizeof(ql_wifi_msg_cmd_info_s)); QL_WIFI_NET_LOG(""); err = ql_rtos_queue_wait(manager->msg_queue, (uint8 *)&cmd_info, sizeof(ql_wifi_msg_cmd_info_s), QL_WAIT_FOREVER); if (err != kNoErr) { QL_WIFI_NET_LOG("wait error err= %d", err); goto exit; } QL_WIFI_NET_LOG("cmd_info.msg_id=%d", cmd_info.msg_id); switch (cmd_info.msg_id) { case QL_WIFI_NPTO_802_3_STREAM: { // Undefined net command // ql_wifi_msg_info_s *msg_ptr = (ql_wifi_msg_info_s *)(cmd_info.msg_info); // ql_wifi_data_input(msg_ptr->data,msg_ptr->data_len); break; } case QL_WIFI_NPTO_STA_IP_START_CMD: { ql_wifi_sta_ip_start(cmd_info.msg_info); break; } case QL_WIFI_NPTO_STA_IP_DOWN_CMD: { ql_wifi_sta_ip_down(cmd_info.msg_info); break; } case QL_WIFI_NPTO_WLAN_CREATE_CMD: { ql_wifi_wlan_create(cmd_info.msg_info); break; } case QL_WIFI_NPTO_WLAN_DESTROY_CMD: { ql_wifi_wlan_destroy(cmd_info.msg_info); break; } case QL_WIFI_NPTO_UAP_IP_START_CMD: case QL_WIFI_NPTO_UAP_IP_DOWN_CMD: case QL_WIFI_NPTO_IP_ADDR_SET_CMD: default: { QL_WIFI_NET_LOG("cmd_info.msg_id=%d ERROR", cmd_info.msg_id); break; } } QL_WIFI_NET_LOG("cmd_info.msg_info=%p", cmd_info.msg_info); if (cmd_info.msg_info != NULL) { free(cmd_info.msg_info); cmd_info.msg_info = NULL; } } exit: ql_rtos_mutex_try_lock(ql_wifi_net_mutex); memset(manager, 0, sizeof(ql_wifi_net_manager_s)); ql_rtos_mutex_unlock(ql_wifi_net_mutex); ql_rtos_task_delete(NULL); return; } ql_wifi_net_errcode_e ql_wifi_net_init(void *argv) { ql_wifi_net_errcode_e ret = QL_WIFI_NET_SUCCESS; ql_wifi_net_manager_s *manager = &ql_wifi_net_manager; QL_WIFI_NET_LOG("ql_wifi_net_init"); // Create mutex.Never delete. if (NULL == ql_wifi_net_mutex) { if (QL_OSI_SUCCESS != ql_rtos_mutex_create(&(ql_wifi_net_mutex))) { ret = QL_WIFI_NET_MUTEX_CREATE_ERR; return ret; } } ql_rtos_mutex_try_lock(ql_wifi_net_mutex); if(manager->task) { return QL_WIFI_NET_SUCCESS; } if (QL_OSI_SUCCESS != ql_rtos_task_create(&(manager->task), 4096, APP_PRIORITY_REALTIME, "ql_wifi_net", ql_wifi_net_thread, NULL, QL_WIFI_NET_TASK_EVENT_CNT)) { QL_WIFI_NET_LOG("ql_wifi_net_init err"); ret = QL_WIFI_NET_TASK_CREATE_ERR; } ql_rtos_mutex_unlock(ql_wifi_net_mutex); return ret; } ql_wifi_net_errcode_e ql_wifi_net_deint(void *argv) { return QL_WIFI_NET_SUCCESS; }