[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;
+}
+
+