From 6f9be6d790a4e8b5bab37f2dda8d37cb835ad90f Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Mon, 16 Aug 2021 15:59:26 +0800 Subject: [PATCH 01/11] APP_Framework/lib/:add queue lib --- APP_Framework/lib/Kconfig | 1 + APP_Framework/lib/queue/Kconfig | 3 ++ APP_Framework/lib/queue/SConscript | 10 +++++ APP_Framework/lib/queue/queue.c | 59 ++++++++++++++++++++++++++++++ APP_Framework/lib/queue/queue.h | 26 +++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 APP_Framework/lib/queue/Kconfig create mode 100644 APP_Framework/lib/queue/SConscript create mode 100644 APP_Framework/lib/queue/queue.c create mode 100644 APP_Framework/lib/queue/queue.h diff --git a/APP_Framework/lib/Kconfig b/APP_Framework/lib/Kconfig index d5064ee3..f92cf7cf 100755 --- a/APP_Framework/lib/Kconfig +++ b/APP_Framework/lib/Kconfig @@ -11,4 +11,5 @@ menu "lib" bool "app select other lib" endchoice source "$APP_DIR/lib/cJSON/Kconfig" + source "$APP_DIR/lib/queue/Kconfig" endmenu diff --git a/APP_Framework/lib/queue/Kconfig b/APP_Framework/lib/queue/Kconfig new file mode 100644 index 00000000..6e5e210b --- /dev/null +++ b/APP_Framework/lib/queue/Kconfig @@ -0,0 +1,3 @@ +menuconfig LIB_USING_QUEUE + bool "USING QUEUE" + default n diff --git a/APP_Framework/lib/queue/SConscript b/APP_Framework/lib/queue/SConscript new file mode 100644 index 00000000..852c0822 --- /dev/null +++ b/APP_Framework/lib/queue/SConscript @@ -0,0 +1,10 @@ +from building import * +import os + +cwd = GetCurrentDir() + +src = Glob('*.c') + +group = DefineGroup('queue', src, depend = ['LIB_USING_QUEUE'], CPPPATH = [cwd]) + +Return('group') \ No newline at end of file diff --git a/APP_Framework/lib/queue/queue.c b/APP_Framework/lib/queue/queue.c new file mode 100644 index 00000000..03949890 --- /dev/null +++ b/APP_Framework/lib/queue/queue.c @@ -0,0 +1,59 @@ +#include +Status InitQueue(SqQueue *Q) +{ + Q->front=0; + Q->rear=0; + return OK; +} + + +Status ClearQueue(SqQueue *Q) +{ + Q->front=Q->rear=0; + return OK; +} + + +Status QueueEmpty(SqQueue *Q) +{ + if(Q->front==Q->rear) + return TRUE; + else + return FALSE; +} + + +int QueueLength(SqQueue *Q) +{ + return (Q->rear-Q->front+MAXSIZE)%MAXSIZE; +} + + +Status GetHead(SqQueue *Q,QElemType *e) +{ + if(Q->front==Q->rear) + return ERROR; + *e=Q->data[Q->front]; + return OK; +} + + +Status EnQueue(SqQueue *Q,QElemType e) +{ + if ((Q->rear+1)%MAXSIZE == Q->front) + return ERROR; + Q->data[Q->rear]=e; + Q->rear=(Q->rear+1)%MAXSIZE; + return OK; +} + + +Status DeQueue(SqQueue *Q,QElemType *e) +{ + if (Q->front == Q->rear) + return ERROR; + *e=Q->data[Q->front]; + Q->front=(Q->front+1)%MAXSIZE; + return OK; +} + diff --git a/APP_Framework/lib/queue/queue.h b/APP_Framework/lib/queue/queue.h new file mode 100644 index 00000000..56541cc9 --- /dev/null +++ b/APP_Framework/lib/queue/queue.h @@ -0,0 +1,26 @@ +#ifndef __QUEUE_H__ +#define __QUEUE_H__ +#include +#define OK 1 +#define ERROR 0 +#define TRUE 1 +#define FALSE 0 +#define MAXSIZE 1024 + +typedef int Status; +typedef int QElemType; +typedef struct +{ + int data[MAXSIZE]; + int front; + int rear; +}SqQueue; + +Status InitQueue(SqQueue *Q); +Status ClearQueue(SqQueue *Q); +Status QueueEmpty(SqQueue *Q); +Status GetHead(SqQueue *Q,QElemType *e); +Status EnQueue(SqQueue *Q,QElemType e); +Status DeQueue(SqQueue *Q,QElemType *e); +int QueueLength(SqQueue *Q); +#endif \ No newline at end of file From d542b4dc9bb66fd8b3843656ed3b26b7e462b40c Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Tue, 17 Aug 2021 11:23:06 +0800 Subject: [PATCH 02/11] APP_Framework/Framework/:update kpu-postprocessing/Kconfig file --- APP_Framework/Framework/knowing/kpu-postprocessing/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/APP_Framework/Framework/knowing/kpu-postprocessing/Kconfig b/APP_Framework/Framework/knowing/kpu-postprocessing/Kconfig index 73ec5548..d77e8c6a 100644 --- a/APP_Framework/Framework/knowing/kpu-postprocessing/Kconfig +++ b/APP_Framework/Framework/knowing/kpu-postprocessing/Kconfig @@ -1,5 +1,6 @@ menuconfig USING_KPU_POSTPROCESSING bool "kpu model postprocessing" default y - -source "$APP_DIR/Framework/knowing/kpu-postprocessing/yolov2/Kconfig" \ No newline at end of file +if USING_KPU_POSTPROCESSING + source "$APP_DIR/Framework/knowing/kpu-postprocessing/yolov2/Kconfig" +endif From e9af33ca78c664ebd5b88496f4e385c41526121b Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Tue, 17 Aug 2021 14:58:31 +0800 Subject: [PATCH 03/11] APP_Framework/Framework/:add filter module in knowing framework,and complete coding recently --- APP_Framework/Framework/knowing/Kconfig | 1 + .../Framework/knowing/filter/Kconfig | 34 +++++++++++++++++++ .../Framework/knowing/filter/SConscript | 14 ++++++++ .../knowing/filter/high_pass_filter/Kconfig | 3 ++ .../filter/high_pass_filter/SConscript | 10 ++++++ .../high_pass_filter/one_order_rc_hpf.c | 1 + .../high_pass_filter/one_order_rc_hpf.h | 5 +++ .../knowing/filter/kalman_filter/Kconfig | 3 ++ .../knowing/filter/kalman_filter/SConscript | 10 ++++++ .../filter/kalman_filter/one_order_kalman.c | 1 + .../filter/kalman_filter/one_order_kalman.h | 4 +++ .../knowing/filter/low_pass_filter/Kconfig | 3 ++ .../knowing/filter/low_pass_filter/SConscript | 10 ++++++ .../filter/low_pass_filter/one_order_rc_lpf.c | 1 + .../filter/low_pass_filter/one_order_rc_lpf.h | 5 +++ .../knowing/filter/mean_filter/Kconfig | 8 +++++ .../knowing/filter/mean_filter/SConscript | 12 +++++++ .../filter/mean_filter/ordinary_mean_filter.c | 1 + .../filter/mean_filter/ordinary_mean_filter.h | 4 +++ .../mean_filter/sliding_window_mean_filter.c | 1 + .../mean_filter/sliding_window_mean_filter.h | 5 +++ 21 files changed, 136 insertions(+) create mode 100644 APP_Framework/Framework/knowing/filter/Kconfig create mode 100644 APP_Framework/Framework/knowing/filter/SConscript create mode 100644 APP_Framework/Framework/knowing/filter/high_pass_filter/Kconfig create mode 100644 APP_Framework/Framework/knowing/filter/high_pass_filter/SConscript create mode 100644 APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c create mode 100644 APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h create mode 100644 APP_Framework/Framework/knowing/filter/kalman_filter/Kconfig create mode 100644 APP_Framework/Framework/knowing/filter/kalman_filter/SConscript create mode 100644 APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c create mode 100644 APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h create mode 100644 APP_Framework/Framework/knowing/filter/low_pass_filter/Kconfig create mode 100644 APP_Framework/Framework/knowing/filter/low_pass_filter/SConscript create mode 100644 APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c create mode 100644 APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h create mode 100644 APP_Framework/Framework/knowing/filter/mean_filter/Kconfig create mode 100644 APP_Framework/Framework/knowing/filter/mean_filter/SConscript create mode 100644 APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c create mode 100644 APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h create mode 100644 APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c create mode 100644 APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h diff --git a/APP_Framework/Framework/knowing/Kconfig b/APP_Framework/Framework/knowing/Kconfig index c283404d..7e6e1827 100644 --- a/APP_Framework/Framework/knowing/Kconfig +++ b/APP_Framework/Framework/knowing/Kconfig @@ -5,4 +5,5 @@ menuconfig SUPPORT_KNOWING_FRAMEWORK if SUPPORT_KNOWING_FRAMEWORK source "$APP_DIR/Framework/knowing/tensorflow-lite/Kconfig" source "$APP_DIR/Framework/knowing/kpu-postprocessing/Kconfig" + source "$APP_DIR/Framework/knowing/filter/Kconfig" endif diff --git a/APP_Framework/Framework/knowing/filter/Kconfig b/APP_Framework/Framework/knowing/filter/Kconfig new file mode 100644 index 00000000..27b0d4db --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/Kconfig @@ -0,0 +1,34 @@ +menuconfig USING_KNOWING_FILTER + bool "filters " + default n + +if USING_KNOWING_FILTER + menuconfig USING_MEAN_FILTER + bool "Using mean filter" + default n + if USING_MEAN_FILTER + source "$APP_DIR/Framework/knowing/filter/mean_filter/Kconfig" + endif + + menuconfig USING_KALMAN_FILTER + bool "Using kalman filter" + default n + if USING_KALMAN_FILTER + source "$APP_DIR/Framework/knowing/filter/kalman_filter/Kconfig" + endif + + menuconfig USING_LOW_PASS_FILTER + bool "Using low pass filter" + default n + if USING_LOW_PASS_FILTER + source "$APP_DIR/Framework/knowing/filter/low_pass_filter/Kconfig" + endif + + menuconfig USING_HIGH_PASS_FILTER + bool "Using high pass filter" + default n + if USING_HIGH_PASS_FILTER + source "$APP_DIR/Framework/knowing/filter/high_pass_filter/Kconfig" + endif + +endif diff --git a/APP_Framework/Framework/knowing/filter/SConscript b/APP_Framework/Framework/knowing/filter/SConscript new file mode 100644 index 00000000..1d6ca7a1 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/SConscript @@ -0,0 +1,14 @@ +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(path, 'SConscript')) + +Return('objs') \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/high_pass_filter/Kconfig b/APP_Framework/Framework/knowing/filter/high_pass_filter/Kconfig new file mode 100644 index 00000000..20e66dc3 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/high_pass_filter/Kconfig @@ -0,0 +1,3 @@ +config ONE_ORDER_RC_HIGH_PASS_FILTER + bool "one order rc hpf" + default n \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/high_pass_filter/SConscript b/APP_Framework/Framework/knowing/filter/high_pass_filter/SConscript new file mode 100644 index 00000000..8af899b9 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/high_pass_filter/SConscript @@ -0,0 +1,10 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = [] +if GetDepend(['ONE_ORDER_RC_HIGH_PASS_FILTER']): + src += ['one_order_rc_hpf.c'] +group = DefineGroup('high_pass_filter', src, depend = ['USING_HIGH_PASS_FILTER'], CPPPATH = [cwd]) + +Return('group') \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c new file mode 100644 index 00000000..79da131d --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h new file mode 100644 index 00000000..d54ad067 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h @@ -0,0 +1,5 @@ +#ifndef _ONE_ORDER_RC_HPF_H +#define _ONE_ORDER_RC_HPF_H + + +#endif \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/kalman_filter/Kconfig b/APP_Framework/Framework/knowing/filter/kalman_filter/Kconfig new file mode 100644 index 00000000..be043e11 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/kalman_filter/Kconfig @@ -0,0 +1,3 @@ +config ONE_ORDER_KALMAN_FILTER + bool "one order kalman filter" + default n \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/kalman_filter/SConscript b/APP_Framework/Framework/knowing/filter/kalman_filter/SConscript new file mode 100644 index 00000000..6afca127 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/kalman_filter/SConscript @@ -0,0 +1,10 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = [] +if GetDepend(['ONE_ORDER_KALMAN_FILTER']): + src += ['one_order_kalman.c'] +group = DefineGroup('kalman filter', src, depend = ['USING_KALMAN_FILTER'], CPPPATH = [cwd]) + +Return('group') \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c new file mode 100644 index 00000000..3d6c9f9b --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h new file mode 100644 index 00000000..2f53b4b3 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h @@ -0,0 +1,4 @@ +#ifndef _ONE_ORDER_KALMAN_H_ +#define _ONE_ORDER_KALMAN_H_ + +#endif \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/low_pass_filter/Kconfig b/APP_Framework/Framework/knowing/filter/low_pass_filter/Kconfig new file mode 100644 index 00000000..0977d0cb --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/low_pass_filter/Kconfig @@ -0,0 +1,3 @@ +config ONE_ORDER_RC_LOW_PASS_FILTER + bool "one order rc lpf" + default n \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/low_pass_filter/SConscript b/APP_Framework/Framework/knowing/filter/low_pass_filter/SConscript new file mode 100644 index 00000000..b7e0b20d --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/low_pass_filter/SConscript @@ -0,0 +1,10 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = [] +if GetDepend(['ONE_ORDER_RC_LOW_PASS_FILTER']): + src += ['one_order_rc_lpf.c'] +group = DefineGroup('low pass filter', src, depend = ['USING_LOW_PASS_FILTER'], CPPPATH = [cwd]) + +Return('group') \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c new file mode 100644 index 00000000..47170096 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h new file mode 100644 index 00000000..9f62b970 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h @@ -0,0 +1,5 @@ +#ifndef _ONE_ORDER_RC_LPF_H +#define _ONE_ORDER_RC_LPF_H + + +#endif \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/Kconfig b/APP_Framework/Framework/knowing/filter/mean_filter/Kconfig new file mode 100644 index 00000000..bdb73b62 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/mean_filter/Kconfig @@ -0,0 +1,8 @@ +config SLIDING_WINDOW_MEAN_FILTER + bool "sliding window mean filter" + select LIB_USING_QUEUE + default n + +config ORDINARY_MEAN_FILTER + bool "ordinary mean filter" + default n \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/SConscript b/APP_Framework/Framework/knowing/filter/mean_filter/SConscript new file mode 100644 index 00000000..65273054 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/mean_filter/SConscript @@ -0,0 +1,12 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = [] +if GetDepend(['SLIDING_WINDOW_MEAN_FILTER']): + src += ['sliding_window_mean_filter.c'] +if GetDepend(['ORDINARY_MEAN_FILTER']): + src += ['ordinary_mean_filter.c'] +group = DefineGroup('mean_filter', src, depend = ['USING_MEAN_FILTER'], CPPPATH = [cwd]) + +Return('group') \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c new file mode 100644 index 00000000..e78fd643 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h new file mode 100644 index 00000000..5ead554e --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h @@ -0,0 +1,4 @@ +#ifndef _ORDINARY_MEAN_FILTER_H +#define _ORDINARY_MEAN_FILTER_H + +#endif \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c new file mode 100644 index 00000000..530aa633 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c @@ -0,0 +1 @@ +#include diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h new file mode 100644 index 00000000..62534d78 --- /dev/null +++ b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h @@ -0,0 +1,5 @@ +#ifndef _SLIDING_WINDOW_MEAN_FILTER_H +#define _SLIDING_WINDOW_MEAN_FILTER_H +#include + +#endif \ No newline at end of file From 6664b2323485f4b58ef1b88279bcd965faff8068 Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Tue, 17 Aug 2021 16:25:24 +0800 Subject: [PATCH 04/11] APP_Framework/Framework/: complete one order RC low pass filter. --- .../filter/low_pass_filter/one_order_rc_lpf.c | 23 ++++++++++++++++++- .../filter/low_pass_filter/one_order_rc_lpf.h | 11 +++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c index 47170096..7e987b8a 100644 --- a/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c +++ b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.c @@ -1 +1,22 @@ -#include \ No newline at end of file +#include +void OneOrderRcLpfInit(OneOrderRcLpfHander* hander,float cutoff_fre,float sampling) +{ + hander->vi = 0; + hander->fcutoff = cutoff_fre; // low pass filter cutoff frequency + hander->vo = 0; + hander->vo_prev = 0; + hander->fs = sampling; //sampling rate +} + +float OneOrderRcLpfFun(OneOrderRcLpfHander *hander) +{ + float rc; + float alpha1; + float alpha2; + rc = (float) 1.0/2.0/3.1415926/hander->fcutoff; + alpha1 = 1/(1+rc*hander->fs); + alpha2 = rc*hander->fs/(1+rc*hander->fs); + hander->vo = alpha1*hander->vi + alpha2 *hander->vo_prev; + hander->vo_prev = hander ->vo; + return hander->vo; +} diff --git a/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h index 9f62b970..d2420742 100644 --- a/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h +++ b/APP_Framework/Framework/knowing/filter/low_pass_filter/one_order_rc_lpf.h @@ -2,4 +2,15 @@ #define _ONE_ORDER_RC_LPF_H +typedef struct +{ + float vi; + float vo_prev; + float vo; + float fcutoff; + float fs; +} OneOrderRcLpfHander; + +void OneOrderRcLpfInit(OneOrderRcLpfHander* hander,float cutoff_fre,float sample); +float OneOrderRcLpfFun(OneOrderRcLpfHander *hander); #endif \ No newline at end of file From 09d86f55b030c5fc2b4e55a1965f83661d41bfe4 Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Tue, 17 Aug 2021 18:28:14 +0800 Subject: [PATCH 05/11] APP_Framework/Framework/: complete one order RC high pass filter. --- .../high_pass_filter/one_order_rc_hpf.c | 23 ++++++++++++++++++- .../high_pass_filter/one_order_rc_hpf.h | 12 ++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c index 79da131d..f1015716 100644 --- a/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c +++ b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.c @@ -1 +1,22 @@ -#include \ No newline at end of file +#include +void OneOrderRcHpfInit(OneOrderRcHpfHander* hander,float cutoff_fre,float sampling) +{ + hander->vi = 0; + hander->fcutoff = cutoff_fre; // low pass filter cutoff frequency + hander->vo = 0; + hander->vo_prev = 0; + hander->fs = sampling; //sampling rate + hander->vi_prev = 0; +} + +float OneOrderRcHpfFun(OneOrderRcHpfHander *hander) +{ + float rc; + float alpha; + rc = (float) 1.0/2.0/3.1415926/hander->fcutoff; + alpha = rc/(rc+1/hander->fs); + hander->vo = (hander->vi - hander->vi_prev + hander->vo_prev)*alpha; + hander->vi_prev = hander ->vi; + hander->vo_prev = hander ->vo; + return hander->vo; +} diff --git a/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h index d54ad067..a8afd0c9 100644 --- a/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h +++ b/APP_Framework/Framework/knowing/filter/high_pass_filter/one_order_rc_hpf.h @@ -1,5 +1,17 @@ #ifndef _ONE_ORDER_RC_HPF_H #define _ONE_ORDER_RC_HPF_H +typedef struct +{ + float vi; + float vi_prev; + float vo_prev; + float vo; + float fcutoff; + float fs; +} OneOrderRcHpfHander; + +void OneOrderRcHpfInit(OneOrderRcHpfHander* hander,float cutoff_fre,float sampling); +float OneOrderRcHpfFun(OneOrderRcHpfHander *hander); #endif \ No newline at end of file From 88d7ef83d35925ec5376b44eae088a70809f624d Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Wed, 18 Aug 2021 14:49:05 +0800 Subject: [PATCH 06/11] APP_Framework/lib:add comments in queue --- APP_Framework/lib/queue/queue.c | 57 +++++++++++++++++++++++++++++---- APP_Framework/lib/queue/queue.h | 10 +++++- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/APP_Framework/lib/queue/queue.c b/APP_Framework/lib/queue/queue.c index 03949890..750b0943 100644 --- a/APP_Framework/lib/queue/queue.c +++ b/APP_Framework/lib/queue/queue.c @@ -1,4 +1,19 @@ +/* + * @Author: chunyexixiaoyu + * @Date: 2021-08-16 15:16:51 + * @LastEditTime: 2021-08-18 14:45:47 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \xiuos\APP_Framework\lib\queue\queue.c + */ #include + + +/** + * @description: Initialize an empty queue + * @param {SqQueue} *Q queue struct + * @return {*} + */ Status InitQueue(SqQueue *Q) { Q->front=0; @@ -6,14 +21,23 @@ Status InitQueue(SqQueue *Q) return OK; } - +/** + * @description: Clear Q to an empty queue + * @param {SqQueue} *Q queue struct + * @return {*} + */ Status ClearQueue(SqQueue *Q) { Q->front=Q->rear=0; return OK; } - +/** + * @description: Return TRUE if Q is an empty queue, FALSE otherwise + * @param {SqQueue} *Q queue struct + * @return TRUE + * FALSE + */ Status QueueEmpty(SqQueue *Q) { if(Q->front==Q->rear) @@ -22,13 +46,23 @@ Status QueueEmpty(SqQueue *Q) return FALSE; } - +/** + * @description: Returns the number of elements of Q, which is the current length of the queue + * @param {SqQueue} *Q queue struct + * @return length of the queue + */ int QueueLength(SqQueue *Q) { return (Q->rear-Q->front+MAXSIZE)%MAXSIZE; } - +/** + * @description: If the queue is not empty, return the header element of Q with e and OK, otherwise return ERROR + * @param {SqQueue} *Q queue struct + * @param {QElemType} *e header element + * @return TRUE + * FALSE + */ Status GetHead(SqQueue *Q,QElemType *e) { if(Q->front==Q->rear) @@ -37,7 +71,13 @@ Status GetHead(SqQueue *Q,QElemType *e) return OK; } - +/** + * @description: If the queue is not full, insert element E as Q's new tail element + * @param {SqQueue} *Q queue struct + * @param {QElemType} e new element + * @return TRUE insert successfully + * FALSE + */ Status EnQueue(SqQueue *Q,QElemType e) { if ((Q->rear+1)%MAXSIZE == Q->front) @@ -47,7 +87,12 @@ Status EnQueue(SqQueue *Q,QElemType e) return OK; } - +/** + * @description: If the queue is not empty, the header element in Q is removed and its value is returned with e + * @param {SqQueue} *Q + * @param {QElemType} *e the header element + * @return {*} + */ Status DeQueue(SqQueue *Q,QElemType *e) { if (Q->front == Q->rear) diff --git a/APP_Framework/lib/queue/queue.h b/APP_Framework/lib/queue/queue.h index 56541cc9..8c06dd8a 100644 --- a/APP_Framework/lib/queue/queue.h +++ b/APP_Framework/lib/queue/queue.h @@ -1,3 +1,11 @@ +/* + * @Author: chunyexixiaoyu + * @Date: 2021-08-16 15:16:51 + * @LastEditTime: 2021-08-18 14:48:11 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \xiuos\APP_Framework\lib\queue\queue.h + */ #ifndef __QUEUE_H__ #define __QUEUE_H__ #include @@ -11,7 +19,7 @@ typedef int Status; typedef int QElemType; typedef struct { - int data[MAXSIZE]; + QElemType data[MAXSIZE]; int front; int rear; }SqQueue; From c251937f9ffa40ee636c7ed62a6e18a28fc45a68 Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Wed, 18 Aug 2021 21:28:34 +0800 Subject: [PATCH 07/11] APP_Framework/Framework/:complete sliding window mean_filter --- .../mean_filter/sliding_window_mean_filter.c | 25 +++++++++++++++++++ .../mean_filter/sliding_window_mean_filter.h | 10 ++++++++ 2 files changed, 35 insertions(+) diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c index 530aa633..50c4ed95 100644 --- a/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c +++ b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.c @@ -1 +1,26 @@ #include +void SlidingWindowsMeanFliterInit(SlidingWindowsHander * hander,unsigned int window_len) +{ + hander->window_len = window_len; + hander->sumlast = 0; + InitQueue(&(hander->window_queue)); +} + +int SlidingWindowsMeanFliterFun(SlidingWindowsHander * hander,int newvalue) +{ + int headtemf = 0; + if(QueueLength(&(hander->window_queue)) < hander->window_len) + { + EnQueue(&(hander->window_queue),newvalue); + hander->sumlast = hander->sumlast + newvalue; + return (int)((hander->sumlast)/(QueueLength(&(hander->window_queue)))); + } + else + { + DeQueue(&(hander->window_queue),&headtemf); + hander->sumlast = hander->sumlast - headtemf + newvalue; + EnQueue(&(hander->window_queue),newvalue); + return (int)((hander->sumlast)/(hander->window_len)); + } + +} \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h index 62534d78..5943a95a 100644 --- a/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h +++ b/APP_Framework/Framework/knowing/filter/mean_filter/sliding_window_mean_filter.h @@ -2,4 +2,14 @@ #define _SLIDING_WINDOW_MEAN_FILTER_H #include +typedef struct +{ + SqQueue window_queue; + unsigned int window_len; //the window_len value must less than MAXSIZE 1024 + long long int sumlast; +}SlidingWindowsHander; + + +void SlidingWindowsMeanFliterInit(SlidingWindowsHander * hander,unsigned int window_len); +int SlidingWindowsMeanFliterFun(SlidingWindowsHander * hander,int newvalue); #endif \ No newline at end of file From d16c6987896797eb2b36ee4271a2025bd3108fa9 Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Thu, 19 Aug 2021 09:57:19 +0800 Subject: [PATCH 08/11] APP_Framework/Framework/:complete ordinary mean_filter --- .../filter/mean_filter/ordinary_mean_filter.c | 17 ++++++++++++++++- .../filter/mean_filter/ordinary_mean_filter.h | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c index e78fd643..33b4b449 100644 --- a/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c +++ b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.c @@ -1 +1,16 @@ -#include \ No newline at end of file +#include +/** + * @description: + * @param {int *} hander array address + * @param {int} len array length + * @return {*} + */ +int OrdinaryMeanFilter(int * hander,int len) +{ + int sum = 0; + for(int i = 0;i < len ;i++) + { + sum = sum + *(hander +i); + } + return (int)(sum/len); +} \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h index 5ead554e..bf5bba52 100644 --- a/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h +++ b/APP_Framework/Framework/knowing/filter/mean_filter/ordinary_mean_filter.h @@ -1,4 +1,4 @@ #ifndef _ORDINARY_MEAN_FILTER_H #define _ORDINARY_MEAN_FILTER_H - +int OrdinaryMeanFilter(int * hander,int len); #endif \ No newline at end of file From 41b8b3e8962ca25617bda16508127f15a1de560e Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Thu, 19 Aug 2021 18:10:40 +0800 Subject: [PATCH 09/11] APP_Framework/Framework/:complete one order ordinary kalman filter. --- .../filter/kalman_filter/one_order_kalman.c | 30 ++++++++++++++++++- .../filter/kalman_filter/one_order_kalman.h | 19 ++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c index 3d6c9f9b..8622fddd 100644 --- a/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c +++ b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.c @@ -1 +1,29 @@ -#include \ No newline at end of file +#include +/** + * equation of state x = A*x + w; w~N(0,Q) + * Measurement equation y = C*x + v; v~N(0,R) + * + */ + +void OneOrderKalmamInit(OneOrderKalmanHander *hander,float A,float C,float Q ,float R) +{ + hander->A = A; + hander->A2 = A * A; + hander->C = C; + hander->C2 = C * C; + hander->Q = Q; + hander->R = R; + hander->x = 0; + hander->P = Q; + hander->K = 1; +} + +float OneOrderKalmanFun(OneOrderKalmanHander *hander,float measure) +{ + hander->x = hander->A * hander->x; //state prediction + hander->P = hander->A2 * hander->P + hander->Q; //covariance prediction + hander->K = hander->P * hander->C / (hander->C2 * hander->P + hander->R); //calculate kalman gain + hander->x = hander->x + hander->K * (measure- hander->C * hander->x); //state correct + hander->P = (1 - hander->K * hander->C) * hander->P; //covariance correction + return hander->C * hander->x; //return resault +} \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h index 2f53b4b3..ae88d696 100644 --- a/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h +++ b/APP_Framework/Framework/knowing/filter/kalman_filter/one_order_kalman.h @@ -1,4 +1,23 @@ #ifndef _ONE_ORDER_KALMAN_H_ #define _ONE_ORDER_KALMAN_H_ +/** + * equation of state x = A*x + w; w~N(0,Q) + * Measurement equation y = C*x + v; v~N(0,R) + * + */ +typedef struct +{ + float A; + float C; + float A2; //A*A + float C2; //C*C + float Q; + float R; + float K; + float P; + float x; +}OneOrderKalmanHander; +void OneOrderKalmamInit(OneOrderKalmanHander *hander,float A,float C,float Q ,float R); +float OneOrderKalmanFun(OneOrderKalmanHander *hander,float measure); #endif \ No newline at end of file From 6dbbfd804e10959b988975dad171925e289dc3a4 Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Mon, 30 Aug 2021 16:10:02 +0800 Subject: [PATCH 10/11] =?UTF-8?q?APP=5FFramework/Applications/=EF=BC=9Afix?= =?UTF-8?q?=20a=20bug=20in=20=20instrusion=5Fdetect.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../knowing_app/instrusion_detect/instrusion_detect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/APP_Framework/Applications/knowing_app/instrusion_detect/instrusion_detect.c b/APP_Framework/Applications/knowing_app/instrusion_detect/instrusion_detect.c index c5ac9ee3..5683ec02 100644 --- a/APP_Framework/Applications/knowing_app/instrusion_detect/instrusion_detect.c +++ b/APP_Framework/Applications/knowing_app/instrusion_detect/instrusion_detect.c @@ -308,7 +308,7 @@ static void *thread_instrusion_detect_entry(void *parameter) instrusion_detect_rl.input = output; region_layer_run(&instrusion_detect_rl, &instrusion_detect_info); /* display result */ -#ifdef BSP_USING_LCD + for (int instrusion_cnt = 0; instrusion_cnt < instrusion_detect_info.obj_number; instrusion_cnt++) { // draw_edge((uint32_t *)showbuffer, &instrusion_detect_info, instrusion_cnt, 0xF800, // (uint16_t)sensor_output_size[1], @@ -321,6 +321,7 @@ static void *thread_instrusion_detect_entry(void *parameter) if (0 != instrusion_detect_info.obj_number) { printf("\n"); } +#ifdef BSP_USING_LCD lcd_draw_picture(0, 0, (uint16_t)sensor_output_size[1], (uint16_t)sensor_output_size[0], (unsigned int *)showbuffer); #endif usleep(1); From 2db749991ee6703ca116cc3beec10cc8e70d7919 Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Mon, 30 Aug 2021 16:12:52 +0800 Subject: [PATCH 11/11] =?UTF-8?q?APP=5FFramework/Framework=EF=BC=9Aadd=20h?= =?UTF-8?q?ttp=20client=20module=20in=20OTA=20for=20KPU=20model=20download?= =?UTF-8?q?ing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP_Framework/Framework/knowing/Kconfig | 1 + APP_Framework/Framework/knowing/ota/Kconfig | 4 + .../Framework/knowing/ota/SConscript | 10 + .../Framework/knowing/ota/httpclient.c | 1643 +++++++++++++++++ .../Framework/knowing/ota/httpclient.h | 132 ++ .../transform_layer/rtthread/transform.h | 15 + 6 files changed, 1805 insertions(+) create mode 100644 APP_Framework/Framework/knowing/ota/Kconfig create mode 100644 APP_Framework/Framework/knowing/ota/SConscript create mode 100644 APP_Framework/Framework/knowing/ota/httpclient.c create mode 100644 APP_Framework/Framework/knowing/ota/httpclient.h diff --git a/APP_Framework/Framework/knowing/Kconfig b/APP_Framework/Framework/knowing/Kconfig index 7e6e1827..6aee6f5e 100644 --- a/APP_Framework/Framework/knowing/Kconfig +++ b/APP_Framework/Framework/knowing/Kconfig @@ -6,4 +6,5 @@ if SUPPORT_KNOWING_FRAMEWORK source "$APP_DIR/Framework/knowing/tensorflow-lite/Kconfig" source "$APP_DIR/Framework/knowing/kpu-postprocessing/Kconfig" source "$APP_DIR/Framework/knowing/filter/Kconfig" + source "$APP_DIR/Framework/knowing/ota/Kconfig" endif diff --git a/APP_Framework/Framework/knowing/ota/Kconfig b/APP_Framework/Framework/knowing/ota/Kconfig new file mode 100644 index 00000000..cefc1bdd --- /dev/null +++ b/APP_Framework/Framework/knowing/ota/Kconfig @@ -0,0 +1,4 @@ +menuconfig USING_OTA_MODEL + bool "OTA (KPU MODEL)" + select PKG_USING_RW007 + default n diff --git a/APP_Framework/Framework/knowing/ota/SConscript b/APP_Framework/Framework/knowing/ota/SConscript new file mode 100644 index 00000000..e6c23e87 --- /dev/null +++ b/APP_Framework/Framework/knowing/ota/SConscript @@ -0,0 +1,10 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = [] +if GetDepend(['USING_OTA_MODEL']): + src += ['httpclient.c'] +group = DefineGroup('ota model', src, depend = [], CPPPATH = [cwd]) + +Return('group') \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/ota/httpclient.c b/APP_Framework/Framework/knowing/ota/httpclient.c new file mode 100644 index 00000000..7a926cde --- /dev/null +++ b/APP_Framework/Framework/knowing/ota/httpclient.c @@ -0,0 +1,1643 @@ +/* + * @Author: chunyexixiaoyu + * @Date: 2021-08-20 13:52:54 + * @LastEditTime: 2021-08-30 15:12:42 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * + * + * @FilePath: \xiuos\APP_Framework\Framework\knowing\ota\httpclient.c + */ +#include +static int httpClientStrncaseCmp(const char *a, const char *b, size_t n) +{ + uint8_t c1, c2; + if (n <= 0) + return 0; + do { + c1 = tolower(*a++); + c2 = tolower(*b++); + } while (--n && c1 && c1 == c2); + return c1 - c2; +} + +static const char *webclient_strstri(const char* str, const char* subStr) +{ + int len = strlen(subStr); + + if(len == 0) + { + return RT_NULL; + } + + while(*str) + { + if(httpClientStrncaseCmp(str, subStr, len) == 0) + { + return str; + } + ++str; + } + return RT_NULL; +} + +static int httpClientSend(struct httpClientSession* session, const void *buffer, size_t len, int flag) +{ + return send(session->socket, buffer, len, flag); +} + +static int httpClientRecv(struct httpClientSession* session, void *buffer, size_t len, int flag) +{ + + return recv(session->socket, buffer, len, flag); +} + +static int httpClientReadLine(struct httpClientSession *session, char *buffer, int size) +{ + int rc, count = 0; + char ch = 0, last_ch = 0; + assert(session); + assert(buffer); + + /* Keep reading until we fill the buffer. */ + while (count < size) + { + rc = httpClientRecv(session, (unsigned char *) &ch, 1, 0); + if (rc <= 0) + return rc; + + if (ch == '\n' && last_ch == '\r') + break; + + buffer[count++] = ch; + + last_ch = ch; + } + + if (count > size) + { + printf("read line failed. The line data length is out of buffer size(%d)!", count); + return -HTTPCLIENT_ERROR; + } + + return count; +} + +/** + * resolve server address + * + * @param session http session + * @param res the server address information + * @param url the input server URI address + * @param request the pointer to point the request url, for example, /index.html + * + * @return 0 on resolve server address OK, others failed +*/ +static int httpClientResolveaddr(struct httpClientSession *session, struct addrinfo **res, + const char *url, const char **request) +{ + int rc = HTTPCLIENT_OK; + char *ptr; + char port_str[6] = "80"; /* default port of 80(http) */ + const char *port_ptr; + const char *path_ptr; + + const char *host_addr = 0; + int url_len, host_addr_len = 0; + + assert(res); + assert(request); + + url_len = strlen(url); + + /* strip protocol(http or https) */ + if (strncmp(url, "http://", 7) == 0) + { + host_addr = url + 7; + } + else if (strncmp(url, "https://", 8) == 0) + { + strncpy(port_str, "443", 4); + host_addr = url + 8; + } + else + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + /* ipv6 address */ + if (host_addr[0] == '[') + { + host_addr += 1; + ptr = strstr(host_addr, "]"); + if (!ptr) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + host_addr_len = ptr - host_addr; + } + + path_ptr = strstr(host_addr, "/"); + *request = path_ptr ? path_ptr : "/"; + + /* resolve port */ + 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); + } + + /* ipv4 or domain. */ + if (!host_addr_len) + { + if (port_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)) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + /* get host address ok. */ + { + char *host_addr_new = HTTP_MALLOC(host_addr_len + 1); + + if (!host_addr_new) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + memcpy(host_addr_new, host_addr, host_addr_len); + host_addr_new[host_addr_len] = '\0'; + session->host = host_addr_new; + } + + printf("host address: %s , port: %s \n\r", session->host, port_str); + + /* resolve the host name. */ + { + struct addrinfo hint; + int ret; + + rt_memset(&hint, 0, sizeof(hint)); + ret = getaddrinfo(session->host, port_str, &hint, res); + if (ret != 0) + { + printf("getaddrinfo err: %d '%s'.", ret, session->host); + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + } + +__exit: + if (rc != HTTPCLIENT_OK) + { + if (session->host) + { + HTTP_FREE(session->host); + session->host = RT_NULL; + } + + if (*res) + { + freeaddrinfo(*res); + *res = RT_NULL; + } + } + + return rc; +} + + +/** + * connect to http server. + * + * @param session http session + * @param URI the input server URI address + * + * @return <0: connect failed or other error + * =0: connect success + */ +static int httpClientConnect(struct httpClientSession *session, const char *URI) +{ + int rc = HTTPCLIENT_OK; + int socket_handle; + struct timeval timeout; + struct addrinfo *res = RT_NULL; + const char *req_url; + + assert(session); + assert(URI); + + timeout.tv_sec = HTTPCLIENT_DEFAULT_TIMEO; + timeout.tv_usec = 0; + + if (strncmp(URI, "https://", 8) == 0) + { + + printf("not support https connect, please enable webclient https configure!"); + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + /* Check valid IP address and URL */ + rc = httpClientResolveaddr(session, &res, URI, &req_url); + if (rc != HTTPCLIENT_OK) + { + printf("connect failed, resolve address error(%d).", rc); + goto __exit; + } + + /* Not use 'getaddrinfo()' for https connection */ + if (session->is_tls == RT_FALSE && res == RT_NULL) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + /* copy host address */ + if (req_url) + { + session->req_url = HTTP_STRDUP(req_url); + } + else + { + printf("connect failed, resolve request address error."); + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + + socket_handle = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); + + if (socket_handle < 0) + { + printf("connect failed, create socket(%d) error.", socket_handle); + rc = -HTTPCLIENT_NOSOCKET; + goto __exit; + } + + /* set receive and send timeout option */ + setsockopt(socket_handle, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeout, + sizeof(timeout)); + setsockopt(socket_handle, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeout, + sizeof(timeout)); + + if (connect(socket_handle, res->ai_addr, res->ai_addrlen) != 0) + { + /* connect failed, close socket */ + printf("connect failed, connect socket(%d) error.", socket_handle); + closesocket(socket_handle); + rc = -HTTPCLIENT_CONNECT_FAILED; + goto __exit; + } + + session->socket = socket_handle; + + +__exit: + if (res) + { + freeaddrinfo(res); + } + + return rc; +} + +/** + * add fields data to request header data. + * + * @param session http session + * @param fmt fields format + * + * @return >0: data length of successfully added + * <0: not enough header buffer size + */ +int httpClientHeaderFieldsAdd(struct httpClientSession *session, const char *fmt, ...) +{ + rt_int32_t length; + va_list args; + + assert(session); + assert(session->header->buffer); + + va_start(args, fmt); + length = rt_vsnprintf(session->header->buffer + session->header->length, + session->header->size - session->header->length, fmt, args); + if (length < 0) + { + printf("add fields header data failed, return length(%d) error.", length); + return -HTTPCLIENT_ERROR; + } + va_end(args); + + session->header->length += length; + + /* check header size */ + if (session->header->length >= session->header->size) + { + printf("not enough header buffer size(%d)!", session->header->size); + return -HTTPCLIENT_ERROR; + } + + return length; +} + +/** + * get fields information from request/response header data. + * + * @param session http session + * @param fields fields keyword + * + * @return = NULL: get fields data failed + * != NULL: success get fields data + */ +const char *httpClientHeaderFieldsGet(struct httpClientSession *session, const char *fields) +{ + char *resp_buf = RT_NULL; + size_t resp_buf_len = 0; + + assert(session); + assert(session->header->buffer); + + resp_buf = session->header->buffer; + while (resp_buf_len < session->header->length) + { + if (webclient_strstri(resp_buf, fields) == resp_buf) + { + char *mime_ptr = RT_NULL; + + /* jump space */ + mime_ptr = rt_strstr(resp_buf, ":"); + if (mime_ptr != NULL) + { + mime_ptr += 1; + + while (*mime_ptr && (*mime_ptr == ' ' || *mime_ptr == '\t')) + mime_ptr++; + + return mime_ptr; + } + } + + if (*resp_buf == '\0') + break; + + resp_buf += rt_strlen(resp_buf) + 1; + resp_buf_len += rt_strlen(resp_buf) + 1; + } + + return RT_NULL; +} + +/** + * get http response status code. + * + * @param session http session + * + * @return response status code + */ +int httpClientRespStatusGet(struct httpClientSession *session) +{ + assert(session); + + return session->resp_status; +} + +/** + * get http response data content length. + * + * @param session http session + * + * @return response content length + */ +int httpClientContentLengthGet(struct httpClientSession *session) +{ + assert(session); + + return session->content_length; +} + +static int httpClientSendHeader(struct httpClientSession *session, int method) +{ + int rc = HTTPCLIENT_OK; + char *header = RT_NULL; + + assert(session); + + header = session->header->buffer; + + if (session->header->length == 0) + { + /* use default header data */ + if (httpClientHeaderFieldsAdd(session, "GET %s HTTP/1.1\r\n", session->req_url) < 0) + return -HTTPCLIENT_NOMEM; + if (httpClientHeaderFieldsAdd(session, "Host: %s\r\n", session->host) < 0) + return -HTTPCLIENT_NOMEM; + if (httpClientHeaderFieldsAdd(session, "User-Agent: XIUOS HTTP Agent\r\n\r\n") < 0) + return -HTTPCLIENT_NOMEM; + + httpClientWrite(session, (unsigned char *) session->header->buffer, session->header->length); + } + else + { + if (method != WEBCLIENT_USER_METHOD) + { + /* check and add fields header data */ + if (memcmp(header, "HTTP/1.", rt_strlen("HTTP/1."))) + { + char *header_buffer = RT_NULL; + int length = 0; + + header_buffer = HTTP_STRDUP(session->header->buffer); + if (header_buffer == RT_NULL) + { + printf("no memory for header buffer!"); + rc = -HTTPCLIENT_NOMEM; + goto __exit; + } + + /* splice http request header data */ + if (method == WEBCLIENT_GET) + length = rt_snprintf(session->header->buffer, session->header->size, "GET %s HTTP/1.1\r\n%s", + session->req_url ? session->req_url : "/", header_buffer); + else if (method == WEBCLIENT_POST) + length = rt_snprintf(session->header->buffer, session->header->size, "POST %s HTTP/1.1\r\n%s", + session->req_url ? session->req_url : "/", header_buffer); + session->header->length = length; + + HTTP_FREE(header_buffer); + } + + if (strstr(header, "Host:") == RT_NULL) + { + if (httpClientHeaderFieldsAdd(session, "Host: %s\r\n", session->host) < 0) + return -HTTPCLIENT_NOMEM; + } + + if (strstr(header, "User-Agent:") == RT_NULL) + { + if (httpClientHeaderFieldsAdd(session, "User-Agent: RT-Thread HTTP Agent\r\n") < 0) + return -HTTPCLIENT_NOMEM; + } + + if (strstr(header, "Accept:") == RT_NULL) + { + if (httpClientHeaderFieldsAdd(session, "Accept: */*\r\n") < 0) + return -HTTPCLIENT_NOMEM; + } + + /* header data end */ + rt_snprintf(session->header->buffer + session->header->length, session->header->size - session->header->length, "\r\n"); + session->header->length += 2; + + /* check header size */ + if (session->header->length > session->header->size) + { + printf("send header failed, not enough header buffer size(%d)!", session->header->size); + rc = -HTTPCLIENT_NOBUFFER; + goto __exit; + } + + httpClientWrite(session, (unsigned char *) session->header->buffer, session->header->length); + } + else + { + httpClientWrite(session, (unsigned char *) session->header->buffer, session->header->length); + } + } + + /* get and echo request header data */ + { + char *header_str, *header_ptr; + int header_line_len; + printf("request header:\n\r"); + + for(header_str = session->header->buffer; (header_ptr = rt_strstr(header_str, "\r\n")) != RT_NULL; ) + { + header_line_len = header_ptr - header_str; + + if (header_line_len > 0) + { + printf("%.*s", header_line_len, header_str); + } + header_str = header_ptr + rt_strlen("\r\n"); + } + + } + +__exit: + return rc; +} + +/** + * resolve server response data. + * + * @param session http session + * + * @return <0: resolve response data failed + * =0: success + */ +int httpClientHandleResponse(struct httpClientSession *session) +{ + int rc = HTTPCLIENT_OK; + char *mime_buffer = RT_NULL; + char *mime_ptr = RT_NULL; + const char *transfer_encoding; + int i; + + assert(session); + + /* clean header buffer and size */ + rt_memset(session->header->buffer, 0x00, session->header->size); + session->header->length = 0; + + printf("response header:\n\r"); + /* We now need to read the header information */ + while (1) + { + mime_buffer = session->header->buffer + session->header->length; + + /* read a line from the header information. */ + rc = httpClientReadLine(session, mime_buffer, session->header->size - session->header->length); + if (rc < 0) + break; + + /* End of headers is a blank line. exit. */ + if (rc == 0) + break; + if ((rc == 1) && (mime_buffer[0] == '\r')) + { + mime_buffer[0] = '\0'; + break; + } + + /* set terminal charater */ + mime_buffer[rc - 1] = '\0'; + + /* echo response header data */ + printf("%s", mime_buffer); + + session->header->length += rc; + + if (session->header->length >= session->header->size) + { + printf("not enough header buffer size(%d)!", session->header->size); + return -HTTPCLIENT_NOMEM; + } + } + + /* get HTTP status code */ + mime_ptr = HTTP_STRDUP(session->header->buffer); + if (mime_ptr == RT_NULL) + { + printf("no memory for get http status code buffer!"); + return -HTTPCLIENT_NOMEM; + } + + if (rt_strstr(mime_ptr, "HTTP/1.")) + { + char *ptr = mime_ptr; + + ptr += rt_strlen("HTTP/1.x"); + + while (*ptr && (*ptr == ' ' || *ptr == '\t')) + ptr++; + + /* Terminate string after status code */ + for (i = 0; ((ptr[i] != ' ') && (ptr[i] != '\t')); i++); + ptr[i] = '\0'; + + session->resp_status = (int) strtol(ptr, RT_NULL, 10); + } + + /* get content length */ + if (httpClientHeaderFieldsGet(session, "Content-Length") != RT_NULL) + { + session->content_length = atoi(httpClientHeaderFieldsGet(session, "Content-Length")); + } + session->content_remainder = session->content_length ? (size_t) session->content_length : 0xFFFFFFFF; + + transfer_encoding = httpClientHeaderFieldsGet(session, "Transfer-Encoding"); + if (transfer_encoding && rt_strcmp(transfer_encoding, "chunked") == 0) + { + char line[16]; + + /* chunk mode, we should get the first chunk size */ + httpClientReadLine(session, line, session->header->size); + session->chunk_sz = strtol(line, RT_NULL, 16); + session->chunk_offset = 0; + } + + if (mime_ptr) + { + HTTP_FREE(mime_ptr); + } + + if (rc < 0) + { + return rc; + } + + return session->resp_status; +} + +/** + * create http session, set maximum header and response size + * + * @param header_sz maximum send header size + * @param resp_sz maximum response data size + * + * @return http session structure + */ +struct httpClientSession *httpClientSessionCreate(size_t header_sz) +{ + struct httpClientSession *session; + + /* create session */ + session = (struct httpClientSession *) HTTP_CALLOC(1, sizeof(struct httpClientSession)); + if (session == RT_NULL) + { + printf("webclient create failed, no memory for webclient session!"); + return RT_NULL; + } + + /* initialize the socket of session */ + session->socket = -1; + session->content_length = -1; + + session->header = (struct httpClientHeader *) HTTP_CALLOC(1, sizeof(struct httpClientHeader)); + if (session->header == RT_NULL) + { + printf("webclient create failed, no memory for session header!"); + HTTP_FREE(session); + session = RT_NULL; + return RT_NULL; + } + + session->header->size = header_sz; + session->header->buffer = (char *) HTTP_CALLOC(1, header_sz); + if (session->header->buffer == RT_NULL) + { + printf("webclient create failed, no memory for session header buffer!"); + HTTP_FREE(session->header); + HTTP_FREE(session); + session = RT_NULL; + return RT_NULL; + } + + return session; +} + +static int httpClientClean(struct httpClientSession *session); + +/** + * send GET request to http server and get response header. + * + * @param session http session + * @param URI input server URI address + * @param header GET request header + * = NULL: use default header data + * != NULL: use custom header data + * + * @return <0: send GET request failed + * >0: response http status code + */ +int httpClientGet(struct httpClientSession *session, const char *URI) +{ + int rc = HTTPCLIENT_OK; + int resp_status = 0; + + assert(session); + assert(URI); + + rc = httpClientConnect(session, URI); + if (rc != HTTPCLIENT_OK) + { + /* connect to webclient server failed. */ + return rc; + } + + rc = httpClientSendHeader(session, WEBCLIENT_GET); + if (rc != HTTPCLIENT_OK) + { + /* send header to webclient server failed. */ + return rc; + } + + /* handle the response header of webclient server */ + resp_status = httpClientHandleResponse(session); + + printf("get position handle response(%d).", resp_status); + + if (resp_status > 0) + { + const char *location = httpClientHeaderFieldsGet(session, "Location"); + + /* relocation */ + if ((resp_status == 302 || resp_status == 301) && location) + { + char *new_url; + + new_url = HTTP_STRDUP(location); + if (new_url == RT_NULL) + { + return -HTTPCLIENT_NOMEM; + } + + /* clean webclient session */ + httpClientClean(session); + /* clean webclient session header */ + session->header->length = 0; + rt_memset(session->header->buffer, 0, session->header->size); + + rc = httpClientGet(session, new_url); + + HTTP_FREE(new_url); + return rc; + } + } + + return resp_status; +} + +/** + * http breakpoint resume. + * + * @param session http session + * @param URI input server URI address + * @param position last downloaded position + * + * @return <0: send GET request failed + * >0: response http status code + */ +int httpClientGetPosition(struct httpClientSession *session, const char *URI, int position) +{ + int rc = HTTPCLIENT_OK; + int resp_status = 0; + + assert(session); + assert(URI); + + rc = httpClientConnect(session, URI); + if (rc != HTTPCLIENT_OK) + { + return rc; + } + + /* splice header*/ + if (httpClientHeaderFieldsAdd(session, "Range: bytes=%d-\r\n", position) <= 0) + { + rc = -HTTPCLIENT_ERROR; + return rc; + } + + rc = httpClientSendHeader(session, WEBCLIENT_GET); + if (rc != HTTPCLIENT_OK) + { + return rc; + } + + /* handle the response header of webclient server */ + resp_status = httpClientHandleResponse(session); + + printf("get position handle response(%d).", resp_status); + + if (resp_status > 0) + { + const char *location = httpClientHeaderFieldsGet(session, "Location"); + + /* relocation */ + if ((resp_status == 302 || resp_status == 301) && location) + { + char *new_url; + + new_url = HTTP_STRDUP(location); + if (new_url == RT_NULL) + { + return -HTTPCLIENT_NOMEM; + } + + /* clean webclient session */ + httpClientClean(session); + /* clean webclient session header */ + session->header->length = 0; + rt_memset(session->header->buffer, 0, session->header->size); + + rc = httpClientGetPosition(session, new_url, position); + + HTTP_FREE(new_url); + return rc; + } + } + + return resp_status; +} + +/** + * send POST request to server and get response header data. + * + * @param session http session + * @param URI input server URI address + * @param header POST request header, can't be empty + * @param post_data data send to the server + * = NULL: just connect server and send header + * != NULL: send header and body data, resolve response data + * @param data_len the length of send data + * + * @return <0: send POST request failed + * =0: send POST header success + * >0: response http status code + */ +int httpClientPost(struct httpClientSession *session, const char *URI, const void *post_data, size_t data_len) +{ + int rc = HTTPCLIENT_OK; + int resp_status = 0; + + assert(session); + assert(URI); + + if ((post_data != RT_NULL) && (data_len == 0)) + { + printf("input post data length failed"); + return -HTTPCLIENT_ERROR; + } + + rc = httpClientConnect(session, URI); + if (rc != HTTPCLIENT_OK) + { + /* connect to webclient server failed. */ + return rc; + } + + rc = httpClientSendHeader(session, WEBCLIENT_POST); + if (rc != HTTPCLIENT_OK) + { + /* send header to webclient server failed. */ + return rc; + } + + if (post_data && (data_len > 0)) + { + httpClientWrite(session, post_data, data_len); + + /* resolve response data, get http status code */ + resp_status = httpClientHandleResponse(session); + printf("post handle response(%d).", resp_status); + } + + return resp_status; +} + + +/** + * set receive and send data timeout. + * + * @param session http session + * @param millisecond timeout millisecond + * + * @return 0: set timeout success + */ +int httpClientSetTimeout(struct httpClientSession *session, int millisecond) +{ + struct timeval timeout; + int second = rt_tick_from_millisecond(millisecond) / 1000; + + assert(session); + + timeout.tv_sec = second; + timeout.tv_usec = 0; + + /* set recv timeout option */ + setsockopt(session->socket, SOL_SOCKET, SO_RCVTIMEO, + (void *) &timeout, sizeof(timeout)); + setsockopt(session->socket, SOL_SOCKET, SO_SNDTIMEO, + (void *) &timeout, sizeof(timeout)); + + return 0; +} + +static int httpClientNextChunk(struct httpClientSession *session) +{ + char line[64]; + int length; + + assert(session); + + rt_memset(line, 0x00, sizeof(line)); + length = httpClientReadLine(session, line, sizeof(line)); + if (length > 0) + { + if (rt_strcmp(line, "\r") == 0) + { + length = httpClientReadLine(session, line, sizeof(line)); + if (length <= 0) + { + closesocket(session->socket); + session->socket = -1; + return length; + } + } + } + else + { + closesocket(session->socket); + session->socket = -1; + + return length; + } + + session->chunk_sz = strtol(line, RT_NULL, 16); + session->chunk_offset = 0; + + if (session->chunk_sz == 0) + { + /* end of chunks */ + closesocket(session->socket); + session->socket = -1; + session->chunk_sz = -1; + } + + return session->chunk_sz; +} + +/** + * read data from http server. + * + * @param session http session + * @param buffer read buffer + * @param length the maximum of read buffer size + * + * @return <0: read data error + * =0: http server disconnect + * >0: successfully read data length + */ +int httpClientRead(struct httpClientSession *session, void *buffer, size_t length) +{ + int bytes_read = 0; + int total_read = 0; + int left; + + assert(session); + + /* get next chunk size is zero, client is already closed, return zero */ + if (session->chunk_sz < 0) + { + return 0; + } + + if (session->socket < 0) + { + return -HTTPCLIENT_DISCONNECT; + } + + if (length == 0) + { + return 0; + } + + /* which is transfered as chunk mode */ + if (session->chunk_sz) + { + if ((int) length > (session->chunk_sz - session->chunk_offset)) + { + length = session->chunk_sz - session->chunk_offset; + } + + bytes_read = httpClientRecv(session, buffer, length, 0); + if (bytes_read <= 0) + { + if (errno == EWOULDBLOCK || errno == EAGAIN) + { + /* recv timeout */ + return -HTTPCLIENT_TIMEOUT; + } + else + { + closesocket(session->socket); + session->socket = -1; + return 0; + } + } + + session->chunk_offset += bytes_read; + if (session->chunk_offset >= session->chunk_sz) + { + httpClientNextChunk(session); + } + + return bytes_read; + } + + if (session->content_length > 0) + { + if (length > session->content_remainder) + { + length = session->content_remainder; + } + + if (length == 0) + { + return 0; + } + } + + /* + * Read until: there is an error, we've read "size" bytes or the remote + * side has closed the connection. + */ + left = length; + do + { + bytes_read = httpClientRecv(session, (void *)((char *)buffer + total_read), left, 0); + if (bytes_read <= 0) + { + printf("receive data error(%d).", bytes_read); + + if (total_read) + { + break; + } + else + { + if (errno == EWOULDBLOCK || errno == EAGAIN) + { + /* recv timeout */ + printf("receive data timeout."); + return -HTTPCLIENT_TIMEOUT; + } + else + { + closesocket(session->socket); + session->socket = -1; + return 0; + } + } + } + + left -= bytes_read; + total_read += bytes_read; + } + while (left); + + if (session->content_length > 0) + { + session->content_remainder -= total_read; + } + + return total_read; +} + +/** + * write data to http server. + * + * @param session http session + * @param buffer write buffer + * @param length write buffer size + * + * @return <0: write data error + * =0: http server disconnect + * >0: successfully write data length + */ +int httpClientWrite(struct httpClientSession *session, const void *buffer, size_t length) +{ + int bytes_write = 0; + int total_write = 0; + int left = length; + + assert(session); + + if (session->socket < 0) + { + return -HTTPCLIENT_DISCONNECT; + } + + if (length == 0) + { + return 0; + } + + /* send all of data on the buffer. */ + do + { + bytes_write = httpClientSend(session, (void *)((char *)buffer + total_write), left, 0); + if (bytes_write <= 0) + { + + if (errno == EWOULDBLOCK || errno == EAGAIN) + { + /* send timeout */ + if (total_write) + { + return total_write; + } + continue; + /* TODO: whether return the TIMEOUT + * return -HTTPCLIENT_TIMEOUT; */ + } + else + { + closesocket(session->socket); + session->socket = -1; + + if (total_write == 0) + { + return -HTTPCLIENT_DISCONNECT; + } + break; + } + } + + left -= bytes_write; + total_write += bytes_write; + } + while (left); + + return total_write; +} + +/* close session socket, free host and request url */ +static int httpClientClean(struct httpClientSession *session) +{ + + if (session->socket >= 0) + { + closesocket(session->socket); + session->socket = -1; + } + if (session->host) + { + HTTP_FREE(session->host); + session->host = RT_NULL; + } + + if (session->req_url) + { + HTTP_FREE(session->req_url); + session->req_url = RT_NULL; + } + + session->content_length = -1; + + return 0; +} + +/** + * close a webclient client session. + * + * @param session http client session + * + * @return 0: close success + */ +int httpClientClose(struct httpClientSession *session) +{ + assert(session); + + httpClientClean(session); + + if (session->header && session->header->buffer) + { + HTTP_FREE(session->header->buffer); + } + + if (session->header) + { + HTTP_FREE(session->header); + } + + if (session) + { + HTTP_FREE(session); + session = RT_NULL; + } + + return 0; +} + +/** + * get wenclient request response data. + * + * @param session wenclient session + * @param response response buffer address + * @param resp_len response buffer length + * + * @return response data size + */ +int httpClientResponse(struct httpClientSession *session, void **response, size_t *resp_len) +{ + unsigned char *buf_ptr; + unsigned char *response_buf = 0; + int length, total_read = 0; + + assert(session); + assert(response); + + /* initialize response */ + *response = RT_NULL; + + /* not content length field kind */ + if (session->content_length < 0) + { + size_t result_sz; + + total_read = 0; + while (1) + { + unsigned char *new_resp = RT_NULL; + + result_sz = total_read + HTTPCLIENT_RESPONSE_BUFSZ; + new_resp = HTTP_REALLOC(response_buf, result_sz + 1); + if (new_resp == RT_NULL) + { + printf("no memory for realloc new response buffer!"); + break; + } + + response_buf = new_resp; + buf_ptr = (unsigned char *) response_buf + total_read; + + /* read result */ + length = httpClientRead(session, buf_ptr, result_sz - total_read); + if (length <= 0) + break; + + total_read += length; + } + } + else + { + int result_sz; + + result_sz = session->content_length; + response_buf = HTTP_CALLOC(1, result_sz + 1); + if (response_buf == RT_NULL) + { + return -HTTPCLIENT_NOMEM; + } + + buf_ptr = (unsigned char *) response_buf; + for (total_read = 0; total_read < result_sz;) + { + length = httpClientRead(session, buf_ptr, result_sz - total_read); + if (length <= 0) + break; + + buf_ptr += length; + total_read += length; + } + } + + if ((total_read == 0) && (response_buf != 0)) + { + HTTP_FREE(response_buf); + response_buf = RT_NULL; + } + + if (response_buf) + { + *response = (void *)response_buf; + *(response_buf + total_read) = '\0'; + *resp_len = total_read; + } + + return total_read; +} + +/** + * add request(GET/POST) header data. + * + * @param request_header add request buffer address + * @param fmt fields format + * + * @return <=0: add header failed + * >0: add header data size + */ + +int httpClientRequestHeaderAdd(char **request_header, const char *fmt, ...) +{ + rt_int32_t length, header_length; + char *header; + va_list args; + + assert(request_header); + + if (*request_header == RT_NULL) + { + header = rt_calloc(1, HTTPCLIENT_HEADER_BUFSZ); + if (header == RT_NULL) + { + printf("No memory for webclient request header add."); + return RT_NULL; + } + *request_header = header; + } + else + { + header = *request_header; + } + + va_start(args, fmt); + header_length = rt_strlen(header); + length = rt_vsnprintf(header + header_length, HTTPCLIENT_HEADER_BUFSZ - header_length, fmt, args); + if (length < 0) + { + printf("add request header data failed, return length(%d) error.", length); + return -HTTPCLIENT_ERROR; + } + va_end(args); + + /* check header size */ + if (rt_strlen(header) >= HTTPCLIENT_HEADER_BUFSZ) + { + printf("not enough request header data size(%d)!", HTTPCLIENT_HEADER_BUFSZ); + return -HTTPCLIENT_ERROR; + } + + return length; +} + +/** + * send request(GET/POST) to server and get response data. + * + * @param URI input server address + * @param header send header data + * = NULL: use default header data, must be GET request + * != NULL: user custom header data, GET or POST request + * @param post_data data sent to the server + * = NULL: it is GET request + * != NULL: it is POST request + * @param data_len send data length + * @param response response buffer address + * @param resp_len response buffer length + * + * @return <0: request failed + * >=0: response buffer size + */ +int httpClientRequest(const char *URI, const char *header, const void *post_data, size_t data_len, void **response, size_t *resp_len) +{ + struct httpClientSession *session = RT_NULL; + int rc = HTTPCLIENT_OK; + int totle_length = 0; + + assert(URI); + + if (post_data == RT_NULL && response == RT_NULL) + { + printf("request get failed, get response data cannot be empty."); + return -HTTPCLIENT_ERROR; + } + + if ((post_data != RT_NULL) && (data_len == 0)) + { + printf("input post data length failed"); + return -HTTPCLIENT_ERROR; + } + + if ((response != RT_NULL && resp_len == RT_NULL) || + (response == RT_NULL && resp_len != RT_NULL)) + { + printf("input response data or length failed"); + return -HTTPCLIENT_ERROR; + } + + if (post_data == RT_NULL) + { + /* send get request */ + session = httpClientSessionCreate(HTTPCLIENT_HEADER_BUFSZ); + if (session == RT_NULL) + { + rc = -HTTPCLIENT_NOMEM; + goto __exit; + } + + if (header != RT_NULL) + { + char *header_str, *header_ptr; + int header_line_length; + + for(header_str = (char *)header; (header_ptr = rt_strstr(header_str, "\r\n")) != RT_NULL; ) + { + header_line_length = header_ptr + rt_strlen("\r\n") - header_str; + httpClientHeaderFieldsAdd(session, "%.*s", header_line_length, header_str); + header_str += header_line_length; + } + } + + if (httpClientGet(session, URI) != 200) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + totle_length = httpClientResponse(session, response, resp_len); + if (totle_length <= 0) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + } + else + { + /* send post request */ + session = httpClientSessionCreate(HTTPCLIENT_HEADER_BUFSZ); + if (session == RT_NULL) + { + rc = -HTTPCLIENT_NOMEM; + goto __exit; + } + + if (header != RT_NULL) + { + char *header_str, *header_ptr; + int header_line_length; + + for(header_str = (char *)header; (header_ptr = rt_strstr(header_str, "\r\n")) != RT_NULL; ) + { + header_line_length = header_ptr + rt_strlen("\r\n") - header_str; + httpClientHeaderFieldsAdd(session, "%.*s", header_line_length, header_str); + header_str += header_line_length; + } + } + + if (rt_strstr(session->header->buffer, "Content-Length") == RT_NULL) + { + httpClientHeaderFieldsAdd(session, "Content-Length: %d\r\n", rt_strlen(post_data)); + } + + if (rt_strstr(session->header->buffer, "Content-Type") == RT_NULL) + { + httpClientHeaderFieldsAdd(session, "Content-Type: application/octet-stream\r\n"); + } + + if (httpClientPost(session, URI, post_data, data_len) != 200) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + totle_length = httpClientResponse(session, response, resp_len); + if (totle_length <= 0) + { + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + } + +__exit: + if (session) + { + httpClientClose(session); + session = RT_NULL; + } + + if (rc < 0) + { + return rc; + } + + return totle_length; +} + + +int httpClientGetFile(const char* URI, const char* filename) +{ + int fd = -1, rc = HTTPCLIENT_OK; + size_t offset; + int length, total_length = 0; + unsigned char *ptr = RT_NULL; + struct httpClientSession* session = RT_NULL; + int resp_status = 0; + + session = httpClientSessionCreate(HTTPCLIENT_HEADER_BUFSZ); + if(session == RT_NULL) + { + rc = -HTTPCLIENT_NOMEM; + goto __exit; + } + + if ((resp_status = httpClientGet(session, URI)) != 200) + { + printf("get file failed, wrong response: %d (-0x%X).", resp_status, resp_status); + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) + { + printf("get file failed, open file(%s) error.", filename); + rc = -HTTPCLIENT_ERROR; + goto __exit; + } + + ptr = (unsigned char *) HTTP_MALLOC(HTTPCLIENT_RESPONSE_BUFSZ); + if (ptr == RT_NULL) + { + printf("get file failed, no memory for response buffer."); + rc = -HTTPCLIENT_NOMEM; + goto __exit; + } + + if (session->content_length < 0) + { + while (1) + { + length = httpClientRead(session, ptr, HTTPCLIENT_RESPONSE_BUFSZ); + if (length > 0) + { + write(fd, ptr, length); + total_length += length; + printf(">"); + } + else + { + break; + } + } + } + else + { + for (offset = 0; offset < (size_t) session->content_length;) + { + length = httpClientRead(session, ptr, + session->content_length - offset > HTTPCLIENT_RESPONSE_BUFSZ ? + HTTPCLIENT_RESPONSE_BUFSZ : session->content_length - offset); + + if (length > 0) + { + write(fd, ptr, length); + total_length += length; + printf(">"); + } + else + { + break; + } + + offset += length; + } + } + + if (total_length) + { + printf("save %d bytes.", total_length); + } + +__exit: + if (fd >= 0) + { + close(fd); + } + + if (session != RT_NULL) + { + httpClientClose(session); + } + + if (ptr != RT_NULL) + { + HTTP_FREE(ptr); + } + + return rc; +} + + +int httpGet(int argc, char** argv) +{ + if (argc != 3) + { + printf("Please using: wget \n"); + return -1; + } + + httpClientGetFile(argv[1], argv[2]); + return 0; +} + +#ifdef __RT_THREAD_H__ +MSH_CMD_EXPORT(httpGet, Get file by URI: httpGet .); +#endif /* FINSH_USING_MSH */ \ No newline at end of file diff --git a/APP_Framework/Framework/knowing/ota/httpclient.h b/APP_Framework/Framework/knowing/ota/httpclient.h new file mode 100644 index 00000000..6334159b --- /dev/null +++ b/APP_Framework/Framework/knowing/ota/httpclient.h @@ -0,0 +1,132 @@ +/* + * @Author: chunyexixiaoyu + * @Date: 2021-08-26 13:53:03 + * @LastEditTime: 2021-08-30 14:44:05 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \xiuos\APP_Framework\Framework\knowing\ota\httpclient.h + */ +#ifndef _OTA_HTTPCLIENT_H +#define _OTA_HTTPCLIENT_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HTTP_MALLOC +#define HTTP_MALLOC malloc +#endif + +#ifndef HTTP_CALLOC +#define HTTP_CALLOC calloc +#endif + +#ifndef HTTP_REALLOC +#define HTTP_REALLOC realloc +#endif + +#ifndef HTTP_FREE +#define HTTP_FREE free +#endif + +#ifndef HTTP_STRDUP +#define HTTP_STRDUP strdup +#endif + +#define HTTPCLIENT_SW_VERSION "2.2.0" +#define HTTPCLIENT_SW_VERSION_NUM 0x20200 + +#define HTTPCLIENT_HEADER_BUFSZ 4096 +#define HTTPCLIENT_RESPONSE_BUFSZ 4096 + +#define HTTPCLIENT_DEFAULT_TIMEO 6 + +enum webClientStatus +{ + HTTPCLIENT_OK, + HTTPCLIENT_ERROR, + HTTPCLIENT_TIMEOUT, + HTTPCLIENT_NOMEM, + HTTPCLIENT_NOSOCKET, + HTTPCLIENT_NOBUFFER, + HTTPCLIENT_CONNECT_FAILED, + HTTPCLIENT_DISCONNECT, + HTTPCLIENT_FILE_ERROR, +}; + +enum httpClientMethod +{ + WEBCLIENT_USER_METHOD, + WEBCLIENT_GET, + WEBCLIENT_POST, +}; + +struct httpClientHeader +{ + char *buffer; + size_t length; /* content header buffer size */ + + size_t size; /* maximum support header size */ +}; + +struct httpClientSession +{ + struct httpClientHeader *header; /* webclient response header information */ + int socket; + int resp_status; + + char *host; /* server host */ + char *req_url; /* HTTP request address*/ + + int chunk_sz; + int chunk_offset; + + int content_length; + size_t content_remainder; /* remainder of content length */ + + int is_tls; /* HTTPS connect */ +}; + +/* create webclient session and set header response size */ +struct httpClientSession *httpClientSessionCreate(size_t header_sz); + +/* send HTTP GET request */ +int httpClientGet(struct httpClientSession *session, const char *URI); +int httpClientGetPosition(struct httpClientSession *session, const char *URI, int position); + +/* send HTTP POST request */ +int httpClientPost(struct httpClientSession *session, const char *URI, const void *post_data, size_t data_len); + +/* close and release wenclient session */ +int httpClientClose(struct httpClientSession *session); + +int httpClientSetTimeout(struct httpClientSession *session, int millisecond); + +/* send or receive data from server */ +int httpClientRead(struct httpClientSession *session, void *buffer, size_t size); +int httpClientWrite(struct httpClientSession *session, const void *buffer, size_t size); + +/* webclient GET/POST header buffer operate by the header fields */ +int httpClientHeaderFieldsAdd(struct httpClientSession *session, const char *fmt, ...); +const char *httpClientHeaderFieldsGet(struct httpClientSession *session, const char *fields); + +/* send HTTP POST/GET request, and get response data */ +int httpClientResponse(struct httpClientSession *session, void **response, size_t *resp_len); +int httpClientRequest(const char *URI, const char *header, const void *post_data, size_t data_len, void **response, size_t *resp_len); +int httpClientRequestHeaderAdd(char **request_header, const char *fmt, ...); +int httpClientRespStatusGet(struct httpClientSession *session); +int httpClientContentLengthGet(struct httpClientSession *session); + +/* +file system must be supported +*/ +/* file related operations */ +int httpClientGetFile(const char *URI, const char *filename); +int httpClientPostFile(const char *URI, const char *filename, const char *form_data); + +extern long int strtol(const char *nptr, char **endptr, int base); +#ifdef __cplusplus + } +#endif +#endif \ No newline at end of file diff --git a/APP_Framework/Framework/transform_layer/rtthread/transform.h b/APP_Framework/Framework/transform_layer/rtthread/transform.h index 2f67b308..25cb9211 100644 --- a/APP_Framework/Framework/transform_layer/rtthread/transform.h +++ b/APP_Framework/Framework/transform_layer/rtthread/transform.h @@ -22,7 +22,13 @@ #define TRANSFORM_H #include #include +#include #include +#include +#include +#include +#include +#include #include #include #include @@ -33,10 +39,19 @@ #ifdef DRV_USING_OV2640 #include #endif +#if defined(RT_USING_SAL) +#include +#include +#else +#include +#include +#endif /* RT_USING_SAL */ #ifdef __cplusplus extern "C" { #endif + + #ifdef __cplusplus } #endif