2025-03-22 22:38:52 +08:00

334 lines
9.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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"
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);
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
// 将 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;
}
// 将手机号转换为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);
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);
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;
}
}