diff --git a/devices/bc35_28_95/bc35_28_95.c b/devices/bc35_28_95/bc35_28_95.c index a2227a3f3a784b2d41c58ebc789c4b46e60de621..5a6c1a3cd3212f8d7a47ac58182c8fa4377af086 100644 --- a/devices/bc35_28_95/bc35_28_95.c +++ b/devices/bc35_28_95/bc35_28_95.c @@ -8,6 +8,20 @@ #include "stdbool.h" #include "ctype.h" +typedef struct ip_addr_st { + uint8_t seg1; + uint8_t seg2; + uint8_t seg3; + uint8_t seg4; +}ip_addr_t; + +at_agent_t bc35_28_95_agent; +static ip_addr_t domain_parser_addr = {0}; +static k_sem_t domain_parser_sem; +static k_stack_t bc35_28_95_at_parse_task_stk[AT_PARSER_TASK_STACK_SIZE]; + +#define AT_AGENT ((at_agent_t *)&bc35_28_95_agent) + static int bc35_28_95_module_port = 5000; static int bc35_28_95_connect(const char *ip, const char *port, sal_proto_t proto) @@ -18,7 +32,7 @@ static int bc35_28_95_connect(const char *ip, const char *port, sal_proto_t prot tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL); - tos_at_cmd_exec(&echo, 2000, "AT+NSOCR=%s,%d,%d,%d\r\n", + tos_at_cmd_exec(AT_AGENT, &echo, 2000, "AT+NSOCR=%s,%d,%d,%d\r\n", proto == TOS_SAL_PROTO_UDP ? "DGRAM" : "STREAM", 6, bc35_28_95_module_port++, 1); if (echo.status != AT_ECHO_STATUS_OK) { @@ -27,13 +41,13 @@ static int bc35_28_95_connect(const char *ip, const char *port, sal_proto_t prot sscanf(echo.buffer, "%d", &id); - id = tos_at_channel_alloc_id(id, ip, port); + id = tos_at_channel_alloc_id(AT_AGENT, id, ip, port); if (id == -1) { return -1; } while (try++ < 10) { - tos_at_cmd_exec(&echo, 1000, "AT+NSOCO=%d,%s,%s\r\n", id, ip, port); + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+NSOCO=%d,%s,%s\r\n", id, ip, port); if (echo.status == AT_ECHO_STATUS_OK) { is_connected = 1; break; @@ -43,7 +57,7 @@ static int bc35_28_95_connect(const char *ip, const char *port, sal_proto_t prot } if (!is_connected) { - tos_at_channel_free(id); + tos_at_channel_free(AT_AGENT, id); return -1; } @@ -52,7 +66,7 @@ static int bc35_28_95_connect(const char *ip, const char *port, sal_proto_t prot static int bc35_28_95_recv_timeout(int id, void *buf, size_t len, uint32_t timeout) { - return tos_at_channel_read_timed(id, buf, len, timeout); + return tos_at_channel_read_timed(AT_AGENT, id, buf, len, timeout); } static int bc35_28_95_recv(int id, void *buf, size_t len) @@ -89,68 +103,53 @@ static int bc35_28_95_send(int id, const void *buf, size_t len) char *str_buf = NULL; at_echo_t echo; - if (tos_at_global_lock_pend() != 0) { - return -1; - } - str_buf = tos_mmheap_calloc(2 * len + 1, sizeof(char)); if (!str_buf) { + printf("tos_mmheap_calloc\n" ); return -1; } __hex2str((uint8_t *)buf, str_buf, len); - tos_at_echo_create(&echo, NULL, 0, NULL); - tos_at_cmd_exec(&echo, 1000, + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+NSOSD=%d,%d,%s\r\n", id, len, str_buf); tos_mmheap_free(str_buf); - if (echo.status != AT_ECHO_STATUS_OK) { - tos_at_global_lock_post(); return -1; } - tos_at_global_lock_post(); - return len; } static int bc35_28_95_close(int id) { - tos_at_cmd_exec(NULL, 1000, "AT+NSOCL=%d\r\n", id); + tos_at_cmd_exec(AT_AGENT, NULL, 1000, "AT+NSOCL=%d\r\n", id); - tos_at_channel_free(id); + tos_at_channel_free(AT_AGENT, id); return 0; } static int bc35_28_95_parse_domain(const char *host_name, char *host_ip, size_t host_ip_len) { - char *str; at_echo_t echo; char echo_buffer[64]; - + + tos_sem_create_max(&domain_parser_sem, 0, 1); tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL); - tos_at_cmd_exec(&echo, 2000, "AT+QDNS=%d,%s\r\n", 0, host_name); + tos_at_cmd_exec(AT_AGENT, &echo, 2000, "AT+QDNS=%d,%s\r\n", 0, host_name); if (echo.status != AT_ECHO_STATUS_OK) { + printf("GOT IP faild\n"); return -1; - } - - /* - +QDNS:xxx.yyy.zzz.www - */ - - str = strstr((const char *)echo.buffer, "+QDNS:"); - if (!str) - { - return -1; - } - sscanf(str, "+QDNS:%s", host_ip); + } + tos_sem_pend(&domain_parser_sem, TOS_TIME_FOREVER); + snprintf(host_ip, host_ip_len, "%d.%d.%d.%d", domain_parser_addr.seg1, domain_parser_addr.seg2, domain_parser_addr.seg3, domain_parser_addr.seg4); host_ip[host_ip_len - 1] = '\0'; + printf("GOT IP: %s\n", host_ip); return 0; } @@ -162,7 +161,7 @@ static int bc35_28_95_reset(void) tos_at_echo_create(&echo, NULL, 0, "Neul"); while (try++ < 10) { - tos_at_cmd_exec(&echo, 5000, "AT+NRB\r\n"); + tos_at_cmd_exec(AT_AGENT, &echo, 5000, "AT+NRB\r\n"); if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { return 0; } @@ -175,7 +174,19 @@ static int bc35_28_95_echo_close(void) at_echo_t echo; tos_at_echo_create(&echo, NULL, 0, NULL); - tos_at_cmd_exec(&echo, 1000, "ATE0\r\n"); + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "ATE0\r\n"); + if (echo.status == AT_ECHO_STATUS_OK) { + return 0; + } + return -1; +} + +static int bc35_28_95_dns_config(void) +{ + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+QIDNSCFG=114.114.114.114,8.8.8.8\r\n"); if (echo.status == AT_ECHO_STATUS_OK) { return 0; } @@ -189,7 +200,7 @@ static int bc35_28_95_open_cfun(void) tos_at_echo_create(&echo, NULL, 0, NULL); while (try++ < 10) { - tos_at_cmd_exec(&echo, 1000, "AT+CFUN=1\r\n"); + tos_at_cmd_exec(AT_AGENT, &echo, 3000, "AT+CFUN=1\r\n"); if (echo.status == AT_ECHO_STATUS_OK) { return 0; } @@ -201,13 +212,15 @@ static int bc35_28_95_check_cfun(void) { int try = 0; at_echo_t echo; - - tos_at_echo_create(&echo, NULL, 0, "+CFUN:1"); + char echo_buffer[32]; + + tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL); while (try++ < 10) { - tos_at_cmd_exec(&echo, 1000, "AT+CFUN?\r\n"); - if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CFUN?\r\n"); + if (strstr(echo_buffer, "+CFUN:1")) { return 0; } + tos_sleep_ms(2000); } return -1; } @@ -219,7 +232,7 @@ static int bc35_28_95_get_net(void) tos_at_echo_create(&echo, NULL, 0, NULL); while (try++ < 10) { - tos_at_cmd_exec(&echo, 1000, "AT+CGATT=1\r\n"); + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CGATT=1\r\n"); if (echo.status == AT_ECHO_STATUS_OK) { return 0; } @@ -227,6 +240,23 @@ static int bc35_28_95_get_net(void) return -1; } +static int bc35_28_95_check_net(void) +{ + int try = 0; + at_echo_t echo; + char echo_buffer[32]; + + tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL); + while (try++ < 40) { + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CGATT?\r\n"); + if (strstr(echo_buffer, "+CGATT:1")) { + return 0; + } + tos_sleep_ms(2000); + } + return -1; +} + static int bc35_28_95_signal_quality_check(void) { int rssi, ber; @@ -234,7 +264,7 @@ static int bc35_28_95_signal_quality_check(void) char echo_buffer[32], *str; tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL); - tos_at_cmd_exec(&echo, 1000, "AT+CSQ\r\n"); + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CSQ\r\n"); if (echo.status != AT_ECHO_STATUS_OK) { return -1; } @@ -261,6 +291,10 @@ static int bc35_28_95_init(void) return -1; } + if (bc35_28_95_dns_config() != 0) { + printf("dns config FAILED\n"); //²»return,ΪÁ˼æÈÝBC35 + } + if (bc35_28_95_echo_close() != 0) { printf("echo close FAILED\n"); return -1; @@ -280,7 +314,12 @@ static int bc35_28_95_init(void) printf("get net FAILED\n"); return -1; } - + + if (bc35_28_95_check_net() != 0) { + printf("check net FAILED\n"); + return -1; + } + if (bc35_28_95_signal_quality_check() != 0) { printf("check csq FAILED\n"); return -1; @@ -318,6 +357,7 @@ __STATIC__ uint8_t hex_stream[256]; __STATIC__ void bc35_28_95_incoming_data_process(void) { uint8_t data; + at_echo_t echo; int channel_id = 0, data_len = 0, read_len, i = 0, ds_i = 0; int socket = 0, ip1 = 0, ip2 = 0, ip3 = 0, ip4 = 0, port = 0, length = 0, remaining_length = 0; @@ -328,7 +368,7 @@ __STATIC__ void bc35_28_95_incoming_data_process(void) */ while (1) { - if (tos_at_uart_read(&data, 1) != 1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { return; } @@ -339,7 +379,7 @@ __STATIC__ void bc35_28_95_incoming_data_process(void) } while (1) { - if (tos_at_uart_read(&data, 1) != 1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { return; } @@ -356,16 +396,16 @@ __STATIC__ void bc35_28_95_incoming_data_process(void) data_len = sizeof(incoming_data_buffer); } - // tos_at_echo_create(&echo, NULL, 0, NULL); - tos_at_cmd_exec(NULL, 0, "AT+NSORF=%d,%d\r\n", channel_id, data_len); + tos_at_echo_create(&echo, NULL, 0, NULL); + tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+NSORF=%d,%d\r\n", channel_id, data_len); // wait for uart buffer to be filled /* ATTENTION: - we cannot use tos_at_cmd_exec(NULL, timeout) to delay, because we are in at framework's parser + we cannot use tos_at_cmd_exec(AT_AGENT, NULL, timeout) to delay, because we are in at framework's parser task now(current function is a callback called by parser task), delay in tos_at_cmd_exec is tos_task_delay, this may cause a task switch, data receiving may be interrupted. - so we must tos_at_cmd_exec(NULL, 0), and do the delay by tos_stopwatch_delay_ms. + so we must tos_at_cmd_exec(AT_AGENT, NULL, 0), and do the delay by tos_stopwatch_delay_ms. */ tos_stopwatch_delay_ms(1000); @@ -380,19 +420,19 @@ __STATIC__ void bc35_28_95_incoming_data_process(void) */ // skip the leading \r\n - if (tos_at_uart_read(&data, 1) != 1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { if (data != '\r') { return; } } - if (tos_at_uart_read(&data, 1) != 1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { if (data != '\n') { return; } } - read_len = tos_at_uart_readline(incoming_data_buffer, sizeof(incoming_data_buffer)); + read_len = tos_at_uart_readline(AT_AGENT, incoming_data_buffer, sizeof(incoming_data_buffer)); for (i = 0; i < read_len; ++i) { if (incoming_data_buffer[i] == ',') { @@ -471,11 +511,58 @@ __STATIC__ void bc35_28_95_incoming_data_process(void) } __asciistr2hex(ascii_stream, hex_stream, length * 2); - tos_at_channel_write(channel_id, hex_stream, length); + tos_at_channel_write(AT_AGENT, channel_id, hex_stream, length); } +__STATIC__ void bc35_28_95_domain_data_process(void) +{ + uint8_t data; + /* + +QDNS:xxx.xxx.xxx.xxx + */ + while (1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { + return; + } + if (data == '.') { + break; + } + domain_parser_addr.seg1 = domain_parser_addr.seg1 *10 + (data-'0'); + } + while (1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { + return; + } + if (data == '.') { + break; + } + domain_parser_addr.seg2 = domain_parser_addr.seg2 *10 + (data-'0'); + } + while (1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { + return; + } + if (data == '.') { + break; + } + domain_parser_addr.seg3 = domain_parser_addr.seg3 *10 + (data-'0'); + } + while (1) { + if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) { + return; + } + if (data == '\r') { + break; + } + domain_parser_addr.seg4 = domain_parser_addr.seg4 *10 + (data-'0'); + } + tos_sem_post(&domain_parser_sem); + return; + +} at_event_t bc35_28_95_at_event[] = { { "+NSONMI:", bc35_28_95_incoming_data_process }, + { "+QDNS:", bc35_28_95_domain_data_process}, }; sal_module_t sal_module_bc35_28_95 = { @@ -490,7 +577,8 @@ sal_module_t sal_module_bc35_28_95 = { int bc35_28_95_sal_init(hal_uart_port_t uart_port) { - if (tos_at_init(uart_port, bc35_28_95_at_event, + if (tos_at_init(AT_AGENT, "bc35_28_95_at", bc35_28_95_at_parse_task_stk, + uart_port, bc35_28_95_at_event, sizeof(bc35_28_95_at_event) / sizeof(bc35_28_95_at_event[0])) != 0) { return -1; }