[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/common.h b/src/lynq/packages/apps/lynq-threadhandle/include/common.h
new file mode 100644
index 0000000..02fcdeb
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/common.h
@@ -0,0 +1,19 @@
+#ifndef _COMMON_H_

+#define _COMMON_H_

+

+

+#define NO_ERROR 			0

+#define ERR_VALID 			70			//valid error

+#define ERR_CMDVALID 		71			//cmd error

+#define ERR_SESSIONVALID 	72			//session error

+#define ERR_MALLOCVALID 	73 			//malloc error

+#define ERR_INVOKE 			74			//invoke error

+#define ERR_SYSTEM 			75			//system error

+#define ERR_TIMEOUT 		76			//time out error

+

+#define BUF_SIZE 		8192

+//int th_error;

+

+int str_arr(char *str, char *substr, char parts[][BUF_SIZE]);

+#endif

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/double_list.h b/src/lynq/packages/apps/lynq-threadhandle/include/double_list.h
new file mode 100644
index 0000000..b8682c0
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/double_list.h
@@ -0,0 +1,49 @@
+#ifndef __DOUBLE_LIST__H__

+#define __DOUBLE_LIST__H__

+

+

+#include "syn_primitive.h"

+

+

+typedef struct tag_d_list 

+{

+	void *data;

+	unsigned int data_len;

+	struct tag_d_list *pre;

+	struct tag_d_list *next;

+}d_list_node_t;

+

+

+typedef struct  

+{

+	unsigned int node_count;

+	d_list_node_t *head;

+	d_list_node_t *tail;

+

+	d_list_node_t *cur_idx;

+}d_list_t;

+

+

+typedef int (*compare_func)(void *usr_data, unsigned int udata_len, void *list_data, unsigned int ldata_len);

+

+BOOL is_empty_d_list(d_list_t *list);

+unsigned int get_d_list_node_count(d_list_t *list);

+d_list_t *create_d_list(void);

+void destroy_d_list(d_list_t *list);

+BOOL insert_d_list_head(d_list_t *list, void *data, unsigned int data_len);

+BOOL insert_d_list_tail(d_list_t *list, void *data, unsigned int data_len);

+BOOL insert_d_list_head_node(d_list_t *list, d_list_node_t *node);

+BOOL insert_d_list_tail_node(d_list_t *list, d_list_node_t *node);

+BOOL delete_d_list_head(d_list_t *list);

+BOOL delete_d_list_tail(d_list_t *list);

+BOOL delete_d_list_node_all(d_list_t *list);

+BOOL remove_d_list_node(d_list_t *list, d_list_node_t *node);

+d_list_node_t *remove_d_list_head_node(d_list_t *list);

+d_list_node_t *remove_d_list_tail_node(d_list_t *list);

+d_list_node_t *find_d_list_node(d_list_t *list, void *user_data, unsigned int data_len, compare_func func);

+d_list_node_t *get_d_list_node(d_list_t *list, int idx);

+d_list_node_t *get_next_node(d_list_t *list);

+

+#endif //__DOUBLE_LIST__H__

+

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/ftp_manager.h b/src/lynq/packages/apps/lynq-threadhandle/include/ftp_manager.h
new file mode 100644
index 0000000..bb833ab
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/ftp_manager.h
@@ -0,0 +1,29 @@
+#ifndef _FTP_MANAGER_H

+#define _FTP_MANAGER_H

+

+#include "thread_pool.h"

+#include "list.h"

+#include "ftp/lynq_ftp.h"

+#include "common.h"

+

+typedef struct  

+{

+	int id;

+	char *action;

+	int (*ftp_action)(lynq_ftp_socker_info* FTP);

+}FTP_MAG_S; 

+

+

+typedef struct FTP_LIST_LINK

+{

+	struct list_head list;

+	lynq_ftp_socker_info data;

+}FTP_LIST_LINK_S;

+

+

+void ftp_list_init(void);

+int ftp_list_locate(void);

+int ftp_param_verification(char result[][BUF_SIZE] , int line);

+int ftp_act_handler(thread_pool_t *pool);

+

+#endif
\ No newline at end of file
diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/http_manager.h b/src/lynq/packages/apps/lynq-threadhandle/include/http_manager.h
new file mode 100644
index 0000000..21f5e70
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/http_manager.h
@@ -0,0 +1,26 @@
+#ifndef _HTTP_MANAGER_H

+#define _HTTP_MANAGER_H

+

+

+#include "http/lynq_http.h"

+#include "thread_pool.h"

+#include "list.h"

+#include "common.h"

+

+

+

+typedef struct

+{

+	struct list_head list;

+	lynq_http_client_t data;

+}HTTP_LIST_LINK_S;

+

+void http_list_init(void);

+int http_list_locate(void);

+int http_param_verification(char result[][BUF_SIZE], int line);

+int http_act_handler(thread_pool_t *pool);

+

+

+

+#endif

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/list.h b/src/lynq/packages/apps/lynq-threadhandle/include/list.h
new file mode 100644
index 0000000..697ff6f
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/list.h
@@ -0,0 +1,122 @@
+#ifndef _LINUX_LIST_H

+#define _LINUX_LIST_H

+

+#ifndef NULL

+#define NULL 0

+#endif

+

+

+#ifndef offsetof

+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

+#endif

+

+#ifndef container_of

+#define container_of(ptr, type, member) ((type *)((char *)ptr - offsetof(type,member)))

+#endif

+

+#define prefetch(x)  ((void)x)

+#define LIST_POISON1  (NULL)

+#define LIST_POISON2  (NULL)

+

+struct list_head{

+    struct list_head *next, *prev;

+};

+

+struct hlist_node{

+    struct hlist_node *next, **pprev;

+};

+

+struct hlist_head{

+    struct hlist_node *first;

+};

+

+#define LIST_HEAD_INIT(name) { &(name), &(name) }

+

+#define LIST_HEAD(name) \

+    struct list_head name = LIST_HEAD_INIT(name)

+

+static void INIT_LIST_HEAD(struct list_head *list)

+{

+    list->next = list;

+    list->prev = list;

+}

+

+

+static void __list_add(struct list_head *node,

+                  struct list_head *prev,

+                  struct list_head *next)

+{

+    next->prev = node;

+    node->next = next;

+    node->prev = prev;

+    prev->next = node;

+}

+

+static void list_add(struct list_head *node, struct list_head *head)

+{

+    __list_add(node, head, head->next);

+}

+

+

+static void list_add_tail(struct list_head *node, struct list_head *head)

+{

+    __list_add(node, head->prev, head);

+}

+

+/*

+ * Delete a list entry by making the prev/next entries

+ * point to each other.

+ *

+ * This is only for internal list manipulation where we know

+ * the prev/next entries already!

+ */

+static void __list_del(struct list_head * prev, struct list_head * next)

+{

+    next->prev = prev;

+    prev->next = next;

+}

+

+/**

+ * list_del - deletes entry from list.

+ * @entry: the element to delete from the list.

+ * Note: list_empty() on entry does not return true after this, the entry is

+ * in an undefined state.

+ */

+static void __list_del_entry(struct list_head *entry)

+{

+    __list_del(entry->prev, entry->next);

+}

+

+static void list_del(struct list_head *entry)

+{

+    __list_del(entry->prev, entry->next);

+    entry->next = LIST_POISON1;

+    entry->prev = LIST_POISON2;

+}

+

+/**

+ * list_entry - get the struct for this entry

+ * @ptr:    the &struct list_head pointer.

+ * @type:    the type of the struct this is embedded in.

+ * @member:    the name of the list_struct within the struct.

+ */

+#define list_entry(ptr, type, member) \

+    container_of(ptr, type, member)

+

+

+/**

+ * list_for_each    -    iterate over a list

+ * @pos:    the &struct list_head to use as a loop cursor.

+ * @head:    the head for your list.

+ */

+#define list_for_each(pos, head) \

+    for (pos = (head)->next; prefetch(pos->next), pos != (head); \

+            pos = pos->next)

+

+#define list_safe_reset_next(pos, n, member)                \

+    n = list_entry(pos->member.next, typeof(*pos), member)

+

+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)

+

+#endif

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/model_manager.h b/src/lynq/packages/apps/lynq-threadhandle/include/model_manager.h
new file mode 100644
index 0000000..78fb3c7
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/model_manager.h
@@ -0,0 +1,31 @@
+#ifndef _MODEL_MANAGER_H

+#define _MODEL_MANAGER_H

+

+#include "http_manager.h"

+#include "ftp_manager.h"

+#include "list.h"

+#include "thread_pool.h"

+#include <log/log.h>

+#include "ril_manager.h"

+#include "mqtt_manager.h"

+#include "common.h"

+

+typedef struct  

+{

+	char *name;

+	void (*func_list_init)(void);

+	int (*func_param_verification)(char result[][BUF_SIZE], int line);

+	int (*func_list_locate)(void);

+	int (*func_act_handler)(thread_pool_t *pool);

+	int (*func_del)(void);

+	int (*func_get)(void);

+	int (*func_set)(void);

+	int (*func_next)(void);

+}MAG_LIST_S; 

+

+

+MAG_LIST_S *list_manager_proc(const char *name);

+

+

+#endif

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/mqtt_manager.h b/src/lynq/packages/apps/lynq-threadhandle/include/mqtt_manager.h
new file mode 100644
index 0000000..5f8cbee
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/mqtt_manager.h
@@ -0,0 +1,25 @@
+#ifndef _MQTT_MANAGER_H

+#define _MQTT_MANAGER_H

+

+#include "lynq_mqtt/lynq_mqtt.h"

+#include "thread_pool.h"

+#include "list.h"

+#include "common.h"

+

+

+

+typedef struct

+{

+	struct list_head list;

+	struct mqtt_set_parament data;

+}MQTT_LIST_LINK_S;

+

+

+void mqtt_list_init();

+int mqtt_param_verification(char result[][BUF_SIZE] , int line);

+int mqtt_list_locate();

+int mqtt_act_handler(thread_pool_t *pool);

+

+

+#endif

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/ril_manager.h b/src/lynq/packages/apps/lynq-threadhandle/include/ril_manager.h
new file mode 100644
index 0000000..c491cda
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/ril_manager.h
@@ -0,0 +1,7 @@
+#include "model_manager.h"

+#include "common.h"

+

+void ril_list_init();

+int ril_param_verification(char result[][BUF_SIZE] , int line);

+int ril_list_locate();

+int ril_act_handler(thread_pool_t *pool);

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/seq_queue.h b/src/lynq/packages/apps/lynq-threadhandle/include/seq_queue.h
new file mode 100644
index 0000000..2aed03e
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/seq_queue.h
@@ -0,0 +1,43 @@
+#ifndef __SEQ_QUEUE__H_

+#define __SEQ_QUEUE__H_

+

+#include "syn_primitive.h"

+

+

+#ifndef in

+#define in

+#define out

+#endif

+

+#define EXPAND_BLOCK_NUM 100

+

+typedef struct  

+{

+	BOOL expandabilit;

+	unsigned int expand_blocks;

+

+	unsigned int block_size;

+	unsigned int total_block;

+

+	unsigned int current_block;

+	unsigned int tail_block;

+	unsigned int used_block;

+

+	void *block_buffer;

+

+	//mutex_handle task_queue_lock;

+	sem_handle task_queue_lock;

+

+}seq_queue_t;

+

+

+seq_queue_t *create_seq_queue(in unsigned int block_size, in unsigned int total_block, in BOOL expand);

+void destroy_seq_queue(in seq_queue_t *queue);

+BOOL en_seq_queue(in seq_queue_t *queue, in void *data);

+BOOL de_seq_queue(in seq_queue_t *queue, out void *data);

+unsigned int get_count_seq_queue(in seq_queue_t *queue);

+unsigned int get_total_seq_queue(in seq_queue_t *queue);

+

+

+#endif //__SEQ_QUEUE__H_

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/syn_primitive.h b/src/lynq/packages/apps/lynq-threadhandle/include/syn_primitive.h
new file mode 100644
index 0000000..77dc2d5
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/syn_primitive.h
@@ -0,0 +1,43 @@
+#ifndef __SYN_PRIMITIVE__H_

+#define __SYN_PRIMITIVE__H_

+

+#include <pthread.h>

+#include <semaphore.h>

+#include "typedefs.h"

+#include <string.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include "liblog/liblog.h"

+#include "liblog/lynq_deflog.h"

+

+typedef pthread_t       thread_id;

+typedef pthread_t       thread_handle;

+typedef pthread_cond_t  condition_handle;

+typedef pthread_mutex_t mutex_handle;

+typedef sem_t			sem_handle;

+

+

+

+#define TIME_WAIT_INFINITE 0x7fffffff

+

+

+

+int init_condition_handle(condition_handle *cond);

+int destroy_condition_handle(condition_handle *cond);

+//int wait_condition(condition_handle *cond, mutex_handle *mutex);

+int wait_condition(condition_handle *cond, mutex_handle *mutex, unsigned int wait);

+int post_condition_signal(condition_handle *cond);

+int init_mutex_handle(mutex_handle *mutex);

+int mutex_lock(mutex_handle *mutex);

+int mutex_unlock(mutex_handle *mutex);

+int mutex_destroy(mutex_handle *mutex);

+int create_sem(sem_handle *sem, int init_count);

+int wait_sem(sem_handle *sem);

+int post_sem(sem_handle *sem);

+int destroy_sem(sem_handle *sem);

+

+

+

+#endif //__SYN_PRIMITIVE__H_

+

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/thread_pool.h b/src/lynq/packages/apps/lynq-threadhandle/include/thread_pool.h
new file mode 100644
index 0000000..cc2cd29
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/thread_pool.h
@@ -0,0 +1,83 @@
+#ifndef __THREAD_POOL__H_

+#define __THREAD_POOL__H_

+

+#include "syn_primitive.h"

+#include "double_list.h"

+#include "seq_queue.h"

+

+typedef enum {EThread_pool_unknown, EThread_pool_alloc, EThread_pool_init

+, EThread_pool_run, EThread_pool_exit, EThread_pool_MAX}EThread_pool_status;

+

+

+#define RELEASE_THREAD_INTERVAL 5*60 

+

+

+typedef void (*THREAD_FUNC)(void *);

+typedef void (*USER_FUNC)(void *thread_para);

+

+

+typedef struct {

+	USER_FUNC timeout_callback;

+	unsigned long time_out;

+}time_out_t;

+

+typedef struct  

+{

+	USER_FUNC process_func;

+	USER_FUNC  release_func;

+	void *args;

+	time_out_t time_out_info;

+}thread_func_t;

+

+typedef struct  

+{

+	thread_func_t thread_para;

+	unsigned int pri;

+

+	BOOL busy;

+	BOOL release;

+

+	unsigned long launch_time;

+	unsigned long time_out;

+

+	EThread_pool_status *pool_status;

+

+	thread_handle h_thread;

+	condition_handle thread_cond;

+	mutex_handle thread_lock;

+

+}thread_info_t;

+

+typedef struct 

+{

+	unsigned int pri;

+	unsigned int min_thread_num;

+	unsigned int max_thread_num;

+

+	unsigned int pool_thread_num;

+

+	condition_handle manage_cond;

+	mutex_handle mange_lock;

+

+	unsigned long release_threads_interval;

+

+	d_list_t *idle_threads;

+	d_list_t *busy_threads;

+	seq_queue_t *task_queue;

+

+	sem_handle sem_inc;

+	thread_handle h_id;

+	

+	EThread_pool_status status;

+}thread_pool_t;

+

+

+thread_pool_t *threadpool_create(unsigned int min_thread_num, unsigned int max_thread_num);

+void threadpool_destroy(thread_pool_t *pool);

+BOOL threadpool_add(thread_pool_t *pool, USER_FUNC process_func, void *args);

+BOOL threadpool_add_timeout(thread_pool_t *pool, USER_FUNC process_func

+		, USER_FUNC release_func, void *args, time_out_t *time_out);

+void tp_sleep(unsigned int ms);

+

+#endif //__THREAD_POOL__H_

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/include/typedefs.h b/src/lynq/packages/apps/lynq-threadhandle/include/typedefs.h
new file mode 100644
index 0000000..d205b1c
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/include/typedefs.h
@@ -0,0 +1,21 @@
+#ifndef __TYPE_DEFS__H_

+#define __TYPE_DEFS__H_

+

+#ifndef NULL

+#define NULL 0

+#endif

+

+#ifndef BOOL

+#define BOOL unsigned char

+#endif

+

+#ifndef TRUE

+#define TRUE 1

+#endif

+

+#ifndef FALSE

+#define FALSE 0

+#endif

+

+

+#endif //__TYPE_DEFS__H_

diff --git a/src/lynq/packages/apps/lynq-threadhandle/makefile b/src/lynq/packages/apps/lynq-threadhandle/makefile
new file mode 100644
index 0000000..529bbd4
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/makefile
@@ -0,0 +1,62 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -fpermissive \
+
+
+
+
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/vendor-ril \
+  -I$(LOCAL_PATH)/include \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(ROOT)$(includedir)/libtel \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(libdir)/glib-2.0/include \
+  -I$(ROOT)$(includedir)/dbus-1.0 \
+  -I$(ROOT)$(libdir)/dbus-1.0/include \
+  -I$(ROOT)$(includedir)/ftp \
+  -I$(ROOT)$(includedir)/http \
+  -I$(ROOT)$(includedir)/lynq_mqtt \
+  -I$(ROOT)$(includedir)/liblynq-broadcast \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lpthread \
+    -llynq-log \
+    -lssl \
+    -llynq-tele-ril \
+    -lglib-2.0 \
+    -lgobject-2.0 \
+    -lgio-2.0 \
+    -ldbus-1 \
+    -llynq-protcl \
+    -llog \
+    -llynq-broadcast \
+
+SOURCES = $(wildcard *.c src/*.c)
+
+EXECUTABLE = lynq-threadhandle
+
+OBJECTS=$(SOURCES:.c=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/common.c b/src/lynq/packages/apps/lynq-threadhandle/src/common.c
new file mode 100644
index 0000000..e8a5968
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/common.c
@@ -0,0 +1,65 @@
+#include <stdio.h>

+#include <malloc.h>

+#include <string.h>

+#include "common.h"

+#include "liblog/lynq_deflog.h"

+

+int str_arr(char *str, char *substr, char parts[][BUF_SIZE])

+{         

+	char *p = NULL;  

+	char *q = NULL;		

+	char tmp[BUF_SIZE] = "";	

+	char end[BUF_SIZE] = "";			

+	char *start = strdup(str);	

+	int i = 0, j = 0, k = 0, par_num=0;

+

+

+	while(*str != '\0')    

+	{        

+		p = str;        

+		q = substr;		

+		tmp[i] = *str;		

+		i++;

+		

+		while((*p == *q) && (*p != '\0') && (*q != '\0'))        

+		{            

+			p++;            

+			q++;        

+		}         

+		if(*q == '\0')

+		{			

+			memset(end, 0, sizeof(end));			

+			strcpy(end, p);

+

+			memset(parts[j], 0, sizeof(parts[j]));

+			

+			j == 0 ? memcpy(parts[j], tmp, strlen(tmp)-1) : memcpy(parts[j], tmp+1, strlen(tmp)-2) ;			

+

+			j++;			

+			memset(tmp, 0, sizeof(tmp));			

+			i = 0;			            

+			par_num++;         

+		}		

+

+		str++;

+	}	

+	

+	

+	if (!par_num) {

+		LYDBGLOG("[%s-%d] cmd is error!!!\n", __FUNCTION__, __LINE__);

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+		return ERR_CMDVALID;

+	}

+		

+	

+	if (strcmp(end, "") != 0) {		

+		memset(parts[j], 0, sizeof(parts[j]));

+		memcpy(parts[j], tmp+1, strlen(tmp)-2);

+	}

+

+	for (i = 0 ; i < par_num + 1 ; i++)

+		memcpy(parts[i], strchr(parts[i],'"')+1,strlen(parts[i]));	

+	

+	return par_num; 			

+}

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/double_list.c b/src/lynq/packages/apps/lynq-threadhandle/src/double_list.c
new file mode 100644
index 0000000..030e677
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/double_list.c
@@ -0,0 +1,378 @@
+#include "double_list.h"

+

+

+BOOL is_empty_d_list(d_list_t *list) {

+	BOOL ret = FALSE;

+	if (list == NULL)

+		return FALSE;

+

+	if (list->node_count == 0 && list->head == NULL && list->tail == NULL) 

+		ret = TRUE;

+	

+	return ret;

+}

+

+

+unsigned int get_d_list_node_count(d_list_t *list) {

+	return list->node_count;

+}

+

+

+d_list_t *create_d_list(void) {

+	d_list_t *temp_list = (d_list_t *)malloc(sizeof(d_list_t));

+	if (temp_list) {

+		memset(temp_list, 0, sizeof(d_list_t));

+	}

+

+	return temp_list;

+}

+

+

+d_list_node_t *create_d_list_node(void *data, unsigned int data_len) {

+

+	d_list_node_t *temp_node = (d_list_node_t *)malloc(sizeof(d_list_node_t));

+	if (temp_node) {

+

+		memset(temp_node, 0, sizeof(d_list_node_t));

+		temp_node->data = data;

+		temp_node->data_len = data_len;

+	}

+

+	return temp_node;

+}

+

+

+d_list_node_t *insert_d_list_node_head_n(d_list_node_t *head, d_list_node_t *node) {

+		

+	if (head && node) {

+		node->pre = head->pre;

+		node->next = head;

+		

+		head->pre = node;

+	}

+	

+	return node;

+}

+

+

+d_list_node_t *insert_d_list_node_tail_n(d_list_node_t *tail, d_list_node_t *node) {

+	

+	if (tail && node) {

+		

+		tail->next = node;

+		node->pre = tail;

+		node->next = NULL;

+	}

+	

+	return node;

+}

+

+

+d_list_node_t *insert_d_list_node_head(d_list_node_t *head, void *data, unsigned int data_len) {

+

+	d_list_node_t *temp_node = create_d_list_node(data, data_len);

+

+	return insert_d_list_node_head_n(head, temp_node);

+}

+

+d_list_node_t *insert_d_list_node_tail(d_list_node_t *tail, void *data, unsigned int data_len) {

+	

+	d_list_node_t *temp_node = create_d_list_node(data, data_len);

+	

+	return insert_d_list_node_tail_n(tail, temp_node);

+}

+

+

+BOOL insert_d_list_head(d_list_t *list, void *data, unsigned int data_len) {

+	

+	if (list) {

+

+		if (list->node_count == 0) {

+			list->head = insert_d_list_node_head(list->head, data, data_len);

+			list->tail = list->head;

+		} else {

+			list->head = insert_d_list_node_head(list->head, data, data_len);

+		}

+

+		list->node_count++;

+

+		return TRUE;

+	}

+	

+	return FALSE;

+}

+

+

+BOOL insert_d_list_head_node(d_list_t *list, d_list_node_t *node) {

+	

+	if (list) {

+		

+		node->next = NULL;

+		node->pre = NULL;

+		if (list->node_count == 0) {

+			list->head = insert_d_list_node_head_n(list->head, node);

+			list->tail = list->head;

+		} else {

+			list->head = insert_d_list_node_head_n(list->head, node);

+		}

+		

+		list->node_count++;

+		

+		return TRUE;

+	}

+	

+	return FALSE;

+}

+

+

+BOOL insert_d_list_tail(d_list_t *list, void *data, unsigned int data_len) {

+

+	if (list && data) {

+

+		if (list->node_count == 0) {

+			list->tail = insert_d_list_node_tail(list->tail, data, data_len);

+			list->head = list->tail;

+		} else {

+			list->tail = insert_d_list_node_tail(list->tail, data, data_len);

+		}

+

+		list->node_count++;

+

+		return TRUE;

+	}

+

+	return FALSE;

+}

+

+

+BOOL insert_d_list_tail_node(d_list_t *list, d_list_node_t *node) {

+

+	BOOL ret = FALSE;

+	if (list) {

+

+		node->next = NULL;

+		node->pre = NULL;

+		if (list->node_count == 0) {

+			list->tail = insert_d_list_node_tail_n(list->tail, node);

+			list->head = list->tail;

+		} else {

+			list->tail = insert_d_list_node_tail_n(list->tail, node);

+		}

+		list->node_count++;

+		ret = TRUE;

+	}

+

+	return ret;

+}

+

+

+BOOL delete_d_list_head(d_list_t *list) {

+

+	BOOL ret = FALSE;

+	if (list == NULL)

+		return FALSE;

+

+	if (list->node_count > 0) {

+		d_list_node_t *temp_node = list->head;

+		

+		list->head = list->head->next;

+		list->node_count--;

+		if (list->node_count == 0 && list->head == NULL) {

+			list->tail = NULL;

+		} else {

+			list->head->pre = NULL;

+		}

+

+		free(temp_node);

+		ret = TRUE;

+	}

+

+	

+	return ret;

+}

+

+

+BOOL delete_d_list_tail(d_list_t *list) {

+	

+	BOOL ret = FALSE;

+	if (list == NULL)

+		return FALSE;

+

+	if (list->node_count > 0) {

+		d_list_node_t *temp_node = list->tail;

+		

+		list->tail = list->tail->pre;

+		list->node_count--;

+		if (list->node_count == 0 && list->tail == NULL) {

+			list->head = NULL;

+		} else {

+			list->tail->next = NULL;

+		}

+		

+		free(temp_node);

+		ret = TRUE;

+	}

+	

+	return ret;

+}

+

+

+BOOL remove_d_list_node(d_list_t *list, d_list_node_t *node) {

+	

+	if (node == NULL || list == NULL || list->node_count == 0)

+		return FALSE;

+

+	if (list->head == node) {

+		list->head = node->next;

+		if (list->head != NULL) {

+			node->next->pre = NULL;

+		} else {

+			list->tail = NULL;

+		}

+	} else {

+		node->pre->next = node->next;

+		if (node->next == NULL) {

+			list->tail = node->pre;

+		} else {

+			node->next->pre = node->pre;

+		}

+	}

+

+	node->next = NULL;

+	node->pre = NULL;

+	list->node_count--;

+

+	return TRUE;

+}

+

+

+d_list_node_t *remove_d_list_head_node(d_list_t *list) {

+

+	d_list_node_t *temp_node = NULL;

+	if (list == NULL)

+		return NULL;

+

+	if (list->head != NULL) {

+

+		temp_node = list->head;

+		list->head = list->head->next;

+		if (list->head == NULL)

+			list->tail = NULL;

+		else

+			list->head->pre = NULL;

+

+		list->node_count--;

+	}

+

+	return temp_node;

+}

+

+

+d_list_node_t *remove_d_list_tail_node(d_list_t *list) {

+

+	d_list_node_t *temp_node = NULL;

+	if (list == NULL)

+		return NULL;

+

+	if (list->tail != NULL) {

+

+		temp_node = list->tail;

+		list->tail = list->tail->pre;

+		if (list->tail == NULL)

+			list->head = NULL;

+		else

+			list->tail->next = NULL;

+

+		list->node_count--;

+	}

+

+	return temp_node;

+}

+

+

+BOOL delete_d_list_node_all(d_list_t *list) {

+

+	if (list) {

+		while (delete_d_list_head(list)) {

+

+		}

+

+		if (list->node_count == 0) {

+			return TRUE;

+		}

+	}

+

+	return FALSE;

+}

+

+void destroy_d_list(d_list_t *list) {

+	if (list == NULL)

+		return;

+

+	delete_d_list_node_all(list);

+	free(list);

+}

+

+

+d_list_node_t *find_d_list_node(d_list_t *list, void *user_data, unsigned int data_len, compare_func func) {

+	

+	d_list_node_t *temp_node = NULL;

+	if (list == NULL)

+		return NULL;

+

+	if (list->node_count > 0) {

+		temp_node = list->head;

+		while (temp_node)

+		{

+			if (func(user_data, data_len, temp_node->data, temp_node->data_len) == 0) {

+				break;

+			}

+

+			temp_node = temp_node->next;

+		}

+	}

+

+	return temp_node;

+}

+

+

+d_list_node_t *get_d_list_node(d_list_t *list, int idx) {

+	d_list_node_t *temp_node = NULL;

+	if (list == NULL)

+		return NULL;

+

+	if (list->node_count >= (unsigned int)abs(idx) && idx != 0) {

+

+		if (idx > 0) {

+			temp_node = list->head;

+			while (--idx)

+			{

+				temp_node = temp_node->next;

+			}

+		} else {

+			temp_node = list->tail;

+			while (++idx)

+			{

+				temp_node = temp_node->pre;

+			}

+		}

+	}

+

+	return temp_node;

+}

+

+

+d_list_node_t *get_next_node(d_list_t *list) {

+

+	d_list_node_t *temp_node;

+	if (list == NULL)

+		return NULL;

+

+	temp_node = list->cur_idx;

+	if (temp_node == NULL)

+		list->cur_idx = list->head;

+	else

+		list->cur_idx = list->cur_idx->next;

+	

+	return temp_node;

+}

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/ftp_manager.c b/src/lynq/packages/apps/lynq-threadhandle/src/ftp_manager.c
new file mode 100644
index 0000000..8f453cc
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/ftp_manager.c
@@ -0,0 +1,327 @@
+#include "ftp_manager.h"

+#include "common.h"

+#include <unistd.h>

+#include <stdio.h>

+#include <string.h>

+

+

+enum FTP_ID { 

+	FTP_LOGIN_ID = 0, 

+	FTP_GET_ID, 

+	FTP_UP_ID, 

+	FTP_QUIT_ID, 

+	FTP_LS_ID,

+	FTP_CD_ID = 5,

+	FTP_MKDIR_ID, 

+	FTP_RMD_ID,

+	FTP_DELETE_ID

+};

+

+

+

+FTP_MAG_S ftp_manager[] = {

+	{FTP_LOGIN_ID, "login", lynq_ftp_login},

+	{FTP_GET_ID, "get", lynq_ftp_download},

+	{FTP_UP_ID, "up", lynq_ftp_up},

+	{FTP_QUIT_ID, "quit", lynq_ftp_quit},

+	{FTP_LS_ID, "ls", lynq_ftp_ls},

+	{FTP_CD_ID, "cd", lynq_ftp_cd},

+	{FTP_MKDIR_ID, "mkdir", lynq_ftp_creat_mkd},

+	{FTP_RMD_ID, "rmd", lynq_ftp_delete_mkd},

+	{FTP_DELETE_ID, "delete", lynq_ftp_deletefile_mkd},

+};

+

+

+static int ftp_init = 0;

+static struct list_head lynq_ftp_list;

+static FTP_LIST_LINK_S* ftp_slider;

+static lynq_ftp_socker_info ftp_cmd = {0};

+

+FTP_MAG_S *ftp_mag_ret = NULL;

+

+

+void *ftp_handler(void * list)

+{

+	FTP_LIST_LINK_S* pos_list  = (FTP_LIST_LINK_S *)list;

+	int ftp_login = 0; 

+	char cmpybuf[64] = "";

+	

+	while(1)

+	{

+		if (pos_list->data.modify_thread != 1 && pos_list->data.add_thread != 1)

+			continue;

+		

+		//LYDBGLOG("[%s-%d] rita thread_id %lu start.\n",__FUNCTION__, __LINE__, pthread_self());

+

+		pos_list->data.add_thread = 0;

+		pos_list->data.modify_thread = 0;

+#if 0

+		LYDBGLOG("**************************ftp_handler debug************************************\n");

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.session = %d\n", __FUNCTION__, __LINE__, pos_list->data.session);

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.sevname = %s\n", __FUNCTION__, __LINE__, pos_list->data.sevname);

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.username = %s\n", __FUNCTION__, __LINE__, pos_list->data.username);

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.pw = %s\n", __FUNCTION__, __LINE__, pos_list->data.pw);

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.is_pasv_mode = %s\n", __FUNCTION__, __LINE__, pos_list->data.is_pasv_mode);

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.action = %s\n", __FUNCTION__, __LINE__, pos_list->data.action);

+		LYDBGLOG("[%s %d] ---------- > pos_list->data.id = %d\n", __FUNCTION__, __LINE__, pos_list->data.id);

+		LYDBGLOG("**************************debug end************************************\n");

+#endif

+		if (ftp_login == 0 && FTP_QUIT_ID != pos_list->data.id) {

+			ftp_login = lynq_ftp_login(&pos_list->data);

+			LYDBGLOG("[%s-%d] rita test for debuging ftp,ftp_login = %d\n", __FUNCTION__, __LINE__, ftp_login);

+			if(!ftp_login)//rita add @2021.7.19 for error connect,reconnect failure

+			{

+				LYDBGLOG("[%s-%d] rita test for debuging ftp,error!!!\n", __FUNCTION__, __LINE__);

+				list_del((struct list_head* )pos_list);

+			}

+		} 

+		else {

+			LYDBGLOG("[%s-%d] +ftplogin: Device logged in before !!!\n", __FUNCTION__, __LINE__);

+		}

+

+		ftp_mag_ret->ftp_action(&pos_list->data);

+	}

+}

+

+

+int ftp_act_handler(thread_pool_t *pool)

+{

+	FTP_LIST_LINK_S* tmp_list = (FTP_LIST_LINK_S *)ftp_slider;

+	struct list_head* slider = NULL;

+	FTP_LIST_LINK_S* tmp = NULL;

+	if(tmp == NULL)

+	{

+		tmp = (FTP_LIST_LINK_S*)malloc(sizeof(FTP_LIST_LINK_S));

+		if(tmp == NULL)

+		{

+			LYVERBLOG("+[thhandle]: error num = %d\n", ERR_MALLOCVALID);

+			return ERR_MALLOCVALID;

+		}

+	}

+	memset(tmp, 0, sizeof(FTP_LIST_LINK_S));

+	LYDBGLOG("[%s-%d] ftp_cmd.id = %d\n", __FUNCTION__, __LINE__, ftp_cmd.id);

+

+	switch(ftp_cmd.id)

+	{

+		case FTP_LOGIN_ID:

+		case FTP_GET_ID:

+		case FTP_UP_ID:

+		case FTP_QUIT_ID:

+		case FTP_LS_ID:

+		case FTP_CD_ID:

+		case FTP_MKDIR_ID:

+		case FTP_RMD_ID:

+		case FTP_DELETE_ID:

+			if (tmp_list == NULL ) {

+				LYDBGLOG("[%s-%d] first time\n", __FUNCTION__, __LINE__);

+				tmp->data = ftp_cmd;

+				tmp->data.add_thread = 1;

+				list_add_tail(&tmp->list, &lynq_ftp_list);

+					

+				ftp_list_locate();

+				if (!threadpool_add(pool, ftp_handler, (void *)ftp_slider)) {

+					LYDBGLOG("add error!!!\n");

+					LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);

+					return ERR_INVOKE;

+				}

+			}

+			else {

+				LYDBGLOG("[%s-%d] change ftp_cmd.file_type = %s \n",__func__, __LINE__, ftp_cmd.file_type);

+				LYDBGLOG("[%s-%d] change ftp_cmd.is_pasv_mode = %s \n",__func__, __LINE__, ftp_cmd.is_pasv_mode);

+				LYDBGLOG("[%s-%d] tmp_list->data.control_sockfd = %d \n", __FUNCTION__, __LINE__, tmp_list->data.control_sockfd);

+

+				//	Save sockfd. If you don't save it, it will be overridden to 0, resulting in unable to connect

+				ftp_cmd.control_sockfd = tmp_list->data.control_sockfd;

+				tmp_list->data = ftp_cmd;

+				tmp_list->data.modify_thread = 1;

+			}

+

+			break;

+		default:

+			LYDBGLOG("[%s-%d] cmd error \n", __FUNCTION__, __LINE__);

+			LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+

+			if (tmp != NULL)

+				free(tmp);

+			return ERR_CMDVALID;

+	}

+

+	tmp = NULL;

+	return NO_ERROR;

+}

+

+

+FTP_MAG_S *ftp_manager_proc(const char *action)

+{

+    int type_num = sizeof(ftp_manager) / sizeof(FTP_MAG_S);

+    int i = 0;

+    for (i = 0; i < type_num; i++)

+    {

+        if (0 == strcmp(ftp_manager[i].action, action))

+        {

+			//LYDBGLOG("[%s-%d] action is ftp %s\n",  __FUNCTION__, __LINE__, ftp_manager[i].action);//rita add @2021.07.19 for debug description

+            return &ftp_manager[i];

+        }

+    }

+	//LYDBGLOG("[%s-%d] error action %s\n", __FUNCTION__, __LINE__, action);

+	return NULL;

+}

+

+

+int ftp_param_verification(char result[][BUF_SIZE] , int line)

+{

+

+	for (int i = 0; i < line; i++) {

+	        LYDBGLOG("[%s-%d]=======>rita,str[%d] = %s \n", __FUNCTION__, __LINE__, i, result[i]);

+	}

+

+	if (line < 3) {

+		LYDBGLOG("[%s-%d] command error\n", __FUNCTION__, __LINE__);

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+		return ERR_CMDVALID;

+	}

+

+

+	memcpy(ftp_cmd.protocol, result[0], sizeof(ftp_cmd.protocol));//rita add @2021.07.19 for protocol type mismatch

+

+	if(!atoi(result[2])) {

+		LYDBGLOG("[%s %d] session error\n", __FUNCTION__, __LINE__);

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_SESSIONVALID);

+		return ERR_SESSIONVALID;

+	}

+	ftp_cmd.session = atoi(result[2]);

+	memcpy(ftp_cmd.action, result[1], sizeof(ftp_cmd.action));//rita add @2021.07.19 for action type mismatch

+	strcpy(ftp_cmd.sevname, result[3]);

+

+	ftp_cmd.portnum = atoi(result[4]);

+	strcpy(ftp_cmd.username, result[5]);

+	strcpy(ftp_cmd.pw, result[6]);

+	

+	//LYDBGLOG("[%s-%d] sevname=%s, portnum=%d, username=%s,pw=%s \n", __FUNCTION__, __LINE__, ftp_cmd.sevname, ftp_cmd.portnum, ftp_cmd.username, ftp_cmd.pw);

+

+	ftp_mag_ret = ftp_manager_proc(ftp_cmd.action);	

+

+	

+	ftp_cmd.id = ftp_mag_ret->id;

+

+	LYDBGLOG("[%s-%d] ftp_cmd.id = %d\n", __FUNCTION__, __LINE__, ftp_cmd.id);

+

+	switch (ftp_mag_ret->id)

+	{

+		case FTP_LOGIN_ID:

+			if(line != 7)

+			{

+				LYDBGLOG("[%s-%d] command error\n", __FUNCTION__, __LINE__);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+				return ERR_CMDVALID;

+			}

+			break;

+			

+		case FTP_GET_ID:

+			if(line != 12)

+			{

+				LYDBGLOG("[%s-%d] command error\n", __FUNCTION__, __LINE__);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+				return ERR_CMDVALID;

+			}			

+			strcpy(ftp_cmd.getfilename_path, result[9]);

+			strcpy(ftp_cmd.getfilename, result[10]);

+		case FTP_UP_ID:

+			if (line != 12) {

+				LYDBGLOG("[%s-%d] command error id = %d\n", __FUNCTION__, __LINE__, ftp_mag_ret->id);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+				return ERR_CMDVALID;

+			}

+			strcpy(ftp_cmd.file_type, result[7]);

+			strcpy(ftp_cmd.is_pasv_mode, result[8]);

+			strcpy(ftp_cmd.put_opt , result[11]);

+

+			if (ftp_mag_ret->id == FTP_UP_ID) {

+				strcpy(ftp_cmd.putfilename_path, result[9]);

+				strcpy(ftp_cmd.putfilename, result[10]);

+			}

+			break;

+

+		case FTP_QUIT_ID:

+			if (line < 8) {

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);				

+				return ERR_CMDVALID;

+			}

+			break;

+

+		case FTP_LS_ID:

+			if (line !=9) {

+				LYDBGLOG("[%s-%d] command error id = %d\n", __FUNCTION__, __LINE__, ftp_mag_ret->id);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+				return ERR_CMDVALID;

+			}

+

+			strcpy(ftp_cmd.dir, result[8]);//rita add @2021.7.19 for ls bug

+			strcpy(ftp_cmd.is_pasv_mode, result[7]);

+			break;

+		case FTP_CD_ID:

+		case FTP_MKDIR_ID:

+		case FTP_RMD_ID:

+		case FTP_DELETE_ID:

+			if (line != 8) {

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+				return ERR_CMDVALID;

+			}

+			strcpy(ftp_cmd.del_mkr_filename, result[7]);

+			//strcpy(ftp_cmd.is_pasv_mode, result[7]);

+			break;

+

+		default:

+			LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+			break;

+			

+	}

+

+	return NO_ERROR;

+

+}

+

+

+int ftp_list_locate()

+{

+	struct list_head* slider = NULL;

+	ftp_slider = NULL;

+	list_for_each(slider, &lynq_ftp_list) {

+		ftp_slider = (FTP_LIST_LINK_S*)slider;

+		LYDBGLOG("[%s-%d]  =============START====================== \n", __func__, __LINE__);

+		LYDBGLOG("[%s-%d]  protocol : %s \n", __FUNCTION__, __LINE__, ftp_slider->data.protocol);

+		LYDBGLOG("[%s-%d]  session : %d \n", __FUNCTION__, __LINE__, ftp_slider->data.session);

+		LYDBGLOG("[%s-%d]  action : %s \n", __FUNCTION__, __LINE__, ftp_slider->data.action);

+		LYDBGLOG("[%s-%d]  port : %d \n", __FUNCTION__, __LINE__, ftp_slider->data.portnum);

+		LYDBGLOG("[%s-%d]  sevname : %s \n", __FUNCTION__, __LINE__, ftp_slider->data.sevname);

+		LYDBGLOG("[%s-%d]  username : %s \n", __FUNCTION__, __LINE__, ftp_slider->data.username);

+		LYDBGLOG("[%s-%d]  pw : %s \n", __FUNCTION__, __LINE__, ftp_slider->data.pw);

+		LYDBGLOG("[%s-%d]  index : %d \n", __FUNCTION__, __LINE__, ftp_slider->data.index);

+		LYDBGLOG("[%s-%d]  ==============END===================== \n", __func__, __LINE__);

+

+		if (!strcmp(ftp_slider->data.protocol, ftp_cmd.protocol) && ftp_slider->data.session == ftp_cmd.session) {

+			//LYDBGLOG("[%s-%d] Node found\n", __FUNCTION__, __LINE__);

+			if (strcmp(ftp_slider->data.sevname, ftp_cmd.sevname) != 0 || strcmp(ftp_slider->data.username, ftp_cmd.username) != 0 || strcmp(ftp_slider->data.pw, ftp_cmd.pw) != 0 || ftp_slider->data.portnum != ftp_cmd.portnum) {

+				LYDBGLOG("[%s-%d] sevname  error\n", __FUNCTION__, __LINE__);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+				return ERR_CMDVALID;

+			}	

+			LYDBGLOG("[%s-%d]=======> Node found\n", __FUNCTION__, __LINE__);

+			return NO_ERROR;

+		}		

+	}

+	ftp_slider = NULL;

+

+	LYDBGLOG("[%s-%d] Not found\n", __FUNCTION__, __LINE__);

+	return NO_ERROR;

+}

+

+

+void ftp_list_init()

+{

+	if (ftp_init == 0) {

+		INIT_LIST_HEAD(&lynq_ftp_list);

+		ftp_init = 1;

+	}

+

+}

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/http_manager.c b/src/lynq/packages/apps/lynq-threadhandle/src/http_manager.c
new file mode 100644
index 0000000..259b10c
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/http_manager.c
@@ -0,0 +1,359 @@
+#include "http_manager.h"

+#include <unistd.h>

+#include <stdio.h>

+#include <string.h>

+

+static struct list_head http_list;

+static HTTP_LIST_LINK_S* http_slider;

+static lynq_http_client_t http_cmd = {0};

+

+

+void *http_handler(void * list)

+{

+	int error_code = 0;

+	HTTP_LIST_LINK_S* pos_list  = (HTTP_LIST_LINK_S *)list;

+	

+	while(1)

+	{

+		if (pos_list->data.modify_thread != 1 && pos_list->data.add_thread != 1)

+			continue;

+		

+		pos_list->data.add_thread = 0;

+		pos_list->data.modify_thread = 0;

+

+		if (!strcmp(pos_list->data.action, "init")) {}

+		else if (!strcmp(pos_list->data.action, "send")) {}

+		else if (!strcmp(pos_list->data.action, "get")) {

+			lynq_http_init();

+			lynq_http_client_t * http_data = lynq_http_new();

+			

+			http_data->session = pos_list->data.session;

+			memcpy(http_data->action, pos_list->data.action, sizeof(http_data->action));//rita add @2021.7.19 for action type mismatch

+			lynq_http_sync_request(http_data , pos_list->data.url, M_GET, M_CLOSE);	

+			

+			error_code = lynq_http_get_error_code(http_data);

+			if(error_code!=0){

+				LYDBGLOG("[%s-%d] get error!!!\n", __FUNCTION__, __LINE__);//rita add @2021.7.19 for debuging error

+				LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http_data->action, http_data->session, error_code);

+			}

+			

+			if (pos_list->data.url)

+				free(pos_list->data.url);

+

+			if (pos_list->data.post_data)

+				free(pos_list->data.post_data);

+

+			list_del((struct list_head* )pos_list);

+			return NULL;

+		}

+

+		else if (!strcmp(pos_list->data.action, "getfile")) {//rita add @2021.7.19 for http get

+			lynq_http_init();

+			lynq_http_client_t * http_data = lynq_http_new();

+			

+			http_data->session = pos_list->data.session;

+			memcpy(http_data->action, pos_list->data.action, sizeof(http_data->action));

+			lynq_http_sync_download_file(http_data, pos_list->data.url, "",M_GET, M_CLOSE);

+

+			error_code = lynq_http_get_error_code(http_data);

+			if(error_code!=0){

+				LYDBGLOG("[%s-%d] get file error!!!\n", __FUNCTION__, __LINE__);//rita add @2021.7.19 for debuging error

+				LYVERBLOG("[http][%s][session%d]: error num = %d\n", http_data->action, http_data->session, error_code);

+			}

+			

+			if (pos_list->data.url) {

+				free(pos_list->data.url);

+			}

+

+			if (pos_list->data.post_data) {

+				free(pos_list->data.post_data);

+			}

+

+			list_del((struct list_head* )pos_list);

+			return NULL;

+		}

+		else if (!strcmp(pos_list->data.action, "post")) {

+			lynq_http_init();

+			lynq_http_client_t * http_data = lynq_http_new();

+

+			http_data->session = pos_list->data.session;

+			memcpy(http_data->action, pos_list->data.action, sizeof(http_data->action));

+			lynq_http_sync_post_request(http_data , pos_list->data.url, pos_list->data.post_data, M_POST, M_CLOSE);

+

+			error_code = lynq_http_get_error_code(http_data);

+			if(error_code!=0){

+				LYDBGLOG("[%s-%d] post error!!!\n", __FUNCTION__, __LINE__);//rita add @2021.7.19 for debuging error

+				LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http_data->action, http_data->session, error_code);

+			}

+			if (pos_list->data.url) {

+				free(pos_list->data.url);

+			}

+			

+			if (pos_list->data.post_data) {

+				free(pos_list->data.post_data);

+			}

+			

+			list_del((struct list_head* )pos_list);

+			return NULL;

+		}

+

+		else if (!strcmp(pos_list->data.action, "lpost")) {

+			lynq_http_init();

+			lynq_http_client_t *http_data = lynq_http_new();

+			

+			memcpy(http_data->action, pos_list->data.action, sizeof(http_data->action));

+			memcpy(http_data->protocol, pos_list->data.protocol, sizeof(http_data->protocol));

+			http_data->session = pos_list->data.session;

+

+			if (pos_list->data.index != 1) {

+				http_data->index = 1;

+				lynq_http_sync_post_request(http_data , pos_list->data.url, pos_list->data.post_data, M_POST, M_KEEP);

+			}

+			else {

+				http_data->fd = pos_list->data.fd;

+				http_data->url = pos_list->data.url;

+				http_data->post_data = pos_list->data.post_data;

+				http_data->post_data_len = pos_list->data.post_data_len;

+				http_data->method = M_POST;

+				http_data->conn_method= M_KEEP;

+

+				if( http_parser_parse_url(http_data->url, strlen(http_data->url), 0, &http_data->u) != 0 )

+				{

+					//printf("[%s-%d] \n", __FUNCTION__, __LINE__);

+					LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);

+					return NULL;

+				}

+				

+				lynq_http_write_head_data(http_data);

+			}

+

+			error_code = lynq_http_get_error_code(http_data);

+			if(error_code != 0) {

+				LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http_data->action, http_data->session, error_code);

+				if (pos_list->data.url)

+					free(pos_list->data.url);

+				

+				if (pos_list->data.post_data)

+					free(pos_list->data.post_data);

+				

+				list_del((struct list_head* )pos_list);

+				return NULL;

+			}

+

+			memcpy(&pos_list->data, http_data, sizeof(lynq_http_client_t));

+			pos_list->data.index = 1;

+		}

+

+		else if (!strcmp(pos_list->data.action, "close")) {

+			lynq_http_client_t *http_data = lynq_http_new();

+

+			http_data->session = pos_list->data.session;

+			memcpy(http_data->action, pos_list->data.action, sizeof(http_data->action));

+			http_data->fd = pos_list->data.fd;

+			http_data->url = pos_list->data.url;

+			http_data->conn_method = M_CLOSE;

+			http_data->post_data = pos_list->data.post_data;

+

+

+			pos_list->data.index = 0;

+			if( http_parser_parse_url(http_data->url, strlen(http_data->url), 0, &http_data->u) != 0 )

+			{

+				//printf("[%s-%d]\n", __FUNCTION__, __LINE__);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);

+				return NULL;

+			}

+				

+			lynq_http_write_head_data(http_data);

+			error_code = lynq_http_get_error_code(http_data);

+			if(error_code!=0)

+				LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http_data->action, http_data->session, error_code);

+			

+			lynq_http_data_send("close");

+

+			if (pos_list->data.url)

+				free(pos_list->data.url);

+			

+			if (pos_list->data.post_data)

+				free(pos_list->data.post_data);

+			

+			list_del((struct list_head* )pos_list);

+			return NULL;

+		}

+	}

+}

+

+

+

+int http_act_handler(thread_pool_t *pool)

+{

+	HTTP_LIST_LINK_S* tmp_list = (HTTP_LIST_LINK_S *)http_slider;

+	struct list_head* slider = NULL;

+	HTTP_LIST_LINK_S* tmp = NULL;

+	if(tmp == NULL)

+	{

+		tmp = (HTTP_LIST_LINK_S*)malloc(sizeof(HTTP_LIST_LINK_S));

+		if(tmp == NULL)

+		{

+			return ERR_MALLOCVALID;

+		}

+	}

+	memset(tmp, 0, sizeof(HTTP_LIST_LINK_S));

+

+	if (tmp_list == NULL ) {

+		if(!strcmp(http_cmd.action, "init") || !strcmp(http_cmd.action, "conn") || !strcmp(http_cmd.action, "send") || !strcmp(http_cmd.action, "get") || !strcmp(http_cmd.action, "post") || !strcmp(http_cmd.action, "lpost")  || !strcmp(http_cmd.action, "getfile")) {

+			tmp->data = http_cmd;

+			if (http_cmd.url != NULL) 

+			{

+			

+				tmp->data.url = (char *)malloc(strlen(http_cmd.url)+1);

+				if (tmp->data.url == NULL)

+					return ERR_MALLOCVALID;

+

+				memset(tmp->data.url, 0x00, strlen(http_cmd.url)+1);

+				memcpy(tmp->data.url, http_cmd.url, strlen(http_cmd.url));

+			}

+

+			if (http_cmd.post_data != NULL) 

+			{

+				tmp->data.post_data = (char *)malloc(strlen(http_cmd.post_data)+1);

+				if (tmp->data.post_data == NULL)

+					return ERR_MALLOCVALID;

+

+				memset(tmp->data.post_data, 0x00, strlen(http_cmd.post_data)+1);

+				memcpy(tmp->data.post_data, http_cmd.post_data, strlen(http_cmd.post_data));

+			}

+

+			tmp->data.add_thread = 1;

+			list_add_tail(&tmp->list, &http_list);				

+			http_list_locate();

+

+			if (!threadpool_add(pool, http_handler, (void *)http_slider)) {

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);	

+				return ERR_INVOKE;

+			}

+		}

+		else	{

+			LYDBGLOG("[%s-%d] cmd error \n", __FUNCTION__, __LINE__);

+			LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+			if (tmp != NULL)

+				free(tmp);

+			return ERR_CMDVALID;

+		}

+	}

+	else {

+		if(!strcmp(http_cmd.action, "send") || !strcmp(http_cmd.action, "lpost") || !strcmp(http_cmd.action, "close")) {

+			memcpy(tmp_list->data.action, http_cmd.action, sizeof(tmp_list->data.action));

+			memcpy(tmp_list->data.post_data, http_cmd.post_data, strlen(http_cmd.post_data));

+			tmp_list->data.modify_thread = 1;

+		}		

+		else	{

+			LYDBGLOG("[%s-%d] cmd error \n", __FUNCTION__, __LINE__);

+			LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+			return ERR_CMDVALID;

+		}

+	}

+

+	tmp = NULL;

+	return NO_ERROR;

+}

+

+

+

+int http_param_verification(char result[][BUF_SIZE] , int line)

+{

+	if (line < 3) {

+		LYDBGLOG("[%s-%d] command error\n", __FUNCTION__, __LINE__);

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+		return ERR_CMDVALID;

+	}

+

+	http_cmd.url = NULL;

+	http_cmd.post_data = NULL;

+	memcpy(http_cmd.protocol, result[0], sizeof(http_cmd.protocol));

+

+	if(!atoi(result[2])) { //session

+		LYDBGLOG("[%s-%d] session error\n", __FUNCTION__, __LINE__);

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_SESSIONVALID);

+		return ERR_SESSIONVALID;

+	}

+	

+	http_cmd.session = atoi(result[2]); 

+	memcpy(http_cmd.action, result[1], sizeof(http_cmd.action));

+

+	if (!(strcmp(result[1], "post"))) {

+		http_cmd.url = result[3];

+		http_cmd.post_data = result[4];

+	}

+

+	else if (!(strcmp(result[1], "lpost"))) {

+		http_cmd.url = result[3];

+		http_cmd.post_data = result[4];

+	}

+

+	else if (!(strcmp(result[1], "get"))) {

+		strcat(result[3], result[4]);

+		http_cmd.url = result[3];

+	}

+

+	else if (!(strcmp(result[1], "getfile"))) {

+		http_cmd.url = result[3];

+		strcat(http_cmd.url, result[4]);//path

+

+	}

+

+	else if (!(strcmp(result[1], "close"))) {

+		http_cmd.conn_method = M_CLOSE;

+		http_cmd.post_data = "s=close";

+	}

+	else {

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+		return ERR_CMDVALID;

+	}

+	

+	return NO_ERROR;

+}

+

+

+int http_list_locate()

+{

+	struct list_head* slider = NULL;

+	http_slider = NULL;

+	list_for_each(slider, &http_list) 

+	{

+		http_slider = (HTTP_LIST_LINK_S*)slider;

+#if 0

+		LYDBGLOG("[%s-%d] =================================== \n", __func__, __LINE__);

+		LYDBGLOG("[%s-%d] protocol : %s \n", __FUNCTION__, __LINE__, http_slider->data.protocol);

+		LYDBGLOG("[%s-%d] session : %d \n", __FUNCTION__, __LINE__, http_slider->data.session);

+		LYDBGLOG("[%s-%d] action : %s \n", __FUNCTION__, __LINE__, http_slider->data.action);

+		LYDBGLOG("[%s-%d] index : %d \n", __FUNCTION__, __LINE__, http_slider->data.index);

+		LYDBGLOG("[%s-%d] =================================== \n", __func__, __LINE__);

+#endif

+

+		if (!strcmp(http_slider->data.protocol, http_cmd.protocol) && http_slider->data.session == http_cmd.session) {

+			if (strcmp(http_cmd.action, "close") != 0) {

+				if (strcmp(http_slider->data.url, http_cmd.url) != 0) {

+					//LYDBGLOG("[%s-%d] URL error\n", __FUNCTION__, __LINE__);

+					LYVERBLOG("+[thhandle]: error num = %d\n", ERR_CMDVALID);

+					return ERR_CMDVALID;

+				}

+			}

+			return NO_ERROR;

+		}

+	}

+	http_slider = NULL;

+

+	return NO_ERROR;

+}

+

+

+static int http_init = 0;

+void http_list_init()

+{

+	if (http_init == 0) {

+		INIT_LIST_HEAD(&http_list);

+		http_init = 1;

+	}

+

+}

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/model_manager.c b/src/lynq/packages/apps/lynq-threadhandle/src/model_manager.c
new file mode 100644
index 0000000..0adb506
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/model_manager.c
@@ -0,0 +1,34 @@
+#include "model_manager.h"

+#include <unistd.h>

+#include <stdio.h>

+#include <string.h>

+

+

+

+

+MAG_LIST_S list_manager[] = {

+	{"http", http_list_init, http_param_verification, http_list_locate, http_act_handler, NULL, NULL, NULL, NULL },

+	{"ftp", ftp_list_init, ftp_param_verification, ftp_list_locate, ftp_act_handler, NULL, NULL, NULL},

+	{"mqtt", mqtt_list_init, mqtt_param_verification, mqtt_list_locate, mqtt_act_handler, NULL, NULL, NULL,NULL},

+	{"ril", ril_list_init,ril_param_verification, ril_list_locate, ril_act_handler, NULL, NULL, NULL,NULL},

+};

+

+

+MAG_LIST_S *list_manager_proc(const char *name)

+{

+	int type_num = sizeof(list_manager) / sizeof(MAG_LIST_S);

+	int i = 0;

+	for (i = 0; i < type_num; i++)

+	{

+		if (0 == strcmp(list_manager[i].name, name))

+		{

+		    LYDBGLOG("[%s-%d] recognized message type is %s\n", __FUNCTION__, __LINE__, list_manager[i].name);

+		    return &list_manager[i];

+		}

+	}

+	LYDBGLOG("[%s-%d] Unrecognized message type %s\n", __FUNCTION__, __LINE__, name);

+	

+	return NULL;

+}

+

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/mqtt_manager.c b/src/lynq/packages/apps/lynq-threadhandle/src/mqtt_manager.c
new file mode 100644
index 0000000..922a7e7
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/mqtt_manager.c
Binary files differ
diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/ril_manager.c b/src/lynq/packages/apps/lynq-threadhandle/src/ril_manager.c
new file mode 100644
index 0000000..29ea6fe
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/ril_manager.c
@@ -0,0 +1,69 @@
+#include "model_manager.h"

+#include <libtel/lib_tele.h>

+#include <libtel/lynq_call.h>

+#include <log/log.h>

+#include "common.h"

+#define P_MAX 100

+static char **ril_param= NULL;

+int eventDial(const char *addr)

+{

+    int32_t token;

+    //const char* addr = "10086";

+    char output[1024] = {0};

+    lynqCallList *msg = (lynqCallList*)malloc(sizeof(lynqCallList));
+    memset(msg,0,sizeof(lynqCallList));
+    msg->addr=(char *)malloc(sizeof(char));
+    memset(msg->addr,0,sizeof(char));
+    //printf("call start \n");

+    token = lynq_call(addr, msg);

+  //  RLOGD("[MAIN_LOG] request is %d,phone number is %s,token is %x,error is %d,call_state is %d",

+  //      msg->base.request,msg->addr,msg->base.token,msg->base.e,msg->call_state);

+ //   printf("[MAIN_LOG] request is %d,phone number is %s,token is %x,error is %d,call_state is %d",

+ //       msg->base.request,msg->addr,msg->base.token,msg->base.e,msg->call_state);

+    lynq_log_output(LOG_THREADHANDLE, LOG_DEBUG, "[MAIN_LOG] request is %d,phone number is %s,token is %x,error is %d,call_state is %d",

+        msg->base.request, msg->addr, msg->base.token, msg->base.e, msg->call_state);

+    //sprintf(output, "Factory_result  error_code:%d\n",msg->base.e);

+    //emResultNotify(output);

+    free(msg->addr);
+    msg->addr=NULL;
+    free(msg);
+    msg=NULL;

+    return 0;
+}

+void *ril_handler(void *list)

+{

+    char *addr = (char*)list;

+    printf("addr = %s\n",addr);

+    eventDial(addr);

+    return NULL;

+}

+void ril_list_init()

+{

+    return;

+}

+int ril_param_verification(char result[][BUF_SIZE] , int line)

+{

+    ril_param = result;

+    for(int i =0;i<line;i++)

+    {

+        //printf("result =%s\n",ril_param[i]);

+        lynq_log_output(LOG_THREADHANDLE, LOG_DEBUG, "result =%s\n", ril_param[i]);

+    }

+    return 0;

+}

+int  ril_list_locate()

+{

+    return 0;

+}

+int ril_act_handler(thread_pool_t *pool)

+{

+    //printf("ril_param[1] = %s\n",ril_param[1]);

+    lynq_log_output(LOG_THREADHANDLE, LOG_DEBUG, "ril_param[1] = %s\n", ril_param[1]);

+    //eventDial(ril_param[1]);

+    if (!threadpool_add(pool, ril_handler, (void *)ril_param[1])) {

+        printf("[%s-%d] error \n", __FUNCTION__, __LINE__);

+        return ERR_INVOKE;

+    }

+    return 0;

+}

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/seq_queue.c b/src/lynq/packages/apps/lynq-threadhandle/src/seq_queue.c
new file mode 100644
index 0000000..787a601
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/seq_queue.c
@@ -0,0 +1,132 @@
+#include "seq_queue.h"

+

+

+seq_queue_t *create_seq_queue(in unsigned int block_size, in unsigned int total_block, in BOOL expand) {

+

+	seq_queue_t *queue = (seq_queue_t *)malloc(sizeof(seq_queue_t));

+	if (queue) {

+

+		memset(queue, 0, sizeof(seq_queue_t));

+		queue->block_buffer = malloc(total_block * block_size);

+		if (queue->block_buffer == NULL) {

+			free(queue);

+			queue = NULL;

+		} else {

+			queue->block_size = block_size;

+			queue->total_block = total_block;

+			queue->expandabilit = expand;

+			queue->expand_blocks = EXPAND_BLOCK_NUM;

+

+			create_sem(&queue->task_queue_lock, 1);

+//			init_mutex_handle(&queue->task_queue_lock);

+		}

+	}

+

+	return queue;

+}

+

+void destroy_seq_queue(in seq_queue_t *queue) {

+

+	if (queue == NULL)

+		return ;

+

+	destroy_sem(&queue->task_queue_lock);

+//	mutex_destroy(&queue->task_queue_lock);

+	free(queue->block_buffer);

+	free(queue);

+}

+

+

+BOOL expand_seq_queue(in seq_queue_t *queue) {

+

+	void *new_buffer;

+	BOOL ret = FALSE;

+	if (queue == NULL || !queue->expandabilit)

+		return FALSE;

+

+	new_buffer = malloc((queue->total_block+queue->expand_blocks) * queue->block_size);

+	if (new_buffer) {

+		if (queue->current_block > queue->tail_block) {

+			memcpy(new_buffer, (char *)queue->block_buffer, queue->total_block * queue->block_size);

+		} else if (queue->current_block < queue->tail_block || (queue->current_block == queue->tail_block && queue->used_block != 0)) {

+			int head_block = queue->total_block - queue->tail_block;

+			int head_data_len = head_block * queue->block_size;

+			memcpy(new_buffer, (char *)queue->block_buffer + queue->tail_block * queue->block_size, head_data_len);

+			memcpy((char *)new_buffer + head_data_len, (char *)queue->block_buffer, queue->current_block * queue->block_size);

+			queue->tail_block = 0;

+			queue->current_block = head_block + queue->current_block;

+		} else if (queue->current_block == queue->tail_block){

+			queue->current_block = 0;

+			queue->tail_block = 0;

+		}

+

+		queue->total_block += queue->expand_blocks;

+

+		free(queue->block_buffer);

+		queue->block_buffer = new_buffer;

+		ret = TRUE;

+	}

+

+	return ret;

+}

+

+

+BOOL en_seq_queue(in seq_queue_t *queue, in void *data) {

+

+	if (queue == NULL || data == NULL)

+		return FALSE;

+

+	wait_sem(&queue->task_queue_lock);

+	//mutex_lock(&queue->task_queue_lock);

+	if (queue->used_block >= queue->total_block) {

+		static int times= 0;

+		times++;

+		if (!expand_seq_queue(queue)) {

+

+			return FALSE;

+		}

+	}

+

+	memcpy((char *)queue->block_buffer + queue->current_block * queue->block_size

+		, data, queue->block_size);

+	queue->current_block++;

+	queue->current_block = queue->current_block % queue->total_block;

+	queue->used_block++;

+	

+	post_sem(&queue->task_queue_lock);

+	//mutex_unlock(&queue->task_queue_lock);

+

+	return TRUE;

+}

+

+BOOL de_seq_queue(in seq_queue_t *queue, out void *data) {

+

+	BOOL ret = FALSE;

+	if (queue == NULL)

+		return FALSE;

+

+	wait_sem(&queue->task_queue_lock);

+	//mutex_lock(&queue->task_queue_lock);

+	if (queue->used_block != 0) {

+		memcpy(data, (char *)queue->block_buffer + queue->tail_block * queue->block_size

+			, queue->block_size);

+		queue->tail_block++;

+		queue->tail_block = queue->tail_block % queue->total_block;

+		queue->used_block--;

+		ret = TRUE;

+	}

+	post_sem(&queue->task_queue_lock);

+	//mutex_unlock(&queue->task_queue_lock);

+

+	return ret;

+}

+

+unsigned int get_count_seq_queue(in seq_queue_t *queue) {

+	return queue->used_block;

+}

+

+unsigned int get_size_seq_queue(in seq_queue_t *queue) {

+	return queue->total_block;

+}

+

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/syn_primitive.c b/src/lynq/packages/apps/lynq-threadhandle/src/syn_primitive.c
new file mode 100644
index 0000000..9494df7
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/syn_primitive.c
@@ -0,0 +1,65 @@
+

+#include "syn_primitive.h"

+#define SEM_VALUE_MAX 32767 

+

+int init_condition_handle(condition_handle *cond) {

+	return pthread_cond_init(cond, NULL);

+}

+

+

+int destroy_condition_handle(condition_handle *cond) {

+	return pthread_cond_destroy(cond);

+}

+

+

+int wait_condition(condition_handle *cond, mutex_handle *mutex, unsigned int wait) {

+	struct timespec wait_time;

+	if (wait == TIME_WAIT_INFINITE)

+		wait_time.tv_sec = TIME_WAIT_INFINITE;

+	else

+		wait_time.tv_sec = wait + time(0);

+	wait_time.tv_nsec = 0;

+	

+	return pthread_cond_timedwait(cond, mutex, &wait_time);

+}

+

+

+int post_condition_signal(condition_handle *cond) {

+	return pthread_cond_signal(cond);

+}

+

+

+int init_mutex_handle(mutex_handle *mutex) {

+	return pthread_mutex_init(mutex, NULL);

+}

+

+int mutex_lock(mutex_handle *mutex) {

+	return pthread_mutex_lock(mutex);

+}

+

+int mutex_unlock(mutex_handle *mutex) {

+	return pthread_mutex_unlock(mutex);

+}

+

+int mutex_destroy(mutex_handle *mutex) {

+	return pthread_mutex_destroy(mutex);

+}

+

+

+int create_sem(sem_handle *sem, int init_count) {	

+	return sem_init(sem, 0, init_count>SEM_VALUE_MAX ? SEM_VALUE_MAX:init_count );

+}

+

+

+int wait_sem(sem_handle *sem) {

+	return sem_wait(sem);

+}

+

+int post_sem(sem_handle *sem) {

+	return sem_post(sem);

+}

+

+int destroy_sem(sem_handle *sem) {

+	return sem_destroy(sem);

+}

+

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/thread_main.c b/src/lynq/packages/apps/lynq-threadhandle/src/thread_main.c
new file mode 100644
index 0000000..b7bfa97
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/thread_main.c
@@ -0,0 +1,86 @@
+#include "model_manager.h"

+#include "list.h"

+#include "thread_pool.h"

+#include "common.h"

+#include <signal.h>

+#include <stdio.h>

+#include <malloc.h>

+#include <gio/gio.h>

+#include <stdlib.h>

+#include <unistd.h> 

+#include <libtel/lib_tele.h>

+#include "liblynq-broadcast/broadcast_receiver.h"

+

+

+#define USER_LOG_TAG "THHANDLE" 

+#define MIN_THR_NUM 	10

+#define MAX_THR_NUM 	100

+

+

+

+thread_pool_t *pool = NULL;

+char cmd_buf[BUF_SIZE] = "";

+

+static void CallbackByName( char*broadcast_name, int data_length,const char*data)

+{

+    LYDBGLOG("[%s-%d] str_arg = %s, data_length = %d, int_arg = %s\n", broadcast_name, data_length, data);

+    memcpy(cmd_buf, data, strlen(data));

+

+    return;

+}

+

+void *cmd_thread_func(void* argv_list)

+{

+	int runing = 1 ;

+	int ret = NO_ERROR;

+	

+	while(runing)

+	{		

+		char result[20][BUF_SIZE] = {0};

+		while (strcmp(cmd_buf, "") == 0) {

+			usleep(100);

+		}

+		LYDBGLOG("[%s-%d]========cmd_buf = %s\n", __FUNCTION__, __LINE__, cmd_buf );

+		int line = str_arr(cmd_buf, "\"&", result)+1;

+		memset(cmd_buf, 0, sizeof(cmd_buf));

+		LYDBGLOG("[%s-%d]========result[0] = %s\n", __FUNCTION__, __LINE__, result[0] );

+		MAG_LIST_S *list_manager = list_manager_proc(result[0]);

+		if (list_manager == NULL) {

+			memset(cmd_buf, 0, sizeof(cmd_buf));

+			continue;

+		}

+

+		ret = list_manager->func_param_verification(result, line);	

+		if (ret != NO_ERROR){

+			memset(cmd_buf, 0, sizeof(cmd_buf));

+			continue;

+		}

+

+		list_manager->func_list_init();

+		ret = list_manager->func_list_locate();

+		if (ret != NO_ERROR)

+			continue;

+		list_manager->func_act_handler(pool);

+	}

+}

+

+

+int main(void)

+{

+	LYLOGEINIT(USER_LOG_TAG);    

+	LYDBGLOG("======lynq-threadhandle start=======\n");

+	pool = threadpool_create(MIN_THR_NUM, MAX_THR_NUM);

+

+	register_broadcast_loop();

+	receive_callback_by_name("function", CallbackByName);//rita add @2021.6.21 for receive dbus info

+	

+	if (!threadpool_add(pool, cmd_thread_func, NULL)) {

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);

+		return 0;

+	}

+	

+	while (1) {

+		usleep(100);

+	}

+	return 0;

+}

diff --git a/src/lynq/packages/apps/lynq-threadhandle/src/thread_pool.c b/src/lynq/packages/apps/lynq-threadhandle/src/thread_pool.c
new file mode 100644
index 0000000..50da0a9
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-threadhandle/src/thread_pool.c
@@ -0,0 +1,504 @@
+#include "thread_pool.h"

+#include <time.h>

+#include "common.h"

+

+EThread_pool_status get_threadpool_status(thread_pool_t *pool);

+void set_threadpool_status(thread_pool_t *pool, EThread_pool_status state);

+thread_info_t *create_thread_info(EThread_pool_status *pool_status);

+thread_handle pool_thread_create(THREAD_FUNC threadFun, int pri, void *para);

+BOOL init_threadpool(thread_pool_t *pool);

+thread_handle get_self_thread_id(void);

+

+#define THREAD_PRI_NOMAL_LEVEL 60

+#define THREAD_PRI_ABOVE_LEVEL 70

+#define THREAD_PRI_HIGH_LEVEL 80

+

+

+#define TASK_QUEUE_COUNT_MAX 100

+#define CONDITION_WAIT_TIME 1000

+#define INCRE_THREADS_UNIT  5

+

+

+

+thread_handle get_self_thread_id() {

+	return pthread_self();

+}

+

+void tp_sleep(unsigned int ms) {

+	struct timeval  delay;

+	

+	delay.tv_sec = ms/1000;

+	delay.tv_usec = (ms%1000) * 1000;

+	select(0, NULL, NULL, NULL, &delay);

+}

+

+

+unsigned long get_current_time(void) {

+	return time(NULL);

+}

+

+void force_exit_thread(thread_info_t *thread_info) {

+

+	int ret;

+	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

+	pthread_cancel(thread_info->h_thread);

+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

+

+	ret = destroy_condition_handle(&thread_info->thread_cond);

+	if (ret) {

+		post_condition_signal(&thread_info->thread_cond);

+		destroy_condition_handle(&thread_info->thread_cond);

+	}

+	

+	ret = mutex_destroy(&thread_info->thread_lock);

+	if (ret) {

+		mutex_unlock(&thread_info->thread_lock);

+		mutex_destroy(&thread_info->thread_lock);

+	}

+}

+

+

+int compare_thread_id(void *usr_data, unsigned int sdata_len, void *list_data, unsigned int ldata_len) {

+	if (((thread_info_t *)usr_data)->h_thread == ((thread_info_t *)list_data)->h_thread) {

+		return 0;

+	} else {

+		return -1;

+	}

+}

+

+

+static void pool_thread_work(void *para)

+{

+	int ret = 0;

+

+	thread_info_t *thread_info = (thread_info_t *)para;

+	thread_func_t *thread_func;

+

+	if (thread_info == NULL) {

+		LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);

+		return;

+	}

+

+	while (*thread_info->pool_status != EThread_pool_exit) {

+		mutex_lock(&thread_info->thread_lock);

+		while (!thread_info->busy) {

+			ret = wait_condition(&thread_info->thread_cond, &thread_info->thread_lock, TIME_WAIT_INFINITE);

+		}

+

+		mutex_unlock(&thread_info->thread_lock);

+

+		if (*thread_info->pool_status == EThread_pool_exit || thread_info->release)

+			break;

+

+		thread_func = &thread_info->thread_para;

+		thread_info->time_out = thread_func->time_out_info.time_out;

+		thread_info->launch_time = get_current_time();

+		thread_info->thread_para.process_func(thread_info->thread_para.args);

+		if (thread_info->thread_para.release_func) {

+			thread_info->thread_para.release_func(thread_info->thread_para.args);

+		}

+		thread_info->launch_time = TIME_WAIT_INFINITE;

+

+		mutex_lock(&thread_info->thread_lock);

+		thread_info->busy = FALSE;

+		mutex_unlock(&thread_info->thread_lock);

+	}

+

+	LYDBGLOG(" thread %lu exit.\n", get_self_thread_id());

+	

+	pthread_exit(0);

+}

+

+

+BOOL scan_idle_thread_from_busy(thread_pool_t *pool) {

+

+	BOOL ret = FALSE;

+	

+	d_list_t *idle_list = pool->idle_threads;

+	d_list_t *busy_list = pool->busy_threads;

+	

+	d_list_node_t *temp_node;

+	thread_info_t *info;

+	if (busy_list == NULL || idle_list == NULL) 

+		return FALSE;

+

+	while ((temp_node = get_next_node(busy_list)) != NULL)

+	{

+		if (temp_node == NULL || temp_node->data == NULL)

+			break;

+		

+		info = (thread_info_t *)temp_node->data;

+		if (!info->busy) {

+

+			if (remove_d_list_node(busy_list, temp_node)) {

+				insert_d_list_tail_node(idle_list, temp_node);

+				ret = TRUE;

+				//break;

+			}

+		} else {

+			if (info->time_out == 0 || info->launch_time == TIME_WAIT_INFINITE) {

+				continue;

+			}

+

+			if (get_current_time() - info->time_out > info->launch_time) {

+			//if (get_current_time() - info->launch_time > info->time_out) {

+				LYDBGLOG("[%s-%d] ####### time out , force exit thread.  %lu #########\n", __FUNCTION__, __LINE__, info->h_thread);

+				LYVERBLOG("+[thhandle]: error num = %d\n", ERR_TIMEOUT);

+				if (remove_d_list_node(busy_list, temp_node)) {

+					force_exit_thread(info);

+

+					if (info->thread_para.time_out_info.timeout_callback) {

+						info->thread_para.time_out_info.timeout_callback(&info->thread_para);

+					}

+

+					init_condition_handle(&info->thread_cond);

+					init_mutex_handle(&info->thread_lock);

+					

+					info->busy = FALSE;

+					info->release = FALSE;

+					info->launch_time = TIME_WAIT_INFINITE;

+					info->h_thread = pool_thread_create(pool_thread_work, info->pri, info);

+					if (info->h_thread < 0) {

+						

+						free(info);

+						free(temp_node);

+						pool->pool_thread_num--;

+					} else {

+						

+						insert_d_list_tail_node(idle_list, temp_node);

+						ret = TRUE;

+					}

+				}				

+			}

+		

+		}

+	}

+	

+	return ret;

+}

+

+

+static void pool_thread_manage(void *para)

+{

+	thread_func_t thread_para;	

+	d_list_node_t *list_node;

+	thread_info_t *thread_info;

+	thread_pool_t *pool = (thread_pool_t *)para;

+	

+	if (pool == NULL) {

+		return;

+	}

+	

+	while (get_threadpool_status(pool) != EThread_pool_exit) {

+

+		if (get_count_seq_queue(pool->task_queue) > 0) {

+	

+			pool->release_threads_interval = 0;

+

+			list_node = remove_d_list_head_node(pool->idle_threads);

+			if (list_node && list_node->data) {

+

+				memset(&thread_para, 0, sizeof(thread_func_t));

+				if (de_seq_queue(pool->task_queue, &thread_para)) {

+

+					thread_info = (thread_info_t *)list_node->data;

+					post_sem(&pool->sem_inc);

+

+					mutex_lock(&thread_info->thread_lock);

+					memcpy(&thread_info->thread_para, &thread_para, sizeof(thread_func_t));

+					thread_info->busy = TRUE;

+					post_condition_signal(&thread_info->thread_cond);

+					mutex_unlock(&thread_info->thread_lock);

+					

+					insert_d_list_tail_node(pool->busy_threads, list_node);

+

+				} else {

+

+					insert_d_list_head_node(pool->idle_threads, list_node);

+				}

+				

+

+			} else {

+				if (scan_idle_thread_from_busy(pool))

+					continue;

+

+				if (pool->pool_thread_num < pool->max_thread_num) {

+					

+					int i;

+					for (i=0; i<INCRE_THREADS_UNIT; i++) {

+						thread_info_t *thread_inf = create_thread_info(&pool->status);

+						insert_d_list_tail(pool->idle_threads, thread_inf, sizeof(thread_info_t));

+						pool->pool_thread_num++;

+					}

+					

+				} else {

+					//continue;

+				}

+			}

+

+		} else {

+			if (get_d_list_node_count(pool->busy_threads) > 0) {

+				pool->release_threads_interval = 0;

+				scan_idle_thread_from_busy(pool);

+			} else {

+				BOOL is_release_threads = FALSE;

+				if (pool->release_threads_interval == 0) {

+					pool->release_threads_interval = get_current_time();

+				} else {

+					is_release_threads = (get_current_time() - pool->release_threads_interval) > RELEASE_THREAD_INTERVAL;

+				}

+

+				if (is_release_threads && get_d_list_node_count(pool->idle_threads) > pool->min_thread_num) {

+					//

+					list_node = remove_d_list_head_node(pool->idle_threads);

+					if (list_node && list_node->data) {							

+						thread_info = (thread_info_t *)list_node->data;

+						if (!thread_info->busy) {

+							mutex_lock(&thread_info->thread_lock);

+							thread_info->release = TRUE;

+							mutex_unlock(&thread_info->thread_lock);

+							post_condition_signal(&thread_info->thread_cond);

+							pool->pool_thread_num--;

+							free(thread_info);

+							free(list_node);

+						} else {

+							insert_d_list_tail(pool->busy_threads, thread_info, sizeof(thread_info_t));

+						}

+					}

+					

+				} else {

+					mutex_lock(&pool->mange_lock);

+					wait_condition(&pool->manage_cond, &pool->mange_lock, CONDITION_WAIT_TIME);

+					mutex_unlock(&pool->mange_lock);

+				}

+			}

+

+		}

+	}

+}

+

+

+thread_handle pool_thread_create(THREAD_FUNC threadFun, int pri, void *para) {

+	

+		thread_handle h_thread;

+		pthread_attr_t attr;

+		struct sched_param p;

+

+		pthread_attr_init(&attr);

+		p.sched_priority = pri;

+		

+		pthread_attr_setschedpolicy(&attr,SCHED_OTHER);

+		pthread_attr_setschedparam(&attr,&p);

+

+		pthread_create(&h_thread, &attr, (void *)threadFun, para);

+		return h_thread;

+}

+

+void pool_thread_release(thread_handle h_thread)

+{

+	pthread_join(h_thread, NULL);

+}

+

+EThread_pool_status get_threadpool_status(thread_pool_t *pool) {

+

+	if (pool) {

+		return pool->status;

+	} else {

+		return EThread_pool_unknown;

+	}

+}

+

+void set_threadpool_status(thread_pool_t *pool, EThread_pool_status state) {

+	

+	if (pool) {

+		pool->status = state;

+	}

+}

+

+thread_pool_t *threadpool_create(unsigned int min_thread_num, unsigned int max_thread_num)

+{

+	thread_pool_t *pool = (thread_pool_t *)malloc(sizeof(thread_pool_t));

+

+	if (pool) {

+		memset(pool, 0, sizeof(thread_pool_t));

+		pool->min_thread_num = min_thread_num;

+		pool->max_thread_num = max_thread_num;

+		pool->pri = THREAD_PRI_HIGH_LEVEL;

+		pool->status = EThread_pool_alloc;

+

+		if (!init_threadpool(pool)) {

+			free(pool);

+			pool = NULL;

+		}

+	}

+

+	return pool;

+}

+

+thread_info_t *create_thread_info(EThread_pool_status *pool_status) {

+	thread_info_t *thread_inf = (thread_info_t *)malloc(sizeof(thread_info_t));

+	if (thread_inf == NULL)

+		return NULL;

+	

+	memset(thread_inf, 0, sizeof(thread_info_t));

+	

+	thread_inf->busy = FALSE;

+	thread_inf->release = FALSE;

+	thread_inf->pri = THREAD_PRI_ABOVE_LEVEL;

+	thread_inf->launch_time = TIME_WAIT_INFINITE;

+	thread_inf->pool_status = pool_status;

+

+	init_condition_handle(&thread_inf->thread_cond);

+	init_mutex_handle(&thread_inf->thread_lock);

+	

+	thread_inf->h_thread = pool_thread_create(pool_thread_work, thread_inf->pri, thread_inf);

+	if (thread_inf->h_thread < 0) {

+		destroy_condition_handle(&thread_inf->thread_cond);

+		mutex_destroy(&thread_inf->thread_lock);

+

+		free(thread_inf);

+		thread_inf = NULL;

+	}

+	

+	return thread_inf;

+}

+

+

+void destroy_thread_info(thread_info_t *thread_info) {

+	if (thread_info == NULL)

+		return;

+

+	thread_info->release = TRUE;

+	pool_thread_release(thread_info->h_thread);

+

+	destroy_condition_handle(&thread_info->thread_cond);

+	mutex_destroy(&thread_info->thread_lock);

+}

+

+BOOL init_threadpool(thread_pool_t *pool) {

+

+	unsigned int thread_num = 0;

+	if (pool == NULL)

+		return FALSE;

+

+	pool->busy_threads = create_d_list();

+	pool->idle_threads = create_d_list();

+	pool->task_queue = create_seq_queue(sizeof(thread_func_t), TASK_QUEUE_COUNT_MAX, TRUE);

+	if (pool->busy_threads == NULL || pool->idle_threads == NULL || pool->task_queue == NULL)

+		goto err_flag;

+

+	for (thread_num=0; thread_num<pool->min_thread_num; thread_num++) {

+		thread_info_t *thread_inf = create_thread_info(&pool->status);

+

+		if (!insert_d_list_tail(pool->idle_threads, thread_inf, sizeof(thread_info_t)))

+			goto err_flag;

+		

+	}

+

+	create_sem(&pool->sem_inc, TASK_QUEUE_COUNT_MAX);

+	init_condition_handle(&pool->manage_cond);

+	init_mutex_handle(&pool->mange_lock);

+	pool->h_id = pool_thread_create(pool_thread_manage, pool->pri, pool);

+

+	pool->status = EThread_pool_init;

+	pool->pool_thread_num = pool->min_thread_num;

+

+	return TRUE;

+

+

+err_flag:

+	LYDBGLOG("[%s-%d]##################### err ################\n", __FUNCTION__, __LINE__);

+	LYVERBLOG("+[thhandle]: error num = %d\n", ERR_INVOKE);

+	threadpool_destroy(pool);

+

+	return FALSE;

+}

+

+void threadpool_destroy(thread_pool_t *pool)

+{

+	d_list_node_t *temp_node;

+	if (pool == NULL)

+		return;

+

+	set_threadpool_status(pool, EThread_pool_exit);

+

+	destroy_sem(&pool->sem_inc);

+	mutex_lock(&pool->mange_lock);

+	post_condition_signal(&pool->manage_cond);

+	mutex_unlock(&pool->mange_lock);

+	pool_thread_release(pool->h_id);

+

+	mutex_destroy(&pool->mange_lock);

+	destroy_condition_handle(&pool->manage_cond);

+

+	while ((temp_node = remove_d_list_head_node(pool->idle_threads))) {

+		thread_info_t *info = (thread_info_t *)temp_node->data;

+		post_condition_signal(&info->thread_cond);

+		destroy_thread_info(info);

+		free(info);

+		free(temp_node);

+	}

+

+	while ((temp_node = remove_d_list_head_node(pool->busy_threads))) {

+		thread_info_t *info = (thread_info_t *)temp_node->data;

+		post_condition_signal(&info->thread_cond);

+		destroy_thread_info(info);

+		free(info);

+		free(temp_node);

+	}

+	

+	destroy_d_list(pool->busy_threads);

+	destroy_d_list(pool->idle_threads);

+	destroy_seq_queue(pool->task_queue);

+

+	free(pool);

+}

+

+BOOL threadpool_add(thread_pool_t *pool, USER_FUNC process_func, void *args)

+{

+	BOOL ret = FALSE;

+	thread_func_t function;

+	

+	if (pool == NULL)

+		return FALSE;

+	

+	memset(&function, 0, sizeof(thread_func_t));

+	function.process_func = process_func;

+	function.args = args;

+

+	wait_sem(&pool->sem_inc);

+	ret = en_seq_queue(pool->task_queue, &function);

+

+	mutex_lock(&pool->mange_lock);

+	post_condition_signal(&pool->manage_cond);

+	mutex_unlock(&pool->mange_lock);

+	

+	return ret;

+}

+

+BOOL threadpool_add_timeout(thread_pool_t *pool, USER_FUNC process_func

+		, USER_FUNC release_func, void *args, time_out_t *time_out)

+{

+	BOOL ret = FALSE;

+	thread_func_t function;

+	

+	if (pool == NULL)

+		return FALSE;

+	

+	memset(&function, 0, sizeof(thread_func_t));

+	function.process_func = process_func;

+	function.release_func = release_func;

+	function.args = args;

+	memcpy(&function.time_out_info, time_out, sizeof(time_out_t));

+	

+	wait_sem(&pool->sem_inc);

+	ret = en_seq_queue(pool->task_queue, &function);

+

+	mutex_lock(&pool->mange_lock);

+	post_condition_signal(&pool->manage_cond);

+	mutex_unlock(&pool->mange_lock);

+	

+	return ret;

+}

+

+