new_func_wifi_1

Change-Id: Ie23b919a0d154becb37e1e6b27ecc98a8377e3b9
diff --git a/mbtk/libmbtk_lib/wifi/sta_ctrl.c b/mbtk/libmbtk_lib/wifi/sta_ctrl.c
new file mode 100644
index 0000000..66c55f5
--- /dev/null
+++ b/mbtk/libmbtk_lib/wifi/sta_ctrl.c
@@ -0,0 +1,599 @@
+#include <string.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <pthread.h>

+#include <unistd.h>

+#include <sys/epoll.h>

+#include <errno.h>

+#include <sys/wait.h>

+#include <sys/types.h>

+

+#include "wpa_ctrl.h"

+#include "sta_ctrl.h"

+//#include "sta_log.h"

+

+#define WPA_SUPPLICANT_LOG_FILE "/data/wpa_supplicant.log"

+

+static void

+sta_ctrl_wpa_req_cb(char *msg, size_t len);

+

+static void*

+sta_ctrl_event_thread_run( void *arg );

+

+static sta_err_enum

+sta_ctrl_close_connection(void);

+

+static sta_err_enum

+sta_ctrl_open_connection(void);

+

+static sta_err_enum

+sta_ctrl_reconnect(void);

+

+static void

+sta_ctrl_recv_event(void);

+

+static sta_err_enum

+sta_ctrl_conf_file_parse

+(

+    const char *key,

+    char *value

+);

+

+extern struct wpa_ctrl;

+

+static struct wpa_ctrl *sta_ctrl_conn;

+static struct wpa_ctrl *sta_mon_conn;

+static int sta_ctrl_attached = 0;

+static pthread_t sta_event_thread_id = -1;

+static int sta_event_thread_is_running = 0;

+static char sta_ctrl_conf_file_path[50];

+static char sta_ctrl_ifname[10];

+static sta_ctrl_msg_cb sta_ctrl_msg = NULL;

+static int sta_ctrl_pipe_fd[2];

+

+static void

+sta_ctrl_wpa_req_cb(char *msg, size_t len)

+{

+	printf("%s\n", msg);

+}

+

+bool

+sta_ctrl_system

+(

+  const char   *command

+)

+{

+    int result = TRUE;

+    FILE *stream = NULL;

+

+    printf("system call: %s\n", command);

+

+    stream = popen( command, "w" );

+    if( stream == NULL )

+    {

+        printf("system command failed\n");

+        result = FALSE;

+    }

+    else if( 0 > pclose( stream ) )

+    {

+        printf("pclose command failed\n");

+    }

+

+    return result;

+}

+

+/*

+* Return TRUE if process <name> is not running after 2 second.

+*/

+bool

+sta_ctrl_kill_check(const char *name)

+{

+#define  PROCESS_KILL_RETRY  40

+    bool result;

+    int tmp = 0;

+    FILE *cmd;

+    char pid_s[STA_BUF_SIZE];

+    int pid;

+    tmp = snprintf(pid_s,STA_BUF_SIZE,

+        "pidof %s",name);

+    pid_s[tmp] = '\0';

+    tmp = 0;

+    while (tmp++ < PROCESS_KILL_RETRY)

+    {

+        usleep(50000);/*50 mili second*/

+        cmd = popen(pid_s, "r");

+        pid = 0;

+        bzero(pid_s, STA_BUF_SIZE);

+        if(cmd)

+        {

+            fgets(pid_s, STA_BUF_SIZE, cmd);

+            pclose(cmd);

+        }

+        pid = atoi(pid_s);

+        printf("%s pid =%d\n", name,pid);

+        /* If pid is zero we break from while*/

+        if(pid == 0)

+        {

+            result = TRUE;

+            goto exit_end;

+        }

+    }

+

+    printf("PID still running after waiting 2 second.\n");

+    result = FALSE;

+exit_end:

+#undef PROCESS_KILL_RETRY

+    return result;

+}

+

+/*

+* Return TRUE if process <name> is running.

+*/

+bool

+sta_ctrl_process_running(const char *name)

+{

+    char pid_s[STA_BUF_SIZE];

+    int tmp = snprintf(pid_s,STA_BUF_SIZE,

+        "pidof %s",name);

+    pid_s[tmp] = '\0';

+    FILE *cmd = popen(pid_s, "r");

+    bzero(pid_s, STA_BUF_SIZE);

+    if(cmd)

+    {

+        fgets(pid_s, STA_BUF_SIZE, cmd);

+        pclose(cmd);

+    }

+

+    int pid = atoi(pid_s);

+    printf("%s pid =%d\n", name,pid);

+    /* If pid is zero we break from while*/

+    if(pid == 0)

+    {

+        printf("%s not runnig.\n",name);

+        return FALSE;

+    }else{

+        printf("%s is runnig.\n",name);

+        return TRUE;

+    }

+}

+

+

+static void*

+sta_ctrl_event_thread_run( void *arg )

+{

+    printf("Thread[%ld] run().\n",pthread_self());

+

+    int nready;

+    struct epoll_event ev_sock,ev_pipe,events[20];

+    int epfd = epoll_create(256);

+    ev_sock.data.fd = wpa_ctrl_get_fd(sta_mon_conn);

+    ev_sock.events = EPOLLIN | EPOLLET;

+    epoll_ctl(epfd,EPOLL_CTL_ADD,wpa_ctrl_get_fd(sta_mon_conn),&ev_sock);

+

+    ev_pipe.data.fd = sta_ctrl_pipe_fd[0];

+    ev_pipe.events = EPOLLIN | EPOLLET;

+    epoll_ctl(epfd,EPOLL_CTL_ADD,sta_ctrl_pipe_fd[0],&ev_pipe);

+

+    for ( ; ; ) {

+        if(!sta_event_thread_is_running){

+            break;

+        }

+		printf("epoll_wait waitting...\n",nready);

+        nready = epoll_wait(epfd,events,20,-1);

+        printf("epoll_wait return.(count = %d)\n",nready);

+        int i;

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

+            if (events[i].events & EPOLLIN) {// Read

+                if (events[i].data.fd < 0)

+                    continue;

+

+                if(sta_mon_conn  // sta_mon_conn can not be NULL

+                    && events[i].data.fd == wpa_ctrl_get_fd(sta_mon_conn)){

+                    sta_ctrl_recv_event();

+                }else if(events[i].data.fd == sta_ctrl_pipe_fd[0]){

+                    printf("Thread end.[fd = %d]\n",events[i].data.fd);

+                    // End thread

+                    char buf_end[10] = {0};

+                    if(read(sta_ctrl_pipe_fd[0],buf_end,10) > 0

+                        && strcmp(buf_end,"0") == 0){

+                        sta_event_thread_is_running = 0;

+                        break;

+                    }

+                }else{

+                    printf("No such fd[%d].\n",events[i].data.fd);

+                }

+            } else {

+                printf("event error.\n");

+            }

+        }

+    }

+

+    close(epfd);

+    printf("Thread exit.\n");

+    return ((void*)0);

+}

+

+static sta_err_enum

+sta_ctrl_close_connection(void)

+{

+    printf("start.\n");

+    if (sta_ctrl_conn == NULL)

+        return STA_ERR_UNKNOWN;

+

+    if (sta_ctrl_attached) {

+        wpa_ctrl_detach(sta_mon_conn);

+        sta_ctrl_attached = 0;

+    }

+    wpa_ctrl_close(sta_ctrl_conn);

+    sta_ctrl_conn = NULL;

+    if (sta_mon_conn) {

+        wpa_ctrl_close(sta_mon_conn);

+        sta_mon_conn = NULL;

+    }

+

+    printf("end.\n");

+    return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_ctrl_open_connection(void)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+

+    if(sta_ctrl_conn){

+        return STA_ERR_UNKNOWN;

+    }

+

+    char ctrl_path[100] = {0};

+    result = sta_ctrl_conf_file_parse("ctrl_interface", ctrl_path);

+    if(STA_ERR_SUCCESS != result){

+        printf("sta_ctrl_conf_file_parse() fail(%d).\n",result);

+        return result;

+    }

+    snprintf(ctrl_path + strlen(ctrl_path),10,

+        "/%s",

+        sta_ctrl_ifname);

+

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

+

+    sta_ctrl_conn = wpa_ctrl_open(ctrl_path);

+    if (sta_ctrl_conn == NULL) {

+        sleep(1);

+        return sta_ctrl_open_connection();

+    }

+

+    sta_mon_conn = wpa_ctrl_open(ctrl_path);

+    if (sta_mon_conn == NULL) {

+        return STA_ERR_UNKNOWN;

+    }

+

+    if (wpa_ctrl_attach(sta_mon_conn) == 0) {

+        sta_ctrl_attached = 1;

+    } else {

+        printf("Warning: Failed to attach to "

+               "wpa_supplicant.\n");

+        sta_ctrl_close_connection();

+        return STA_ERR_UNKNOWN;

+    }

+

+    if(!sta_event_thread_is_running) {

+        sta_event_thread_is_running = 1;

+        int ret = pthread_create(&sta_event_thread_id,

+            NULL,

+            sta_ctrl_event_thread_run,

+            NULL);

+        if( ret != 0 ) {

+            printf( "Create thread error!\n");

+        }

+    }else{

+        printf("sta_event_thread is running.\n");

+        return STA_ERR_UNKNOWN;

+    }

+    return result;

+}

+

+static sta_err_enum

+sta_ctrl_reconnect(void)

+{

+    if(STA_ERR_SUCCESS == sta_ctrl_close_connection()){

+        return sta_ctrl_open_connection();

+    }else{

+        return STA_ERR_UNKNOWN;

+    }

+}

+

+static void

+sta_ctrl_recv_event(void)

+{

+	printf("start.\n");

+    if (sta_ctrl_conn == NULL) {

+        sta_ctrl_reconnect();

+		printf("sta_ctrl_conn == NULL:end.\n");

+        return;

+    }

+

+    while (wpa_ctrl_pending(sta_mon_conn) > 0) {

+        char buf[4096];

+        size_t len = sizeof(buf) - 1;

+        if (wpa_ctrl_recv(sta_mon_conn, buf, &len) == 0) {

+            buf[len] = '\0';

+            printf("<<%s>>\n",buf);

+            if(sta_ctrl_msg)

+                sta_ctrl_msg(buf);

+        } else {

+            printf("Could not read pending message.\n");

+            break;

+        }

+    }

+

+    if (wpa_ctrl_pending(sta_mon_conn) < 0) {

+        printf("Connection to wpa_supplicant lost - trying to "

+               "reconnect\n");

+        sta_ctrl_reconnect();

+    }

+

+	printf("end.\n");

+}

+

+static sta_err_enum

+sta_ctrl_conf_file_parse

+(

+    const char *key,

+    char *value

+)

+{

+    sta_err_enum result = STA_ERR_UNKNOWN;

+    FILE *fd = fopen(sta_ctrl_conf_file_path,"r");

+    if(!fd){

+        printf("Open file(%s) fail(%d).\n",sta_ctrl_conf_file_path,errno);

+        return STA_ERR_UNKNOWN;

+    }

+

+    char buf[1024];

+    while(fgets(buf,1024,fd)){

+        char *start = strstr(buf,key);

+        if(start){ // Find key

+            char *tmp = start + strlen(start) -1;

+            while(*tmp){

+                if(*tmp == '\r'

+                    || *tmp == '\n'){

+                    *tmp = '\0';

+                }else{

+                    break;

+                }

+                *tmp--;

+            }

+

+            int size = snprintf(value,100,

+                "%s",

+                start + strlen(key) + 1);

+            value[size] = '\0';

+            result = STA_ERR_SUCCESS;

+            break;

+        }

+    }

+

+    fclose(fd);

+

+    return result;

+}

+

+/***************************************************************/

+/************************ Public Fuction ***********************/

+/***************************************************************/

+sta_err_enum

+sta_ctrl_cmd_process

+(

+    const char *cmd,

+    char *reply,

+    size_t reply_len

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    bzero(reply,reply_len);

+    reply_len = reply_len - 1;

+    int ret = wpa_ctrl_request(sta_ctrl_conn,

+        cmd,

+        strlen(cmd),

+        reply,

+        &reply_len,

+        sta_ctrl_wpa_req_cb);

+    if (ret == -2) {

+        printf("command timed out.\n");

+        result = STA_ERR_TIMEOUT;

+        goto end_fail;

+    } else if (ret < 0) {

+        printf("command failed.\n");

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    } else {

+        reply[reply_len] = '\0';

+        printf("1:%s\n", reply);

+

+        if(reply_len > 0 && reply[reply_len - 1] != '\n')

+            printf("\n");

+    }

+

+end_success:

+

+    return result;

+end_fail:

+

+    return result;

+}

+

+/**

+* Open or close wlan driver.

+*/

+sta_err_enum

+sta_ctrl_driver_init(bool open)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+

+    FILE *fd_tmp = NULL;

+    if(open){

+        fd_tmp = popen("/etc/wifi/mbtk_wifi_driver.sh sta start","r");

+    }else{

+        fd_tmp = popen("/etc/wifi/mbtk_wifi_driver.sh driver_rmmod","r");

+    }

+

+    if(fd_tmp){

+        char buf[200] = {0};

+        fgets(buf,200,fd_tmp);

+        pclose(fd_tmp);

+        if(strlen(buf) > 0){

+            printf("Driver %s fail.(%s)\n",(open?"open":"close"),buf);

+            result = STA_ERR_DRIVER;

+        }else{// Open wpa_supplicant

+            printf("Driver %s success.\n",(open?"open":"close"));

+        }

+    }else{

+        printf("Driver %s fail.(%s)\n",(open?"open":"close"));

+        result = STA_ERR_DRIVER;

+    }

+

+    return result;

+}

+

+sta_err_enum

+sta_ctrl_wpa_init

+(

+    const char *conf_file,

+    const char *interface,

+    sta_ctrl_msg_cb cb

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    if(!conf_file

+        || strlen(conf_file) == 0){

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    if(!interface

+        || strlen(interface) == 0){

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    sta_ctrl_msg = cb;

+

+    int size = snprintf(sta_ctrl_conf_file_path,

+        50,

+        "%s",

+        conf_file);

+    sta_ctrl_conf_file_path[size] = '\0';

+    size = snprintf(sta_ctrl_ifname,

+        10,

+        "%s",

+        interface);

+    sta_ctrl_ifname[size] = '\0';

+

+    if(pipe(sta_ctrl_pipe_fd)){

+        printf("pipe() fail(%d).\n",errno);

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    FILE *fd_tmp = popen("pidof wpa_supplicant","r");

+    if(fd_tmp){

+        char buf[200] = {0};

+        fgets(buf,200,fd_tmp);

+        pclose(fd_tmp);

+        if(strlen(buf) > 0){

+            printf("wpa_supplicant is running.(%s)\n",buf);

+        }else{// Open wpa_supplicant

+            bzero(buf,200);

+            

+            snprintf(buf,200,

+                "wpa_supplicant -Dnl80211 -c%s -i%s -f%s -ddd &",

+                conf_file,

+                interface,

+                WPA_SUPPLICANT_LOG_FILE);

+            

+            /*

+             snprintf(buf,200,

+                "wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wifi/wpa_supplicant.conf -B");

+                */

+            if (sta_ctrl_system(buf)){

+                printf("\"%s\" success.\n",buf);

+                sleep(1);

+            }else{

+                printf("\"%s\" fail.\n",buf);

+                result = STA_ERR_UNKNOWN;

+                goto end_fail;

+            }

+        }

+    }else{

+        printf("\"pidof wpa_supplicant\" fail\n");

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    result = sta_ctrl_open_connection();

+    if(STA_ERR_SUCCESS != result) {

+        printf("sta_ctrl_open_connection() fail(%d).\n",result);

+        goto end_fail;

+    }

+

+end_success:

+

+    return result;

+end_fail:

+

+    return result;

+}

+

+sta_err_enum

+sta_ctrl_wpa_deinit

+(

+    void

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    result = sta_ctrl_close_connection();

+    if(STA_ERR_SUCCESS != result){

+        goto end_fail;

+    }

+

+    bzero(sta_ctrl_conf_file_path,50);

+    bzero(sta_ctrl_ifname,10);

+

+    sta_event_thread_is_running = 0;

+    // End thread.

+    write(sta_ctrl_pipe_fd[1],"0",1);

+

+

+    printf("Waitting for thread(%ld) exit.\n",sta_event_thread_id);

+

+    pthread_join(sta_event_thread_id,NULL);

+

+    printf("pthread_join() return.\n");

+

+

+    close(sta_ctrl_pipe_fd[0]);

+    close(sta_ctrl_pipe_fd[1]);

+

+    sta_event_thread_id = -1;

+    sta_ctrl_msg = NULL;

+

+    // Stop process wpa_supplicant

+    if(sta_ctrl_system("killall -15 wpa_supplicant")

+        && sta_ctrl_kill_check("wpa_supplicant")){

+        printf("\"killall -15 wpa_supplicant\" success.\n");

+    }else{

+        if(sta_ctrl_system("killall -9 wpa_supplicant")){

+            printf("\"killall -9 wpa_supplicant\" success.\n");

+        }else{

+            printf("\"killall -9 wpa_supplicant\" fail.\n");

+        }

+    }

+

+end_success:

+    printf("sta_ctrl_wpa_deinit() end(success).\n");

+    return result;

+end_fail:

+    printf("sta_ctrl_wpa_deinit() end(fail)[%s].\n",result);

+    return result;

+}

+