#include "at.h" #include "board.h" #include "drv_gpio.h" #include "rtatomic.h" #include "rtthread.h" #include #include #include #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; } }