#include "http_down.h"
#include "gsocket.h"
#include "gsyscfg.h"
#include "gosconfig.h"
#define LOG_TAG "HTTP"
#include <elog.h>
extern uint8_t * rxOtabuf;
static uint32_t content_len=0;
static runStatusEnum otaRunStatus = RUN_INIT;
static int8_t clientId =0;
/*文件下载以后怎么处理
这里完成-数据写到W24Q64
*/
static void bin_handle(uint8_t *data,uint8_t page,uint16_t flag)//flag--0 正常4096 1--最后一个
{
}
/*
范例:
http://192.168.10.102:8445/api1/v1/image/STM32F412REapp.bin
GET /api1/v1/image/STM32F412REapp.bin HTTP/1.1
Host:192.168.10.102:8445
其实我已经准备好了
192.168.10.102:8445
api1/v1/image/STM32F412REapp.bin
本次:
【GET /api1/v1/packages/Entrance_Guard/Touch/31c2a5b9fca4dc195e510c0a09f810a4/otatest.bin HTTP/1.1
Host: 47.103.134.150:8445
】
[HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Application-Context: abdoor-ui:8445
Last-Modified: Tue, 12 Nov 2019 07:36:34 GMT
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Length: 6
Date: Thu, 14 Nov 2019 04:26:50 GMT
"3DUf]
*/
char *pack_httpget_head(void)
{
char *host=NULL;
config.read(CFG_MQTT_OTAADDR_STRING , (void **)&host );
char *path=NULL;
config.read(CFG_MQTT_OTAPATH , (void **)&path );
static char get[500];
memset(get,0,sizeof(get));
//sprintf(get,"GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n",path,host);这样是直接下载 如果BIN只要123456可以一次过来如果200K你这样会死机
sprintf(get,"GET /%s HTTP/1.1\r\nHost: %s\r\nRange: bytes=0-3\r\n\r\n",path,host);
log_e("【%s】",get);
return get;
}
/*把数据整理到 buf 中 而返回值sprintf正好可以表达 buf的长度*/
uint16_t pack_http_head(char *buf,int L,int R)
{
char *host=NULL;
config.read(CFG_MQTT_OTAADDR_STRING , (void **)&host );
char *path=NULL;
config.read(CFG_MQTT_OTAPATH , (void **)&path );
return sprintf(buf,"GET /%s HTTP/1.1\r\nHost: %s\r\nRange: bytes=%d-%d\r\n\r\n",path,host,L,R);
}
/*1.0完成一个TX-RX的模型 它的len是走sockeArry[4].len RX是信号量 不可理喻 后面优化*/
/*
本次:
GET /api1/v1/packages/Entrance_Guard/Touch/31c2a5b9fca4dc195e510c0a09f810a4/otatest.bin HTTP/1.1
Host: 47.103.134.150:8445
Range: bytes=0-3
】
[HTTP/1.1 206
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Application-Context: abdoor-ui:8445
Last-Modified: Tue, 12 Nov 2019 07:36:34 GMT
Accept-Ranges: bytes
Content-Range: bytes 0-3/6
Content-Type: application/octet-stream
Content-Length: 4
Date: Thu, 14 Nov 2019 05:31:58 GMT
"3D]
*/
int http_download_file_getbinlen(void)
{
int file_len=0,http_bin_len=0,ret = 0;
char *get=NULL,*p=NULL;
char sub[10];
get = pack_httpget_head();
//TX之前先把RX缓存清空
memset(rxOtabuf,0,SIMOTABUF);
sockeArry[4].len=0;
ret = gsocket.send(clientId,(uint8_t *)get,strlen(get),80000);
if( ret != GSOCKET_OK) { log_e("发送HTTP FAIL\r\n");return -1;}
log_e("发送HTTP OK\r\n");
/*TX以后 需要等待RX 其实RX是需要一个任务一直在后台跑的 就是函数 gsm_receive_data_handle */
if( xSemaphoreTake( xOTACOMESemaphore, 30000 ) == pdTRUE )
{
log_e("OTA收到!\n");
if(strstr((char *)rxOtabuf,"HTTP/1.1 200 "))//第一次
{
printb("[%s]\r\n",rxOtabuf);
Gmid((char*)rxOtabuf,"Content-Length: ","\r\n",sub);
file_len = ATOI32(sub,10);
p=strstr((char *)rxOtabuf,"\r\n\r\n");
p+=4;//此时p指向BIN文件第一个字节
http_bin_len = sockeArry[4].len - ( p-(char*)rxOtabuf);
log_arry("http_bin" ,(uint8_t*) p ,http_bin_len );
printb("【本次下发长度 http_bin_len =%d 全文 file_len=%d】\r\n",http_bin_len,file_len);
return file_len;
}
return 0;
}
return 0;
}
/*2.0修改1.0每次拿部分文件*/
int http_download_file_getbinpart(int L,int R)
{
char request[256];
int sendLen = 0,http_bin_len=0, ret = 0;
char *p=NULL;
sendLen = pack_http_head(request,L,R);
//TX之前先把RX缓存清空
memset(rxOtabuf,0,SIMOTABUF);
sockeArry[4].len=0;
ret = gsocket.send(clientId,(uint8_t *)request,sendLen,80000);
if( ret != GSOCKET_OK) { log_e("发送HTTP FAIL\r\n");return -1;}
log_e("【%s】\r\n",request);
log_e("发送HTTP OK\r\n");
if( xSemaphoreTake( xOTACOMESemaphore, 30000 ) == pdTRUE )
{
log_e("OTA收到!\n"); printb("[%s]\r\n",rxOtabuf);
if(strstr((char *)rxOtabuf,"HTTP/1.1 206 "))
{
printb("[%s]\r\n",rxOtabuf);
p=strstr((char *)rxOtabuf,"\r\n\r\n");
p+=4;//此时p指向BIN文件第一个字节
http_bin_len = sockeArry[4].len - ( p-(char*)rxOtabuf);
log_arry("http_bin" ,(uint8_t*) p ,http_bin_len );
printb("【本次RX长度 http_bin_len =%d 】\r\n",http_bin_len);
return http_bin_len;
}
return 0;
}
return 0;
}
typedef struct
{
int file_len;
int once_len;
uint8_t all_cnt;
uint8_t now_cnt;
int L;
int R;
}otamark_t;
otamark_t otamark;
void show_otamark(otamark_t *p)
{
printy("p->file_len= %d\n" , p->file_len);
printr("p->once_len= %d\n" , p->once_len);
printy("p->all_cnt= %d\n" , p->all_cnt);
printr("p->now_cnt= %d\n" , p->now_cnt);
printr("p->L= %d\n" , p->L);
printr("p->R= %d\n" , p->R);
}
int8_t http_download_file(void)
{
int len=0;
len = http_download_file_getbinlen();
if(len ==0)
{ log_d("http_download_file_getbinlen err\r\n");return 44;};
otamark.file_len = len;
otamark.once_len = 1024;
otamark.all_cnt =(otamark.file_len %otamark.file_len)?(otamark.file_len /otamark.file_len +1):(otamark.file_len /otamark.file_len);
otamark.now_cnt =0;
otamark.L =0;
otamark.R =otamark.once_len;
show_otamark(&otamark);
while(otamark.now_cnt < otamark.all_cnt )
{
len = http_download_file_getbinpart(otamark.L,otamark.R);
if(len == otamark.once_len)
{
otamark.L +=otamark.once_len;
otamark.R +=otamark.once_len;
otamark.now_cnt++;
log_d("if(len == otamark.once_len)\r\n"); show_otamark(&otamark);
}
else if(len==0)
{
log_d("if(len ==0)\r\n");return 44;
}
else
{
log_d("预计是最后一个啦len =%d\r\n",len );
}
}
return 44;
}
int8_t ota_download_file( void )
{
int ret = -1;
char id = (GSOCKET_CONNECT_MAX-1);
switch(otaRunStatus)
{
case RUN_INIT:
{
if( gsocket.isOK() == TRUE)
{
otaRunStatus = RUN_CONNECTING;
}
}break;
case RUN_CONNECTING:
{
//拿到IP-PORT
serverAddrType *ipport=NULL;
config.read(CFG_MQTT_OTAADDR , (void **)&ipport );
if(ipport==NULL)break;
//47.103.134.150:8445
//拿到设计的通道号
//id=OTA_SOCKET_CHG();
//TCP连接
if( (ret = gsocket.connect(id,ipport->ip , ipport->port ,(char *)rxOtabuf , SIMOTABUF)) >= 0)
{
clientId = ret;
log_d("ota connect server success , client id = %d\n" , clientId);
otaRunStatus = RUN_CONNECT;
}
else
{
otaRunStatus = RUN_INIT;
}
}break;
case RUN_CONNECT://已经链接开始操作
{
ret = http_download_file();
if( ret == 0 )
{
printr("文件下载成功,可以进行升级\n");
return 0;//-----HERE
}
else if( ret == 44 )
{
printr("文件下载失败\n");
otaRunStatus = RUN_INIT;
clientId = -1;
return 44;//-----HERE
}
}break;
default:break;
}
return -1;//------HERE
}
//