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