#include #include #include #include #include #include "gpio_map.h" #include "gpio_driver.h" #include #include // #include "bk_wifi_netif.h" #include "bk_wifi.h" #include #include "bk_uart.h" #include #include #include #include #include #include "ota_client.h" #include "common.h" #include #define TAG "ota_clint" #include "components/webclient.h" #include "httpc.h" #define GET_LOCAL_URI "http://106.52.233.130:8888/HC32L07X.bin" //"http://www.rt-thread.com/service/rt-thread.txt" #define GET_HEADER_BUFSZ 1024 #define GET_RESP_BUFSZ 128 // webclient post /* send HTTP POST request by simplify request interface, it used to received shorter data */ static int test_webclient_post_smpl(const char *uri, const char *post_data, int data_len) { char *response = NULL; char *header = NULL; size_t resp_len = 0; int index = 0; webclient_request_header_add(&header, "Content-Length: %d\r\n", strlen(post_data)); webclient_request_header_add(&header, "Content-Type: application/octet-stream\r\n"); if (webclient_request(uri, header, post_data, data_len, (void **)&response, &resp_len) < 0) { BK_LOGE(TAG, "webclient send post request failed."); web_free(header); return -1; } BK_LOGE(TAG, "webclient send post request by simplify request interface.\n"); BK_LOGE(TAG, "webclient post response data: \n"); for (index = 0; index < resp_len; index++) { os_printf("%c", response[index]); } BK_LOGE(TAG, "\n"); BK_LOGE(TAG, "%s\n", response); BK_LOGE(TAG, "\n"); if (header) { web_free(header); } if (response) { web_free(response); } return 0; } void test_upload_photo() { char *uri = NULL; uri = web_strdup("https://www.rt-thread.com/service/echo"); if (uri == NULL) { BK_LOGE(TAG, "no memory for create post request uri buffer.\n"); return; } test_webclient_post_smpl(uri, "helloworld ,i'm use webclient to test https post interface,this is a test data", 79); // test_webclient_post_smpl(const char *uri, const char *post_data, int data_len) } // webclient post int ota_file_download_from_http(char *ota_file_url, ota_file_t *ota_file) { char *uri = NULL; uri = web_strdup(ota_file_url); if (uri == NULL) { BK_LOGE(TAG, "no memory for create get request uri buffer.\n"); return BK_ERR_NO_MEM; } struct webclient_session *session = NULL; unsigned char *buffer = NULL; int index, ret = 0; int bytes_read, resp_status; int content_length = -1; buffer = (unsigned char *)web_malloc(GET_RESP_BUFSZ); if (buffer == NULL) { BK_LOGE(TAG, "no memory for receive buffer.\n"); ret = BK_ERR_NO_MEM; goto __exit; } /* create webclient session and set header response size */ session = webclient_session_create(GET_HEADER_BUFSZ); if (session == NULL) { ret = BK_ERR_NO_MEM; goto __exit; } /* send GET request by default header */ if ((resp_status = webclient_get(session, uri)) != 200) { BK_LOGE(TAG, "webclient GET request failed, response(%d) error.\n", resp_status); ret = BK_ERR_STATE; goto __exit; } BK_LOGI(TAG, "webclient get response data: \n"); content_length = webclient_content_length_get(session); BK_LOGE(TAG, "webclient get content_length : %d\n", content_length); if (content_length < 0) { BK_LOGI(TAG, "webclient GET request type is chunked.\n"); do { bytes_read = webclient_read(session, (void *)buffer, GET_RESP_BUFSZ); if (bytes_read <= 0) { break; } for (index = 0; index < bytes_read; index++) { BK_LOG_RAW("%c", buffer[index]); } } while (1); BK_LOGI(TAG, "\n"); } else { ota_file->ota_data_len = content_length; // uint8_t *ota_data = (uint8_t *)ota_file->ota_data; // BK_LOGE(TAG,"ota_file->ota_data :%d\n",ota_file->ota_data); ota_file->ota_data = malloc(content_length); // uint8_t *ota_data = (uint8_t *)psram_malloc(content_length); if (ota_file->ota_data == NULL) // if (ota_data == NULL) { BK_LOGE(TAG, "no memory for ota_data buffer.\n"); ret = BK_ERR_NO_MEM; goto __exit; } BK_LOGE(TAG, "ota_file->ota_data :%d\n", ota_file->ota_data); int content_pos = 0; do { bytes_read = webclient_read(session, (void *)buffer, content_length - content_pos > GET_RESP_BUFSZ ? GET_RESP_BUFSZ : content_length - content_pos); BK_LOGE(TAG, "Rx: %d\n", bytes_read); if (bytes_read <= 0) { BK_LOGE(TAG, "finish!!\n"); break; } // BK_LOGE(TAG, "@@ %02X %02X %02X %02X\n",buffer[0],buffer[1],buffer[2],buffer[3]); os_memcpy(ota_file->ota_data + content_pos, buffer, bytes_read); // os_memcpy(ota_data+content_pos, buffer, bytes_read); // BK_LOGE(TAG, "++ %02X %02X %02X %02X\n",ota_file->ota_data[content_pos],ota_file->ota_data[content_pos+1],ota_file->ota_data[content_pos+2],ota_file->ota_data[content_pos+3]); // unsigned char out [128] = {0}; // hex_to_asciistring(ota_file->ota_data+content_pos,bytes_read,out); // BK_LOGE(TAG, "SEND: %s\n",out); content_pos += bytes_read; rtos_delay_milliseconds(10); } while (content_pos < content_length); rtos_delay_milliseconds(200); BK_LOGE(TAG, "finish22!!\n"); int sum = checksum(ota_file->ota_data, content_length); BK_LOGE(TAG, "check sum: %d\n", sum); ret = BK_OK; } __exit: if (session) { webclient_close(session); } if (buffer) { web_free(buffer); } if (uri) { web_free(uri); } return ret; } #if 1 #define USE_HTTPS 0 #define SERVER_HOST "192.168.32.250" //"www.rt-thread.com"//"www.baidu.com" #define RCV_HEADER_SIZE 5 * 1024 #define RCV_BUFF_SIZE 5 * 1024 #define SEND_HEADER_SIZE 1024 static void bk_httpc_hex_dump(char *s, int length) { BK_LOGE(TAG, "begin to print (length=%d):\r\n", length); for (int index = 0; index < length; index++) { BK_LOG_RAW("%c", s[index]); } os_printf("\r\n"); } #define BOUNDARY "RTTHREAD_FORM_DATA_BOUNDARY" //#define HOST "http://your.server.com/upload" /* 构建multipart请求体 */ static int build_multipart_data(char **body, int *content_length, uint8_t *data, int data_len, char *field_name) { //char * filepath = "/data/a.jpg"; /* 计算各部分长度 */ char *header_fmt = "--"BOUNDARY"\r\n" "Content-Disposition: form-data; name=\"file\"; filename=\"a.jpg\"\r\n" "Content-Type: image/jpeg\r\n\r\n"; char *footer = "\r\n--"BOUNDARY"--\r\n"; //int header_len = strlen(header_fmt) + strlen(field_name) + strlen(filepath); int header_len = strlen(header_fmt) ; int total_len = header_len + data_len + strlen(footer); /* 分配内存并拼接数据 */ *body = web_malloc(total_len); char *ptr = *body; memset(ptr,0,total_len); ptr += sprintf(ptr, header_fmt); BK_LOGE(TAG,"%s\n",ptr); memcpy(ptr, data, data_len); ptr += data_len; sprintf(ptr, "%s", footer); BK_LOGE(TAG,"%s\n",footer); *content_length = total_len; return 0; } // http://httpbin.org/post void webclient_post_photo(char *url, uint8_t *mjpeg_data, int data_len) { BK_LOGE(TAG, "------webclient_post_photo ------\r\n"); unsigned char *buffer = NULL; //int ret = 0; int bytes_read, resp_status; int RCV_BUF_SIZE = 1024*2; buffer = (unsigned char *) web_malloc(RCV_BUF_SIZE); if (buffer == NULL) { BK_LOGE(TAG,"no memory for receive response buffer.\n"); } struct webclient_session* session = NULL; /* create webclient session and set header response size */ session = webclient_session_create(2*1024); if (session == NULL) { BK_LOGE(TAG, "webclient_session_create failed\r\n"); } #if 0 char *boundary = "W941239598192928926881402"; // 发送multipart体 char part_header[256]; snprintf(part_header, sizeof(part_header), "--%s\r\n" "Content-Disposition: form-data; name=\"file\";\r\n" "Content-Type: image/png\r\n\r\n", boundary); // 发送结束标记 char footer[64]; snprintf(footer, sizeof(footer), "\r\n--%s--\r\n\r\n", boundary); BK_LOGE(TAG, "data_len %d \r\n", data_len); BK_LOGE(TAG, "part_header %d \r\n", strlen(part_header)); BK_LOGE(TAG, "footer %d \r\n", strlen(footer)); int total_content_length = data_len + strlen(part_header) + strlen(footer); BK_LOGE(TAG,"total_content_length: %d\n",total_content_length); /* build header for upload */ webclient_header_fields_add(session, "Accept: */*\r\n"); webclient_header_fields_add(session, "User-Agent: Apifox/1.0.0 (https://apifox.com)\r\n"); webclient_header_fields_add(session, "Connection: keep-alive\r\n"); webclient_header_fields_add(session, "Content-Type: multipart/form-data; boundary=%s\r\n",boundary); webclient_header_fields_add(session, "Content-Length: %d\r\n", total_content_length); char post_data[512]={0}; int pos = 0; os_memcpy(post_data,part_header,strlen(part_header)); pos =pos+ strlen(part_header); os_memcpy(post_data+pos,mjpeg_data,data_len); pos =pos+data_len; os_memcpy(post_data+pos,footer,strlen(footer)); pos =pos+strlen(footer); BK_LOGE(TAG,"pos: %d\n",pos); #endif char *post_data = NULL; int content_length = 0; if (build_multipart_data(&post_data, &content_length, mjpeg_data,data_len, "file") != 0) { BK_LOGE(TAG,"Build multipart data failed!\n"); return; } webclient_header_fields_add(session, "Accept: */*\r\n"); webclient_header_fields_add(session, "User-Agent: Apifox/1.0.0 (https://apifox.com)\r\n"); webclient_header_fields_add(session, "Connection: keep-alive\r\n"); webclient_header_fields_add(session, "Content-Length: %d\r\n", content_length); webclient_header_fields_add(session, "Content-Type: multipart/form-data; boundary="BOUNDARY"\r\n"); /* send POST request by default header */ if ((resp_status = webclient_post(session, url, post_data, content_length)) != 200) { BK_LOGE(TAG,"webclient POST request failed, response(%d) error.\n", resp_status); } BK_LOGI(TAG,"webclient post response data: \n"); do { bytes_read = webclient_read(session, buffer, RCV_BUF_SIZE); if (bytes_read <= 0) { break; } //strncat(rep_data,(char*)buffer,bytes_read); BK_LOGE(TAG,"rep_data %s.\n", buffer); } while (1); webclient_close(session); } // http://httpbin.org/post void ota_example_httpc_post(char *url, uint8_t *mjpeg_data, int data_len) { BK_LOGE(TAG, "------Example: HTTPC post------\r\n"); struct httpc_conn *conn = NULL; #if 1 const char *host_addr = 0; const char *path_ptr; const char *request; char *req_url = NULL; const char *port_ptr; char port_str[6] = "80"; int host_addr_len = 0; int url_len = strlen(url); if (strncmp(url, "http://", 7) == 0) { host_addr = url + 7; } else if (strncmp(url, "https://", 8) == 0) { host_addr = url + 8; } else { return; } path_ptr = strstr(host_addr, "/"); request = path_ptr ? path_ptr : "/"; if (request) { req_url = strdup(request); } port_ptr = strstr(host_addr + host_addr_len, ":"); if (port_ptr && path_ptr && (port_ptr < path_ptr)) { int port_len = path_ptr - port_ptr - 1; strncpy(port_str, port_ptr + 1, port_len); port_str[port_len] = '\0'; } if (port_ptr && (!path_ptr)) { strcpy(port_str, port_ptr + 1); } if (!host_addr_len) { if ((port_ptr && path_ptr && (port_ptr < path_ptr)) || (port_ptr && (!path_ptr))) { host_addr_len = port_ptr - host_addr; } else if (path_ptr) { host_addr_len = path_ptr - host_addr; } else { host_addr_len = strlen(host_addr); } } if ((host_addr_len < 1) || (host_addr_len > url_len)) { return; } char *host_addr_new = os_malloc(host_addr_len + 1); if (!host_addr_new) { return; } memcpy(host_addr_new, host_addr, host_addr_len); host_addr_new[host_addr_len] = '\0'; BK_LOGE(TAG, "host_addr_new:%s port_str:%d\r\n", host_addr_new, port_str); #endif BK_LOGE(TAG, "11111\r\n"); #if USE_HTTPS conn = httpc_conn_new(HTTPC_SECURE_TLS, NULL, NULL, NULL); #else conn = httpc_conn_new(HTTPC_SECURE_NONE, NULL, NULL, NULL); #endif BK_LOGE(TAG, "2222\r\n"); if (conn) { #if USE_HTTPS // if(httpc_conn_connect(conn, host_addr_new, 443, 0) == 0) { if (httpc_conn_connect(conn, host_addr_new, 443, 0) == 0) { #else if (httpc_conn_connect(conn, "192.168.0.39", 8080, 0) == 0) { #endif /* HTTP POST request */ BK_LOGE(TAG, "----------------BEGIN WRITE HEADER------------\r\n"); #if 1 BK_LOGE(TAG, "3333 %s \r\n", req_url); /* char *post_data = "param1=test_data1¶m2=test_data2"; // start a header and add Host (added automatically), Content-Type and Content-Length (added by input param) httpc_request_write_header_start(conn, "POST", req_url, NULL, strlen(post_data));//"/post" // finish and send header httpc_request_write_header_finish(conn); httpc_request_write_data(conn, (uint8_t *)post_data, strlen(post_data)); */ char *boundary = "W941239598192928926881402"; // 发送multipart体 char part_header[256]; snprintf(part_header, sizeof(part_header), "--%s\r\n" "Content-Disposition: form-data; name=\"file\";\r\n" "Content-Type: image/png\r\n\r\n", boundary); // 发送结束标记 char footer[64]; snprintf(footer, sizeof(footer), "\r\n--%s--\r\n\r\n", boundary); BK_LOGE(TAG, "data_len %d \r\n", data_len); BK_LOGE(TAG, "part_header %d \r\n", strlen(part_header)); BK_LOGE(TAG, "footer %d \r\n", strlen(footer)); int total_content_length = data_len + strlen(part_header) + strlen(footer); // 构造HTTP头 char header[512]; snprintf(header, sizeof(header), "POST /upload HTTP/1.1\r\n" "Host: %s\r\n" "Accept: */*\r\n" "User-Agent: Apifox/1.0.0 (https://apifox.com)\r\n" "Connection: keep-alive\r\n" "Content-Type: multipart/form-data; boundary=%s\r\n" "Content-Length: %d\r\n\r\n", "192.168.0.39", boundary, total_content_length); // 需计算实际长度 // BK_LOGE(TAG,"%s",header); // BK_LOGE(TAG,"%s",part_header); // BK_LOGE(TAG,"%s",footer); // send(sock, header, strlen(header), 0); httpc_request_write_data(conn, (uint8_t *)header, strlen(header)); // send(sock, part_header, strlen(part_header), 0); httpc_request_write_data(conn, (uint8_t *)part_header, strlen(part_header)); // 发送图片数据(假设已获取到图片指针和长度) // send(sock, image_data, image_len, 0); httpc_request_write_data(conn, mjpeg_data, data_len); // send(sock, footer, strlen(footer), 0); httpc_request_write_data(conn, (uint8_t *)footer, strlen(footer)); #else httpc_request_write_header_start(conn, "POST", req_url, NULL, 0); //"/post" httpc_request_write_header(conn, "Accept", "*/*"); httpc_request_write_header(conn, "Accept-Encoding", "gzip, deflate, br"); httpc_request_write_header(conn, "User-Agent", "PostmanRuntime-ApipostRuntime/1.1.0"); httpc_request_write_header(conn, "Connection", "keep-alive"); httpc_request_write_header(conn, "Cache-Control", "no-cache"); httpc_request_write_header(conn, "Content-Type", "multipart/form-data; boundary=---011000010111000001101001"); // send Content-Disposition char *post_data = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\nContent-Type: image/jpeg\r\n\r\n"; // send end char *end_data = "\r\n-----011000010111000001101001--\r\n\r\n"; // BK_LOGE(TAG,"LENLEN:%d\n",strlen(end_data)); char strContentLen[12] = {0}; sprintf(strContentLen, "%d", data_len + strlen(post_data) + strlen(end_data)); httpc_request_write_header(conn, "Content-Length", strContentLen); // add other header fields if necessary // httpc_request_write_header(conn, "Connection", "close"); // finish and send header BK_LOGE(TAG, "%s\n", conn->request_header); httpc_request_write_header_finish(conn); BK_LOGE(TAG, "%s\n", (uint8_t *)post_data); httpc_request_write_data(conn, (uint8_t *)post_data, strlen(post_data)); BK_LOGE(TAG, "(IMG)\n"); // send http body httpc_request_write_data(conn, mjpeg_data, data_len); BK_LOGE(TAG, "%s\n", (uint8_t *)end_data); httpc_request_write_data(conn, (uint8_t *)end_data, strlen(end_data)); #endif BK_LOGE(TAG, "----------------BEGIN READ HEADER------------\r\n"); // receive response header if (httpc_response_read_header(conn) == 0) { httpc_conn_dump_header(conn); // receive response body if (httpc_response_is_status(conn, "200 OK")) { // uint8_t buf[RCV_BUFF_SIZE]; uint8_t *buf = (uint8_t *)malloc(RCV_BUFF_SIZE); int read_size = 0, total_size = 0; BK_LOGE(TAG, "----------------BEGIN READ PAYLOAD---------------\r\n"); while (1) { memset(buf, 0, RCV_BUFF_SIZE); read_size = httpc_response_read_data(conn, buf, RCV_BUFF_SIZE - 1); if (read_size > 0) { total_size += read_size; // bk_httpc_hex_dump((char *)buf, read_size); BK_LOGE(TAG, "RES:%s\r\n", buf); } else { break; } if (conn->response.content_len && (total_size >= conn->response.content_len)) break; } if (buf) { os_free(buf); buf = NULL; } } } } else { os_printf("\nERROR: httpc_conn_connect\n"); } } BK_LOGE(TAG, "----------------BEGIN CLOSE---------------\r\n"); httpc_conn_close(conn); httpc_conn_free(conn); httpc_free(conn); } void ilock_example_httpc_get(char *url) { BK_LOGE(TAG, "-------Example: HTTPC get-----\r\n"); struct httpc_conn *conn = NULL; #if 1 const char *host_addr = 0; const char *path_ptr; const char *request; char *req_url = NULL; const char *port_ptr; char port_str[6] = "80"; int host_addr_len = 0; int url_len = strlen(url); if (strncmp(url, "http://", 7) == 0) { host_addr = url + 7; } else if (strncmp(url, "https://", 8) == 0) { host_addr = url + 8; } else { return; } path_ptr = strstr(host_addr, "/"); request = path_ptr ? path_ptr : "/"; if (request) { req_url = strdup(request); } port_ptr = strstr(host_addr + host_addr_len, ":"); if (port_ptr && path_ptr && (port_ptr < path_ptr)) { int port_len = path_ptr - port_ptr - 1; strncpy(port_str, port_ptr + 1, port_len); port_str[port_len] = '\0'; } if (port_ptr && (!path_ptr)) { strcpy(port_str, port_ptr + 1); } if (!host_addr_len) { if ((port_ptr && path_ptr && (port_ptr < path_ptr)) || (port_ptr && (!path_ptr))) { host_addr_len = port_ptr - host_addr; } else if (path_ptr) { host_addr_len = path_ptr - host_addr; } else { host_addr_len = strlen(host_addr); } } if ((host_addr_len < 1) || (host_addr_len > url_len)) { return; } char *host_addr_new = os_malloc(host_addr_len + 1); if (!host_addr_new) { return; } memcpy(host_addr_new, host_addr, host_addr_len); host_addr_new[host_addr_len] = '\0'; // BK_LOGE(TAG,"host_addr_new:%s port_str:%d\r\n", host_addr_new, port_str); #endif #if USE_HTTPS conn = httpc_conn_new(HTTPC_SECURE_TLS, NULL, NULL, NULL); #else conn = httpc_conn_new(HTTPC_SECURE_NONE, NULL, NULL, NULL); #endif if (conn) { #if USE_HTTPS if (httpc_conn_connect(conn, host_addr_new, 443, 0) == 0) { #else if (httpc_conn_connect(conn, host_addr_new, 8888, 0) == 0) { #endif /* HTTP GET request */ BK_LOGE(TAG, "----------------BEGIN WRITE HEADER------------\r\n"); httpc_request_write_header_start(conn, "GET", req_url, NULL, 0); httpc_request_write_header(conn, "User-Agent", "BEKEN HTTP Client/1.0"); // finish and send header httpc_request_write_header_finish(conn); BK_LOGE(TAG, "----------------BEGIN READ HEADER---------------\r\n"); // receive response header if (httpc_response_read_header(conn) == 0) { httpc_conn_dump_header(conn); // receive response body if (httpc_response_is_status(conn, "200 OK")) { // uint8_t buf[RCV_BUFF_SIZE]; uint8_t *buf = (uint8_t *)malloc(RCV_BUFF_SIZE); int read_size = 0, total_size = 0; BK_LOGE(TAG, "----------------BEGIN READ PAYLOAD---------------\r\n"); while (1) { memset(buf, 0, RCV_BUFF_SIZE); read_size = httpc_response_read_data(conn, buf, RCV_BUFF_SIZE - 1); if (read_size > 0) { BK_LOGE(TAG, "httpc get response data: \r\n"); total_size += read_size; bk_httpc_hex_dump((char *)buf, read_size); } else { break; } if (conn->response.content_len && (total_size >= conn->response.content_len)) break; } if (buf) { os_free(buf); buf = NULL; } } } } else { printf("\nERROR: httpc_conn_connect\n"); } } BK_LOGE(TAG, "----------------BEGIN CLOSE---------------\r\n"); httpc_conn_close(conn); httpc_conn_free(conn); httpc_free((void *)conn); } #endif