new_func_wifi_1
Change-Id: Ie23b919a0d154becb37e1e6b27ecc98a8377e3b9
diff --git a/mbtk/libmbtk_lib/wifi/sta_cli.c b/mbtk/libmbtk_lib/wifi/sta_cli.c
new file mode 100644
index 0000000..316d70f
--- /dev/null
+++ b/mbtk/libmbtk_lib/wifi/sta_cli.c
@@ -0,0 +1,2008 @@
+#include <stdio.h>
+#include <pthread.h>
+#include <time.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <string.h>
+
+
+#include "sta_cli.h"
+#include "sta_ctrl.h"
+//#include "sta_log.h"
+//#include "mbtk_string.h"
+
+#define STA_CLI_TIMEOUT 15000 // 15s
+#define UNIXSTR_PATH "/data/sta_cli_sock"
+#define SA struct sockaddr
+#define LISTENQ 1024 /* 2nd argument to listen() */
+#define STA_CMD_SEPARATED "#$#"
+#define STA_MAC_LEN 17 // xx:xx:xx:xx:xx:xx
+#define STA_SSID_MAX_LEN (32 * 5)
+
+
+#ifndef INFTIM
+#define INFTIM (-1) /* infinite poll timeout */
+#endif
+
+#define STA_TAG_IND "IND"
+#define STA_TAG_CMD "CMD"
+#define STA_TAG_CMD_SUCCESS "SUCCESS"
+#define STA_TAG_CMD_FAIL "FAIL"
+#define STA_TAG_CMD_FAIL_BUSY "FAIL-BUSY"
+#define STA_CMD_OPEN "OPEN"
+//#define STA_CMD_EXIT "EXIT"
+#define STA_CMD_CLOSE "CLOSE"
+#define STA_CMD_SCAN "SCAN"
+#define STA_CMD_STATUS "STATUS"
+#define STA_CMD_MIB "MIB"
+#define STA_CMD_RECONFIGURE "RECONFIGURE"
+#define STA_CMD_DISCONNECT "DISCONNECT"
+#define STA_CMD_RECONNECT "RECONNECT"
+#define STA_CMD_SAVE_CONFIG "SAVE_CONFIG"
+#define STA_CMD_SET_NETWORK "SET_NETWORK"
+#define STA_CMD_GET_NETWORK "GET_NETWORK"
+#define STA_CMD_REMOVE_NETWORK "REMOVE_NETWORK"
+#define STA_CMD_ADD_NETWORK "ADD_NETWORK"
+#define STA_CMD_DISABLE_NETWORK "DISABLE_NETWORK"
+#define STA_CMD_ENABLE_NETWORK "ENABLE_NETWORK"
+#define STA_CMD_SELECT_NETWORK "SELECT_NETWORK"
+#define STA_CMD_LIST_NETWORKS "LIST_NETWORKS"
+#define STA_CMD_REASSOCIATE "REASSOCIATE"
+#define STA_CMD_REATTACH "REATTACH"
+
+// /var/run/wpa_supplicant
+static sta_cli_cmd_id_enum sta_cli_cmd_id = CMD_ID_NON;
+static char sta_cli_cmd_reply[STA_BUF_SIZE];
+static pthread_cond_t cond;
+static pthread_mutex_t mutex;
+static int sta_cli_conn_fd = -1;
+static char sta_cli_buf[STA_BUF_SIZE];
+static bool sta_should_send_connected_msg = TRUE;
+//static bool sta_connected = FALSE;
+static bool sta_disconnectting = FALSE;
+//static pthread_mutex_t sta_mutex;
+
+
+
+int sta_cli_ssid_get(char *ssid)
+{
+ FILE *fd_tmp = NULL;
+
+ fd_tmp = popen("cat /etc/wifi/sta_network.conf | grep -w 'SSID' | cut -d '=' -f 2","r");
+
+ if(fd_tmp){
+ char buf[200] = {0};
+ fgets(ssid,200,fd_tmp);
+ pclose(fd_tmp);
+ if(strlen(ssid) > 0){
+ printf("test 100:%s, len:%d\n", ssid, strlen(ssid));
+
+ }else{// Open wpa_supplicant
+ printf("test 101:%s\n", ssid);
+ }
+ }else{
+
+ printf("test 102:%s\n");
+ }
+
+ return 0;
+}
+
+int sta_cli_psk_get(char *psk)
+{
+ FILE *fd_tmp = NULL;
+
+ fd_tmp = popen("cat /etc/wifi/sta_network.conf | grep -w 'PASSWORD' | cut -d '=' -f 2","r");
+
+ if(fd_tmp){
+ char buf[200] = {0};
+ fgets(psk,200,fd_tmp);
+ pclose(fd_tmp);
+ if(strlen(psk) > 0){
+ printf("test 100:%s\n", psk);
+
+ }else{// Open wpa_supplicant
+ printf("test 101:%s\n", psk);
+ }
+ }else{
+
+ printf("test 102:%s\n");
+ }
+
+ return 0;
+}
+
+
+
+static char*
+sta_cli_ssid_process
+(
+ const char *ssid,
+ char *result,
+ int len
+)
+{
+ bzero(result,len);
+ int ascii = 1;
+ int i;
+ for (i = 0; i < strlen(ssid); i++){
+ if (!isascii(ssid[i])){
+ //printf("0x%02x\n",(unsigned char)ssid[i]);
+ //return 0;
+ ascii = 0;
+ break;
+ }
+ }
+
+ if(ascii)
+ {
+ snprintf(result,len,
+ "\"%s\"",ssid);
+ }else{
+ int pos = 0;
+ for (i = 0; i < strlen(ssid); i++){
+ printf("0x%02x\n",(unsigned char)ssid[i]);
+ snprintf(result + pos,len - pos,
+ "%02x",(unsigned char)ssid[i]);
+ pos += 2;
+ }
+ }
+ return result;
+}
+
+
+static char*
+sta_cli_mac_get
+(
+ char *ifname,
+ char *mac,
+ size_t mac_len
+)
+{
+ struct ifreq ifreq;
+ int sock;
+ bzero(mac,mac_len);
+
+ if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
+ {
+ printf("socket:errno(%d)\n",errno);
+ return NULL;
+ }
+ strcpy(ifreq.ifr_name,ifname);
+ if(ioctl(sock,SIOCGIFHWADDR,&ifreq) <0)
+ {
+ printf("ioctl:errno(%d)\n",errno);
+ return NULL;
+ }
+ snprintf(mac,mac_len,
+ "%02x%02x%02x%02x%02x%02x",
+ (unsigned char)ifreq.ifr_hwaddr.sa_data[0],
+ (unsigned char)ifreq.ifr_hwaddr.sa_data[1],
+ (unsigned char)ifreq.ifr_hwaddr.sa_data[2],
+ (unsigned char)ifreq.ifr_hwaddr.sa_data[3],
+ (unsigned char)ifreq.ifr_hwaddr.sa_data[4],
+ (unsigned char)ifreq.ifr_hwaddr.sa_data[5]);
+ return mac;
+}
+
+
+static char*
+sta_cli_sta_name_get
+(
+ char *name,
+ size_t name_len
+)
+{
+ bzero(name,name_len);
+
+ // Get host name.
+ FILE *stream = NULL;
+ char host[100];
+ bzero(host,100);
+ stream = popen("hostname","r");
+ if(stream != NULL)
+ {
+ fgets(host, 100, stream);
+ pclose(stream);
+ int index = str_indexof(host,"\n");
+ if(strlen(host) > 0
+ && index != 0)
+ {
+ if(index > 0)
+ {
+ host[index] = '\0';
+ }
+
+ // index < 0
+ // No "\n"
+ }
+ else // No data or empty line.
+ {
+ // Can not get host,set default to "MBTK".
+ memcpy(host,"MBTK",4);
+ }
+ }
+ else
+ {
+ // Can not get host,set default to "MBTK".
+ memcpy(host,"MBTK",4);
+ }
+
+ // Get mac address.
+ char mac[20];
+ if(NULL == sta_cli_mac_get("wlan0", mac, 20))
+ {
+ // Can not get mac,set default to current time.
+ time_t t;
+ t = time(NULL);
+ snprintf(mac,20,
+ "%ld",t);
+ }
+
+ snprintf(name,name_len,
+ "%s-%s",host,mac);
+
+ return name;
+}
+
+static void
+sta_cli_wpa_open_success
+(
+ void
+)
+{
+ char buf[100];
+ int len = snprintf(buf,100,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ STA_CMD_OPEN,
+ STA_TAG_CMD_SUCCESS);
+ buf[len] = '\0';
+ if(sta_cli_conn_fd != -1){
+ if(write(sta_cli_conn_fd,buf,len) != len){
+ printf("Send open msg to client fail.\n");
+ }else{
+ printf("Send open msg to client success.\n");
+ }
+ }else{
+ printf("No client connected.\n");
+ }
+ sta_should_send_connected_msg = FALSE;
+}
+
+
+static void
+sta_cli_wpa_msg_cb
+(
+ char *msg
+)
+{
+ printf("cmd_id = %d,[%s]\n",sta_cli_cmd_id,msg);
+
+// if(sta_cli_conn_fd != -1){
+// if(write(sta_cli_conn_fd,msg,strlen(msg)) != strlen(msg)){
+// printf("Send msg to client fail.\n");
+// }else{
+// printf("Send msg to client success.\n");
+// }
+// }else{
+// printf("No client connected.\n");
+// }
+
+ // Send msg(CMD_OPEN_SUCCESS) to wifi_server.
+ if(sta_should_send_connected_msg) {
+ sta_cli_wpa_open_success();
+ }
+
+ // Connected to AP
+ if(str_contains(msg, "CTRL-EVENT-CONNECTED")){
+ //sta_connected = TRUE;
+ char sta_name[100];
+ sta_cli_sta_name_get(sta_name,100);
+ char cmd[200];
+ int size = snprintf(cmd,200,
+ "dhcpcd -h %s -o domain_name_servers --noipv4ll wlan0",sta_name);
+ //dhcpcd wlan0 -t 0 -o domain_name_servers --noipv4ll -b -G
+ cmd[size] = '\0';
+ if(sta_ctrl_system(cmd)){
+ char buf[100];
+ int len = snprintf(buf,100,
+ "%s-CONNECTED"STA_CMD_SEPARATED,
+ STA_TAG_IND);
+ buf[len] = '\0';
+ if(sta_cli_conn_fd != -1){
+ usleep(500);
+ if(write(sta_cli_conn_fd,buf,len) != len){
+ printf("Send msg to client fail.\n");
+ }else{
+ printf("Send msg to client success.\n");
+ }
+ }else{
+ printf("No client connected.\n");
+ }
+ }
+ return;
+ }
+#if 1
+ else if(str_contains(msg, "CTRL-EVENT-DISCONNECTED")
+ && !str_contains(msg, "bssid=00:00:00:00:00:00")
+ && !sta_disconnectting)
+ {
+ //pthread_mutex_lock(&sta_mutex);
+ //if(sta_connected){
+ // Disconnected from AP
+ char buf[100];
+ int len = snprintf(buf,100,
+ "%s-DISCONNECTED"STA_CMD_SEPARATED,
+ STA_TAG_IND);
+ buf[len] = '\0';
+ if(sta_cli_conn_fd != -1){
+ if(write(sta_cli_conn_fd,buf,len) != len){
+ printf("Send msg to client fail.\n");
+ }else{
+ printf("Send msg to client success.\n");
+ }
+ }else{
+ printf("No client connected.\n");
+ }
+ //sta_connected = FALSE;
+ //pthread_mutex_unlock(&sta_mutex);
+ return;
+ //}
+ //pthread_mutex_unlock(&sta_mutex);
+ }
+#endif
+
+ switch(sta_cli_cmd_id)
+ {
+ case CMD_ID_NON:
+ {
+
+ break;
+ }
+ case CMD_ID_SCAN:
+ {
+ if(str_contains(msg, "CTRL-EVENT-SCAN-RESULTS")){
+ printf("Start resume thread.\n");
+ pthread_mutex_lock(&mutex);
+ pthread_cond_signal(&cond);
+ //pthread_cond_broadcast(&cond);
+ pthread_mutex_unlock(&mutex);
+ }
+ break;
+ }
+ default:
+ printf("cmd_id[%d] unknown.\n",sta_cli_cmd_id);
+ break;
+ }
+}
+
+static void
+sta_cli_thread_pause
+(
+ long time /* ms */
+)
+{
+ struct timeval now_1;
+ struct timespec outtime;
+ int thread_id = pthread_self();
+ printf("Thread(%ld) pause.\n",thread_id);
+ pthread_mutex_lock(&mutex);
+ gettimeofday(&now_1, NULL);
+ outtime.tv_sec = now_1.tv_sec + time / 1000;
+ outtime.tv_nsec = now_1.tv_usec * 1000;
+ pthread_cond_timedwait(&cond, &mutex, &outtime);
+ pthread_mutex_unlock(&mutex);
+ printf("Thread(%ld) resume.\n",thread_id);
+}
+
+static bool
+sta_cli_is_empty_char(char ch)
+{
+ if(/*ch == ' ' || */ch == '\r' || ch == '\n'
+ || ch == '\t')
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static char*
+sta_cli_value_get
+(
+ const char *data,
+ const char *key, // "key="
+ char *value,
+ int len
+)
+{
+ bzero(value,len);
+ char *ptr = strstr(data,key);
+ if(ptr)
+ {
+ ptr += strlen(key);
+ int i = 0;
+ while(*ptr != '\r' && *ptr != '\n')
+ {
+ if(i == len - 1)
+ return NULL;
+ value[i++] = *ptr++;
+ }
+ return value;
+ }else{
+ return NULL;
+ }
+}
+
+
+static sta_err_enum
+sta_cli_cmd_scan_parse
+(
+ const char *reply,
+ char *data,
+ size_t len
+)
+{
+ char *data_base = data;
+ printf("SCAN:\n%s\n",reply);
+ bzero(data,len);
+ const char *ptr = reply;
+ bool start = FALSE;
+ int count = 0; // count for ',' by every line.
+ while(*ptr){
+ if(!start && *ptr == '\n'){
+ start = TRUE;
+ ptr++;
+ }
+
+ if(start){
+ if(sta_cli_is_empty_char(*ptr)){
+ if(*ptr == '\r' || *ptr == '\n'){
+ *data++ = '\r';
+ *data++ = '\n';
+ while(*++ptr == '\r' || *ptr == '\n')
+ ;
+ count = 0; // reset for next line.
+ }else{
+ if(count < 4) {
+ *data++ = ',';
+ count++;
+ while(*++ptr == ' ' || *ptr == '\t')
+ ;
+ } else {
+ *data++ = *ptr++;
+ }
+ }
+ }else{
+ *data++ = *ptr++;
+ }
+ }else{
+ ptr++;
+ }
+ }
+
+ printf("SCAN 0:\n%s\n",data_base);
+
+ // Delete empty ssid line.
+ char *tmp = (char*)calloc(len,1);
+ memcpy(tmp,data_base,strlen(data_base));
+ bzero(data_base,len);
+
+ char *ptr_pre = tmp;
+ ptr = strstr(ptr_pre,"\r\n");
+ printf("line:%s\n",ptr == NULL?"NULL":ptr);
+ char ssid[STA_BUF_SIZE] = {0};
+ char *p;
+ while(ptr)
+ {
+ printf("Get line.\n");
+ // Get ssid.
+ if(*(ptr - 1) == ',') // No ssid
+ {
+ printf("Delete one line.\n");
+ }else{
+ char s[STA_BUF_SIZE] = {0};
+ p = ptr - 1;
+ int len = 0;
+ while(*p-- != ','){
+ len++;
+ }
+ p += 2;
+ memcpy(s,p,len);
+ printf("ssid = %s;s = %s\n",ssid,s);
+ if(str_contains(ssid,s))
+ {
+ printf("Jump the same ssid:%s\n",s);
+ ptr_pre = ptr + 2;
+ ptr = strstr(ptr_pre,"\r\n");
+ continue;
+ }
+
+ if(strlen(ssid) > 0){
+ ssid[strlen(ssid)] = ',';
+ }
+ memcpy(ssid + strlen(ssid),s,len);
+
+ memcpy(data_base + strlen(data_base),ptr_pre,ptr + 2 - ptr_pre);
+ printf("Copy ssid:\"%s\"\n",s);
+ }
+ ptr_pre = ptr + 2;
+ ptr = strstr(ptr_pre,"\r\n");
+ }
+
+ printf("Scan parse end.\n");
+
+ free(tmp);
+ tmp = NULL;
+
+ printf("SCAN 1:\n%s\n",data_base);
+
+ return STA_ERR_SUCCESS;
+}
+
+static sta_err_enum
+sta_cli_cmd_status_parse
+(
+ const char *reply,
+ char *data,
+ size_t data_len
+)
+{
+ printf("STATUS:\n%s\n",reply);
+
+ bzero(data,data_len);
+
+// const char *ptr = reply;
+// while(*ptr){
+// if(*ptr == '\r' || *ptr == '\n'){
+// *data++ = '\r';
+// *data++ = '\n';
+// while(*++ptr == '\r' || *ptr == '\n')
+// ;
+// }else{
+// *data++ = *ptr++;
+// }
+// }
+
+#define BUF_SIZE 500
+ int len = 0;
+ char buf[BUF_SIZE];
+ char mac_ap[STA_MAC_LEN + 1];
+ int size;
+ if(sta_cli_value_get(reply,
+ "bssid=",
+ mac_ap,
+ STA_MAC_LEN + 1)) // Connected.
+ {
+ // State
+ memcpy(data + len,"1",1);
+ len += 1;
+
+ // mac_own
+ if(sta_cli_value_get(reply,
+ "\naddress=",
+ buf,
+ BUF_SIZE))
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%s",buf);
+ len += size;
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get own MAC address.\n");
+ }
+
+ // net_id
+ if(sta_cli_value_get(reply,
+ "\nid=",
+ buf,
+ BUF_SIZE))
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%s",buf);
+ len += size;
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get net id.\n");
+ }
+
+ // ssid
+ if(sta_cli_value_get(reply,
+ "\nssid=",
+ buf,
+ BUF_SIZE))
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%s",buf);
+ len += size;
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get ssid.\n");
+ }
+
+ // freq
+ if(sta_cli_value_get(reply,
+ "freq=",
+ buf,
+ BUF_SIZE))
+ {
+ int freq = atoi(buf);
+ int channel = (freq - 2412) / 5 + 1;
+ size = snprintf(data + len,data_len - len,
+ ",%d,%s",channel,buf);
+ len += size;
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get freq.\n");
+ }
+
+ // auth
+ if(sta_cli_value_get(reply,
+ "key_mgmt=",
+ buf,
+ BUF_SIZE))
+ {
+ // WPA/WPA2
+ if(strncmp(buf,"WPA",3)== 0)
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%d",2);
+ len += size;
+ }else{
+ if(sta_cli_value_get(reply,
+ "group_cipher=",
+ buf,
+ BUF_SIZE))
+ {
+ // Open
+ if(strncmp(buf,"NONE",4) == 0)
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%d",0);
+ len += size;
+ }else{// WEP
+ size = snprintf(data + len,data_len - len,
+ ",%d",1);
+ len += size;
+ }
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get group_cipher.\n");
+ }
+ }
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get key_mgmt.\n");
+ }
+
+ // mac_ap
+ size = snprintf(data + len,data_len - len,
+ ",%s",mac_ap);
+ len += size;
+
+ // ip
+ if(sta_cli_value_get(reply,
+ "ip_address=",
+ buf,
+ BUF_SIZE))
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%s",buf);
+ len += size;
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get IP.\n");
+ }
+ }else{
+ memcpy(data + len,"0",1);
+ len += 1;
+
+ if(sta_cli_value_get(reply,
+ "\naddress=",
+ buf,
+ BUF_SIZE))
+ {
+ size = snprintf(data + len,data_len - len,
+ ",%s",buf);
+ len += size;
+
+ }else{
+ memcpy(data + len,",",1);
+ len += 1;
+ printf("Not get MAC address.\n");
+ }
+
+ memcpy(data + len,",,,,,,,",7);
+ len += 7;
+ }
+
+ memcpy(data + len,"\r\n",2);
+ len += 2;
+ data[len] = '\0';
+
+ printf("STATUS:\n%s\n",data);
+#undef BUF_SIZE
+ return STA_ERR_SUCCESS;
+}
+
+static sta_err_enum
+sta_cli_cmd_mib_parse
+(
+ const char *reply,
+ char *data,
+ size_t len
+)
+{
+ printf("MIB:\n%s\n",reply);
+
+ memcpy(data,reply,strlen(reply));
+
+ return STA_ERR_SUCCESS;
+}
+
+static sta_err_enum
+sta_cli_cmd_list_network_parse
+(
+ const char *reply,
+ char *data,
+ size_t len
+)
+{
+ printf("LIST_NETWORK:\n%s\n",reply);
+
+ bzero(data,len);
+ const char *ptr = reply;
+ bool start = FALSE;
+ bool skip = FALSE;
+ int count = 0; // count for ',' by every line.
+ while(*ptr){
+ if(!start && *ptr == '\n'){
+ start = TRUE;
+ ptr++;
+ }
+
+ if(start){
+ if(sta_cli_is_empty_char(*ptr)){
+ if(*ptr == '\r' || *ptr == '\n'){
+ *data++ = '\r';
+ *data++ = '\n';
+ while(*++ptr == '\r' || *ptr == '\n')
+ ;
+ count = 0;
+ skip = FALSE;
+ }else{
+ if(count < 1) {
+ *data++ = ',';
+ count++;
+ while(*++ptr == ' ' || *ptr == '\t')
+ ;
+ } else {
+ skip = TRUE;
+ ptr++;
+ }
+ }
+ }else{
+ if(!skip)
+ *data++ = *ptr++;
+ else
+ ptr++;
+ }
+ }else{
+ ptr++;
+ }
+ }
+
+ //memcpy(data,reply,strlen(reply));
+
+ printf("LIST_NETWORK:\n%s\n",data);
+
+ return STA_ERR_SUCCESS;
+}
+
+static sta_err_enum
+sta_cli_process_cmd
+(
+ const char *cmd
+)
+{
+ sta_err_enum err = sta_ctrl_cmd_process(cmd,sta_cli_cmd_reply,STA_BUF_SIZE);
+ if(err == STA_ERR_SUCCESS){
+ if(strncmp(cmd,STA_CMD_SCAN,strlen(STA_CMD_SCAN)) == 0
+ && strncmp(sta_cli_cmd_reply,STA_TAG_CMD_FAIL_BUSY,strlen(STA_TAG_CMD_FAIL_BUSY)) == 0){
+ printf("\"%s\" busy.\n",cmd);
+ return STA_ERR_SUCCESS;
+ }
+
+ if(strncmp(sta_cli_cmd_reply,STA_TAG_CMD_FAIL,strlen(STA_TAG_CMD_FAIL)) == 0){
+ printf("\"%s\" fail.\n",cmd);
+ return STA_ERR_UNKNOWN;
+ }
+ printf("[%s]:\n%s\n",cmd,sta_cli_cmd_reply);
+ }else{
+ printf("[%s]:FAIL\n",cmd);
+ }
+ return err;
+}
+
+static sta_err_enum
+sta_cli_cmd_scan
+(
+ const char *cmd,
+ char *data,
+ size_t len
+)
+{
+ bzero(data,len);
+ sta_cli_cmd_id = CMD_ID_SCAN;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0
+ || strncmp(sta_cli_cmd_reply,STA_TAG_CMD_FAIL_BUSY,strlen(STA_TAG_CMD_FAIL_BUSY)) == 0){// Is scanning ...
+ sta_cli_thread_pause(STA_CLI_TIMEOUT);
+
+ // Scan end.
+
+ sta_cli_cmd_id = CMD_ID_SCAN_RESULTS;
+ err = sta_cli_process_cmd("SCAN_RESULTS");
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(STA_ERR_SUCCESS == err){
+ return sta_cli_cmd_scan_parse(sta_cli_cmd_reply,
+ data,
+ len);
+ }else{
+ printf("SCAN_RESULTS cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("SCAN cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("SCAN cmd fail.\n");
+ return err;
+ }
+}
+
+
+static char*
+sta_cli_flag_get
+(
+ const char *ssid,
+ char *flag,
+ size_t len
+)
+{
+ sta_err_enum err;
+ char data[STA_BUF_SIZE];
+ bzero(flag,len);
+ err = sta_cli_cmd_scan("SCAN", data,STA_BUF_SIZE);
+ if(err == STA_ERR_SUCCESS){
+ if(strlen(data) == 0)
+ {
+ return NULL;
+ }
+ ssize_t end = str_indexof(data,ssid) - 1; // Point to ','
+ if(end > 0)
+ {
+ char *ptr = data + end - 1;// Jump the ','
+ int len = 0;
+ while(*ptr != ',' && ptr != data)
+ {
+ ptr--;
+ len++;
+ }
+ ptr++; // Point to flag.
+
+ memcpy(flag,ptr,len);
+ printf("%s : %s\n",ssid,flag);
+ return flag;
+ }
+ }else{
+ printf("SCAN_RESULTS cmd fail.");
+ return NULL;
+ }
+ return NULL;
+}
+
+
+static sta_err_enum
+sta_cli_cmd_status
+(
+ const char *cmd,
+ char *data,
+ size_t len
+)
+{
+ bzero(data,len);
+ sta_cli_cmd_id = CMD_ID_STATUS;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(STA_ERR_SUCCESS == err){
+ return sta_cli_cmd_status_parse(sta_cli_cmd_reply,
+ data,
+ len);
+ }else{
+ printf("STATUS cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_mib
+(
+ const char *cmd,
+ char *data,
+ size_t len
+)
+{
+ bzero(data,len);
+ sta_cli_cmd_id = CMD_ID_MIB;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(STA_ERR_SUCCESS == err){
+ return sta_cli_cmd_mib_parse(sta_cli_cmd_reply,
+ data,
+ len);
+ }else{
+ printf("MIB cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_reconfigure
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_RECONFIGURE;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("RECONFIGURE cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("RECONFIGURE cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_disconnect
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_DISCONNECT;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("DISCONNECT cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("DISCONNECT cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_reconnect
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_RECONNECT;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("RECONNECT cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("RECONNECT cmd fail.\n");
+ return err;
+ }
+}
+
+
+static sta_err_enum
+sta_cli_cmd_save_config
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_SAVE_CONFIG;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("SAVE_CONFIG cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("SAVE_CONFIG cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_set_network_process
+(
+ char *c
+)
+{
+ printf("cmd = %s\n",c);
+ char *ptr = c;
+
+ sta_cli_cmd_id = CMD_ID_SET_NETWORK;
+ sta_err_enum err = STA_ERR_SUCCESS;
+ char cmd[100];
+ int index = str_indexof(ptr,"#");
+ bzero(cmd,100);
+ if(index > 0)
+ {
+ memcpy(cmd,ptr,index);
+ ptr += (index + 1);
+ }else
+ {
+ memcpy(cmd,ptr,strlen(ptr));
+ ptr = NULL;
+ }
+
+ while(TRUE)
+ {
+ err = sta_cli_process_cmd(c);
+ if(STA_ERR_SUCCESS == err){
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ //return STA_ERR_SUCCESS;
+ printf("Success:%s\n",cmd);
+ }else{
+ printf("Fail:%s\n",cmd);
+ sta_cli_cmd_id = CMD_ID_NON;
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("Fail:%s\n",cmd);
+ return err;
+ }
+
+ if(ptr == NULL)
+ break;
+
+ printf("ptr = %s",ptr);
+
+ index = str_indexof(ptr,"#");
+ bzero(cmd,100);
+ if(index > 0)
+ {
+ memcpy(cmd,ptr,index);
+ ptr += (index + 1);
+ }else
+ {
+ memcpy(cmd,ptr,strlen(ptr));
+ ptr = NULL;
+ }
+ }
+
+ sta_cli_cmd_id = CMD_ID_NON;
+ return STA_ERR_SUCCESS;
+}
+
+static sta_err_enum
+sta_cli_cmd_set_network
+(
+ const char *cmd,
+ const char *flag
+)
+{
+ printf("cmd = %s\n",cmd);
+ char buf[500];
+ printf("test11\n");
+ int index = str_indexof(cmd," psk ");
+ printf("test12\n");
+ int net_id = atoi(cmd + strlen(STA_CMD_SET_NETWORK) + 1);
+ printf("test13\n");
+ if(index > 0){ // Is set "psk"
+ printf("test14\n");
+ char psk[64] = {0};
+ int start = index + 5; // " psk "
+ if(*(cmd + start) == '"')
+ {
+ printf("test15\n");
+ memcpy(psk,cmd + start + 1,strlen(cmd) - start - 2);
+ }else{
+ printf("test16\n");
+ memcpy(psk,cmd + start,strlen(cmd) - start);
+ }
+ printf("psk = %s\n",psk);
+
+ // Set to OPEN (No psk)
+ // SET_NETWORK <net_id> key_mgmt NONE
+ if(strcmp(psk,"0") == 0)
+ {
+ int size = snprintf(buf,500,
+ "%s %d key_mgmt NONE",
+ STA_CMD_SET_NETWORK,
+ net_id);
+ buf[size] = '\0';
+ return sta_cli_cmd_set_network_process(buf);
+ }
+
+ // WEP
+ // key_mgmt=NONE
+ // auth_alg=OPEN SHARED
+ // wep_key0="0123456789abc"
+ if(flag && str_contains(flag, "WEP")
+ &&(strlen(psk) == 5
+ || strlen(psk) == 13
+ || strlen(psk) == 10
+ || strlen(psk) == 26))
+ {
+ int size = 0;
+ if(strlen(psk) == 5
+ || strlen(psk) == 13)
+ {
+ size = snprintf(buf,500,
+ "%s %d key_mgmt NONE#%s %d auth_alg SHARED#%s %d wep_key0 \"%s\"",
+ STA_CMD_SET_NETWORK,
+ net_id,
+ STA_CMD_SET_NETWORK,
+ net_id,
+ STA_CMD_SET_NETWORK,
+ net_id,
+ psk);
+ }else{
+ size = snprintf(buf,500,
+ "%s %d key_mgmt NONE#%s %d auth_alg SHARED#%s %d wep_key0 %s",
+ STA_CMD_SET_NETWORK,
+ net_id,
+ STA_CMD_SET_NETWORK,
+ net_id,
+ STA_CMD_SET_NETWORK,
+ net_id,
+ psk);
+ }
+
+ buf[size] = '\0';
+ return sta_cli_cmd_set_network_process(buf);
+ }
+
+ // Default is "WPA/WPA2"
+ int size = snprintf(buf,500,
+ "%s#%s %d key_mgmt WPA-PSK",
+ cmd,
+ STA_CMD_SET_NETWORK,
+ net_id);
+ buf[size] = '\0';
+ return sta_cli_cmd_set_network_process(buf);
+ }
+ else // SSID
+ {
+ printf("test21\n");
+ index = str_indexof(cmd," ssid ");
+ char ssid[STA_BUF_SIZE] = {0};
+ int start = index + 6; // " ssid "
+ if(*(cmd + start) == '"')
+ {
+ memcpy(ssid,cmd + start + 1,strlen(cmd) - start - 2);
+ }else{
+ memcpy(ssid,cmd + start,strlen(cmd) - start);
+ }
+ printf("ssid = %s\n",ssid);
+
+
+ //char ssid_result[STA_SSID_MAX_LEN + 1];
+ //sta_cli_ssid_process(ssid,ssid_result,STA_SSID_MAX_LEN + 2 + 1);
+ // printf("test22, ssid_result: %s\n", ssid_result);
+ char cmd_result[STA_BUF_SIZE];
+ int size = snprintf(cmd_result,STA_BUF_SIZE,
+ "%s %d ssid %s",
+ STA_CMD_SET_NETWORK,
+ net_id,
+ ssid);
+ cmd_result[size] = '\0';
+ printf("cmd = %s\n",cmd_result);
+
+ return sta_cli_cmd_set_network_process(cmd);
+ }
+}
+
+
+static sta_err_enum
+sta_cli_cmd_get_network
+(
+ const char *cmd,
+ char *value,
+ int len
+)
+{
+ bzero(value,len);
+ sta_cli_cmd_id = CMD_ID_GET_NETWORK;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+
+ char *tmp = sta_cli_cmd_reply;
+ while(*tmp == '\"'){
+ tmp++;
+ }
+ // Copy with '\0'
+ memcpy(value,tmp,strlen(tmp) + 1);
+
+ tmp = value + strlen(value) -1;
+ while(*tmp == '\"'){
+ tmp = '\0';
+ tmp--;
+ }
+
+ printf("GET_NETWORK:%s.\n",value);
+ return STA_ERR_SUCCESS;
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("GET_NETWORK cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_remove_network
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_REMOVE_NETWORK;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("REMOVE_NETWORK cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("REMOVE_NETWORK cmd fail.\n");
+ return err;
+ }
+}
+
+
+static sta_err_enum
+sta_cli_cmd_add_network
+(
+ const char *cmd
+)
+{
+ printf("cmd = %s\n",cmd);
+ sta_cli_cmd_id = CMD_ID_ADD_NETWORK;
+ sta_err_enum err = sta_cli_process_cmd(STA_CMD_ADD_NETWORK);
+ printf("test1\n");
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ int net_id = atoi(sta_cli_cmd_reply);
+ printf("test2\n");
+ if(net_id >= 0){ // Add network success.
+ // Point to ssid
+ printf("test3\n");
+ /*
+ const char *ptr = cmd + strlen(STA_CMD_ADD_NETWORK) + 1;
+
+ //int index = str_indexof(ptr," ");
+
+ char *pass_ptr = cmd + strlen(cmd);
+ while(*--pass_ptr != ' ')
+ ;
+ pass_ptr++; // Point to pass.
+
+
+ char ssid[STA_BUF_SIZE] = {0};
+ printf("test4\n");
+ memcpy(ssid,ptr,pass_ptr - ptr - 1);
+ */
+
+ char buf[STA_BUF_SIZE] = {'\0'};
+ char ssid[STA_BUF_SIZE] = {'\0'};
+ char psk[STA_BUF_SIZE] = {'\0'};
+ int len = 0;
+ printf("test5\n");
+
+ sta_cli_ssid_get(ssid);
+ len = strlen(ssid);
+ ssid[len - 1] = '\0';
+
+ sta_cli_psk_get(psk);
+ len = strlen(psk);
+ psk[len - 1] = '\0';
+
+
+ int size = snprintf(buf,STA_BUF_SIZE,
+ "%s %d ssid \"%s\"",
+ STA_CMD_SET_NETWORK,
+ net_id,
+ ssid);
+ printf("test6\n");
+ buf[size] = '\0';
+
+
+ err = sta_cli_cmd_set_network(buf,NULL);
+ printf("test7\n");
+ if(STA_ERR_SUCCESS == err){
+ char flag[50];
+ sta_cli_flag_get(ssid,flag,50);
+ size = snprintf(buf,100,
+ "%s %d psk \"%s\"",
+ STA_CMD_SET_NETWORK,
+ net_id,
+ psk);
+ buf[size] = '\0';
+ err = sta_cli_cmd_set_network(buf,flag);
+ if(STA_ERR_SUCCESS == err){
+ return STA_ERR_SUCCESS;
+ }
+ }
+
+ if(err != STA_ERR_SUCCESS) // remove network
+ {
+ int size = snprintf(buf,STA_BUF_SIZE,
+ "%s %d",
+ STA_CMD_REMOVE_NETWORK,
+ net_id);
+ buf[size] = '\0';
+ sta_cli_process_cmd(buf);
+ }
+
+ return err;
+ }else{
+ printf("ADD_NETWORK cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ printf("ADD_NETWORK cmd fail.\n");
+ sta_cli_cmd_id = CMD_ID_NON;
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_disable_network
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_DISABLE_NETWORK;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("DISABLE_NETWORK cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("DISABLE_NETWORK cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_enable_network
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_ENABLE_NETWORK;
+ sta_err_enum err = sta_cli_process_cmd("ENABLE_NETWORK 1");
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("ENABLE_NETWORK cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("ENABLE_NETWORK cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_select_network
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_SELECT_NETWORK;
+ sta_err_enum err = sta_cli_process_cmd("SELECT_NETWORK 1");
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("SELECT_NETWORK cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("SELECT_NETWORK cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_list_networks
+(
+ const char *cmd,
+ char *data,
+ size_t len
+)
+{
+ bzero(data,len);
+ sta_cli_cmd_id = CMD_ID_LIST_NETWORKS;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(STA_ERR_SUCCESS == err){
+ return sta_cli_cmd_list_network_parse(sta_cli_cmd_reply,
+ data,
+ len);
+ }else{
+ printf("LIST_NETWORKS cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_reassociate
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_REASSOCIATE;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("REASSOCIATE cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("REASSOCIATE cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_cmd_reattach
+(
+ const char *cmd
+)
+{
+ sta_cli_cmd_id = CMD_ID_REATTACH;
+ sta_err_enum err = sta_cli_process_cmd(cmd);
+ if(STA_ERR_SUCCESS == err){
+ sta_cli_cmd_id = CMD_ID_NON;
+ if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){
+ return STA_ERR_SUCCESS;
+ }else{
+ printf("REATTACH cmd fail.\n");
+ return STA_ERR_UNKNOWN;
+ }
+ }else{
+ sta_cli_cmd_id = CMD_ID_NON;
+ printf("REATTACH cmd fail.\n");
+ return err;
+ }
+}
+
+static sta_err_enum
+sta_cli_init
+(
+ void
+)
+{
+ sta_err_enum result = STA_ERR_SUCCESS;
+ if((result = sta_ctrl_driver_init(TRUE)) != STA_ERR_SUCCESS){
+ printf("Driver init fail(%d).\n",result);
+ return result;
+ }
+
+ if((result = sta_ctrl_wpa_init(
+ "/etc/wifi/wpa_supplicant.conf",
+ "wlan0",
+ sta_cli_wpa_msg_cb)) != STA_ERR_SUCCESS){
+ printf("wpa_supplicant init fail(%d).\n",result);
+ return result;
+ }
+ //pthread_mutex_init(&sta_mutex,NULL);
+ return result;
+}
+
+static sta_err_enum
+sta_cli_deinit
+(
+ void
+)
+{
+ sta_err_enum result = STA_ERR_SUCCESS;
+ if((result = sta_ctrl_wpa_deinit()) != STA_ERR_SUCCESS){
+ printf("sta_ctrl_wpa_deinit fail(%d).",result);
+ return result;
+ }
+
+ if((result = sta_ctrl_driver_init(FALSE)) != STA_ERR_SUCCESS){
+ printf("Driver close fail(%d).\n",result);
+ return result;
+ }
+ //pthread_mutex_destroy(&sta_mutex);
+ return result;
+}
+
+/**
+* CMD-CLOSE-SUCCESS
+* CMD-CLOSE-FAIL:2
+*
+* CMD-SCAN-XXX
+*
+* IND-XXX
+*
+*/
+bool sta_cli_cmd_parse
+(
+ const char *cmd,
+ char *reply,
+ size_t reply_len
+)
+{
+ printf("cmd:%s\n",cmd);
+ bzero(reply,reply_len);
+ sta_err_enum err = STA_ERR_UNKNOWN;
+ if(strncmp(cmd,(STA_CMD_OPEN),strlen(STA_CMD_OPEN)) == 0){
+ // Will OPEN connection with wpa_supplicant.
+ err = sta_cli_init();
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ sta_should_send_connected_msg = FALSE;
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_CLOSE,strlen(STA_CMD_CLOSE)) == 0){
+ err = sta_cli_deinit();
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ sta_should_send_connected_msg = TRUE;
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_SCAN,strlen(STA_CMD_SCAN)) == 0){
+ char data[STA_BUF_SIZE];
+ err = sta_cli_cmd_scan(cmd, data,STA_BUF_SIZE);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ data);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_STATUS,strlen(STA_CMD_STATUS)) == 0){
+ char data[STA_BUF_SIZE];
+ err = sta_cli_cmd_status(cmd, data,STA_BUF_SIZE);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ data);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_MIB,strlen(STA_CMD_MIB)) == 0){
+ char data[STA_BUF_SIZE];
+ err = sta_cli_cmd_mib(cmd, data,STA_BUF_SIZE);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ data);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_RECONFIGURE,strlen(STA_CMD_RECONFIGURE)) == 0){
+ err = sta_cli_cmd_reconfigure(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_DISCONNECT,strlen(STA_CMD_DISCONNECT)) == 0){
+ sta_disconnectting = TRUE;
+ err = sta_cli_cmd_disconnect(cmd);
+ // Not reply(Reply after disconnecd).
+#if 0
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+#endif
+ if(err == STA_ERR_SUCCESS)
+ {
+ printf("sta_cli_cmd_disconnect success.\n");
+ //pthread_mutex_lock(&sta_mutex);
+ //if(sta_connected)
+ //{
+ #define GET_STATUS_MAX 5
+ int count = 0;
+ bool ok = FALSE;
+ usleep(500);
+ while(count++ < GET_STATUS_MAX)
+ {
+ sta_err_enum err = sta_cli_process_cmd(STA_CMD_STATUS);
+ if(STA_ERR_SUCCESS == err){
+ char mac_ap[STA_MAC_LEN + 1];
+ if(!sta_cli_value_get(sta_cli_cmd_reply,
+ "bssid=",
+ mac_ap,
+ STA_MAC_LEN + 1)) // Disconnected.
+ {
+ printf("Disconnected success.\n");
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ ok = TRUE;
+ break;
+ }else{ // Connected.
+ printf("Not disconnected.Try again(STATUS).\n");
+ usleep(500);
+ }
+ }else{
+ printf("STATUS cmd fail.\n");
+ break;
+ }
+ }
+
+ if(!ok) // fail
+ {
+ printf("Disconnect fail.\n");
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ STA_ERR_UNKNOWN);
+ }
+ //sta_connected = FALSE;
+ //}
+ //pthread_mutex_unlock(&sta_mutex);
+ }else{
+ printf("sta_cli_cmd_disconnect fail.\n");
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ sta_disconnectting = FALSE;
+ }else if(strncmp(cmd,STA_CMD_RECONNECT,strlen(STA_CMD_RECONNECT)) == 0){
+ err = sta_cli_cmd_reconnect(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_SAVE_CONFIG,strlen(STA_CMD_SAVE_CONFIG)) == 0){
+ err = sta_cli_cmd_save_config(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_SET_NETWORK,strlen(STA_CMD_SET_NETWORK)) == 0){
+ err = sta_cli_cmd_set_network(cmd,NULL);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_GET_NETWORK,strlen(STA_CMD_GET_NETWORK)) == 0){
+ char data[100];
+ err = sta_cli_cmd_get_network(cmd,data,100);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ data);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_REMOVE_NETWORK,strlen(STA_CMD_REMOVE_NETWORK)) == 0){
+ err = sta_cli_cmd_remove_network(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_ADD_NETWORK,strlen(STA_CMD_ADD_NETWORK)) == 0){
+ err = sta_cli_cmd_add_network(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_DISABLE_NETWORK,strlen(STA_CMD_DISABLE_NETWORK)) == 0){
+ err = sta_cli_cmd_disable_network(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_ENABLE_NETWORK,strlen(STA_CMD_ENABLE_NETWORK)) == 0){
+ err = sta_cli_cmd_enable_network(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_SELECT_NETWORK,strlen(STA_CMD_SELECT_NETWORK)) == 0){
+ err = sta_cli_cmd_select_network(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_LIST_NETWORKS,strlen(STA_CMD_REASSOCIATE)) == 0){
+ char data[STA_BUF_SIZE];
+ err = sta_cli_cmd_list_networks(cmd, data,STA_BUF_SIZE);
+
+// char reply_tmp[STA_BUF_SIZE];
+// memset(reply_tmp,0,STA_BUF_SIZE);
+// char *reply_ptr = data;
+// int index = 0;
+// int pos = 0;
+// while(*reply_ptr != '\0'){
+// if(*reply_ptr == ','){
+// index++;
+// }
+
+// if(index == 3){
+// if(*reply_ptr == '\n'){
+// index = 0;
+// reply_tmp[pos++] = '\r';
+// reply_tmp[pos++] = '\n';
+// }
+// }else{
+// reply_tmp[pos++] = *reply_ptr;
+// }
+
+// reply_ptr++;
+// }
+
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ data);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_REASSOCIATE,strlen(STA_CMD_REASSOCIATE)) == 0){
+ err = sta_cli_cmd_reassociate(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else if(strncmp(cmd,STA_CMD_REATTACH,strlen(STA_CMD_REATTACH)) == 0){
+ err = sta_cli_cmd_reattach(cmd);
+ if(err == STA_ERR_SUCCESS){
+ snprintf(reply,reply_len,
+ "%s-%s-%s"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_SUCCESS);
+ }else{
+ snprintf(reply,reply_len,
+ "%s-%s-%s:%d"STA_CMD_SEPARATED,
+ STA_TAG_CMD,
+ cmd,
+ STA_TAG_CMD_FAIL,
+ err);
+ }
+ }else{
+ printf("Unknown cmd:%s\n",cmd);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
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;
+}
+