334 lines
9.8 KiB
C
334 lines
9.8 KiB
C
|
||
#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;
|
||
}
|
||
} |