123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- #include "learnHttp.h"
- #include "nwy_osi_api.h"
- #include "nwy_http.h"
- #include "nwy_ftp.h"
- #include "log.h"
- #include "ohpoc.h"
- #include "base64.h"
- #include "app.h"
- #define GET_FILE_MAX_SIZE 10*1024
- #define HTTP_TASK_STACK_SIZE (1024*64)
- #define LEN_SEG "Content-Length: "
- typedef enum{
- HPROC_START,
- HPROC_BUSY,
- HPROC_OK,
- HPROC_FAILED
- }HTTP_PRO_ENUM;
- typedef struct{
- UHTTP_ENUM httpType;
- char url[200];
- unsigned char lteStatus;//下载文件状态
- unsigned char timeout;
- HTTP_PRO_ENUM processStatus;
- int fsize;
- int offset;
- unsigned short port;
- HttpCallBack recvCb;
- unsigned char *data;
- unsigned int dlength;
- unsigned char done;
- }HttpInfoSet;
- unsigned char *httpDataPtr=NULL;
- HttpInfoSet httpinfo;
- nwy_osiThread_t *learnHttpThread=NULL;
- typedef enum{
- HTTP_STATUS_IDLE,
- HTTP_STATUS_SETUP,
- HTTP_STATUS_SETUP_OK,
- HTTP_STATUS_GET,
- HTTP_STATUS_GET_OK,
- HTTP_STATUS_DNSERR,
- HTTP_STATUS_GET_ERR_HEAD,
- HTTP_STATUS_GET_REJECT_HEAD,
- HTTP_STATUS_GET_FAILED_HEAD,
- HTTP_STATUS_GET_ERR_FSIZE,
- HTTP_STATUS_GET_FAILED_FSIZE,
- HTTP_STATUS_GET_ERR_OFFSET,
- HTTP_STATUS_GET_FSIZE_OVER,
- HTTP_STATUS_POST_BUSY,
- HTTP_STATUS_POST_BAD,
- HTTP_STATUS_POST_DONE,
- HTTP_STATUS_DATA_MALLOC_ERR,
- HTTP_STATUS_TOUT,
- HTTP_STATUS_CLOSED
- }HTTP_STATUS_ENUM;
- static void learnEntry(void *param);
- void learn_http_set_status_false(unsigned char newStatus){
- MSG_INFO(1, "learn Status:%d",newStatus);
- httpinfo.lteStatus=newStatus;
- httpinfo.processStatus=HPROC_FAILED;
- }
- void learnHttpStart(UHTTP_ENUM httpType, char *url, unsigned short port, HttpCallBack *httpCb, unsigned char *udata, unsigned int dlen){
- if(httpCb==NULL){
- MSG_INFO(1, "httpCb is invalid");
- return;
- }
- if(NULL != learnHttpThread){
- MSG_INFO(1, "learnHttp is busy");
- return;
- }
- memset(&httpinfo, 0, sizeof(HttpInfoSet));
- httpinfo.data=udata;
- httpinfo.dlength=dlen;
- httpinfo.httpType=httpType;
- httpinfo.port=port;
- httpinfo.recvCb=httpCb;
- snprintf(httpinfo.url, sizeof(httpinfo.url), "%s",url);//120.77.66.129、1.txt 不需要http:头
- learnHttpThread=nwy_create_thread("learnHttpThread", learnEntry,NULL,NWY_OSI_PRIORITY_NORMAL,HTTP_TASK_STACK_SIZE,15);
- if(NULL==learnHttpThread){
- MSG_ERR(1,"learnHttpThread thread error");//因为是阻塞的,故需要开线程,且栈要比较大
- }
- }
- #define USER_DATA_SIZE (1024*3) //每次http post最大用户数据长度
- static void nwy_http_result_cb(nwy_ftp_result_t *param);
- static void learnEntry(void *param){
- unsigned char *ptr;
- int channel=1;
- int keepalive=1;
- int pIndex,lLen,pLen,tLen,rLen;
- unsigned char *postBuf=NULL;
- char tmp[30];
- float tmpSpeed;
-
- appSleepCtl(ASLEEP_LEARN, 1);
- boolean http_https=false;//http
- nwy_osiEvent_t event = {};
- MSG_INFO(1,"learn thread start:url=%s",httpinfo.url);
-
- int result = nwy_http_setup(channel, httpinfo.url, httpinfo.port, nwy_http_result_cb);
- if(0!=result){
- MSG_INFO(1, "learn http setup api failed");
- goto HTTP_END;
- }
- MSG_INFO(1, "learn http wait setup result");
- for(;;){
- nwy_wait_thead_event(nwy_get_current_thread(), &event,0);
- if(OHPOC_EVENT_HTTP==event.id) break;
- }
- if(httpinfo.lteStatus==HTTP_STATUS_DNSERR) goto HTTP_END;
- if(httpinfo.httpType==UHTTP_FILE_GET){
- httpinfo.lteStatus=HTTP_STATUS_GET;//start get
- result = nwy_http_get(keepalive, 0, GET_FILE_MAX_SIZE, http_https);
- if(result!=0){
- MSG_INFO(1,"learn http get api failed");
- goto HTTP_END;
- }
- MSG_INFO(1, "learn http wait get ack");
- for(;;){
- nwy_wait_thead_event(nwy_get_current_thread(), &event,0);
- if(OHPOC_EVENT_HTTP==event.id){
- if(httpinfo.lteStatus==HTTP_STATUS_GET_OK ||
- httpinfo.lteStatus==HTTP_STATUS_CLOSED ||
- httpinfo.lteStatus==HTTP_STATUS_TOUT) break;
- }
- }
- }else if(httpinfo.httpType==UHTTP_POST){
- httpinfo.processStatus=HPROC_START;
- pIndex=0;
- #if 0//强制发送长度为20的测试数据
- httpinfo.dlength=20;
- memset(httpinfo.data, 0x55, httpinfo.dlength);
- #endif
- lLen=httpinfo.dlength;
- postBuf=(unsigned char *)malloc(USER_DATA_SIZE);
- if(postBuf==NULL){
- MSG_ERR(1, "http post malloc failed");
- httpinfo.processStatus=HPROC_FAILED;
- goto HTTP_END;
- }
- for(;;){
- httpinfo.lteStatus=HTTP_STATUS_POST_BUSY;
-
- tmpSpeed=learnGetRecordRecSpeed();
- //先填充必须的一些字段信息,数据未填充,包有效数据长度未填(原始数据,非base64后)
- snprintf(postBuf, USER_DATA_SIZE, "{\"tid\":%s,\"uid\":%d,\"gid\":%d,\"dsv\":%d,\"dss\":%.1f,\"fsize\":%d,\"offset\":%d,\"token\":\"%s\",\"data\":\"",
- learnGetTid(),
- getLearnUid(),
- getLearnGid(),
- learnGetRecordMaxVolume(),
- tmpSpeed,
- httpinfo.dlength,
- pIndex,
- getLearnToken());
- //计算剩下可以填充多少实际数据,最后预留:","size":3000},即14字节,我们给20字节吧
- tLen=USER_DATA_SIZE-strlen(postBuf)-20;
- //计算tLen最多能装多少个原始数据,每4个base64表示3个原始数据
- rLen=tLen/4;//最多能装多少'组'原始数据
- rLen *= 3;//最多能装多少字节原始数据
- //计算本次填充多少有效数据
- if(lLen>rLen) pLen=rLen;
- else pLen=lLen;
- //填充有效数据
- ptr=httpinfo.data+pIndex;
- base64_encode(ptr, postBuf+strlen(postBuf), pLen);//结尾会被填充'\0'
- //添加size字段
- snprintf(tmp, sizeof(tmp), "\",\"size\":%d}", pLen);
- strcat(postBuf, tmp);
- //MSG_INFO(1, "send:<%s>\r\n", postBuf);
- //可以发送了(json)
- result = nwy_http_post(keepalive, 2 , postBuf, strlen(postBuf), http_https);
- MSG_INFO(1, "Post dataOffset:%d,dataLen:%d,jsonLen:%d %s", pIndex, pLen, strlen(postBuf), (result==0)?"Ok":"Failed");
- if(result==0){//执行成功,等待结果
- for(;;){
- nwy_wait_thead_event(nwy_get_current_thread(), &event,0);
- if(OHPOC_EVENT_HTTP==event.id){
- if(httpinfo.lteStatus==HTTP_STATUS_POST_DONE ||
- httpinfo.lteStatus==HTTP_STATUS_POST_BAD ||
- httpinfo.lteStatus==HTTP_STATUS_CLOSED ||
- httpinfo.lteStatus==HTTP_STATUS_TOUT) break;
- }
- }
- if(httpinfo.lteStatus==HTTP_STATUS_POST_DONE){
- pIndex += pLen;
- lLen -= pLen;
- MSG_INFO(1, "http post len:%d done", pLen);
- httpPostResetUserTimer(pIndex*100/httpinfo.dlength);
- if(lLen<=0){
- MSG_INFO(1, "http post done");
- httpinfo.processStatus=HPROC_OK;
- break;
- }
- }else if(httpinfo.lteStatus==HTTP_STATUS_POST_BAD){
- MSG_INFO(1, "http post ack bad");
- httpinfo.processStatus=HPROC_FAILED;
- break;
- }else{
- MSG_INFO(1, "http connection close/tout");
- httpinfo.processStatus=HPROC_FAILED;
- break;
- }
- }else{
- MSG_INFO(1, "http post err");
- httpinfo.processStatus=HPROC_FAILED;
- break;
- }
- }
- }
- MSG_INFO(1, "learn done");
- HTTP_END:
- if(NULL!=postBuf) free(postBuf);
- MSG_INFO(1, "learn http end");
- nwy_http_close(http_https);
- for(;;){
- if(httpinfo.lteStatus==HTTP_STATUS_DNSERR) break;//如果setup未成功,是不会有事件响应的
- nwy_wait_thead_event(nwy_get_current_thread(), &event,0);
- if(OHPOC_EVENT_HTTP==event.id){
- if(httpinfo.lteStatus==HTTP_STATUS_GET_OK ||
- httpinfo.lteStatus==HTTP_STATUS_CLOSED ||
- httpinfo.lteStatus==HTTP_STATUS_TOUT) break;
- }
- }
- learnHttpThread=NULL;
- httpinfo.done=1;
- appSleepCtl(ASLEEP_LEARN, 0);
- MSG_INFO(1, "learn http thread exit");
- nwy_exit_thread();
- }
- //检测接受到数据是否是成功的
- //HTTP/1.1 200
- static bool isHttpRecvValid(char *msg){
- int i;
- //检测是否是HTTP/头
- if(0!=memcmp(msg, "HTTP/", 5)) return true;//非首包
- //找空格后面的串是否是200
- for(i=0;i<strlen(msg);i++){
- if(msg[i]==' '){
- if(0==memcmp(msg+i+1, "200", 3)) return true;
- else return false;
- }
- }
- return false;
- }
- static void nwy_http_result_cb(nwy_ftp_result_t *param){
- char *ptr;
- int dlen,i;
- char info[55];
-
- snprintf(info,sizeof(info),"[HEvent:%d]",param->event);
- switch(param->event){
- case NWY_HTTP_DATA_RECVED: strcat(info,"NWY_HTTP_DATA_RECVED");break;
- case NWY_HTTP_DNS_ERR: strcat(info,"NWY_HTTP_DNS_ERR");break;
- case NWY_HTTP_OPEN_FAIL: strcat(info,"NWY_HTTP_OPEN_FAIL");break;
- case NWY_HTTP_OPENED: strcat(info,"NWY_HTTP_OPENED");break;
- case NWY_HTTPS_SSL_CONNECTED: strcat(info,"NWY_HTTPS_SSL_CONNECTED");break;
- case NWY_HTTP_CLOSED_PASV: strcat(info,"NWY_HTTP_CLOSED_PASV");break;
- case NWY_HTTP_CLOSED: strcat(info,"NWY_HTTP_CLOSED");break;
- case NWY_HTTP_DATA_SEND_ERR: strcat(info,"NWY_HTTP_DATA_SEND_ERR");break;
- case NWY_HTTPS_SSL_INIT_ERROR: strcat(info,"NWY_HTTPS_SSL_INIT_ERROR");break;
- case NWY_HTTPS_SSL_HANDSHAKE_ERROR: strcat(info,"NWY_HTTPS_SSL_HANDSHAKE_ERROR");break;
- case NWY_HTTPS_SSL_AUTH_FAIL: strcat(info,"NWY_HTTPS_SSL_AUTH_FAIL");break;
- case NWY_HTTP_DATA_SEND_FINISHED: strcat(info,"NWY_HTTP_DATA_SEND_FINISHED");break;
- default:strcat(info,"Unknown");break;
- }
- MSG_INFO(1, info);
- switch(param->event){
- case NWY_HTTP_DATA_RECVED:
- //MSG_INFO(1, "httpRecv:%d,%s", param->data_len, param->data);
- if(httpinfo.httpType==UHTTP_FILE_GET){//发HTTP_GET指令时的响应处理
- if(httpinfo.processStatus==HPROC_START){//响应第一包,需要获取总长度,有效数据长度等信息
- //检测是否是HTTP/头或非首包
- if(false==isHttpRecvValid(param->data)){
- MSG_WARN(1, "UHTTP_FILE_GET Recv Ack Not 200");
- break;
- }
- //获取有效数据总长度
- ptr=strstr(param->data, LEN_SEG);
- if(NULL==ptr){//没有字段,无法提取
- MSG_ERR(1, "No '%s' seg!",LEN_SEG);
- learn_http_set_status_false(HTTP_STATUS_GET_ERR_FSIZE);
- break;
- }
- dlen=atoi(ptr+strlen(LEN_SEG));//
- if(dlen<=0 || dlen>GET_FILE_MAX_SIZE || dlen==param->data_len){
- MSG_ERR(1, "data len invalid:%d",dlen);
- learn_http_set_status_false(HTTP_STATUS_GET_FSIZE_OVER);
- break;
- }
- MSG_INFO(1, "total data len:%d", dlen);
- httpDataPtr=(unsigned char *)malloc(dlen+2);
- if(NULL==httpDataPtr){
- MSG_ERR(1, "data malloc err:%d",dlen);
- learn_http_set_status_false(HTTP_STATUS_DATA_MALLOC_ERR);
- break;
- }
- //获取有效数据开始索引
- ptr=strstr(param->data,"\r\n\r\n");
- if(NULL==ptr){
- MSG_ERR(1, "data offset err");
- learn_http_set_status_false(HTTP_STATUS_GET_ERR_OFFSET);
- free(httpDataPtr);
- break;
- }
- httpinfo.fsize=dlen;
- httpinfo.offset=0;
- //提取本包中的有效数据
- ptr += 4;
- i=param->data_len-(ptr-(char *)param->data);
- memcpy(httpDataPtr+httpinfo.offset, ptr, i);
- //更新
- httpinfo.offset += i;
- httpinfo.processStatus=HPROC_BUSY;
- }else if(httpinfo.processStatus==HPROC_BUSY){//第一包以后均为有效数据
- memcpy(httpDataPtr+httpinfo.offset, param->data, param->data_len);
- httpinfo.offset += param->data_len;
- i=param->data_len;
- }
- if(httpinfo.processStatus<=HPROC_BUSY){
- MSG_INFO(1, "learn getdata offset:%d, fsize:%d", i, httpinfo.offset,httpinfo.fsize);
- if(httpinfo.offset>=httpinfo.fsize){
- MSG_INFO(1,"learn get data done");
- httpinfo.lteStatus=HTTP_STATUS_GET_OK;
- httpinfo.recvCb(httpDataPtr, httpinfo.fsize);
- free(httpDataPtr);
- httpinfo.processStatus=HPROC_OK;
- }
- }
- }else if(httpinfo.httpType==UHTTP_POST){//HTTP_POST时的响应处理接口
- //MSG_INFO(1, "httpRecv:%d,%s", param->data_len, param->data);
- //检测是否是HTTP/头或非首包
- if(false==isHttpRecvValid(param->data)){
- MSG_WARN(1, "UHTTP_POST Recv Ack Not 200");
- httpinfo.lteStatus=HTTP_STATUS_POST_BAD;
- break;
- }
- MSG_INFO(1, "http post get done ack");
- httpinfo.lteStatus=HTTP_STATUS_POST_DONE;
- }
- break;
- case NWY_HTTP_DNS_ERR:httpinfo.lteStatus=HTTP_STATUS_DNSERR;break;
- case NWY_HTTP_OPEN_FAIL: break;
- case NWY_HTTP_OPENED:httpinfo.lteStatus=HTTP_STATUS_SETUP_OK;break;
- case NWY_HTTPS_SSL_CONNECTED: break;
- case NWY_HTTP_CLOSED_PASV:
- case NWY_HTTP_CLOSED:httpinfo.lteStatus=HTTP_STATUS_CLOSED;break;
- case NWY_HTTP_DATA_SEND_ERR: break;
- case NWY_HTTPS_SSL_INIT_ERROR: break;
- case NWY_HTTPS_SSL_HANDSHAKE_ERROR: break;
- case NWY_HTTPS_SSL_AUTH_FAIL: break;
- case NWY_HTTP_DATA_SEND_FINISHED: break;
- }
- threadPostEvent(nwy_get_current_thread(),OHPOC_EVENT_HTTP, NULL,NULL,NULL);
- }
- void hearnHttpOverTime(void){
- if(NULL == learnHttpThread) return;
- httpinfo.lteStatus=HTTP_STATUS_TOUT;
- threadPostEvent(learnHttpThread,OHPOC_EVENT_HTTP, NULL,NULL,NULL);
- }
- unsigned char getHttpLearnStatus(void){
- if(httpinfo.done==0) return 1;//未完成
- if(httpinfo.processStatus==HPROC_OK) return 0;//已完成,且获取成功
- else return 2;//已完成,且失败
- }
- #include "cJSON.h"
- void jsonTestNow(void){
- char* data = "{\"name\":\"Messi\",\"age\":\"29\"}";
- //char* buf = "{\"uid\":12345,\"list\":[{\"tid\":\"5126\"},{\"tid\":\"5127\"},{\"tid\":\"8867\"},{\"tid\":\"8868\"},{\"tid\":\"1221\"},{\"tid\":\"2546\"}]}";
- const char * buf="{\"uid\":12348,\"list\":[{\"s\":4,\"c\":\"What is your name?\",\"t\":\"task 1\",\"f\":1,\"tid\":5126},{\"s\":3,\"c\":\"Where are you?\",\"t\":\"task 2\",\"f\":1,\"tid\":5127}]}";
- //const char * buf="{\"uid\":12348,\"list\":[{\"s\":\"4\",\"c\":\"What is your name?\",\"t\":\"task 1\",\"f\":\"1\",\"tid\":\"5126\"},{\"s\":\"3\",\"c\":\"Where are you?\",\"t\":\"task 2\",\"f\":\"1\",\"tid\":\"5127\"}]}";
- cJSON* root = cJSON_Parse(data);
- if(NULL==root){
- MSG_ERR(1, "root null1");
- return;
- }
- cJSON* itemName = cJSON_GetObjectItem(root, "name");
- if(itemName!=NULL) MSG_INFO(1, "name:%s", itemName->valuestring);
- else MSG_WARN(1, "name:NULL");
-
- cJSON* itemAge = cJSON_GetObjectItem(root, "age");
- if(itemAge!=NULL) MSG_INFO(1, "name:%s", itemAge->valuestring);
- else MSG_WARN(1, "age:NULL");
- cJSON_Delete(root);
- MSG_INFO(1, "JSON DONE");
-
- root = cJSON_Parse(buf);
- if(NULL==root){
- MSG_ERR(1, "root null2");
- return;
- }
-
-
- MSG_INFO(1, "--------------");
- itemName = cJSON_GetObjectItem(root, "list");
-
- if(itemName==NULL){
- MSG_WARN(1, "list:NULL");
- cJSON_Delete(root);
- return;
- }
-
- int num=cJSON_GetArraySize(itemName);
- MSG_INFO(1, "num=%d", num);
- int i=0;
- cJSON* tmp,*t;
- char *buf1;
- while(1){
- tmp=cJSON_GetArrayItem(itemName, i);
- if(tmp==NULL){
- MSG_INFO(1, "NULL");
- break;
- }
- buf1=cJSON_Print(tmp);
- MSG_INFO(1, "Detail:%s",buf1);
- free(buf1);
- t=cJSON_GetObjectItem(tmp, "tid");
- if(t!=NULL) MSG_INFO(1, "element[%d]%s", i++,t->valuestring);
- else MSG_INFO(1, "element[%d]NULL", i++);
- }
- cJSON_Delete(root);
- MSG_INFO(1, "JSON DONE2");
- }
|