new_func_wifi_1
Change-Id: Ie23b919a0d154becb37e1e6b27ecc98a8377e3b9
diff --git a/mbtk/include/mbtk/sta_cli.h b/mbtk/include/mbtk/sta_cli.h
new file mode 100644
index 0000000..74ac0d3
--- /dev/null
+++ b/mbtk/include/mbtk/sta_cli.h
@@ -0,0 +1,40 @@
+#ifndef STA_CLI_INCLUDE
+#define STA_CLI_INCLUDE
+#include <stdio.h>
+#include <stdbool.h>
+
+typedef enum
+{
+ CMD_ID_NON = 0,
+ CMD_ID_SCAN,
+ CMD_ID_SCAN_RESULTS,
+ CMD_ID_STATUS,
+ CMD_ID_MIB,
+ CMD_ID_RECONFIGURE,
+ CMD_ID_DISCONNECT,
+ CMD_ID_RECONNECT,
+ CMD_ID_SAVE_CONFIG,
+ CMD_ID_GET_NETWORK,
+ CMD_ID_SET_NETWORK,
+ CMD_ID_REMOVE_NETWORK,
+ CMD_ID_ADD_NETWORK,
+ CMD_ID_DISABLE_NETWORK,
+ CMD_ID_ENABLE_NETWORK,
+ CMD_ID_SELECT_NETWORK,
+ CMD_ID_LIST_NETWORKS,
+ CMD_ID_REASSOCIATE,
+ CMD_ID_REATTACH
+}sta_cli_cmd_id_enum;
+
+bool sta_cli_cmd_parse
+(
+ const char *cmd,
+ char *reply,
+ size_t reply_len
+);
+
+int sta_cli_ssid_get(char *ssid);
+int sta_cli_psk_get(char *psk);
+
+
+#endif /* STA_CLI_INCLUDE */
\ No newline at end of file
diff --git a/mbtk/include/mbtk/sta_ctrl.h b/mbtk/include/mbtk/sta_ctrl.h
new file mode 100644
index 0000000..ae25c99
--- /dev/null
+++ b/mbtk/include/mbtk/sta_ctrl.h
@@ -0,0 +1,43 @@
+#ifndef STA_CTRL_INCLUDE
+#define STA_CTRL_INCLUDE
+
+#include "mbtk_type.h"
+
+#define STA_BUF_SIZE 2048
+
+typedef enum{
+ STA_ERR_SUCCESS,
+ STA_ERR_DRIVER,
+ STA_ERR_TIMEOUT,
+ STA_ERR_UNKNOWN
+} sta_err_enum;
+
+typedef void (*sta_ctrl_msg_cb)(char*);
+
+sta_err_enum
+sta_ctrl_cmd_process
+(
+ const char *cmd,
+ char *cmd_rsp,
+ size_t rsp_len
+);
+
+sta_err_enum
+sta_ctrl_driver_init(bool open);
+
+sta_err_enum
+sta_ctrl_wpa_init
+(
+ const char *conf_file,
+ const char *interface,
+ sta_ctrl_msg_cb cb
+);
+
+sta_err_enum
+sta_ctrl_wpa_deinit
+(
+ void
+);
+
+#endif /* STA_CTRL_INCLUDE */
+
diff --git a/mbtk/include/mbtk/wpa_ctrl.h b/mbtk/include/mbtk/wpa_ctrl.h
new file mode 100644
index 0000000..ee6f6de
--- /dev/null
+++ b/mbtk/include/mbtk/wpa_ctrl.h
@@ -0,0 +1,415 @@
+/*
+ * wpa_supplicant/hostapd control interface library
+ * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_CTRL_H
+#define WPA_CTRL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* wpa_supplicant control interface - fixed message prefixes */
+
+/** Interactive request for identity/password/pin */
+#define WPA_CTRL_REQ "CTRL-REQ-"
+
+/** Response to identity/password/pin request */
+#define WPA_CTRL_RSP "CTRL-RSP-"
+
+/* Event messages with fixed prefix */
+/** Authentication completed successfully and data connection enabled */
+#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
+/** Disconnected, data connection is not available */
+#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
+/** Association rejected during connection attempt */
+#define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT "
+/** wpa_supplicant is exiting */
+#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
+/** Password change was completed successfully */
+#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
+/** EAP-Request/Notification received */
+#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
+/** EAP authentication started (EAP-Request/Identity received) */
+#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
+/** EAP method proposed by the server */
+#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD "
+/** EAP method selected */
+#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
+/** EAP peer certificate from TLS */
+#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
+/** EAP TLS certificate chain validation error */
+#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
+/** EAP status */
+#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS "
+/** EAP authentication completed successfully */
+#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
+/** EAP authentication failed (EAP-Failure received) */
+#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "
+/** Network block temporarily disabled (e.g., due to authentication failure) */
+#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED "
+/** Temporarily disabled network block re-enabled */
+#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED "
+/** New scan started */
+#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED "
+/** New scan results available */
+#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
+/** Scan command failed */
+#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED "
+/** wpa_supplicant state change */
+#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE "
+/** A new BSS entry was added (followed by BSS entry id and BSSID) */
+#define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
+/** A BSS entry was removed (followed by BSS entry id and BSSID) */
+#define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
+/** Change in the signal level was reported by the driver */
+#define WPA_EVENT_SIGNAL_CHANGE "CTRL-EVENT-SIGNAL-CHANGE "
+/** Regulatory domain channel */
+#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
+
+/** RSN IBSS 4-way handshakes completed with specified peer */
+#define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED "
+
+/** Notification of frequency conflict due to a concurrent operation.
+ *
+ * The indicated network is disabled and needs to be re-enabled before it can
+ * be used again.
+ */
+#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
+/** Frequency ranges that the driver recommends to avoid */
+#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
+/** WPS overlap detected in PBC mode */
+#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
+/** Available WPS AP with active PBC found in scan results */
+#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC "
+/** Available WPS AP with our address as authorized in scan results */
+#define WPS_EVENT_AP_AVAILABLE_AUTH "WPS-AP-AVAILABLE-AUTH "
+/** Available WPS AP with recently selected PIN registrar found in scan results
+ */
+#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN "
+/** Available WPS AP found in scan results */
+#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE "
+/** A new credential received */
+#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
+/** M2D received */
+#define WPS_EVENT_M2D "WPS-M2D "
+/** WPS registration failed after M2/M2D */
+#define WPS_EVENT_FAIL "WPS-FAIL "
+/** WPS registration completed successfully */
+#define WPS_EVENT_SUCCESS "WPS-SUCCESS "
+/** WPS enrollment attempt timed out and was terminated */
+#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT "
+/* PBC mode was activated */
+#define WPS_EVENT_ACTIVE "WPS-PBC-ACTIVE "
+/* PBC mode was disabled */
+#define WPS_EVENT_DISABLE "WPS-PBC-DISABLE "
+
+#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
+
+#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
+
+/* WPS ER events */
+#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
+#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
+#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD "
+#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE "
+#define WPS_EVENT_ER_AP_SETTINGS "WPS-ER-AP-SETTINGS "
+#define WPS_EVENT_ER_SET_SEL_REG "WPS-ER-AP-SET-SEL-REG "
+
+/** P2P device found */
+#define P2P_EVENT_DEVICE_FOUND "P2P-DEVICE-FOUND "
+
+/** P2P device lost */
+#define P2P_EVENT_DEVICE_LOST "P2P-DEVICE-LOST "
+
+/** A P2P device requested GO negotiation, but we were not ready to start the
+ * negotiation */
+#define P2P_EVENT_GO_NEG_REQUEST "P2P-GO-NEG-REQUEST "
+#define P2P_EVENT_GO_NEG_SUCCESS "P2P-GO-NEG-SUCCESS "
+#define P2P_EVENT_GO_NEG_FAILURE "P2P-GO-NEG-FAILURE "
+#define P2P_EVENT_GROUP_FORMATION_SUCCESS "P2P-GROUP-FORMATION-SUCCESS "
+#define P2P_EVENT_GROUP_FORMATION_FAILURE "P2P-GROUP-FORMATION-FAILURE "
+#define P2P_EVENT_GROUP_STARTED "P2P-GROUP-STARTED "
+#define P2P_EVENT_GROUP_REMOVED "P2P-GROUP-REMOVED "
+#define P2P_EVENT_CROSS_CONNECT_ENABLE "P2P-CROSS-CONNECT-ENABLE "
+#define P2P_EVENT_CROSS_CONNECT_DISABLE "P2P-CROSS-CONNECT-DISABLE "
+/* parameters: <peer address> <PIN> */
+#define P2P_EVENT_PROV_DISC_SHOW_PIN "P2P-PROV-DISC-SHOW-PIN "
+/* parameters: <peer address> */
+#define P2P_EVENT_PROV_DISC_ENTER_PIN "P2P-PROV-DISC-ENTER-PIN "
+/* parameters: <peer address> */
+#define P2P_EVENT_PROV_DISC_PBC_REQ "P2P-PROV-DISC-PBC-REQ "
+/* parameters: <peer address> */
+#define P2P_EVENT_PROV_DISC_PBC_RESP "P2P-PROV-DISC-PBC-RESP "
+/* parameters: <peer address> <status> */
+#define P2P_EVENT_PROV_DISC_FAILURE "P2P-PROV-DISC-FAILURE"
+/* parameters: <freq> <src addr> <dialog token> <update indicator> <TLVs> */
+#define P2P_EVENT_SERV_DISC_REQ "P2P-SERV-DISC-REQ "
+/* parameters: <src addr> <update indicator> <TLVs> */
+#define P2P_EVENT_SERV_DISC_RESP "P2P-SERV-DISC-RESP "
+#define P2P_EVENT_INVITATION_RECEIVED "P2P-INVITATION-RECEIVED "
+#define P2P_EVENT_INVITATION_RESULT "P2P-INVITATION-RESULT "
+#define P2P_EVENT_FIND_STOPPED "P2P-FIND-STOPPED "
+#define P2P_EVENT_PERSISTENT_PSK_FAIL "P2P-PERSISTENT-PSK-FAIL id="
+#define P2P_EVENT_PRESENCE_RESPONSE "P2P-PRESENCE-RESPONSE "
+#define P2P_EVENT_NFC_BOTH_GO "P2P-NFC-BOTH-GO "
+#define P2P_EVENT_NFC_PEER_CLIENT "P2P-NFC-PEER-CLIENT "
+#define P2P_EVENT_NFC_WHILE_CLIENT "P2P-NFC-WHILE-CLIENT "
+
+/* parameters: <PMF enabled> <timeout in ms> <Session Information URL> */
+#define ESS_DISASSOC_IMMINENT "ESS-DISASSOC-IMMINENT "
+#define P2P_EVENT_REMOVE_AND_REFORM_GROUP "P2P-REMOVE-AND-REFORM-GROUP "
+
+#define INTERWORKING_AP "INTERWORKING-AP "
+#define INTERWORKING_BLACKLISTED "INTERWORKING-BLACKLISTED "
+#define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH "
+#define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED "
+#define INTERWORKING_SELECTED "INTERWORKING-SELECTED "
+
+/* Credential block added; parameters: <id> */
+#define CRED_ADDED "CRED-ADDED "
+/* Credential block modified; parameters: <id> <field> */
+#define CRED_MODIFIED "CRED-MODIFIED "
+/* Credential block removed; parameters: <id> */
+#define CRED_REMOVED "CRED-REMOVED "
+
+#define GAS_RESPONSE_INFO "GAS-RESPONSE-INFO "
+/* parameters: <addr> <dialog_token> <freq> */
+#define GAS_QUERY_START "GAS-QUERY-START "
+/* parameters: <addr> <dialog_token> <freq> <status_code> <result> */
+#define GAS_QUERY_DONE "GAS-QUERY-DONE "
+
+#define HS20_SUBSCRIPTION_REMEDIATION "HS20-SUBSCRIPTION-REMEDIATION "
+#define HS20_DEAUTH_IMMINENT_NOTICE "HS20-DEAUTH-IMMINENT-NOTICE "
+
+#define EXT_RADIO_WORK_START "EXT-RADIO-WORK-START "
+#define EXT_RADIO_WORK_TIMEOUT "EXT-RADIO-WORK-TIMEOUT "
+
+/* hostapd control interface - fixed message prefixes */
+#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
+#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
+#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
+#define WPS_EVENT_AP_SETUP_LOCKED "WPS-AP-SETUP-LOCKED "
+#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED "
+#define WPS_EVENT_AP_PIN_ENABLED "WPS-AP-PIN-ENABLED "
+#define WPS_EVENT_AP_PIN_DISABLED "WPS-AP-PIN-DISABLED "
+#define AP_STA_CONNECTED "AP-STA-CONNECTED "
+#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
+
+#define AP_REJECTED_MAX_STA "AP-REJECTED-MAX-STA "
+#define AP_REJECTED_BLOCKED_STA "AP-REJECTED-BLOCKED-STA "
+
+#define AP_EVENT_ENABLED "AP-ENABLED "
+#define AP_EVENT_DISABLED "AP-DISABLED "
+
+#define ACS_EVENT_STARTED "ACS-STARTED "
+#define ACS_EVENT_COMPLETED "ACS-COMPLETED "
+#define ACS_EVENT_FAILED "ACS-FAILED "
+
+#define DFS_EVENT_RADAR_DETECTED "DFS-RADAR-DETECTED "
+#define DFS_EVENT_NEW_CHANNEL "DFS-NEW-CHANNEL "
+#define DFS_EVENT_CAC_START "DFS-CAC-START "
+#define DFS_EVENT_CAC_COMPLETED "DFS-CAC-COMPLETED "
+#define DFS_EVENT_NOP_FINISHED "DFS-NOP-FINISHED "
+
+#define AP_CSA_FINISHED "AP-CSA-FINISHED "
+
+/* BSS command information masks */
+
+#define WPA_BSS_MASK_ALL 0xFFFDFFFF
+#define WPA_BSS_MASK_ID BIT(0)
+#define WPA_BSS_MASK_BSSID BIT(1)
+#define WPA_BSS_MASK_FREQ BIT(2)
+#define WPA_BSS_MASK_BEACON_INT BIT(3)
+#define WPA_BSS_MASK_CAPABILITIES BIT(4)
+#define WPA_BSS_MASK_QUAL BIT(5)
+#define WPA_BSS_MASK_NOISE BIT(6)
+#define WPA_BSS_MASK_LEVEL BIT(7)
+#define WPA_BSS_MASK_TSF BIT(8)
+#define WPA_BSS_MASK_AGE BIT(9)
+#define WPA_BSS_MASK_IE BIT(10)
+#define WPA_BSS_MASK_FLAGS BIT(11)
+#define WPA_BSS_MASK_SSID BIT(12)
+#define WPA_BSS_MASK_WPS_SCAN BIT(13)
+#define WPA_BSS_MASK_P2P_SCAN BIT(14)
+#define WPA_BSS_MASK_INTERNETW BIT(15)
+#define WPA_BSS_MASK_WIFI_DISPLAY BIT(16)
+#define WPA_BSS_MASK_DELIM BIT(17)
+#define WPA_BSS_MASK_FST BIT(21)
+
+
+/* VENDOR_ELEM_* frame id values */
+enum wpa_vendor_elem_frame {
+ VENDOR_ELEM_PROBE_REQ_P2P = 0,
+ VENDOR_ELEM_PROBE_RESP_P2P = 1,
+ VENDOR_ELEM_PROBE_RESP_P2P_GO = 2,
+ VENDOR_ELEM_BEACON_P2P_GO = 3,
+ VENDOR_ELEM_P2P_PD_REQ = 4,
+ VENDOR_ELEM_P2P_PD_RESP = 5,
+ VENDOR_ELEM_P2P_GO_NEG_REQ = 6,
+ VENDOR_ELEM_P2P_GO_NEG_RESP = 7,
+ VENDOR_ELEM_P2P_GO_NEG_CONF = 8,
+ VENDOR_ELEM_P2P_INV_REQ = 9,
+ VENDOR_ELEM_P2P_INV_RESP = 10,
+ VENDOR_ELEM_P2P_ASSOC_REQ = 11,
+ VENDOR_ELEM_P2P_ASSOC_RESP = 12,
+ NUM_VENDOR_ELEM_FRAMES
+};
+
+
+/* wpa_supplicant/hostapd control interface access */
+
+/**
+ * wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd
+ * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
+ * Returns: Pointer to abstract control interface data or %NULL on failure
+ *
+ * This function is used to open a control interface to wpa_supplicant/hostapd.
+ * ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd. This path
+ * is configured in wpa_supplicant/hostapd and other programs using the control
+ * interface need to use matching path configuration.
+ */
+struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
+
+
+/**
+ * wpa_ctrl_close - Close a control interface to wpa_supplicant/hostapd
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ *
+ * This function is used to close a control interface.
+ */
+void wpa_ctrl_close(struct wpa_ctrl *ctrl);
+
+
+/**
+ * wpa_ctrl_request - Send a command to wpa_supplicant/hostapd
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * @cmd: Command; usually, ASCII text, e.g., "PING"
+ * @cmd_len: Length of the cmd in bytes
+ * @reply: Buffer for the response
+ * @reply_len: Reply buffer length
+ * @msg_cb: Callback function for unsolicited messages or %NULL if not used
+ * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
+ *
+ * This function is used to send commands to wpa_supplicant/hostapd. Received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply. This function will block for up to two seconds while waiting
+ * for the reply. If unsolicited messages are received, the blocking time may
+ * be longer.
+ *
+ * msg_cb can be used to register a callback function that will be called for
+ * unsolicited messages received while waiting for the command response. These
+ * messages may be received if wpa_ctrl_request() is called at the same time as
+ * wpa_supplicant/hostapd is sending such a message. This can happen only if
+ * the program has used wpa_ctrl_attach() to register itself as a monitor for
+ * event messages. Alternatively to msg_cb, programs can register two control
+ * interface connections and use one of them for commands and the other one for
+ * receiving event messages, in other words, call wpa_ctrl_attach() only for
+ * the control interface connection that will be used for event messages.
+ */
+int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
+ char *reply, size_t *reply_len,
+ void (*msg_cb)(char *msg, size_t len));
+
+
+/**
+ * wpa_ctrl_attach - Register as an event monitor for the control interface
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * Returns: 0 on success, -1 on failure, -2 on timeout
+ *
+ * This function registers the control interface connection as a monitor for
+ * wpa_supplicant/hostapd events. After a success wpa_ctrl_attach() call, the
+ * control interface connection starts receiving event messages that can be
+ * read with wpa_ctrl_recv().
+ */
+int wpa_ctrl_attach(struct wpa_ctrl *ctrl);
+
+
+/**
+ * wpa_ctrl_detach - Unregister event monitor from the control interface
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * Returns: 0 on success, -1 on failure, -2 on timeout
+ *
+ * This function unregisters the control interface connection as a monitor for
+ * wpa_supplicant/hostapd events, i.e., cancels the registration done with
+ * wpa_ctrl_attach().
+ */
+int wpa_ctrl_detach(struct wpa_ctrl *ctrl);
+
+
+/**
+ * wpa_ctrl_recv - Receive a pending control interface message
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * @reply: Buffer for the message data
+ * @reply_len: Length of the reply buffer
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function will receive a pending control interface message. The received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply.
+
+ * wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach()
+ * must have been used to register the control interface as an event monitor.
+ */
+int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);
+
+
+/**
+ * wpa_ctrl_pending - Check whether there are pending event messages
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * Returns: 1 if there are pending messages, 0 if no, or -1 on error
+ *
+ * This function will check whether there are any pending control interface
+ * message available to be received with wpa_ctrl_recv(). wpa_ctrl_pending() is
+ * only used for event messages, i.e., wpa_ctrl_attach() must have been used to
+ * register the control interface as an event monitor.
+ */
+int wpa_ctrl_pending(struct wpa_ctrl *ctrl);
+
+
+/**
+ * wpa_ctrl_get_fd - Get file descriptor used by the control interface
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * Returns: File descriptor used for the connection
+ *
+ * This function can be used to get the file descriptor that is used for the
+ * control interface connection. The returned value can be used, e.g., with
+ * select() while waiting for multiple events.
+ *
+ * The returned file descriptor must not be used directly for sending or
+ * receiving packets; instead, the library functions wpa_ctrl_request() and
+ * wpa_ctrl_recv() must be used for this.
+ */
+int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl);
+
+char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl);
+
+#ifdef ANDROID
+/**
+ * wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that
+ * may be left over from clients that were previously connected to
+ * wpa_supplicant. This keeps these files from being orphaned in the
+ * event of crashes that prevented them from being removed as part
+ * of the normal orderly shutdown.
+ */
+void wpa_ctrl_cleanup(void);
+#endif /* ANDROID */
+
+#ifdef CONFIG_CTRL_IFACE_UDP
+/* Port range for multiple wpa_supplicant instances and multiple VIFs */
+#define WPA_CTRL_IFACE_PORT 9877
+#define WPA_CTRL_IFACE_PORT_LIMIT 50 /* decremented from start */
+#define WPA_GLOBAL_CTRL_IFACE_PORT 9878
+#define WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT 20 /* incremented from start */
+#endif /* CONFIG_CTRL_IFACE_UDP */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WPA_CTRL_H */
diff --git a/mbtk/libmbtk_lib/Makefile b/mbtk/libmbtk_lib/Makefile
old mode 100755
new mode 100644
index 679250b..ebd38d9
--- a/mbtk/libmbtk_lib/Makefile
+++ b/mbtk/libmbtk_lib/Makefile
@@ -16,11 +16,12 @@
-I$(LOCAL_PATH)/mqtt/MQTTPacket \
-I$(LOCAL_PATH)/net \
-I$(LOCAL_PATH)/tcpip \
- -I$(LOCAL_PATH)/ril
+ -I$(LOCAL_PATH)/ril \
+ -I$(LOCAL_PATH)/wifi
LIB_DIR +=
-LIBS += -llog -lubus -lubox -luci -lprop2uci -lrilutil -lblobmsg_json -ldl -lcutils -laudio-apu -lssl -lcrypto
+LIBS += -llog -lubus -lubox -luci -lprop2uci -lrilutil -lblobmsg_json -ldl -lcutils -laudio-apu -lssl -lcrypto -lwpa_client
ifeq ($(BUILD_LIB_TYPE), shared)
CFLAGS += -shared -Wl,-shared,-Bsymbolic
@@ -135,6 +136,11 @@
# tcpip
LOCAL_SRC_FILES += \
tcpip/mbtk_tcpip_at.c
+
+#wifi
+LOCAL_SRC_FILES += \
+ wifi/sta_cli.c \
+ wifi/sta_ctrl.c
OBJS = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(LOCAL_SRC_FILES)))
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;
+}
+
diff --git a/mbtk/test/libmbtk_wifi/Makefile b/mbtk/test/libmbtk_wifi/Makefile
new file mode 100644
index 0000000..920fc81
--- /dev/null
+++ b/mbtk/test/libmbtk_wifi/Makefile
@@ -0,0 +1,36 @@
+BUILD_ROOT = $(shell pwd)/../..
+include $(BUILD_ROOT)/Make.defines
+
+INC_DIR +=
+
+LIB_DIR +=
+
+LIBS += -lmbtk_lib
+
+CFLAGS +=
+
+DEFINE +=
+
+
+LOCAL_SRC_FILES = mbtk_wifi_test.c
+
+
+$(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES))
+
+OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(LOCAL_SRC_FILES)))
+BINS = $(patsubst %.o,%,$(OBJS))
+
+all: $(BINS)
+
+$(BINS):$(OBJS)
+ @echo " BIN $@"
+ $(CC) $(CFLAGS) $(LIB_DIR) $(LIBS) $@.o -o $(OUT_DIR)/bin/$@
+
+%.o:%.c
+ $(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+%.o:%.cpp
+ $(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+clean:
+ rm -f $(OBJS)
diff --git a/mbtk/test/libmbtk_wifi/mbtk_wifi_test.c b/mbtk/test/libmbtk_wifi/mbtk_wifi_test.c
new file mode 100644
index 0000000..1842b2a
--- /dev/null
+++ b/mbtk/test/libmbtk_wifi/mbtk_wifi_test.c
@@ -0,0 +1,80 @@
+#include "sta_cli.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define STA_BUF_SIZE 2048
+
+
+int main(int argc, char *argv[])
+{
+ static char sta_cli_buf[STA_BUF_SIZE] = "OPEN";
+ char reply[STA_BUF_SIZE];
+
+
+ if(sta_cli_cmd_parse(sta_cli_buf, reply, STA_BUF_SIZE)){
+ if(strlen(reply) > 0)
+ {
+ printf("reply data(%s).\n",reply);
+ }else{
+ printf("No reply data(%s).\n",sta_cli_buf);
+ }
+ }else{
+ printf("Parse cmd fail.\n");
+ }
+
+
+ if(sta_cli_cmd_parse("ADD_NETWORK", reply, STA_BUF_SIZE))
+ {
+ if(strlen(reply) > 0)
+ {
+ printf("reply data(%s).\n",reply);
+ }else
+ {
+ printf("No reply data\n");
+ }
+ }
+ else
+ {
+ printf("Parse cmd fail.\n");
+ }
+
+
+ if(sta_cli_cmd_parse("SELECT_NETWORK", reply, STA_BUF_SIZE))
+ {
+ if(strlen(reply) > 0)
+ {
+ printf("reply data(%s).\n",reply);
+ }else
+ {
+ printf("No reply data\n");
+ }
+ }
+ else
+ {
+ printf("Parse cmd fail.\n");
+ }
+
+ if(sta_cli_cmd_parse("ENABLE_NETWORK", reply, STA_BUF_SIZE))
+ {
+ if(strlen(reply) > 0)
+ {
+ printf("reply data(%s).\n",reply);
+ }else
+ {
+ printf("No reply data\n");
+ }
+ }
+ else
+ {
+ printf("Parse cmd fail.\n");
+ }
+
+ system("udhcpc -i wlan0");
+
+
+
+ return 0;
+}
+