helloyifa 31f179cb76 init
2025-05-15 14:19:56 +08:00

768 lines
25 KiB
C
Executable File

#include <components/log.h>
#include <components/system.h>
#include <os/os.h>
#include <components/shell_task.h>
#include <common/bk_include.h>
#include "gpio_map.h"
#include "gpio_driver.h"
#include <driver/gpio.h>
#include <common/bk_kernel_err.h>
// #include "bk_wifi_netif.h"
#include "bk_wifi.h"
#include <os/str.h>
#include "bk_uart.h"
#include <os/mem.h>
#include <os/os.h>
#include <common/bk_kernel_err.h>
#include <string.h>
#include <driver/uart.h>
#include "ota_client.h"
#include "common.h"
#include <stdlib.h>
#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&param2=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