334 lines
9.8 KiB
C
Raw Normal View History

2025-03-14 10:41:56 +08:00
#include "at.h"
#include "board.h"
#include "drv_gpio.h"
#include "rtatomic.h"
#include "rtthread.h"
#include <rtdevice.h>
#include <stdbool.h>
#include <stdlib.h>
#define LOG_TAG "sim"
#define DBG_LVL DBG_LOG
// #define DBG_LVL DBG_INFO
#define USE_LOG1
#define USE_LOG2
#define USE_LOG3
// #define USE_LOG4
#define USE_LOG5
// #define USE_LOG6
// #define USE_LOG_D
#include "logn.h"
#define AT_UART_NAME "uart2"
2025-03-14 10:41:56 +08:00
static at_client_t at_client;
#define AT_SEND_CMD(cmd, resp) \
do \
{ \
rc = RT_EOK; \
if (at_obj_exec_cmd((at_client), (resp), (cmd)) < 0) \
{ \
rc = -RT_ERROR; \
goto __exit; \
} \
} while (0)
rt_err_t sim_call(char *phonenum)
{
rt_err_t rc = RT_EOK;
at_response_t resp = NULL;
resp = at_create_resp(256, 1, 5 * RT_TICK_PER_SECOND);
if (!resp)
{
LOG_E("No memory for AT response structure!");
return -RT_ENOMEM;
}
char at_str[32];
rt_snprintf(at_str, sizeof(at_str), "ATD%s;", phonenum);
AT_SEND_CMD(at_str, resp);
2025-03-14 10:41:56 +08:00
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
2025-03-22 22:38:52 +08:00
// 将 UTF-8 字符串转换为 UTF-16BE 编码的十六进制字符串
void str_to_unicode(const char *input, uint8_t *output) {
uint16_t unicode;
uint8_t *ptr = output;
while (*input) {
// UTF-8 转 Unicode仅处理基本多语言平面字符
if ((*input & 0xE0) == 0xE0) { // 3字节UTF-8字符如中文
unicode = ((input[0] & 0x0F) << 12) | ((input[1] & 0x3F) << 6) | (input[2] & 0x3F);
input += 3;
} else if ((*input & 0xC0) == 0xC0) { // 2字节UTF-8字符如拉丁扩展字符
unicode = ((input[0] & 0x1F) << 6) | (input[1] & 0x3F);
input += 2;
} else { // 1字节ASCII字符
unicode = *input;
input += 1;
}
// 转换为大端序UTF-16BE
*ptr++ = (unicode >> 8) & 0xFF;
*ptr++ = unicode & 0xFF;
}
*ptr = '\0'; // 结束符
}
//参数utf8_in要转码的UTF8编码地址高字节在前
//参数uni_out转码后输出的uni编码存储地址的指针在转码后地址自动向后移编
//返回值下一个utf8编码地址
uint8_t *utf82uni (const uint8_t *uft8_in,uint8_t **uni_out)
{
if ((uft8_in)&&(*uft8_in))
{
if (uft8_in[0]<0x80)
{
(*uni_out)[0]=0;
(*uni_out)[1]=*uft8_in;
(*uni_out)+=2;
return (uint8_t*)uft8_in+1;
}
else
{
(*uni_out)[0]=uft8_in[0]<<4;
(*uni_out)[0]|=(uft8_in[1]>>2)&0x0f;
(*uni_out)[1]=(uft8_in[1]<<6);
(*uni_out)[1]|=(uft8_in[2])&0x3f;
(*uni_out)+=2;
return (uint8_t*)uft8_in+3;
}
}
return 0;
}
2025-03-14 10:41:56 +08:00
2025-03-22 22:38:52 +08:00
// 将手机号转换为UTF-16BE 格式(如 13812345678 -> "003100380032003100340035003600370038"
void format_phone_number(const char *phone, char *output) {
for (int i = 0; phone[i]; i++) {
rt_sprintf(output + 4*i, "00%X", phone[i]); // 每位数字转为3位十六进制如 '1' -> 0031
}
}
rt_err_t sim_message(char *phonenum, char *message)
{
rt_err_t rc = RT_EOK;
at_response_t resp = NULL;
resp = at_create_resp(256, 1, 5 * RT_TICK_PER_SECOND);
if (!resp)
{
LOG_E("No memory for AT response structure!");
return -RT_ENOMEM;
}
char at_str[64];
AT_SEND_CMD("AT+CMGF=1", resp);
AT_SEND_CMD("AT+CSMP=17,167,1,8", resp);
AT_SEND_CMD("AT+CSCS=\"UCS2\"", resp);
uint8_t unicode_msg[256];
char formatted_phone[32];
// 1. 编码转换
format_phone_number(phonenum, formatted_phone);
rt_sprintf(at_str, "AT+CMGS=\"%s\"", formatted_phone);
AT_SEND_CMD(at_str, resp);
// str_to_unicode("005B5DE553825B895168536B58EB005D8B6662A5FF1A4EBA54588FDB516553719669533A57DF8D858FC7003100300073", unicode_msg);
// int cnt=0;
// if(rt_strcmp(at_resp_get_line(resp, 1),">") == 0)
// {
AT_SEND_CMD("005B5DE553825B895168536B58EB005D8B6662A5FF1A4EBA54588FDB516553719669533A57DF8D858FC7003100300073", resp);
AT_SEND_CMD("\x1A", resp);
// }
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
int cmd_sim_message(int argc, char**argv)
{
char testtmp[129];
format_phone_number(argv[1],testtmp);
LOG5("phone:%s",testtmp);
// str_to_unicode(argv[2], testtmp);
// LOG5("msg:%04X → %04X",argv[2],testtmp);
// format_phone_number(argv[2],testtmp);
// LOG5("msg(by phone):%s",testtmp);
// utf82uni(argv[2],testtmp);
// LOG5("msg(by utf82uni):%s",testtmp);
sim_message(argv[1], "");
}
MSH_CMD_EXPORT_ALIAS(cmd_sim_message,SIM_MSG, send message);
int cmd_sim_test(int argc, char**argv)
{
rt_err_t rc = RT_EOK;
at_response_t resp = NULL;
resp = at_create_resp(256, 1, 5 * RT_TICK_PER_SECOND);
if (!resp)
{
LOG_E("No memory for AT response structure!");
return -RT_ENOMEM;
}
char at_str[64];
if(!rt_strcmp(argv[1],"1"))
{
AT_SEND_CMD("AT+CMGF=1", resp);
return 1;
}
if(!rt_strcmp(argv[1],"2"))
{
AT_SEND_CMD("AT+CSMP=17,167,1,8", resp);
return 2;
}
if(!rt_strcmp(argv[1],"3"))
{
AT_SEND_CMD("AT+CSCS=\"UCS2\"", resp);
return 3;
}
if(!rt_strcmp(argv[1],"4"))
{
AT_SEND_CMD("AT+CMGS=\"00310037003300310038003100310032003300360030\"", resp);
return 4;
}
// 1. 编码转换
// str_to_unicode("005B5DE553825B895168536B58EB005D8B6662A5FF1A4EBA54588FDB516553719669533A57DF8D858FC7003100300073", unicode_msg);
// int cnt=0;
// if(rt_strcmp(at_resp_get_line(resp, 1),">") == 0)
// {
if(!rt_strcmp(argv[1],"5"))
{
AT_SEND_CMD("005B5DE553825B895168536B58EB005D8B6662A5FF1A4EBA54588FDB516553719669533A57DF8D858FC7003100300073", resp);
AT_SEND_CMD("\x1A", resp);
return 5;
}
// AT_SEND_CMD("005B5DE553825B895168536B58EB005D8B6662A5FF1A4EBA54588FDB516553719669533A57DF8D858FC7003100300073", resp);
if (!rt_strcmp(argv[1],"6"))
{
/* code */AT_SEND_CMD("\x1A", resp);
return 6;
}
// }
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
MSH_CMD_EXPORT_ALIAS(cmd_sim_test,OTEST, send message);
2025-03-14 10:41:56 +08:00
int cmd_at_send(int argc, char**argv)
{
rt_err_t rc = RT_EOK;
at_response_t resp = NULL;
resp = at_create_resp(256, 1, 5 * RT_TICK_PER_SECOND);
if (!resp)
{
LOG_E("No memory for AT response structure!");
return -RT_ENOMEM;
}
char at_str[128];
AT_SEND_CMD(argv[1], resp);
LOG5("%s",at_resp_get_line(resp, 1));
LOG5("%s",at_resp_get_line(resp, 2));
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
MSH_CMD_EXPORT_ALIAS(cmd_at_send, AT_SEND, send AT command);
static void urc_hang_up_handler(struct at_client *client, const char *buf, size_t len)
{
(void)client;
LOG3("The call was hung up.");
}
static void urc_ok_handler(struct at_client *client, const char *buf, size_t len)
{
(void)client;
LOG3("at receive OK.");
}
static void urc_error_handler(struct at_client *client, const char *buf, size_t len)
{
(void)client;
LOG3("at receive ERROR.");
}
static struct at_urc urc_table[] = {
{"NO CARRIER", "\r\n", urc_hang_up_handler},
{"OK", "\r\n", urc_ok_handler},
{"ERROR", "\r\n", urc_error_handler},
};
rt_err_t sim_dev_init()
{
// cmd_mq = ((struct bt_global *)parameter)->cmd_mq;
// init pin
// rt_pin_mode(BT_RST_PIN, PIN_MODE_OUTPUT_OD);
// rt_pin_mode(BT_LINK_STATUS_PIN, PIN_MODE_INPUT);
// init cmd lock
// rt_mutex_init(&cmd_lock, "cmd_lock", RT_IPC_FLAG_FIFO);
// init at client
at_client_init(AT_UART_NAME, 128, 128);
2025-03-14 10:41:56 +08:00
at_client = at_client_get_first();
if (at_client)
{
/* step2修改串口配置参数 */
const struct serial_configure config = {
.baud_rate = BAUD_RATE_115200, // 修改波特率为 115200
.data_bits = DATA_BITS_8, // 数据位 8
.stop_bits = STOP_BITS_1, // 停止位 1
.parity = PARITY_NONE, // 无奇偶校验位
.bit_order = BIT_ORDER_LSB, // 小端模式
.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE, // 无流控
.invert = NRZ_NORMAL, // NRZ 正常模式
#if defined(RT_USING_SERIAL_V1)
.bufsz = RT_SERIAL_RB_BUFSZ,
#elif defined(RT_USING_SERIAL_V2)
.rx_bufsz = BSP_UART2_RX_BUFSIZE, // 修改缓冲区 rx buff size 为 128
.tx_bufsz = BSP_UART2_TX_BUFSIZE, // 修改缓冲区 tx buff size 为 128
#endif // RT_USING_SERIAL_Vx
};
/* step3控制串口设备。通过控制接口传入命令控制字与控制参数 */
rt_device_control(at_client->device, RT_DEVICE_CTRL_CONFIG, (void *)&config);
/* 添加多种 URC 数据至 URC 列表中,当接收到同时匹配 URC 前缀和后缀的数据,执行
* URC
*/
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
LOG_I("sim initialization success");
return RT_EOK;
}
else
{
LOG_E("sim initialization failed");
return -RT_ERROR;
}
}