diff --git a/devices/m5313/m5313.c b/devices/m5313/m5313.c new file mode 100644 index 00000000..8ffe6511 --- /dev/null +++ b/devices/m5313/m5313.c @@ -0,0 +1,525 @@ +#include "m5313.h" +#include "tos_k.h" +#include "tos_at.h" +#include "tos_hal.h" +#include "sal_module_wrapper.h" + +#include "stdio.h" +#include "stdbool.h" +#include "ctype.h" + +#define M5313_USE_MUX 1 //使用多路链接 + +static int m5313_recv_timeout(int id, void *buf, size_t len, uint32_t timeout) +{ + return tos_at_channel_read_timed(id, buf, len, timeout); +} + +static int m5313_recv(int id, void *buf, size_t len) +{ + return m5313_recv_timeout(id, buf, len, (uint32_t)10000); +} + +static int m5313_connect(const char *ip, const char *port, sal_proto_t proto) +{ + int id; + at_echo_t echo; + + char buffer[100]; + + id = tos_at_channel_alloc(ip, port); + if (id == -1) { + return -1; + } + + sprintf(buffer,"%d,CONNECT OK\r\n",id); + + tos_at_echo_create(&echo, NULL, 0, buffer); + #if defined(M5313_USE_MUX) + tos_at_cmd_exec_until(&echo, 10000, "AT+IPSTART=%d,\"%s\",\"%s\",%s\r\n",id, + proto == TOS_SAL_PROTO_UDP ? "UDP" : "TCP", + ip,port); + #else + tos_at_cmd_exec_until(&echo, 10000, "AT+IPSTART=\"%s\",\"%s\",%s\r\n", + proto == TOS_SAL_PROTO_UDP ? "UDP" : "TCP", + ip,port); + #endif + if (echo.status == AT_ECHO_STATUS_EXPECT) { + return id; + } + tos_at_channel_free(id); + return -1; +} + + +static int m5313_send(int id, const void *buf, size_t len) +{ + at_echo_t echo; + + if (tos_at_global_lock_pend() != 0) { + return -1; + } + + tos_at_echo_create(&echo, NULL, 0, ">"); + #if defined(M5313_USE_MUX) + tos_at_cmd_exec_until(&echo, 3000, "AT+IPSEND=%d,%d\r\n",id,len); + #else + tos_at_cmd_exec_until(&echo, 3000, "AT+IPSEND=%d\r\n",len); + #endif + if (echo.status == AT_ECHO_STATUS_EXPECT) + { + printf(buf); + tos_at_echo_create(&echo, NULL, 0, "SEND OK"); + tos_at_raw_data_send_until(&echo, 10000, buf,len); + if (echo.status == AT_ECHO_STATUS_EXPECT) + { + tos_at_global_lock_post(); + return len; + } + } + tos_at_global_lock_post(); + return -1; +} + + +static int m5313_close(int id) +{ +#if defined(M5313_USE_MUX) + + tos_at_cmd_exec(NULL, 1000, "AT+IPCLOSE=%d\r\n",id); + + tos_at_channel_free(id); + + printf("close %d called\n", id); +#else + tos_at_cmd_exec(NULL, 1000, "AT+IPCLOSE\r\n"); + + tos_at_channel_free(0); + + printf("close %d called\n", 0); +#endif + + return 0; +} + +//多路链接 +static int m5313_set_cmmux(void) +{ + tos_at_cmd_exec(NULL, 1000, "AT+CMMUX=1\r\n"); + + return 0; +} + +//单路链接 +static int m5313_reset_cmmux(void) +{ + tos_at_cmd_exec(NULL, 1000, "AT+CMMUX=0\r\n"); + + return 0; +} + +static int m5313_parse_domain(const char *host_name, char *host_ip, size_t host_ip_len) { + char *str; + at_echo_t echo; + char echo_buffer[100]; + + tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), "+CMDNSGIP:"); + tos_at_cmd_exec_until(&echo, 10000, "AT+CMDNSGIP=\"%s\"\r\n", host_name); + if (echo.status != AT_ECHO_STATUS_EXPECT) { + return -1; + } +// printf(echo.buffer); + /* +CMDNSGIP:"name","1.2.3.4"\r\n */ + str = strstr((const char *)echo.buffer, "+CMDNSGIP:"); + if (!str) { + return -1; + } + sscanf(str, "+CMDNSGIP:\"%*[^\"]\",\"%[^\"]",host_ip); + host_ip[host_ip_len - 1] = '\0'; + + int iplen = strlen(host_ip); + if (iplen > 1 && host_ip[iplen-1] == '"') { + host_ip[iplen-1] = 0; + } + + printf("GOT IP: %s\n", host_ip); + return 0; +} + +static int m5313_reset(void) +{ + at_echo_t echo; + + HAL_GPIO_WritePin(NB_RST_GPIO_Port, NB_RST_Pin, GPIO_PIN_RESET); + tos_task_delay(200); + HAL_GPIO_WritePin(NB_RST_GPIO_Port, NB_RST_Pin, GPIO_PIN_SET); + tos_task_delay(200); + + tos_at_echo_create(&echo, NULL, 0, "+CTZV:"); + tos_at_cmd_exec_until(&echo, 60000, "AT+TRB\r\n"); + if (echo.status != AT_ECHO_STATUS_EXPECT) { + return -1; + } + + return 0; +} + +static int m5313_echo_close(void) +{ + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(&echo, 1000, "ATE0\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) { + return 0; + } + + return -1; +} + +static int m5313_pin_ready(void) +{ + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, "+CPIN:READY"); + tos_at_cmd_exec_until(&echo, 5000, "AT+CPIN?\r\n"); + if (echo.status == AT_ECHO_STATUS_EXPECT) { + return 0; + } + + return -1; +} + + +static int m5313_signal_quality_check(void) +{ + int rssi, ber; + at_echo_t echo; + char echo_buffer[32], *str; + + tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), "+CSQ:"); + tos_at_cmd_exec_until(&echo, 5000, "AT+CSQ\r\n"); + if (echo.status != AT_ECHO_STATUS_EXPECT) { + return -1; + } + printf(echo.buffer); + str = strstr(echo.buffer, "+CSQ:"); + sscanf(str, "+CSQ:%d,%d", &rssi, &ber); + if (rssi == 99) { + return -1; + } + + return 0; +} + + +//Network switching mode ---Automatic mode +static int m5313_Net_switch_mode(void) +{ + at_echo_t echo; + tos_at_echo_create(&echo, NULL, 0, "+CFGDUALMODE: 1,0\r\n"); + tos_at_cmd_exec_until(&echo, 5000, "AT+CFGDUALMODE?\r\n"); + if (echo.status == AT_ECHO_STATUS_EXPECT){ + return 0; + }else{ + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(&echo, 2000, "AT+CFGDUALMODE=1,0\r\n"); + if(echo.status == AT_ECHO_STATUS_OK) + { + if (m5313_reset() != 0) { + return -1; + } + return 0; + } + } + return -1; +} +// +static int m5313_Check_net_type(void) +{ + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, "+COPS: 0,2,\"46000\", 0"); + tos_at_cmd_exec_until(&echo, 8000, "AT+COPS?\r\n"); + if (echo.status != AT_ECHO_STATUS_EXPECT) + { + tos_at_echo_create(&echo, NULL, 0, "+CTZV:"); + tos_at_cmd_exec_until(&echo, 25000, "AT+CFGRATPRIO=2\r\n"); + if (echo.status == AT_ECHO_STATUS_EXPECT) + { + return 0; + } + }else{ + return 0; + } + return -1; +} +// +static int m5313_Check_sim_numb(void) +{ + at_echo_t echo; + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec_until(&echo, 2000, "AT+CIMI\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) + { + return 0; + } + return -1; +} + +static int m5313_cm_head(void) +{ + at_echo_t echo; + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(&echo, 1000, "AT+CMHEAD=1\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) + { + return 0; + } + return -1; +} + +static int m5313_cm_showpt(void) +{ + at_echo_t echo; + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(&echo, 1000, "AT+CMSHOWPT=1\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) + { + return 0; + } + return -1; +} + +static int m5313_cm_showra0(void) +{ + at_echo_t echo; + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(&echo, 1000, "AT+CMSHOWRA=0\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) + { + return 0; + } + return -1; +} + + +static int m5313_activate(void) { + int try = 0; + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, NULL); + while (try++ < 5) { + tos_at_cmd_exec(&echo, 3000, "AT+CGACT=1,1\r\n"); + if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { + return 0; + } + } + + return -1; +} + + +// +static int m5313_Activate_pdp(void) +{ + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, "+CGACT: 1, 1\r\n"); + tos_at_cmd_exec_until(&echo, 2000, "AT+CGACT?\r\n"); + if (echo.status == AT_ECHO_STATUS_EXPECT) + { + return 0; + } + else + { + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec_until(&echo, 20000, "AT+CGACT=1,1\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) + { + return 0; + } + + } + return -1; +} + +static int m5313_init(void) +{ + printf("Init M5313 ...\n" ); + + if (m5313_reset() != 0) { + printf("m5313 reset FAILED\n"); + return -1; + } + + if (m5313_echo_close() != 0) { + printf("m5313 echo close FAILED\n"); + return -1; + } + + if (m5313_pin_ready() != 0) { + printf("m5313 pin not ready\n"); + return -1; + } + + if (m5313_Net_switch_mode() != 0) { + printf("nb Netswitch mode err!\n"); +// return -1; + } + + if (m5313_Check_net_type() != 0) { + printf("nb net type err!\n"); + } + + if (m5313_signal_quality_check() != 0) { + printf("nb signal err!\n"); + } + + if (m5313_activate() != 0) { + printf("nb pdp err!\n"); + } + + + if (m5313_cm_head() != 0) { + printf("cm head err!\n"); + } + + + if (m5313_cm_showpt() != 0) { + printf("cm showpt err!\n"); + } + +#if defined(M5313_USE_MUX) + if (m5313_set_cmmux() != 0) { + printf("cm showpt err!\n"); + } +#endif + return 0; +} + +#define M5313_INCOMING_DATA_LEN 2048 +__STATIC__ uint8_t incoming_data_buffer[M5313_INCOMING_DATA_LEN]; + +__STATIC__ void m5313_server_ip_port(void) +{ + +} +#if defined(M5313_USE_MUX) +__STATIC__ void m5313_incoming_data(void) +{ + uint8_t data=0; + int id = 0; + int data_len = 0; + int discard_suffix = 1; + if (tos_at_uart_read(&data, 1) != 1) { + return; + } + if(data >= '0' && data <= '9') { + id = data - '0'; + } + + if (tos_at_uart_read(&data, 1) != 1) { + return; + } + + while (1) { + if (tos_at_uart_read(&data, 1) != 1) { + return; + } + + if(data >= '0' && data <= '9') { + data_len = data_len * 10 + (data - '0'); + }else if(data == ':'){ + break; + }else{ + return; + } + } + + if (data_len > sizeof(incoming_data_buffer)) { + discard_suffix = 0; + data_len = sizeof(incoming_data_buffer); + } + + if (tos_at_uart_read(incoming_data_buffer, data_len) != data_len) { + return; + } + + tos_at_channel_write(id, incoming_data_buffer, data_len); + +// printf(incoming_data_buffer); + +} + +#else +__STATIC__ void m5313_incoming_data(void) +{ + uint8_t data=0; + int data_len = 0; + int discard_suffix = 1; + + while (data != ':') { + if (tos_at_uart_read(&data, 1) != 1) { + return; + } + + if(data >= '0' && data <= '9') { + data_len = data_len * 10 + (data - '0'); + } + } + + if (data_len > sizeof(incoming_data_buffer)) { + discard_suffix = 0; + data_len = sizeof(incoming_data_buffer); + } + + if (tos_at_uart_read(incoming_data_buffer, data_len) != data_len) { + return; + } + + tos_at_channel_write(0, incoming_data_buffer, data_len); + +// printf(incoming_data_buffer); + +} +#endif + +at_event_t m5313_at_event[] = { + {"+RECV FROM:", m5313_server_ip_port}, +#if defined(M5313_USE_MUX) + {"+RECEIVE,", m5313_incoming_data }, +#else + {"+IPD,", m5313_incoming_data }, +#endif + +}; + +sal_module_t sal_module_m5313 = { + .init = m5313_init, + .connect = m5313_connect, + .send = m5313_send, + .recv_timeout = m5313_recv_timeout, + .recv = m5313_recv, + .close = m5313_close, + .parse_domain = m5313_parse_domain, +}; + +int m5313_sal_init(hal_uart_port_t uart_port) +{ + if (tos_at_init(uart_port, m5313_at_event, + sizeof(m5313_at_event) / sizeof(m5313_at_event[0])) != 0) { + return -1; + } + + if (tos_sal_module_register(&sal_module_m5313) != 0) { + return -1; + } + + if (tos_sal_module_init() != 0) { + return -1; + } + + return 0; +} + diff --git a/devices/m5313/m5313.h b/devices/m5313/m5313.h new file mode 100644 index 00000000..9498fb53 --- /dev/null +++ b/devices/m5313/m5313.h @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef __M5313_H__ +#define __M5313_H__ + +#include "tos_at.h" + +int m5313_sal_init(hal_uart_port_t uart_port); + +#endif /* __M5310A_H__ */ +