EC600U_esp32_iap_uart/usbnet/usbnet_demo.c

299 lines
7.7 KiB
C
Raw Permalink Normal View History

2024-02-05 17:39:56 +08:00
/*============================================================================
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ql_api_osi.h"
#include "ql_log.h"
#include "ql_api_nw.h"
#include "ql_api_datacall.h"
#include "ql_api_usbnet.h"
#include "ql_power.h"
#define QL_USBNET_LOG_LEVEL QL_LOG_LEVEL_INFO
#define QL_USBNET_DEMO_LOG(msg, ...) QL_LOG(QL_USBNET_LOG_LEVEL, "usbnet_demo", msg, ##__VA_ARGS__)
#define QUEC_USBNET_STOP_REQ 100|(QL_COMPONENT_NETWORK_USBNET<<16)
ql_sem_t ql_nw_reg_sem = NULL;
ql_task_t usbnet_task = NULL;
ql_timer_t usbnet_stop_timer = NULL;
static void usbnet_timer_callback(void *ctx)
{
ql_event_t event={0};
event.id = QUEC_USBNET_STOP_REQ;
ql_rtos_event_send(usbnet_task, &event); //send event to reconnect
return;
}
static void ql_nw_event_callback(uint8_t sim_id, unsigned int event_type, void *ind_msg_buf)
{
if(QUEC_NW_DATA_REG_STATUS_IND == event_type)
{
ql_nw_common_reg_status_info_s *data_reg_status=(ql_nw_common_reg_status_info_s *)ind_msg_buf;
QL_USBNET_DEMO_LOG("Sim%d data reg status changed, current status is %d", sim_id, data_reg_status->state);
if((QL_NW_REG_STATE_HOME_NETWORK == data_reg_status->state) || (QL_NW_REG_STATE_ROAMING == data_reg_status->state))
{
ql_rtos_semaphore_release(ql_nw_reg_sem);
}
}
}
static void ql_usbnet_event_callback(unsigned int event_type, ql_usbnet_errcode_e errcode, void *ctx)
{
QL_USBNET_DEMO_LOG("event_type: 0x%x, errcode: 0x%x", event_type, errcode);
switch(event_type)
{
case QUEC_USBNET_START_RSP_IND:
{
if(QL_USBNET_SUCCESS == errcode)
{
QL_USBNET_DEMO_LOG("usbnet connect success");
//run the following blocked code, the RNDIS/ECM dial will be disconnected after two minutes
#if 0
int ret = ql_rtos_timer_start(usbnet_stop_timer, 1000 * 120, 0);
if(ret != 0)
{
QL_USBNET_DEMO_LOG("usbnet_stop_timer start failed");
}
#endif
}
else
{
QL_USBNET_DEMO_LOG("usbnet connect fail, err: 0x%x", errcode);
ql_rtos_timer_stop(usbnet_stop_timer);
}
break;
}
case QUEC_USBNET_DEACTIVE_IND:
{
QL_USBNET_DEMO_LOG("PDP deactived");
ql_rtos_timer_stop(usbnet_stop_timer);
ql_event_t event={0};
event.id = QUEC_USBNET_DEACTIVE_IND;
ql_rtos_event_send(usbnet_task, &event); //send event to reconnect
break;
}
case QUEC_USBNET_PORT_CONNECT_IND:
{
QL_USBNET_DEMO_LOG("usb port plug in");
ql_event_t event={0};
event.id = QUEC_USBNET_PORT_CONNECT_IND;
ql_rtos_event_send(usbnet_task, &event); //send event to reconnect
break;
}
case QUEC_USBNET_PORT_DISCONNECT_IND:
{
QL_USBNET_DEMO_LOG("usb port pull out");
ql_rtos_timer_stop(usbnet_stop_timer);
break;
}
}
}
static void usbent_app_thread(void * arg)
{
ql_usbnet_errcode_e ret = 0;
uint8_t sim_id = 0;
int profile_idx = 1; //range 1 to 7
ql_nw_reg_status_info_s nw_info = {0};
ql_event_t event;
ql_usbnet_type_e saved_type = 0;
ql_usbnet_type_e target_type = QL_USBNET_ECM;
ql_usbnet_state_e status = QL_USBNET_STATE_NONE;
uint8_t reset_flag = false;
ret = ql_rtos_timer_create(&usbnet_stop_timer, usbnet_task, usbnet_timer_callback, NULL);
QL_USBNET_DEMO_LOG("create timer ret: 0x%x", ret);
if(ret != 0)
{
goto exit;
}
ret = ql_usbnet_get_type(&saved_type);
QL_USBNET_DEMO_LOG("get usbnet saved type ret: 0x%x, %d", ret, saved_type);
if(0 != ret)
{
goto exit;
}
//run the following blocked code, RNDIS/ECM and Socket can use profile 1 simultaneously
#if 0
uint32_t saved_list = 0;
uint32_t target_list = 0x1; //enable sim0 profile 1 nat function
ret = ql_datacall_get_nat(&saved_list);
QL_USBNET_DEMO_LOG("get datacall saved nat ret: 0x%x, %d", ret, saved_list);
if(0 != ret)
{
goto exit;
}
if(saved_list != target_list)
{
ret = ql_datacall_set_nat(target_list);
QL_USBNET_DEMO_LOG("ql_datacall_set_nat err, ret=0x%x", ret);
if(0 != ret)
{
goto exit;
}
reset_flag = true; //NAT function reboot to take effect
}
/*ql_nat_subnet_config_s config = {"192.168.1.0","255.255.255.0"};
ret = ql_datacall_set_subnet(sim_id, profile_idx, &config);
QL_USBNET_DEMO_LOG("ql_datacall_set_subnet ret=0x%x", ret);
if(0 != ret)
{
goto exit;
}*/
#endif
if(saved_type != target_type)
{
ret = ql_usbnet_set_type(target_type);
QL_USBNET_DEMO_LOG("ql_usbnet_set_type err, ret=0x%x", ret);
if(0 != ret)
{
goto exit;
}
reset_flag = true; //usbnet type reboot to take effect
}
if(reset_flag)
{
ql_power_reset(RESET_NORMAL);
}
ql_rtos_semaphore_create(&ql_nw_reg_sem, 0);
ret = ql_nw_register_cb(ql_nw_event_callback);
QL_USBNET_DEMO_LOG("register network callback ret=0x%x", ret);
if(0 != ret)
{
goto exit;
}
ret = ql_nw_get_reg_status(sim_id, &nw_info);
QL_USBNET_DEMO_LOG("ret: 0x%x, current data reg status=%d", ret, nw_info.data_reg.state);
if((QL_NW_REG_STATE_HOME_NETWORK != nw_info.data_reg.state) && (QL_NW_REG_STATE_ROAMING != nw_info.data_reg.state))
{
ql_rtos_semaphore_wait(ql_nw_reg_sem, QL_WAIT_FOREVER); //wait network registered
}
ret = ql_usbnet_register_cb(ql_usbnet_event_callback, NULL);
QL_USBNET_DEMO_LOG("register usbnet callback ret=0x%x", ret);
if(ret != QL_USBNET_SUCCESS)
{
goto exit;
}
ret = ql_usbnet_get_status(&status);
QL_USBNET_DEMO_LOG("ret: 0x%x, usbnet status: %d", ret, status);
if((QL_USBNET_SUCCESS == ret) && (QL_USBNET_STATE_NONE == status))
{
ret = ql_usbnet_start(sim_id, profile_idx, NULL);
QL_USBNET_DEMO_LOG("ql_usbnet_start ret=0x%x", ret);
}
while(1)
{
if(ql_event_try_wait(&event) != 0)
{
continue;
}
switch (event.id)
{
case QUEC_USBNET_DEACTIVE_IND:
{
ql_rtos_task_sleep_ms(5000); //wait network status update
ret = ql_nw_get_reg_status(sim_id, &nw_info);
if((QL_NW_REG_STATE_HOME_NETWORK != nw_info.data_reg.state) && (QL_NW_REG_STATE_ROAMING != nw_info.data_reg.state))
{
ql_rtos_semaphore_wait(ql_nw_reg_sem, QL_WAIT_FOREVER);
}
ret = ql_usbnet_start(sim_id, profile_idx, NULL);
QL_USBNET_DEMO_LOG("ql_usbnet_start ret=0x%x", ret);
break;
}
case QUEC_USBNET_PORT_CONNECT_IND:
{
ret = ql_usbnet_start(sim_id, profile_idx, NULL);
QL_USBNET_DEMO_LOG("ql_usbnet_start ret=0x%x", ret);
break;
}
case QUEC_USBNET_STOP_REQ:
{
ret = ql_usbnet_get_status(&status);
QL_USBNET_DEMO_LOG("ret: 0x%x, usbnet status: %d", ret, status);
if((QL_USBNET_SUCCESS == ret) && (QL_USBNET_STATE_CONNECT == status))
{
ret = ql_usbnet_stop();
QL_USBNET_DEMO_LOG("ql_usbnet_stop ret=0x%x", ret);
}
break;
}
}
}
exit:
if(ql_nw_reg_sem != NULL)
{
ql_rtos_semaphore_delete(ql_nw_reg_sem);
ql_nw_reg_sem = NULL;
}
if(usbnet_stop_timer != NULL)
{
ql_rtos_timer_delete(usbnet_stop_timer);
usbnet_stop_timer = NULL;
}
if(usbnet_task != NULL)
{
ql_rtos_task_delete(usbnet_task);
usbnet_task = NULL;
}
}
void ql_usbnet_app_init(void)
{
QlOSStatus err = QL_OSI_SUCCESS;
err = ql_rtos_task_create(&usbnet_task, 4*1024, APP_PRIORITY_NORMAL, "QUSBNETDEMO", usbent_app_thread, NULL, 10);
if(err != QL_OSI_SUCCESS)
{
QL_USBNET_DEMO_LOG("task created failed");
return;
}
}