EC600U_esp32_iap_uart/stk/stk_demo.c

443 lines
13 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_stk.h"
#include "ql_api_osi.h"
#include "ql_power.h"
#include "ql_log.h"
#define QL_STK_DEMO_LOG_LEVEL QL_LOG_LEVEL_INFO
#define QL_STK_DEMO_LOG(msg, ...) QL_LOG(QL_STK_DEMO_LOG_LEVEL, "ql_STK_DEMO", msg, ##__VA_ARGS__)
#define QL_STK_DEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_STK_DEMO", msg, ##__VA_ARGS__)
#define QL_STK_ALPHABET_SET (QL_STK_ALPHABET_SET_UCS2)
#ifndef ARR_SIZE
#define ARR_SIZE(a) (sizeof((a)) / sizeof((a[0])))
#endif
typedef enum
{
MAIN_MENU = 0x00,
SUB_MENU = 0x01,
} ql_stk_menu_e;
static ql_task_t stk_task = NULL;
static ql_stk_alphabet_set_e stk_alphabet = QL_STK_ALPHABET_SET;
ql_stk_setup_menu_s menu_info = {0};
ql_stk_select_item_s submenu_info = {0};
static const ql_stk_errcode_e (*get_item_list_fp[])(uint8_t nSim, uint8_t item_identifier, ql_stk_item_s *info) = {
[MAIN_MENU] = ql_stk_acquire_setup_menu_item_list, [SUB_MENU] = ql_stk_acquire_sub_menu_item_list};
static bool hex_to_string(uint8_t const *data, uint16_t length, char *hexString)
{
uint16_t i = 0;
for(i=0; i<length; i++)
{
sprintf(&hexString[i*2], "%02X", data[i]);
}
return true;
}
void user_stk_event_callback(uint8_t nSim, uint32_t ind_type, void *ctx)
{
ql_event_t event = {0};
QL_STK_DEMO_LOG("nSim:%d, ind:%#02X", nSim, ind_type);
switch (ind_type)
{
case QUEC_STK_PROACTIVE_CMD_IND: {
QL_STK_DEMO_LOG("QUEC_STK_PROACTIVE_CMD_IND");
ql_stk_proactive_cmd_s *cmd = (ql_stk_proactive_cmd_s *)ctx;
event.id = QUEC_STK_PROACTIVE_CMD_IND;
event.param1 = nSim;
event.param2 = cmd->proactive_cmd_id;
ql_rtos_event_send(stk_task, &event);
break;
}
case QUEC_STK_TIMEOUT_IND: {
QL_STK_DEMO_LOG("QUEC_STK_TIMEOUT_IND");
ql_stk_timeout_s *cmd = (ql_stk_timeout_s *)ctx;
event.id = QUEC_STK_TIMEOUT_IND;
event.param1 = nSim;
event.param2 = cmd->proactive_cmd_id;
ql_rtos_event_send(stk_task, &event);
break;
}
case QUEC_STK_SIM_LOST_IND: {
QL_STK_DEMO_LOG("QUEC_STK_SIM_LOST_IND");
event.id = QUEC_STK_SIM_LOST_IND;
event.param1 = nSim;
ql_rtos_event_send(stk_task, &event);
break;
}
case QUEC_STK_NO_PROACTIVE_CMD_IND: {
QL_STK_DEMO_LOG("QUEC_STK_NO_PROACTIVE_CMD_IND");
event.id = QUEC_STK_NO_PROACTIVE_CMD_IND;
event.param1 = nSim;
ql_rtos_event_send(stk_task, &event);
break;
}
default:
break;
}
}
static void stk_item_list_info(uint8_t nSim, ql_stk_menu_e menu_type, uint8_t *id_arr, uint8_t id_total)
{
ql_stk_item_s item_info = {0};
uint8_t *str_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX);
if (str_buffer == NULL)
{
return;
}
item_info.item_text.text = str_buffer;
item_info.item_text.length = QL_STK_STRING_LENGTH_MAX;
char *item_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX * 2 + 1);
if (item_buffer == NULL)
{
return;
}
for (size_t i = 0; i < id_total; i++)
{
item_info.item_text.length = QL_STK_STRING_LENGTH_MAX;
ql_stk_errcode_e err = get_item_list_fp[menu_type](nSim, id_arr[i], &item_info);
if (err == QL_STK_SUCCESS)
{
if (stk_alphabet == QL_STK_ALPHABET_SET_UCS2)
{
hex_to_string(item_info.item_text.text, item_info.item_text.length, item_buffer);
}
else
{
memcpy(item_buffer, item_info.item_text.text, strlen((const char *)item_info.item_text.text));
}
if (MAIN_MENU == menu_type)
{
QL_STK_DEMO_LOG(" |%d : %s", id_arr[i], item_buffer);
}
else
{
QL_STK_DEMO_LOG(" ||%d : %s", id_arr[i], item_buffer);
}
}
}
free(str_buffer);
str_buffer = NULL;
free(item_buffer);
item_buffer = NULL;
}
static void stk_setup_menu_info(uint8_t nSim)
{
uint8_t *str_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX);
if (str_buffer == NULL)
{
return;
}
menu_info.title.text = str_buffer;
menu_info.title.length = QL_STK_STRING_LENGTH_MAX;
/* get proactive command SET UP MENU */
ql_stk_errcode_e err = ql_stk_acquire_setup_menu_info(nSim, &menu_info);
if (QL_STK_SUCCESS != err)
{
QL_STK_DEMO_LOG("failed to get setup menu info, error:%d", err);
return;
}
/* command details */
QL_STK_DEMO_LOG("qualifier:%d", menu_info.qualifier);
char *title_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX * 2 + 1);
if (title_buffer == NULL)
{
return;
}
if (stk_alphabet == QL_STK_ALPHABET_SET_UCS2)
{
hex_to_string(menu_info.title.text, menu_info.title.length, title_buffer);
}
else
{
memcpy(title_buffer, menu_info.title.text, strlen((const char *)menu_info.title.text));
}
QL_STK_DEMO_LOG("------- Title:%s -------", title_buffer);
free(str_buffer);
str_buffer = NULL;
free(title_buffer);
title_buffer = NULL;
stk_item_list_info(nSim, MAIN_MENU, menu_info.item_id, menu_info.num_items);
}
static void stk_select_item_info(uint8_t nSim)
{
uint8_t *str_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX);
if (str_buffer == NULL)
{
return;
}
submenu_info.title.text = str_buffer;
submenu_info.title.length = QL_STK_STRING_LENGTH_MAX;
/* get proactive command SELECT ITEM */
ql_stk_errcode_e err = ql_stk_acquire_sub_menu_info(nSim, &submenu_info);
if (QL_STK_SUCCESS != err)
{
QL_STK_DEMO_LOG("failed to get sub menu info, error:%d", err);
return;
}
/* command details */
QL_STK_DEMO_LOG("qualifier:%d",submenu_info.qualifier);
char *title_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX * 2 + 1);
if (title_buffer == NULL)
{
return;
}
if (stk_alphabet == QL_STK_ALPHABET_SET_UCS2)
{
hex_to_string(submenu_info.title.text, submenu_info.title.length, title_buffer);
}
else
{
memcpy(title_buffer, submenu_info.title.text, strlen((const char *)submenu_info.title.text));
}
QL_STK_DEMO_LOG("======= Title:%s =======", title_buffer);
free(str_buffer);
str_buffer = NULL;
free(title_buffer);
title_buffer = NULL;
stk_item_list_info(nSim, SUB_MENU, submenu_info.item_id, submenu_info.num_items);
}
static void stk_display_text_info(uint8_t nSim)
{
ql_stk_display_text_s display_text_info = {0};
uint8_t *str_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX);
if (str_buffer == NULL)
{
return;
}
display_text_info.text_string.text = str_buffer;
display_text_info.text_string.length = QL_STK_STRING_LENGTH_MAX;
/* DISPLAY TEXT */
ql_stk_errcode_e err = ql_stk_acquire_display_text_info(nSim, &display_text_info);
if (QL_STK_SUCCESS != err)
{
QL_STK_DEMO_LOG("failed to get sub menu info, error:%d", err);
return;
}
/* command details */
QL_STK_DEMO_LOG("qualifier:%d", display_text_info.qualifier);
char *text_buffer = calloc(1, QL_STK_STRING_LENGTH_MAX * 2 + 1);
if (text_buffer == NULL)
{
return;
}
if (stk_alphabet == QL_STK_ALPHABET_SET_UCS2)
{
hex_to_string(display_text_info.text_string.text, display_text_info.text_string.length, text_buffer);
}
else
{
memcpy(text_buffer, display_text_info.text_string.text, strlen((const char *)display_text_info.text_string.text));
}
QL_STK_DEMO_LOG("******* text:%s *******", text_buffer);
free(str_buffer);
str_buffer = NULL;
free(text_buffer);
text_buffer = NULL;
}
void stk_proactive_cmd_handler(uint8_t nSim, uint8_t proactive_cmd)
{
QL_STK_DEMO_LOG("get proactive command:'%02x' on sim:%d", proactive_cmd, nSim);
switch (proactive_cmd)
{
case QL_STK_PROACTIVE_CMD_SETUP_MENU: {
stk_setup_menu_info(nSim);
/* response proactive command with result '00' */
ql_stk_send_command_result(nSim, proactive_cmd, QL_STK_PERFORMED_SUCCESSFULLY, 0, NULL);
break;
}
case QL_STK_PROACTIVE_CMD_SELECT_ITEM:
stk_select_item_info(nSim);
/* select an item, send terminal response(ok) with item ID */
//ql_stk_send_command_result(nSim, proactive_cmd, QL_STK_PERFORMED_SUCCESSFULLY, submenu_info.item_id[0], NULL);
ql_stk_send_command_result(nSim, QSTK_TERMINATE_STK_SESSION, QL_STK_PROACTIVE_SIM_SESSION_TERMINATED_BY_THE_USER, 0, NULL);
break;
case QL_STK_PROACTIVE_CMD_DISPLAY_TEXT:
stk_display_text_info(nSim);
ql_stk_send_command_result(nSim, proactive_cmd, QL_STK_PERFORMED_SUCCESSFULLY, 0, NULL);
break;
default:
/* terminate current command */
ql_stk_send_command_result(nSim, QSTK_TERMINATE_STK_SESSION, QL_STK_PROACTIVE_SIM_SESSION_TERMINATED_BY_THE_USER, 0, NULL);
break;
}
}
static void stk_app_thread(void *arg)
{
QlOSStatus err = 0;
uint8_t nSim = 0;
ql_stk_errcode_e ret = QL_STK_SUCCESS;
ql_stk_mode_e stk_mode = QL_STK_MODE_DISABLE;
ql_stk_alphabet_set_e stk_alphabet_type = QL_STK_ALPHABET_SET_GSM;
uint16_t stk_auto_response_timeout = 300;
ql_stk_profile_s profile = {0};
char profile_str[100] = {0};
QL_STK_DEMO_LOG("========== stk demo start ==========");
ql_stk_register_cb(user_stk_event_callback);
ql_stk_cfg_get(&stk_mode, &stk_alphabet_type, &stk_auto_response_timeout);
QL_STK_DEMO_LOG("get stk config mode:%d alphabet type:%d auto response timeout:%d",
stk_mode, stk_alphabet_type, stk_auto_response_timeout);
if (QL_STK_MODE_DISABLE == stk_mode)
{
/* config stk function */
ret = ql_stk_cfg_set(QL_STK_MODE_ENABLE, QL_STK_ALPHABET_SET_UCS2, QL_STK_AUTO_RESPONSE_TIMEOUT_DEF);
QL_STK_DEMO_LOG("ql_stk_cfg_set ret:%d", ret);
ql_power_reset(RESET_NORMAL);
goto exit;
}
/* get TERMINAL PROFILE data */
ql_stk_get_terminal_profile(nSim, &profile);
hex_to_string(profile.profile_buf, profile.profile_len, profile_str);
QL_STK_DEMO_LOG("profile:%s", profile_str);
while (1)
{
ql_event_t event = {0};
ql_event_try_wait(&event);
QL_STK_DEMO_LOG("get event: 0x%08x/0x%08x/0x%08x/0x%08x", event.id, event.param1, event.param2, event.param3);
switch (event.id)
{
case QUEC_STK_PROACTIVE_CMD_IND: {
uint8_t nSim = event.param1;
uint8_t proactive_cmd = event.param2;
stk_proactive_cmd_handler(nSim, proactive_cmd);
break;
}
case QUEC_STK_TIMEOUT_IND: {
break;
}
case QUEC_STK_SIM_LOST_IND: {
break;
}
case QUEC_STK_NO_PROACTIVE_CMD_IND: {
uint8_t nSim = event.param1;
static bool select_setup_menu = true; /* avoid loopback */
ql_stk_state_e state;
ql_stk_proactive_cmd_e cur_cmd;
if ((true == select_setup_menu) && (0 != menu_info.item_id[0]))
{
select_setup_menu = false;
ql_stk_get_stk_proactive_cmd(nSim, &cur_cmd, &state);
QL_STK_DEMO_LOG("command:%d state:%d", cur_cmd, state);
/**
* allow to select setup menu item while TERMINAL_RSP_STATE and none proactive command,
* this will cause a ENVELOPE (MENU SELECTION) command to SIM
*
*/
if ((QL_STK_PROACTIVE_CMD_TERMINAL_RSP_STATE == state) && (QL_STK_PROACTIVE_CMD_NONE == cur_cmd))
{
// depend on SIM's MENU
// QL_STK_DEMO_LOG("select setup menu item:%d", menu_info.item_id[0]);
// ql_stk_send_command_result(nSim, QSTK_SIM_ENVELOPE_MENU_SELECTION, QL_STK_PERFORMED_SUCCESSFULLY, menu_info.item_id[0], NULL);
}
}
break;
}
default:
break;
}
ql_rtos_task_sleep_s(1);
}
exit:
err = ql_rtos_task_delete(NULL);
if (err != QL_OSI_SUCCESS)
{
QL_STK_DEMO_LOG("task deleted failed");
}
return;
}
int ql_stk_app_init(void)
{
QlOSStatus err = QL_OSI_SUCCESS;
err = ql_rtos_task_create(&stk_task, 8 * 1024, 23, "stk_app", stk_app_thread, NULL, 5);
if (err != QL_OSI_SUCCESS)
{
QL_STK_DEMO_LOG("stk_app init failed");
}
return err;
}