#include "sim7600.h" #include #include #include "fifo.h" #include "usart.h" #include "stdlib.h" #include "timer4.h" #define ATC_RSP_FINISH 1 #define ATC_RSP_WAIT 0 #define AT_MAX_RESPONSE_TIME 300 #define HTTP_HEADER_CONTENT_TYPE "application/json" #define MAX_HTTP_SIZE 1000 u8 g_iemi_buf[16]; struct module_buffer { u8 *buffer; u16 length; }; struct module_buf { u8 *buf; u16 length; }; static struct module_buffer *module_send_data_buffer = NULL; static module_tcp_connected_callback tcp_connect_cb = NULL; static module_tcp_sent_callback tcp_sent_cb = NULL; static module_tcp_recv_callback tcp_recv_cb = NULL; static module_tcp_disconnected_callback tcp_disconnected_cb = NULL; static module_http_callback s_http_cb = NULL; static char s_http_buffer[MAX_HTTP_SIZE]; typedef s8 (*AT_cmdHandle)(BOOL *urc, char* buf); // 信号强度 static u8 s_csq_value = 0; typedef struct { char *name; AT_cmdHandle at_cmd_handler; } AtcHandlerType; static s8 at_handler(BOOL *urc, char* buf); static s8 ate_handler(BOOL *urc, char* buf); static s8 csq_handler(BOOL *urc, char* buf); static s8 cpin_handler(BOOL *urc, char *buf); //static s8 reg_handler(BOOL *urc, char *buf); //static s8 creg_handler(BOOL *urc, char *buf); static s8 getip_handler(BOOL *urc, char *buf); // net open handler static s8 net_open_handler(BOOL *urc, char* buf); static s8 net_close_handler(BOOL *urc, char* buf); static s8 gsn_handler(BOOL *urc, char* buf); // http handler static s8 http_send_handler(BOOL *urc, char*buf); static s8 http_read_handler(BOOL *urc, char*buf); static s8 cch_open_handle(BOOL *urc, char*buf); static s8 cch_send_handle(BOOL *urc, char*buf); // tcp handle. static s8 tcp_connect_handle(BOOL *urc, char*buf); static s8 ipsend_handle(BOOL *urc, char*buf); static s8 urc_handle(BOOL *urc, char *buf); static s8 tcp_closed_handle(BOOL *urc, char *buf); static s8 tcp_disconnect_handle(BOOL *urc, char *buf); // AT Command table AtcHandlerType atCmdTable[ ] = { // 打开或关闭AT指令回显 {"ATE", ate_handler}, // 设置本地流量控制 {"AT+IFC", at_handler}, // 输入PIN码 {"AT+CPIN", cpin_handler}, // 查询信号强度 {"AT+CSQ", csq_handler}, // 获取序列号ID {"AT+CGSN", gsn_handler}, // 设置 TCP/IP 应用模式 // 0: 非透传 // 1: 命令模式 {"AT+CIPMODE", at_handler}, // 打开SOCKET {"AT+NETOPEN", net_open_handler}, {"AT+NETCLOSE", net_close_handler}, // 查询注册网络状态 {"AT+CREG", at_handler}, // 注册 信息 {"AT+CPSI?", at_handler}, {"AT+IPADDR", getip_handler}, // http {"AT+CHTTPACT", http_send_handler}, // tcp // 建立tcp连接 {"AT+CIPOPEN", tcp_connect_handle}, // 向远端tcp或udp连接发送数据 {"AT+CIPSEND", ipsend_handle}, // 关闭tcp或ucp连接 {"AT+CIPCLOSE", tcp_closed_handle}, // 设置收到消息时是否显示远程IP和端口 {"AT+CIPSRIP", at_handler}, // 在CIPCLOSE指令后调用,关闭所有网络链接 {"AT+NETCLOSE", at_handler}, {"AT+CCHSET", at_handler}, {"AT+CCHSTART", at_handler}, {"AT+CCHOPEN", cch_open_handle}, {"AT+CCHSEND", cch_send_handle}, {"AT+CCHCLOSE", at_handler}, // TODO: consider response after OK. {"AT+CCHSTOP", at_handler}, }; AtcHandlerType urc_table[] = { {"+IPCLOSE:", tcp_disconnect_handle} }; struct at_cmd_entity { char at_name[20]; char at_cmd[128]; }; static s8 s_module_status = MODULE_OFF_LINE; static struct FIFO s_at_fifo; static u8 s_at_status = ATC_RSP_FINISH; static struct at_cmd_entity *s_current_at_command = NULL; // 发送at指令 static void send_at_command(const char* cmd) { Usart2_Send_Data((u8*)cmd, strlen(cmd)); } // urc 处理函数 static s8 urc_handle(BOOL *urc, char* buf) { // //printf("urc handler: %s\n", buf); return 0; } // at指令返回处理函数 static s8 at_handler(BOOL *urc, char *buf) { char *rep_str[] = {"OK", "ERROR"}; s8 res = -1; char *p; u8 i = 0; p = (char *)buf; while ( 'r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: s_at_status = ATC_RSP_FINISH; break; case 1: s_at_status = ATC_RSP_FINISH; break; default: break; } return s_at_status; } // CPIN指令返回处理函数 static s8 cpin_handler(BOOL *urc, char *buf) { char *rep_str[] = {"OK", "ERROR", "+CPIN: "}; s8 res = -1; char *p; u8 i = 0; p = (char *)buf; while ( 'r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: //s_at_status = ATC_RSP_FINISH; break; case 1: //s_at_status = ATC_RSP_FINISH; break; case 2: // 返回ready说明正常 if(strstr(p, "READY")!=NULL) { s_at_status = ATC_RSP_FINISH; } break; default: break; } return s_at_status; } static s8 csq_handler(BOOL *urc, char *buf) { char *rep_str [] = {"OK", "ERROR", "+CSQ: "}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: p = strstr(p, "+CSQ: "); s_csq_value = atoi(p + strlen("+CSQ: ")); s_at_status = ATC_RSP_FINISH; break; case 1: s_at_status = ATC_RSP_FINISH; break; case 2: PRINTF("csq:%s\r\n", p); s_csq_value = atoi(p + sizeof("+CSQ: ")); s_at_status = ATC_RSP_FINISH; break; default: break; } return s_at_status; } static s8 getip_handler(BOOL *urc, char *buf) { char *rep_str[ ] = {"OK", "ERROR", "+IPADDR: ", "+IP ERROR: "}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // OK { s_at_status = ATC_RSP_FINISH; s_module_status = MODULE_GET_IP; } break; case 1: // ERROR { } break; case 2: { s_at_status = ATC_RSP_FINISH; s_module_status = MODULE_GET_IP; } break; case 3: // +IP ERROR: { PRINTF("Net\r\n"); } break; default: break; } return s_at_status; } static s8 ate_handler(BOOL *urc, char* buf) { char *rep_str[ ] = {"OK","ERROR", "ATE"}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // OK { s_at_status = ATC_RSP_FINISH; } break; case 1: // ERROR { s_at_status = ATC_RSP_FINISH; } break; case 2: // ATE { //printf("open"); } break; default: break; } return s_at_status; } static s8 gsn_handler(BOOL *urc, char*buf) { char *rep_str[ ] = {"OK","ERROR"}; s8 res = -1; char *p; u8 i = 0; static u8 flag = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } if(flag == 0) { memcpy(g_iemi_buf, p, 15); g_iemi_buf[15] = 0; PRINTF("g_iemi_buf:%s", g_iemi_buf); flag = 1; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // OK { s_at_status = ATC_RSP_FINISH; } break; case 1: // ERROR { s_at_status = ATC_RSP_FINISH; } break; default: s_at_status = ATC_RSP_FINISH; break; } return s_at_status; } static s8 net_open_handler( BOOL *urc, char* buf) { char *rep_str[ ] = {"OK","ERROR", "+NETOPEN: "}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // OK { } break; case 1: // ERROR { s_at_status = ATC_RSP_FINISH; s_module_status = MODULE_GET_IP; } break; case 2: { s_at_status = ATC_RSP_FINISH; s_module_status = MODULE_GET_IP; } break; default: break; } return s_at_status; } static s8 net_close_handler( BOOL *urc, char* buf) { char *rep_str[ ] = {"OK","ERROR", "+NETCLOSE: ", "+IP ERROR: "}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // OK { //s_at_status = ATC_RSP_FINISH; } break; case 1: // ERROR { // s_at_status = ATC_RSP_FINISH; } break; case 2: { s_at_status = ATC_RSP_FINISH; } break; case 3: // +IP ERROR { s_at_status = ATC_RSP_FINISH; } break; default: break; } return s_at_status; } static s8 tcp_connect_handle(BOOL *urc, char*buf) { char *rep_str[ ] = {"+CCHOPEN", "ERROR", "OK"}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // CONNECT OK. { if(tcp_connect_cb != NULL) { tcp_connect_cb(0, 0); } s_at_status = ATC_RSP_FINISH; } break; case 1: // ERROR { //tcp_connect_cb(conn, 1); s_at_status = ATC_RSP_FINISH; } break; case 2: { } break; default: break; } return s_at_status; } s8 ipsend_handle(BOOL *urc, char*buf) { char *rep_str[ ] = {"+CCHSEND:", "ERROR", ">", "OK", "+CCH_PEER_CLOSED:"}; s8 res = -1; char *p; u8 i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: //+CCHSEND: { if(module_send_data_buffer != NULL) { if(module_send_data_buffer->buffer != NULL) { free(module_send_data_buffer->buffer); module_send_data_buffer->buffer = NULL; } } free(module_send_data_buffer); module_send_data_buffer = NULL; s_at_status = ATC_RSP_FINISH; if(tcp_sent_cb != NULL) { tcp_sent_cb(0,0); } } break; case 1: //ERROR { if(tcp_sent_cb != NULL) { tcp_sent_cb(0,-1); } s_at_status = ATC_RSP_FINISH; } break; case 2: // > { struct fifo_data* tcp_data_buffer = fifo_get_data(&s_at_fifo); //printf("sending.....,%p,\n", module_send_data_buffer); if(tcp_data_buffer != NULL) { Usart2_Send_Data(tcp_data_buffer->buf, tcp_data_buffer->length); if(tcp_data_buffer->buf != NULL) { free(tcp_data_buffer->buf); tcp_data_buffer->buf = NULL; } free(tcp_data_buffer); tcp_data_buffer = NULL; } } break; case 3: //OK { } break; case 4: //+CCH_PEER_CLOSED { if(tcp_sent_cb != NULL) { tcp_sent_cb(0,-1); } s_at_status = ATC_RSP_FINISH; } break; default: break; } return s_at_status; } static void show_package(u8 *buf, u16 len) { int i = 0; PRINTF("Package length: %d\ncontent is: \n", len); for (i = 0; i < len; i++) { PRINTF("%02x ",(uint8_t)buf[i]); } PRINTF("\n"); } static int8_t cch_open_handle(bool *urc, char*buf) { // TODO: deal with urc char *rep_str[ ] = {"+CCHOPEN", "OK", "ERROR"}; int8_t res = -1; char *p; uint8_t i = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // +CCHOPEN { s_at_status = ATC_RSP_FINISH; } break; case 1: // OK { } break; case 2: { s_at_status = ATC_RSP_FINISH; } break; default: break; } return s_at_status; } static int8_t cch_send_handle(bool *urc, char*buf) { char *rep_str[ ] = {"+CCHRECV", ">", "OK", "ERROR", "+CCHSEND:", "+CCH_PEER_CLOSED:"}; int8_t res = -1; char *p; uint8_t i = 0; static uint16_t s_http_data_len = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: // +HTTPSRECV: { // check response length. p = strstr(p, "+CCHRECV: DATA,1,"); p = p + strlen("+CCHRECV: DATA,1,"); int response_len = atoi(p); if(response_len>1000) { printf("response size is illegal:%d!\n", response_len); if(s_http_cb != NULL) { s_http_cb(NULL); } s_at_status = ATC_RSP_FINISH; return -1; } p = strstr(p, "\r\n"); p = p + strlen("\r\n"); memcpy(s_http_buffer + s_http_data_len, p, response_len); s_http_data_len += response_len; } break; case 1: // > { struct fifo_data* http_post_data; http_post_data = fifo_get_data(&s_at_fifo); if(http_post_data != NULL) { printf("sending.....\n"); usart2_send(http_post_data->buf, http_post_data->length); if(http_post_data->buf != NULL) { myfree(http_post_data->buf); http_post_data->buf = NULL; } myfree(http_post_data); http_post_data = NULL; } } break; case 2: { } break; case 3: { //TODO: consider error situation. s_at_status = ATC_RSP_FINISH; } break; case 4: { } break; case 5: { // check http protocol. char* http_response_buffer = NULL; const char * version = "HTTP/1.1 "; printf("receive:%s\n", s_http_buffer); p = strstr(s_http_buffer, version); if (p == NULL) { printf("Invalid version in %s\n", p); if(s_http_cb != NULL) { s_http_cb(NULL); } s_at_status = ATC_RSP_FINISH; return -1; } // check http status. int http_status = atoi(p + strlen(version)); if(http_status != 200) { printf("Invalid version in %s\n", p); if(s_http_cb != NULL) { s_http_cb(NULL); } s_at_status = ATC_RSP_FINISH; return -1; } http_response_buffer = (char *)strstr(p, "\r\n\r\n") + 4; s_http_data_len = 0; s_at_status = ATC_RSP_FINISH; if(s_http_cb != NULL) { s_http_cb(http_response_buffer); } } default: break; } return s_at_status; } static s8 http_send_handler(BOOL *urc, char *buf) { char *rep_str[] = {"+CHTTPACT: REQUEST", "+CHTTPACT: DATA,", "ERROR", "+CHTTPACT: 0"}; int8_t res = -1; char *p; uint8_t i = 0; static uint16_t s_http_data_len = 0; p= (char *)buf; while ( '\r' == *p || '\n' == *p) { p++; } for (i = 0; i < sizeof(rep_str) / sizeof(rep_str[0]); i++) { if (strstr( p,rep_str[i])) { res = i; break; } } switch (res) { case 0: { struct fifo_data* http_post_data; http_post_data = fifo_get_data(&s_at_fifo); if(http_post_data != NULL) { PRINTF("sending Data:%s\r\n", http_post_data->buf); Usart2_Send_Data(http_post_data->buf, http_post_data->length); if(http_post_data->buf != NULL) { free(http_post_data->buf); http_post_data->buf = NULL; } free(http_post_data); http_post_data = NULL; } } break; case 1: // get response { p = strstr(p, "+CHTTPACT: DATA,"); p = p + strlen("+CHTTPACT: DATA,"); int response_len = atoi(p); PRINTF("response size is :%d!\n", response_len); if(response_len>10000) { //printf("response size is illegal:%d!\n", response_len); if(s_http_cb != NULL) { s_http_cb(NULL); } s_at_status = ATC_RSP_WAIT; return s_at_status; } p = strstr(p, "\r\n"); p = p + strlen("\r\n"); memcpy(s_http_buffer + s_http_data_len, p,response_len); s_http_data_len += response_len; } break; case 2: //error s_at_status = ATC_RSP_FINISH; break; case 3: { char *http_response_buffer = NULL; const char *version = "http/1.1 "; PRINTF("http recive:%s\n", s_http_buffer); p = strstr(s_http_buffer, version); if (p == NULL) { PRINTF("Invalid version in %s\n", p); if(s_http_cb != NULL) { s_http_cb(NULL); } s_at_status = ATC_RSP_WAIT; return s_at_status; } // check http response code int http_status = atoi(p + strlen(version)); if(http_status != 200) { PRINTF("response code error is %d, not 200", http_status); if(s_http_cb != NULL) { s_http_cb(NULL); } s_at_status = ATC_RSP_WAIT; return s_at_status; } http_response_buffer = (char *)strstr(p, "\r\n\r\n") + 4; PRINTF("get http response:%s", http_response_buffer); s_http_data_len = 0; s_at_status = ATC_RSP_FINISH; if(s_http_cb != NULL) { s_http_cb(http_response_buffer); } } break; default: break; } return s_at_status; } u8 inquire_signal_quality(void) { add_send_at_command("AT+CSQ", "AT+CSQ\r\n"); return s_csq_value; } // void module_tcp_connect(u16 fd, uint32_t ip, u16 port) // { // char connect_buf[80]; // u8 ip1, ip2, ip3, ip4; // ip1 = ((u8*)(&ip))[0]; // ip2 = ((u8*)(&ip))[1]; // ip3 = ((u8*)(&ip))[2]; // ip4 = ((u8*)(&ip))[3]; // // AT+CCHSET. // add_send_at_command("AT+CCHSET", "AT+CCHSET=1\r\n"); // // AT+CCHSTART. // add_send_at_command("AT+CCHSTART", "AT+CCHSTART\r\n"); // // AT+CCHOPEN. // sprintf(connect_buf, "AT+CCHOPEN=%d,\"%d.%d.%d.%d\",%d, 2\r\n", 1, ip1, ip2, ip3, ip4, port); // //printf("tcp connecting:%s\n", connect_buf); // add_send_at_command("AT+CCHOPEN_TLS", connect_buf); // } static s8 tcp_closed_handle(BOOL *urc, char *buf) { if(tcp_disconnected_cb != NULL) { tcp_disconnected_cb(0, -1); } return -1; } static s8 tcp_disconnect_handle(BOOL *urc, char *buf) { if(tcp_disconnected_cb != NULL) { tcp_disconnected_cb(0, -1); } return -1; } void register_module_tcp_connect_callback(u16 fd, module_tcp_connected_callback connect_cb) { tcp_connect_cb = connect_cb; } void register_module_tcp_sent_callback(u16 fd, module_tcp_sent_callback sent_callback) { tcp_sent_cb = sent_callback; } void register_module_tcp_recv_callback(u16 fd, module_tcp_recv_callback recv_callback) { tcp_recv_cb = recv_callback; } void register_module_tcp_disconnected_callback(u16 fd, module_tcp_disconnected_callback tcp_disconnected_callback) { tcp_disconnected_cb = tcp_disconnected_callback; } // fifo 定时检测 static s8 at_fifo_check(void *arg) { static s8 wait_response_tick = 0; if(s_module_status == MODULE_START) { PRINTF("start send AT\r\n") send_at_command("AT\r\n"); } else if(MODULE_INIT ==s_module_status|| MODULE_INIT_DONE == s_module_status) { if ((NULL == s_current_at_command)) { if ((!FIFO_isEmpty(&s_at_fifo)) &&(s_at_status == ATC_RSP_FINISH)) { s_current_at_command = (struct at_cmd_entity*)malloc(sizeof(struct at_cmd_entity)); if (FIFO_Get(&s_at_fifo, s_current_at_command->at_name, s_current_at_command->at_cmd)) { s_at_status = ATC_RSP_WAIT; send_at_command(s_current_at_command->at_cmd); } } else { PRINTF("fifo is empty or the previous at command not complete!\r\n"); } } else { // PRINTF("sending:%s", s_current_at_command->at_cmd); //send //send_at_command(s_current_at_command->at_cmd); if(wait_response_tick > (s8)AT_MAX_RESPONSE_TIME) { } wait_response_tick++; } } return 0; } // 模块启动 u8 module_system_start(void) { s_module_status = MODULE_START; timer3_init(1000, 1, at_fifo_check); timer3_start(); return s_module_status; } // 模块初始化 u8 module_system_init() { Usart_Send_Str_Data("module_init!!!\r\n"); FIFO_Init (&s_at_fifo); add_send_at_command("ATE", "ATE0\r\n"); //AT+IFC=0, set no flow control. //add_send_at_command("AT+IFC", "AT+IFC=0\r\n"); //AT+CPIN, query ..... add_send_at_command("AT+CPIN", "AT+CPIN?\r\n"); //AT+CSQ add_send_at_command("AT+CSQ", "AT+CSQ\r\n"); //AT+GSN request for the IMEI of the module.; add_send_at_command("AT+CGSN", "AT+CGSN\r\n"); //AT+CREG //add_send_at_command("AT+CREG", "AT+CREG?\r\n"); // AT+CGREG? //add_send_at_command("AT+CGREG", "AT+CGREG?\r\n"); //AT+CIPMODE add_send_at_command("AT+CIPMODE", "AT+CIPMODE=0\r\n"); //AT+NETCLOSE关闭上次开启的网络 add_send_at_command("AT+NETCLOSE", "AT+NETCLOSE\r\n"); //AT+NETOPEN开启网络 add_send_at_command("AT+NETOPEN", "AT+NETOPEN\r\n"); //AT+IPADDR获取模块IP地址 //add_send_at_command("AT+IPADDR", "AT+IPADDR\r\n"); s_module_status = MODULE_INIT; return s_module_status; } // 获取模块状态 s8 get_module_status() { return s_module_status; } // 设置模块 状态 void set_module_status(s8 status) { s_module_status = status; } void add_send_at_command(char *name_buffer, char *cmd_buffer) { char at_cmd_Buff[64] = {0}; char at_name_Buff[20] = {0}; strcpy(at_name_Buff, name_buffer); strcpy(at_cmd_Buff, cmd_buffer); if(FIFO_Put(&s_at_fifo, at_name_Buff, at_cmd_Buff) ==-1) { PRINTF("write fifo error!\r\n"); } } // 模块发送http post 请求 void module_http_post(const char *url, const char *data, module_http_callback http_cb) { s_http_cb = http_cb; char host_name[64] = ""; char http_path[64] = ""; int port = 80; BOOL is_http = strncmp(url, "http://", strlen("http://")) == 0; BOOL is_https = strncmp(url, "https://", strlen("https://")) == 0; if (is_http) url += strlen("http://"); // Get rid of the protocol. else if (is_https) { url += strlen("https://"); // Get rid of the protocol. } else { PRINTF("url is not http:// or https://") return; } char * path = strchr(url, '/'); if (path == NULL) { path = strchr(url, '\0'); // Pointer to end of string. } char *colon = strchr(url, ':'); if(colon > path) { colon = NULL; } if (colon == NULL) { memcpy(host_name, url, path - url); } else { port = atoi(colon + 1); if (port == 0) { //printf("Port error %s\n", url); return; } memcpy(host_name, url, colon - url); host_name[colon - url] = '\0'; } host_name[path - url] = '\0'; memcpy(http_path, path, strlen(url)- strlen(host_name)); PRINTF("host_name:%s\n", host_name); PRINTF("http_path:%s\n", http_path); PRINTF("http_port:%d\n", port); // AT+CCHSET. add_send_at_command("AT+CCHSET", "AT+CCHSET=1\r\n"); // AT+CCHSTART. add_send_at_command("AT+CCHSTART", "AT+CCHSTART\r\n"); char http_url[64]; memset(http_url, 0x0, sizeof(http_url)); sprintf(http_url, "AT+CCHOPEN=%d,\"%s\",%d,1\r\n", 1, host_name, port); PRINTF("ready to http post:%s", http_url); add_send_at_command("AT+CCHOPEN", http_url); char post_headers[128] = ""; char at_send_buffer[20] = ""; sprintf(post_headers, "Content-Type:" HTTP_HEADER_CONTENT_TYPE "\r\n" "Content-Length: %d\r\n", strlen(data)); struct fifo_data* http_post_data =(struct fifo_data*)malloc(sizeof(struct fifo_data)); http_post_data->buf =(uint8_t*)malloc(512); int len = sprintf((char*)http_post_data->buf, "POST %s HTTP/1.1\r\n" "Host: %s:%d\r\n" "Connection: close\r\n" "User-Agent: SIM7600\r\n" "%s" "\r\n%s", http_path, host_name, port, post_headers, data); http_post_data->length = len; PRINTF("http post:%s", http_post_data->buf); sprintf(at_send_buffer, "AT+CCHSEND=%d,%d\r\n", 1, len); add_send_at_command("AT+CCHSEND", at_send_buffer); fifo_put_data(&s_at_fifo, http_post_data); // AT+CCHCLOSE add_send_at_command("AT+CCHCLOSE", "AT+CCHCLOSE=1\r\n"); // AT+CCHSTOP add_send_at_command("AT+CCHSTOP", "AT+CCHSTOP\r\n"); } static s8 data_process(struct module_buf *buf) { struct module_buf *data_buf = buf; u8 *p = data_buf->buf; if(strncmp((char*)data_buf->buf, "http/1.1", strlen("http/1.1")) == 0) { memcpy(s_http_buffer, p, data_buf->length); return 1; } else { return 0; } } // 模块返回数据处理 s8 module_data_handler(void* data) { u8 urc = 0; struct module_buf* module_data = (struct module_buf*)data; if(module_data->length < 3) { PRINTF("module response not enough length!\r\n"); if(module_data != NULL) { if(module_data->buf != NULL) { free(module_data->buf); module_data->buf = NULL; } free(module_data); module_data = NULL; } return -1; } if(MODULE_START == s_module_status) { if((strstr((char*)module_data->buf, "OK"))) { Usart_Send_Str_Data("the \"at\" cmd response \"OK\"\r\n"); s_module_status = MODULE_SYNC; } } if (MODULE_INIT ==s_module_status|| MODULE_INIT_DONE == s_module_status) { int i = 0; if (NULL != s_current_at_command) { for (i = 0; i at_name, atCmdTable[i].name)) { s_at_status =atCmdTable[i].at_cmd_handler(&urc, (char*)module_data->buf); if (ATC_RSP_FINISH ==s_at_status) { free(s_current_at_command); s_current_at_command = NULL; } break; } } } else { // http response if(data_process(module_data)==1) { } } } if(module_data != NULL) { Usart_Send_Str_Data("free\r\n"); if(module_data->buf != NULL) { free(module_data->buf); module_data->buf = NULL; } free(module_data); module_data = NULL; } return 0; }