led server for v2

Change-Id: I08244310bd94a42fd736d0acc80ba0a5ac5cef93
diff --git a/mbtk/Make.defines b/mbtk/Make.defines
index 7e2ded7..e7bd90a 100755
--- a/mbtk/Make.defines
+++ b/mbtk/Make.defines
@@ -74,6 +74,9 @@
 

 DEFINE += -DMBTK_ALL_CID_SUPPORT

 

+#LED DEF_OPEN

+DEFINE += -DMBTK_LED

+

 ifeq ($(MBTK_SOURCE_VERSION), 2)
 DEFINE += -DMBTK_SOURCE_VERSION_2

 endif

diff --git a/mbtk/include/mbtk/mbtk_led_control.h b/mbtk/include/mbtk/mbtk_led_control.h
new file mode 100755
index 0000000..7ffe279
--- /dev/null
+++ b/mbtk/include/mbtk/mbtk_led_control.h
@@ -0,0 +1,29 @@
+#ifndef __MBTK_LED_CONTROL_H__
+#define __MBTK_LED_CONTROL_H__
+
+typedef enum
+{
+    MBTK_LED_STATUS_CLOSE = 0,	/*close status_led*/
+    MBTK_LED_STATUS_OPEN  = 1,	/*open status_led*/
+}mbtk_led_status_type;
+
+typedef enum
+{
+    MBTK_LED_STATUS = 0,	/*status_led*/
+    MBTK_LED_NET    = 1,	/*net_led*/
+	
+	MBTK_LED_MUM
+}mbtk_led_all;
+
+typedef struct
+{
+	int led_type;
+    int status;
+}led_info_s;
+
+
+int mbtk_led_set(led_info_s led_info);
+
+#endif
+
+
diff --git a/mbtk/libmbtk_lib/Makefile b/mbtk/libmbtk_lib/Makefile
index eba855b..abb76bc 100755
--- a/mbtk/libmbtk_lib/Makefile
+++ b/mbtk/libmbtk_lib/Makefile
@@ -79,6 +79,7 @@
 	common/mbtk_version.c \
 	common/mbtk_gpio.c \
 	common/mbtk_adc.c \
+	common/mbtk_led_control.c \
 	common/mbtk_loopbuff.c
 
 # audio
diff --git a/mbtk/libmbtk_lib/common/mbtk_led_control.c b/mbtk/libmbtk_lib/common/mbtk_led_control.c
new file mode 100755
index 0000000..0161a3f
--- /dev/null
+++ b/mbtk/libmbtk_lib/common/mbtk_led_control.c
@@ -0,0 +1,94 @@
+#if 1
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>  
+#include <fcntl.h> 
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <sys/epoll.h>
+#include <time.h>
+#include <arpa/inet.h>
+
+#include "mbtk_log.h"
+#include "mbtk_utils.h"
+#include "mbtk_led_control.h"
+
+
+#define LED_SOCK_PATH  "/tmp/mbtk_led_sock"
+
+static int led_cli_fd = -1;
+
+int mbtk_led_contril_init()
+{
+    if(led_cli_fd > 0) {
+        LOGW("led_contril client has inited.");
+        return 0;
+    }
+
+    led_cli_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+    if(led_cli_fd < 0)
+    {
+        LOGE("socket() fail[%d].", errno);
+        goto error;
+    }
+
+    struct sockaddr_un cli_addr;
+    memset(&cli_addr, 0, sizeof(cli_addr));
+    cli_addr.sun_family = AF_LOCAL;
+    strcpy(cli_addr.sun_path, LED_SOCK_PATH);
+    if(connect(led_cli_fd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)))
+    {
+        LOGE("connect() fail[%d].", errno);
+        goto error;
+    }
+
+    return 0;
+error:
+    if(led_cli_fd > 0) {
+        close(led_cli_fd);
+        led_cli_fd = -1;
+    }
+
+    return -1;
+}
+
+int mbtk_led_send(char *data)
+{  
+    int ret = mbtk_led_contril_init();
+    if (ret == -1)
+    {
+        LOGE("mbtk_led_contril_init error");
+        return -1;
+    }
+    //LOGI("data %s",data);
+    mbtk_write(led_cli_fd, data, strlen(data)+1);
+
+    return 0;
+}
+
+int mbtk_led_set(led_info_s led_info)
+{
+    char resp_buf[4];
+    int type,status,ret;
+    
+    memset(resp_buf,0,4);
+    type = led_info.led_type;
+    status = led_info.status;
+    sprintf(resp_buf, "%d,%d",type,status);
+    ret = mbtk_led_send(resp_buf);
+    if (ret)
+    {
+        LOGE("[led]mbtk_led_set error");
+    }
+
+    return ret;
+}
+
+#endif
+
+
diff --git a/mbtk/mbtk_servicesd_v2/inc/mbtk_led.h b/mbtk/mbtk_servicesd_v2/inc/mbtk_led.h
index 244805c..7bcecdb 100755
--- a/mbtk/mbtk_servicesd_v2/inc/mbtk_led.h
+++ b/mbtk/mbtk_servicesd_v2/inc/mbtk_led.h
@@ -27,6 +27,10 @@
 
 int mbtk_led_init(void);
 
+int mbtk_led_contril_server_init(void);
+
+int mbtk_status_led_control_get();
+
 #endif
 
 
diff --git a/mbtk/mbtk_servicesd_v2/src/led_control_service.c b/mbtk/mbtk_servicesd_v2/src/led_control_service.c
index 9f87cf5..7cd144b 100755
--- a/mbtk/mbtk_servicesd_v2/src/led_control_service.c
+++ b/mbtk/mbtk_servicesd_v2/src/led_control_service.c
@@ -7,9 +7,18 @@
 #include <string.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <sys/epoll.h>
+#include <time.h>
+#include <arpa/inet.h>
 
 #include "mbtk_led.h"
 #include "mbtk_log.h"
+#include "mbtk_ril_api.h"
 
 /****************************DEFINE***************************************/
 #define MBTK_RESULT_FAIL   -1
@@ -17,6 +26,9 @@
 
 #define MBTK_NET_LED 99
 #define MBTK_STATUS_LED 8
+
+#define LED_SOCK_PATH  "/tmp/mbtk_led_sock"
+
 /****************************DEFINE***************************************/
 
 /****************************VARIABLE***************************************/
@@ -25,9 +37,399 @@
 static mbtk_status_led_type mbtk_status_led_state = MBTK_STATUS_LED_CLOSE;
 
 static int MBTK_NET_LED_LOCK_SET = 0;
+static int led_server_fd = -1;
+static int sock_cli_fds[2];
+
 /****************************VARIABLE***************************************/
 
 /******************************FUNC*****************************************/
+static int led_cli_fd_find(int fd)
+{
+    int i = 0;
+    while(i < 2) {
+        if(fd == sock_cli_fds[i])
+            return i;
+        i++;
+    }
+
+    return -1;
+}
+
+int mbtk_led_grcv(char *data)
+{
+    int led_type,led_statue;
+
+    //LOGI("[led]type and statue data >>%s",data);
+    led_type = (int)((data[0]) - '0');
+    led_statue = (int)((data[2]) - '0');
+    //LOGI("[led]>>[type=%d] [statue=%d]",led_type, led_statue);
+    if (led_type == 0)//MBTK_STATUS_LED
+    {
+        if (led_statue == 0)
+        {
+            status_led_set(MBTK_STATUS_LED_CLOSE);
+        }
+        else if (led_statue == 1)
+        {
+            status_led_set(MBTK_STATUS_LED_OPEN);
+        }
+        else
+        {
+            LOGE("[led]led_statue error(%d)",led_statue);
+            return MBTK_RESULT_FAIL;
+        }
+    }
+    else if (led_type == 1)//MBTK_NET_LED
+    {
+        if (led_statue == 0)
+        {
+            mbtk_net_led_set(MBTK_NET_LED_CLOSE);
+        }
+        else if (led_statue == 1)
+        {
+            mbtk_net_led_set(MBTK_NET_LED_OPEN);
+        }
+        else
+        {
+            LOGE("[led]led_statue error(%d)",led_statue);
+            return MBTK_RESULT_FAIL;
+        }
+    }
+    else
+    {
+        LOGE("[led]led_type error(%d)",led_type);
+        return MBTK_RESULT_FAIL;
+    }
+
+    return MBTK_RESULT_SUCCESS;    
+}
+
+static void* led_control_thread_run()
+{
+    int i,numEvents;
+    
+    int epoll_fd = epoll_create(2);
+    if(epoll_fd < 0)
+    {
+        LOGE("epoll_create() fail[%d].", errno);
+        return NULL;
+    }
+
+    uint32 event = EPOLLIN | EPOLLET;
+    struct epoll_event ev_cli;
+    ev_cli.data.fd = led_server_fd;
+    ev_cli.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
+    epoll_ctl(epoll_fd,EPOLL_CTL_ADD,led_server_fd,&ev_cli);
+
+    struct epoll_event events[2];
+
+    while (1)
+    {
+        numEvents = epoll_wait(epoll_fd, events, 2, -1);
+
+        for (i = 0; i < numEvents; ++i)
+        {
+            if (events[i].events & EPOLLHUP)
+            {
+                int index = led_cli_fd_find(events[i].data.fd);
+                if(index != -1)
+                {
+                    memset(&ev_cli,0,sizeof(struct epoll_event));
+                    ev_cli.data.fd = events[i].data.fd;
+                    ev_cli.events = EPOLLIN | EPOLLERR | EPOLLET;
+                    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, &ev_cli);
+                
+                    close(events[i].data.fd);
+                    sock_cli_fds[index] = -1;
+                }
+                else
+                {
+                    LOGE("Unknown client[fd = %d].", events[i].data.fd);
+                }
+            }
+            else if (events[i].events & EPOLLIN)
+            {
+                if (events[i].data.fd == led_server_fd)
+                {
+                    int client_fd = -1;
+                     while(1)
+                     {
+                         struct sockaddr_un cliaddr;                                               
+                         socklen_t clilen = sizeof(cliaddr);
+                         client_fd = accept(events[i].data.fd, (struct sockaddr *) &cliaddr, &clilen);
+                         if(client_fd <= 0)
+                         {
+                             if(errno == EAGAIN)
+                             {
+                                 LOGE("All client connect get.");
+                             }
+                             else
+                             {
+                                 LOGE("accept() error[%d].", errno);
+                             }
+                             break;
+                         } else {
+                            i = 0;
+                             while(i < 2) {
+                                 if(sock_cli_fds[i] <= 0) {
+                                     sock_cli_fds[i] = client_fd;
+                                     break;
+                                 }
+                                 i++;
+                             }
+                    
+                             if(i >= 2) {
+                                 LOGE("Client is full.");
+                                 break;
+                             }
+                         }
+                         // Set O_NONBLOCK
+                         int flags = fcntl(client_fd, F_GETFL, 0);
+                         if (flags > 0)
+                         {
+                             flags |= O_NONBLOCK;
+                             if (fcntl(client_fd, F_SETFL, flags) < 0)
+                             {
+                                 LOGE("Set flags error:%d", errno);
+                             }
+                         }
+                    
+                         memset(&ev_cli,0,sizeof(struct epoll_event));
+                         ev_cli.data.fd = client_fd;
+                         ev_cli.events = event;//EPOLLIN | EPOLLERR | EPOLLET;
+                         epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev_cli);
+                     }
+                     
+                }
+                else if (events[i].data.fd > 0) // data grcv
+                {
+                    char buff[8];
+                    memset(buff, 0, strlen(buff));
+                    int len = read(events[i].data.fd, buff, 8);
+                    if(len > 0) {
+                        mbtk_led_grcv(buff);
+                    }
+                }
+                else
+                {
+                    LOGE("Unknown events[i].data.fd = %d", events[i].data.fd);
+                }
+            }
+            else
+            {
+                LOGW("Unknown event : %x", events[i].events);
+            }
+       }
+    }
+    return NULL;
+
+}
+
+int mbtk_led_contril_server_init()
+{
+    if(led_server_fd > 0) {
+        LOGW("LED Server has inited.");
+        return MBTK_RESULT_SUCCESS;
+    }
+
+    led_server_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+    if(led_server_fd < 0)
+    {
+        LOGE("socket() fail[%d].", errno);
+        goto error;
+    }
+
+    // Set O_NONBLOCK
+    int flags = fcntl(led_server_fd, F_GETFL, 0);
+    if (flags < 0)
+    {
+        LOGE("Get flags error:%d", errno);
+        goto error;
+    }
+    flags |= O_NONBLOCK;
+    if (fcntl(led_server_fd, F_SETFL, flags) < 0)
+    {
+        LOGE("Set flags error:%d", errno);
+        goto error;
+    }
+
+    struct sockaddr_un sever_addr;
+
+    unlink(LED_SOCK_PATH);
+
+    memset(&sever_addr, 0, sizeof(sever_addr));
+    sever_addr.sun_family = AF_LOCAL;
+    strcpy(sever_addr.sun_path, LED_SOCK_PATH);
+
+    if(bind(led_server_fd, (struct sockaddr *)&sever_addr, sizeof(sever_addr)))
+    {
+        LOGE("bind() fail[%d].", errno);
+        goto error;
+    }
+
+    if(listen(led_server_fd, 2))
+    {
+        LOGE("listen() fail[%d].", errno);
+        goto error;
+    }
+    
+    pthread_attr_t thread_attr;
+    pthread_t led_control_thread_id;
+    pthread_attr_init(&thread_attr);
+    if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
+    {
+        LOGE("[led] pthread_attr_setdetachstate() fail.");
+        return MBTK_RESULT_FAIL;
+    }
+
+    if(pthread_create(&led_control_thread_id, &thread_attr, led_control_thread_run, NULL))
+    {
+        LOGE("[led] pthread_create() fail.");
+        return MBTK_RESULT_FAIL;
+    }
+
+    pthread_attr_destroy(&thread_attr);
+
+    return MBTK_RESULT_SUCCESS;
+
+error:
+    if(led_server_fd > 0) {
+        close(led_server_fd);
+        led_server_fd = -1;
+    }
+
+    return MBTK_RESULT_FAIL;
+}
+
+static void led_net_reg_state_change_cb(const void* data, int data_len)
+{
+    static bool net_led_gms_wcdma = FALSE;
+    static bool net_led_lte = FALSE;
+
+    if(data) {
+        mbtk_ril_net_reg_state_info_t *state = (mbtk_ril_net_reg_state_info_t*)data;
+        LOGD("[led]net reg state change : type - %d, tech - %d, reg_state - %d\n", state->type,
+            state->tech, state->reg_state);
+        if (state->type == MBTK_NET_REG_TYPE_DATA_GSM_WCDMA)
+        {
+            if (state->reg_state == MBTK_NET_REG_STATE_HOME)
+            {
+                net_led_gms_wcdma = TRUE;
+            }
+            else
+            {
+                net_led_gms_wcdma = FALSE;
+            }
+        }
+        else
+        {
+           if (state->reg_state == MBTK_NET_REG_STATE_HOME)
+           {
+               net_led_lte = TRUE;
+           }
+           else
+           {
+               net_led_lte = FALSE;
+           }            
+        }
+        
+        if(FALSE == net_led_gms_wcdma && FALSE == net_led_lte)
+        {
+           mbtk_net_led_set(MBTK_NET_LED_SEARCH_NETWORK);
+        }
+        else
+        {
+           mbtk_net_led_set(MBTK_NET_LED_NET_CONNECT);
+        }
+    }
+}
+
+static void led_call_state_change_cb(const void* data, int data_len)
+{
+    if(data) {
+        mbtk_ril_call_state_info_t *state = (mbtk_ril_call_state_info_t*)data;
+        LOGD("[led]call state change : call_id-%d, dir-%d, state-%d, num_type-%d,number-%s\n", state->call_id,
+            state->dir, state->state, state->num_type, state->call_number);
+
+        if(state->state == 2 || state->state == 3 || state->state == 0)
+        {
+            mbtk_net_led_set(MBTK_NET_LED_CALL_CONNECT);
+        }
+
+        if(state->state == 4 && state->dir == 1)
+        {
+            mbtk_net_led_set(MBTK_NET_LED_CALL_CONNECT);
+        }
+
+        if(state->state == MBTK_RIL_CALL_STATE_DISCONNECT)
+        {
+            mbtk_net_led_set(MBTK_NET_LED_CALL_DISCONNECT);
+        }
+        
+    }
+}
+
+int mbtk_status_led_control_get()
+{
+    int ret;
+    mbtk_ril_handle* handle_def = mbtk_ril_open(MBTK_AT_PORT_DEF);
+    if(handle_def == NULL) {
+        LOGE("[led]mbtk_ril_open(MBTK_AT_PORT_DEF/ATPORTTYPE_0) fail.");
+        goto error;
+    }
+    
+    mbtk_ril_handle* handle_1 = mbtk_ril_open(ATPORTTYPE_1);
+    if(handle_1 == NULL) {
+        LOGE("mbtk_ril_open(ATPORTTYPE_1) fail.");
+        goto error;
+    }
+
+    mbtk_net_info_array_t net_list;
+    ret = mbtk_available_net_get(handle_1, &net_list);
+    if(ret != MBTK_RIL_ERR_SUCCESS) {
+        LOGE("[led]Error : %d\n", ret);
+        goto error;
+    } else {
+        LOGD("[led]Available net number:%d\n", net_list.num);
+        int i = 0;
+        while(i < net_list.num) {
+            LOGD("[led]NET : %d,%d,%d,%d\n", net_list.net_info[i].net_sel_mode,
+                net_list.net_info[i].net_type, net_list.net_info[i].net_state,
+                net_list.net_info[i].plmn);
+            if (net_list.net_info[i].net_state == 2)
+            {
+                mbtk_net_led_set(MBTK_NET_LED_NET_CONNECT);
+                break;
+            }
+            i++;
+        }
+    }
+    mbtk_ril_close(ATPORTTYPE_1);
+    
+    ret = mbtk_net_reg_state_change_cb_reg(led_net_reg_state_change_cb);
+    if(ret != MBTK_RIL_ERR_SUCCESS)
+    {
+        LOGE("[led]mbtk_net_reg_state_change_cb_reg fail.");
+        goto error;
+    }
+
+    ret = mbtk_call_state_change_cb_reg(led_call_state_change_cb);
+    if(ret != MBTK_RIL_ERR_SUCCESS)
+    {
+        LOGE("[led]mbtk_call_state_change_cb_reg fail.");
+        goto error;
+    }
+
+    return MBTK_RESULT_SUCCESS;
+
+error:
+    mbtk_ril_close(MBTK_AT_PORT_DEF);
+    mbtk_ril_close(ATPORTTYPE_1);
+    return MBTK_RESULT_FAIL;
+}
+
+
+
 int mbtk_read_ccinet(void)
 {
     FILE *fp;
@@ -94,6 +496,7 @@
         else
         {
             mbtk_net_led_prev_state = status;
+			return;
         }
     }
     else
@@ -211,9 +614,9 @@
 static void net_led_flicker_200ms(void)
 {
     mbtk_led_gpio_level_set(MBTK_NET_LED, 1);
-    usleep(200000);
+    usleep(100000);
     mbtk_led_gpio_level_set(MBTK_NET_LED, 0);
-    usleep(200000);
+    usleep(100000);
 }
 
 static void net_led_flicker_800ms(void)
@@ -227,6 +630,7 @@
 static void* net_led_thread_run(void* arg)
 {
     mbtk_net_led_type status = MBTK_NET_LED_CLOSE;
+    
     while(1)
     {
         status = mbtk_net_led_get();
@@ -244,13 +648,13 @@
                 case MBTK_NET_LED_POWER:
                 {
                     net_led_close();
-                    sleep(2);
+                    sleep(3);
                     break;
                 }
                 case MBTK_NET_LED_SEARCH_NETWORK:
                 {
                     net_led_open();
-                    sleep(2);
+                    sleep(3);
                     break;
                 }
                 case MBTK_NET_LED_DATA_CONNECT:
@@ -266,11 +670,12 @@
                 default:
                 {
                     LOGE("[led]Uknown status.");
+                    sleep(1);
                     break;
                 }
             }
         }
-        sleep(1);
+        usleep(100000);
     }
     return NULL;
 }
@@ -301,7 +706,6 @@
 
     pthread_attr_t thread_attr;
     pthread_t net_led_thread_id;
-//    pthread_t status_led_thread_id;
     pthread_attr_init(&thread_attr);
     if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
     {
@@ -316,6 +720,12 @@
     }
 
     pthread_attr_destroy(&thread_attr);
+
+    if(mbtk_status_led_control_get())
+    {
+        LOGW("mbtk_status_led_control_get() fail.");
+    }
+
     return MBTK_RESULT_SUCCESS;
 }
 /******************************FUNC*****************************************/
diff --git a/mbtk/mbtk_servicesd_v2/src/main.c b/mbtk/mbtk_servicesd_v2/src/main.c
index 0165835..171906e 100755
--- a/mbtk/mbtk_servicesd_v2/src/main.c
+++ b/mbtk/mbtk_servicesd_v2/src/main.c
@@ -25,6 +25,7 @@
 #include "instance_info.h"
 #include "mbtk_str.h"
 #include "mbtk_utils.h"
+#include "mbtk_led.h"
 
 #define MBTK_SERVICES_PID_FILE "/var/run/mbtk_servicesd.pid"
 #define MBTK_SERVICES_CONF_FILE "/etc/mbtk_servicesd.conf"
@@ -104,6 +105,19 @@
         LOGW("ins_monitor_service_start() fail.");
     }
 
+#ifdef MBTK_LED
+    //led services
+    if(mbtk_led_init())
+    {
+        LOGW("LED_service_start() fail.");
+    }
+
+    if(mbtk_led_contril_server_init())
+    {
+        LOGW("LED_contril_service_start() fail.");
+    }
+#endif
+
     while(1) {
         sleep(24 * 60 * 60);
     }