#include #include #include #include #include #include #include #include #define DBG 1 #if DBG #define DEBUG_INFO(M, ...) printf("Hostapd %d: " M, __LINE__, ##__VA_ARGS__) #else #define DEBUG_INFO(M, ...) do {} while (0) #endif #define DEBUG_ERR(M, ...) printf("Hostapd %d: " M, __LINE__, ##__VA_ARGS__) static void exec_command(char cmdline[], char recv_buff[], int len) { printf("[BT_DEBUG] execute: %s\n", cmdline); FILE *stream = NULL; char *tmp_buff = recv_buff; memset(recv_buff, 0, len); if ((stream = popen(cmdline, "r")) != NULL) { while (fgets(tmp_buff, len, stream)) { //pr_info("tmp_buf[%d]: %s\n", strlen(tmp_buff), tmp_buff); tmp_buff += strlen(tmp_buff); len -= strlen(tmp_buff); if (len <= 1) break; } printf("[BT_DEBUG] execute_r: %s \n", recv_buff); pclose(stream); } else printf("[popen] error: %s\n", cmdline); } static const int console_run(const char *cmdline) { int ret; DEBUG_INFO("cmdline = %s\n", cmdline); ret = system(cmdline); if (ret < 0) { DEBUG_ERR("Running cmdline failed: %s\n", cmdline); return 0; } return 1; } static int create_hostapd_file(char *ap, char *ssid, char *psk) { FILE* fp; char cmdline[256] = {0}; static char HOSTAPD_CONF_DIR[] = "/userdata/bin/hostapd.conf"; fp = fopen(HOSTAPD_CONF_DIR, "wt+"); if (NULL == fp) return -1; sprintf(cmdline, "interface=%s\n", ap); fputs(cmdline, fp); fputs("ctrl_interface=/var/run/hostapd\n", fp); fputs("driver=nl80211\n", fp); fputs("ssid=", fp); fputs(ssid, fp); fputs("\n", fp); fputs("channel=6\n", fp); fputs("hw_mode=g\n", fp); fputs("ieee80211n=1\n", fp); fputs("ignore_broadcast_ssid=0\n", fp); if (psk != NULL && 0 != strcmp(psk, "")) { fputs("auth_algs=1\n", fp); fputs("wpa=3\n", fp); fputs("wpa_passphrase=", fp); fputs(psk, fp); fputs("\n", fp); fputs("wpa_key_mgmt=WPA-PSK\n", fp); fputs("wpa_pairwise=TKIP\n", fp); fputs("rsn_pairwise=CCMP", fp); } fclose(fp); return 0; } static int creat_dnsmasq_file() { FILE* fp; static char DNSMASQ_CONF_DIR[] = "/userdata/bin/dnsmasq.conf"; static char SOFTAP_INTERFACE_STATIC_IP[] = "10.201.126.1"; system("rm /userdata/bin/dnsmasq.conf -rf"); fp = fopen(DNSMASQ_CONF_DIR, "wt+"); if (NULL == fp) return 0; fputs("user=root\n", fp); fputs("listen-address=", fp); fputs(SOFTAP_INTERFACE_STATIC_IP, fp); fputs("\n", fp); fputs("dhcp-range=10.201.126.50,10.201.126.150\n", fp); fputs("server=/google/8.8.8.8\n", fp); fclose(fp); return 1; } static int start_hostapd(char *ap, char *ssid, char *psk, char *ip) { char cmdline[256] = {0}; static char DNSMASQ_CONF_DIR[] = "/userdata/bin/dnsmasq.conf"; static char HOSTAPD_CONF_DIR[] = "/userdata/bin/hostapd.conf"; create_hostapd_file(ap, ssid, psk); sprintf(cmdline, "ifconfig %s up", ap); console_run(cmdline); sleep(1); sprintf(cmdline, "ifconfig %s 10.201.126.1 netmask 255.255.255.0", ap); console_run(cmdline); //sprintf(cmdline, "route add default gw %s %s", ip, ap); //console_run(cmdline); creat_dnsmasq_file(); memset(cmdline, 0, sizeof(cmdline)); sprintf(cmdline, "dnsmasq -C %s --interface=%s", DNSMASQ_CONF_DIR, ap); console_run(cmdline); memset(cmdline, 0, sizeof(cmdline)); sprintf(cmdline, "hostapd %s &", HOSTAPD_CONF_DIR); console_run(cmdline); int time = 100; while (time-- > 0 && access("/var/run/hostapd", F_OK)) { usleep(100 * 1000); } return 0; } int wifi_start_hostapd(char *ssid, char *psk, char *ip) { char wifi_type[128]; char ap[64]; console_run("killall dnsmasq"); console_run("killall hostapd"); console_run("killall udhcpc"); exec_command("ifconfig -a | grep p2p0", wifi_type, 128); if (strstr(wifi_type, "p2p0")) { strcpy(ap, "p2p0"); console_run("ifconfig p2p0 down"); console_run("rm -rf /userdata/bin/p2p0"); } else { strcpy(ap, "wlan1"); console_run("ifconfig wlan1 down"); console_run("rm -rf /userdata/bin/wlan1"); console_run("iw dev wlan1 del"); console_run("ifconfig wlan0 up"); if (!strncmp(wifi_type, "AP6181", 6)) console_run("iw dev wlan0 interface add wlan1 type __ap"); else console_run("iw phy0 interface add wlan1 type managed"); } return start_hostapd(ap, ssid, psk, ip); } int wifi_stop_hostapd(void) { char wifi_type[128]; console_run("killall hostapd"); console_run("killall dnsmasq"); exec_command("ifconfig -a | grep p2p0", wifi_type, 128); if (strstr(wifi_type, "p2p0")) { console_run("ifconfig p2p0 down"); } else { console_run("ifconfig wlan1 down"); } int time = 100; while (time-- > 0 && !access("/var/run/hostapd", F_OK)) { usleep(10 * 1000); } return 0; } #include #include #include #include #include #include #include #include typedef struct { RK_SOFTAP_STATE_CALLBACK callback; RK_SOFTAP_SERVER_TYPE server_type; } RkSoftAp; #define REQUEST_WIFI_LIST "/provision/wifiListInfo" #define REQUEST_WIFI_SET_UP "/provision/wifiSetup" #define REQUEST_IS_WIFI_CONNECTED "/provision/wifiState" #define REQUEST_POST_CONNECT_RESULT "/provision/connectResult" #define MSG_BUFF_LEN 8888 static char HTTP_RESPOSE_MESSAGE[] = "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\nContent-Length:%d\r\n\r\n%s"; RkSoftAp m_softap; #define SOCKET_PORT 8443 pthread_t m_thread; bool m_isConnecting = false; static int fd_server = -1; static int m_port; static RK_SOFTAP_STATE_CALLBACK m_cb = NULL; static RK_SOFTAP_STATE m_state = RK_SOFTAP_STATE_IDLE; static void sendState(RK_SOFTAP_STATE state, const char* data) { if(m_cb != NULL) m_cb(state, data); } static int initSocket(const unsigned int port) { int ret, fd_socket, val = 1; struct sockaddr_in server_addr; /* create a socket */ fd_socket = socket(AF_INET, SOCK_STREAM, 0); if (fd_socket < 0) { printf("%s: create socket failed\n", __func__); return -1; } /* set socket non-blocking */ //int flags; //flags = fcntl(fd_socket, F_GETFL, 0); //fcntl(sock, F_SETFL, flags | O_NONBLOCK); ret = setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int)); if (ret < 0) { printf("%s: setsockopt failed, ret: %d\n", __func__, ret); return -2; } /* initialize server address */ bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(port); /* bind with the local file */ ret = bind(fd_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { printf("%s: bind failed, ret: %d\n", __func__, ret); close(fd_socket); return -3; } /* listen */ ret = listen(fd_socket, 1); if (ret < 0) { printf("%s: listen failed, ret: %d\n", __func__, ret); close(fd_socket); return -4; } return fd_socket; } static int sendWifiList(const int fd, const char* buf) { char msg[MSG_BUFF_LEN] = {0}; char send_msg[MSG_BUFF_LEN] = {0}; size_t i, size = 0; char *wifilist; scan_retry: printf("[RK] RK_wifi_scan ...\n"); RK_wifi_scan(); usleep(800000); printf("[RK] RK_wifi_scan_r_sec ...\n"); wifilist = RK_wifi_scan_for_softap(); printf("[RK] RK_wifi_scan_r_sec end wifilist: %p\n", wifilist); if (wifilist == NULL) goto scan_retry; if (wifilist && (strlen(wifilist) < 3)) { free(wifilist); goto scan_retry; } strcpy(msg, "{\"type\":\"WifiList\", \"content\":"); strcat(msg, wifilist); strcat(msg, "}"); snprintf(send_msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, strlen(msg), msg); printf("scan_r: %s\n", send_msg); if (send(fd, send_msg, sizeof(send_msg), 0) < 0) { return false; } free(wifilist); return true; } static int isWifiConnected(const int fd, const char* buf) { char msg[MSG_BUFF_LEN] = {0}; bool isConn = 0; RK_WIFI_INFO_Connection_s info; if (!RK_wifi_running_getConnectionInfo(&info)) { if (strncmp(info.wpa_state, "COMPLETED", 9) == 0) isConn = 1; } memset(msg, 0, sizeof(msg)); snprintf(msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, 1, isConn ? "1" : "0"); m_isConnecting = false; if (send(fd, msg, sizeof(msg), 0) < 0) { return false; } return true; } static char softap_ssid[128]; static char softap_psk[128]; static bool wifiSetup(const int fd, const char* buf) { char msg[MSG_BUFF_LEN] = {0}; char *str1, *str2; char tmp[128]; int ret; printf("enter %s\n", __func__); memset(msg, 0, sizeof(msg)); snprintf(msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, 0, ""); if (send(fd, msg, sizeof(msg), 0) < 0) { return false; } if (m_isConnecting == true) return false; memset(softap_ssid, 0, 128); memset(softap_psk, 0, 128); //{"ssid":"YHX","pwd":"rk123456789"} str1 = strstr(buf, "\"ssid\""); str2 = strstr(buf, "\"\,\"pwd\""); strncpy(softap_ssid, str1 + 8, str2 - str1 - 8); str1 = strstr(buf, "\"pwd\""); str2 = strstr(str1, "\"\}"); strncpy(softap_psk, str1 + 7, str2 - str1 - 7); printf("do connect ssid:\"%s\", psk:\"%s\", isConnecting:%d\n", softap_ssid, softap_psk, m_isConnecting); sendState(RK_SOFTAP_STATE_CONNECTTING, NULL); m_state = RK_SOFTAP_STATE_CONNECTTING; system("wpa_cli -i wlan0 remove_network all"); ret = RK_wifi_connect(softap_ssid, softap_psk); if (ret < 0) { sendState(RK_SOFTAP_STATE_FAIL, NULL); m_state = RK_SOFTAP_STATE_FAIL; m_isConnecting = false; return false; } m_isConnecting = true; printf("exit %s\n", __func__); return true; } static bool doConnectResult(const int fd, const char* buf) { char msg[MSG_BUFF_LEN] = {0}; char result[2]; char *str; memset(msg, 0, sizeof(msg)); snprintf(msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, 0, ""); if (send(fd, msg, sizeof(msg), 0) < 0) { return false; } //{"result":"0"} str = strstr(buf, "\"result\""); strncpy(result, str + 10, 1); printf("%s: %s", __func__, result); if (strncmp(result, "1", 1) == 0) { // connect success, disable ap sendState(RK_SOFTAP_STATE_SUCCESS, NULL); m_state = RK_SOFTAP_STATE_SUCCESS; wifi_stop_hostapd(); } else { sendState(RK_SOFTAP_STATE_FAIL, NULL); m_state = RK_SOFTAP_STATE_FAIL; } return true; } static void handleRequest(const int fd_client) { size_t n; char buf[2048] = {0}; n = recv(fd_client, buf, sizeof(buf), 0); if (n <= 0) { close(fd_client); return; } buf[n] = '\0'; printf("TcpServer recv buf:\n[%s]\n", buf); if (strstr(buf, REQUEST_WIFI_LIST)) { sendWifiList(fd_client, buf); } else if (strstr(buf, REQUEST_WIFI_SET_UP)) { wifiSetup(fd_client, buf); } else if (strstr(buf, REQUEST_IS_WIFI_CONNECTED)) { isWifiConnected(fd_client, buf); } else if (strstr(buf, REQUEST_POST_CONNECT_RESULT)) { doConnectResult(fd_client, buf); } close(fd_client); } static void *threadAccept(void *arg) { int fd_client, port; struct sockaddr_in addr_client; socklen_t len_addr_client; len_addr_client = sizeof(addr_client); prctl(PR_SET_NAME, "threadAccept"); port = *(int *)arg; printf("threadAccept port = %d\n", port); fd_server = initSocket(port); if (fd_server < 0) { printf("TcpServer::threadAccept init tcp socket port %d fail. error:%d\n", port, fd_server); goto end; } /* Accept connection all time */ while (1) { printf("accept...\n"); fd_client = accept(fd_server, (struct sockaddr *)&addr_client, &len_addr_client); printf("accept fd_client = %d\n", fd_client); if (fd_client < 0) goto end; handleRequest(fd_client); if (m_state == RK_SOFTAP_STATE_SUCCESS) break; } end: printf("Exit Tcp accept thread\n"); shutdown(fd_server, SHUT_RDWR); close(fd_server); fd_server = -1; return NULL; } static int startTcpServer(void) { int ret; m_port = SOCKET_PORT; m_state = RK_SOFTAP_STATE_IDLE; printf("startTcpServer m_port = %d\n", m_port); ret = pthread_create(&m_thread, NULL, threadAccept, &m_port); return ret; } static int stopTcpServer() { if (m_thread <= 0) return 0; if (fd_server >= 0) { shutdown(fd_server, SHUT_RDWR); close(fd_server); fd_server = -1; } if (0 != pthread_join(m_thread, NULL)) { printf("stopTcpServer fail\n"); return -1; } m_thread = 0; printf("stopTcpServer success\n"); return 0; } int RK_softap_start(char *name, RK_SOFTAP_SERVER_TYPE server_type) { RK_wifi_enable(1); wifi_start_hostapd(name, NULL, NULL); startTcpServer(); return 0; } int RK_softap_stop(void) { stopTcpServer(); wifi_stop_hostapd(); return 0; } int RK_softap_register_callback(RK_SOFTAP_STATE_CALLBACK cb) { m_cb = cb; return 0; } int RK_softap_getState(RK_SOFTAP_STATE *pState) { return m_state; }