xref: /OK3568_Linux_fs/external/rkwifibt-app/test/softap/softap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun #include <fcntl.h>
2*4882a593Smuzhiyun #include <stdio.h>
3*4882a593Smuzhiyun #include <stdlib.h>
4*4882a593Smuzhiyun #include <string.h>
5*4882a593Smuzhiyun #include <unistd.h>
6*4882a593Smuzhiyun #include <stdbool.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <Rk_softap.h>
9*4882a593Smuzhiyun #include <Rk_wifi.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define DBG 1
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #if DBG
14*4882a593Smuzhiyun #define DEBUG_INFO(M, ...) printf("Hostapd %d: " M, __LINE__, ##__VA_ARGS__)
15*4882a593Smuzhiyun #else
16*4882a593Smuzhiyun #define DEBUG_INFO(M, ...) do {} while (0)
17*4882a593Smuzhiyun #endif
18*4882a593Smuzhiyun #define DEBUG_ERR(M, ...) printf("Hostapd %d: " M, __LINE__, ##__VA_ARGS__)
19*4882a593Smuzhiyun 
exec_command(char cmdline[],char recv_buff[],int len)20*4882a593Smuzhiyun static void exec_command(char cmdline[], char recv_buff[], int len)
21*4882a593Smuzhiyun {
22*4882a593Smuzhiyun 	printf("[BT_DEBUG] execute: %s\n", cmdline);
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun 	FILE *stream = NULL;
25*4882a593Smuzhiyun 	char *tmp_buff = recv_buff;
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 	memset(recv_buff, 0, len);
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun 	if ((stream = popen(cmdline, "r")) != NULL) {
30*4882a593Smuzhiyun 		while (fgets(tmp_buff, len, stream)) {
31*4882a593Smuzhiyun 			//pr_info("tmp_buf[%d]: %s\n", strlen(tmp_buff), tmp_buff);
32*4882a593Smuzhiyun 			tmp_buff += strlen(tmp_buff);
33*4882a593Smuzhiyun 			len -= strlen(tmp_buff);
34*4882a593Smuzhiyun 			if (len <= 1)
35*4882a593Smuzhiyun 				break;
36*4882a593Smuzhiyun 		}
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 		printf("[BT_DEBUG] execute_r: %s \n", recv_buff);
39*4882a593Smuzhiyun 		pclose(stream);
40*4882a593Smuzhiyun 	} else
41*4882a593Smuzhiyun 		printf("[popen] error: %s\n", cmdline);
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
console_run(const char * cmdline)44*4882a593Smuzhiyun static const int console_run(const char *cmdline)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	int ret;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	DEBUG_INFO("cmdline = %s\n", cmdline);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	ret = system(cmdline);
51*4882a593Smuzhiyun 	if (ret < 0) {
52*4882a593Smuzhiyun 		DEBUG_ERR("Running cmdline failed: %s\n", cmdline);
53*4882a593Smuzhiyun 		return 0;
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	return 1;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
create_hostapd_file(char * ap,char * ssid,char * psk)59*4882a593Smuzhiyun static int create_hostapd_file(char *ap, char *ssid, char *psk)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	FILE* fp;
62*4882a593Smuzhiyun 	char cmdline[256] = {0};
63*4882a593Smuzhiyun 	static char HOSTAPD_CONF_DIR[] = "/userdata/bin/hostapd.conf";
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	fp = fopen(HOSTAPD_CONF_DIR, "wt+");
66*4882a593Smuzhiyun 	if (NULL == fp)
67*4882a593Smuzhiyun 		return -1;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	sprintf(cmdline, "interface=%s\n", ap);
70*4882a593Smuzhiyun 	fputs(cmdline, fp);
71*4882a593Smuzhiyun 	fputs("ctrl_interface=/var/run/hostapd\n", fp);
72*4882a593Smuzhiyun 	fputs("driver=nl80211\n", fp);
73*4882a593Smuzhiyun 	fputs("ssid=", fp);
74*4882a593Smuzhiyun 	fputs(ssid, fp);
75*4882a593Smuzhiyun 	fputs("\n", fp);
76*4882a593Smuzhiyun 	fputs("channel=6\n", fp);
77*4882a593Smuzhiyun 	fputs("hw_mode=g\n", fp);
78*4882a593Smuzhiyun 	fputs("ieee80211n=1\n", fp);
79*4882a593Smuzhiyun 	fputs("ignore_broadcast_ssid=0\n", fp);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	if (psk != NULL && 0 != strcmp(psk, "")) {
82*4882a593Smuzhiyun 		fputs("auth_algs=1\n", fp);
83*4882a593Smuzhiyun 		fputs("wpa=3\n", fp);
84*4882a593Smuzhiyun 		fputs("wpa_passphrase=", fp);
85*4882a593Smuzhiyun 		fputs(psk, fp);
86*4882a593Smuzhiyun 		fputs("\n", fp);
87*4882a593Smuzhiyun 		fputs("wpa_key_mgmt=WPA-PSK\n", fp);
88*4882a593Smuzhiyun 		fputs("wpa_pairwise=TKIP\n", fp);
89*4882a593Smuzhiyun 		fputs("rsn_pairwise=CCMP", fp);
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	fclose(fp);
93*4882a593Smuzhiyun 	return 0;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
creat_dnsmasq_file()96*4882a593Smuzhiyun static int creat_dnsmasq_file()
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	FILE* fp;
99*4882a593Smuzhiyun 	static char DNSMASQ_CONF_DIR[] = "/userdata/bin/dnsmasq.conf";
100*4882a593Smuzhiyun 	static char SOFTAP_INTERFACE_STATIC_IP[] = "10.201.126.1";
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	system("rm /userdata/bin/dnsmasq.conf -rf");
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	fp = fopen(DNSMASQ_CONF_DIR, "wt+");
105*4882a593Smuzhiyun 	if (NULL == fp)
106*4882a593Smuzhiyun 		return 0;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	fputs("user=root\n", fp);
109*4882a593Smuzhiyun 	fputs("listen-address=", fp);
110*4882a593Smuzhiyun 	fputs(SOFTAP_INTERFACE_STATIC_IP, fp);
111*4882a593Smuzhiyun 	fputs("\n", fp);
112*4882a593Smuzhiyun 	fputs("dhcp-range=10.201.126.50,10.201.126.150\n", fp);
113*4882a593Smuzhiyun 	fputs("server=/google/8.8.8.8\n", fp);
114*4882a593Smuzhiyun 	fclose(fp);
115*4882a593Smuzhiyun 	return 1;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
start_hostapd(char * ap,char * ssid,char * psk,char * ip)118*4882a593Smuzhiyun static int start_hostapd(char *ap, char *ssid, char *psk, char *ip)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	char cmdline[256] = {0};
121*4882a593Smuzhiyun 	static char DNSMASQ_CONF_DIR[] = "/userdata/bin/dnsmasq.conf";
122*4882a593Smuzhiyun 	static char HOSTAPD_CONF_DIR[] = "/userdata/bin/hostapd.conf";
123*4882a593Smuzhiyun 	create_hostapd_file(ap, ssid, psk);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	sprintf(cmdline, "ifconfig %s up", ap);
126*4882a593Smuzhiyun 	console_run(cmdline);
127*4882a593Smuzhiyun 	sleep(1);
128*4882a593Smuzhiyun 	sprintf(cmdline, "ifconfig %s 10.201.126.1 netmask 255.255.255.0", ap);
129*4882a593Smuzhiyun 	console_run(cmdline);
130*4882a593Smuzhiyun 	//sprintf(cmdline, "route add default gw %s %s", ip, ap);
131*4882a593Smuzhiyun 	//console_run(cmdline);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	creat_dnsmasq_file();
134*4882a593Smuzhiyun 	memset(cmdline, 0, sizeof(cmdline));
135*4882a593Smuzhiyun 	sprintf(cmdline, "dnsmasq -C %s --interface=%s", DNSMASQ_CONF_DIR, ap);
136*4882a593Smuzhiyun 	console_run(cmdline);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	memset(cmdline, 0, sizeof(cmdline));
139*4882a593Smuzhiyun 	sprintf(cmdline, "hostapd %s &", HOSTAPD_CONF_DIR);
140*4882a593Smuzhiyun 	console_run(cmdline);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	int time = 100;
143*4882a593Smuzhiyun 	while (time-- > 0 && access("/var/run/hostapd", F_OK)) {
144*4882a593Smuzhiyun 		usleep(100 * 1000);
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun 	return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
wifi_start_hostapd(char * ssid,char * psk,char * ip)149*4882a593Smuzhiyun int wifi_start_hostapd(char *ssid, char *psk, char *ip)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun 	char wifi_type[128];
152*4882a593Smuzhiyun 	char ap[64];
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	console_run("killall dnsmasq");
155*4882a593Smuzhiyun 	console_run("killall hostapd");
156*4882a593Smuzhiyun 	console_run("killall udhcpc");
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	exec_command("ifconfig -a | grep p2p0", wifi_type, 128);
159*4882a593Smuzhiyun 	if (strstr(wifi_type, "p2p0")) {
160*4882a593Smuzhiyun 		strcpy(ap, "p2p0");
161*4882a593Smuzhiyun 		console_run("ifconfig p2p0 down");
162*4882a593Smuzhiyun 		console_run("rm -rf /userdata/bin/p2p0");
163*4882a593Smuzhiyun 	} else {
164*4882a593Smuzhiyun 		strcpy(ap, "wlan1");
165*4882a593Smuzhiyun 		console_run("ifconfig wlan1 down");
166*4882a593Smuzhiyun 		console_run("rm -rf /userdata/bin/wlan1");
167*4882a593Smuzhiyun 		console_run("iw dev wlan1 del");
168*4882a593Smuzhiyun 		console_run("ifconfig wlan0 up");
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 		if (!strncmp(wifi_type, "AP6181", 6))
171*4882a593Smuzhiyun 			console_run("iw dev wlan0 interface add wlan1 type __ap");
172*4882a593Smuzhiyun 		else
173*4882a593Smuzhiyun 			console_run("iw phy0 interface add wlan1 type managed");
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	return start_hostapd(ap, ssid, psk, ip);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
wifi_stop_hostapd(void)179*4882a593Smuzhiyun int wifi_stop_hostapd(void)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	char wifi_type[128];
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	console_run("killall hostapd");
184*4882a593Smuzhiyun 	console_run("killall dnsmasq");
185*4882a593Smuzhiyun 	exec_command("ifconfig -a | grep p2p0", wifi_type, 128);
186*4882a593Smuzhiyun 	if (strstr(wifi_type, "p2p0")) {
187*4882a593Smuzhiyun 		console_run("ifconfig p2p0 down");
188*4882a593Smuzhiyun 	} else {
189*4882a593Smuzhiyun 		console_run("ifconfig wlan1 down");
190*4882a593Smuzhiyun 	}
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	int time = 100;
193*4882a593Smuzhiyun 	while (time-- > 0 && !access("/var/run/hostapd", F_OK)) {
194*4882a593Smuzhiyun 		usleep(10 * 1000);
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	return 0;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun #include <arpa/inet.h>
201*4882a593Smuzhiyun #include <netinet/in.h>
202*4882a593Smuzhiyun #include <sys/socket.h>
203*4882a593Smuzhiyun #include <sys/types.h>
204*4882a593Smuzhiyun #include <sys/wait.h>
205*4882a593Smuzhiyun #include <sys/prctl.h>
206*4882a593Smuzhiyun #include <unistd.h>
207*4882a593Smuzhiyun #include <pthread.h>
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun typedef struct {
210*4882a593Smuzhiyun 	RK_SOFTAP_STATE_CALLBACK callback;
211*4882a593Smuzhiyun 	RK_SOFTAP_SERVER_TYPE server_type;
212*4882a593Smuzhiyun } RkSoftAp;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun #define REQUEST_WIFI_LIST					"/provision/wifiListInfo"
215*4882a593Smuzhiyun #define REQUEST_WIFI_SET_UP					"/provision/wifiSetup"
216*4882a593Smuzhiyun #define REQUEST_IS_WIFI_CONNECTED			"/provision/wifiState"
217*4882a593Smuzhiyun #define REQUEST_POST_CONNECT_RESULT			"/provision/connectResult"
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun #define MSG_BUFF_LEN 8888
220*4882a593Smuzhiyun static char HTTP_RESPOSE_MESSAGE[] = "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\nContent-Length:%d\r\n\r\n%s";
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun RkSoftAp m_softap;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun #define SOCKET_PORT 8443
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun pthread_t m_thread;
227*4882a593Smuzhiyun bool m_isConnecting = false;
228*4882a593Smuzhiyun static int fd_server = -1;
229*4882a593Smuzhiyun static int m_port;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun static RK_SOFTAP_STATE_CALLBACK m_cb = NULL;
232*4882a593Smuzhiyun static RK_SOFTAP_STATE m_state = RK_SOFTAP_STATE_IDLE;
233*4882a593Smuzhiyun 
sendState(RK_SOFTAP_STATE state,const char * data)234*4882a593Smuzhiyun static void sendState(RK_SOFTAP_STATE state, const char* data) {
235*4882a593Smuzhiyun 	if(m_cb != NULL)
236*4882a593Smuzhiyun 		m_cb(state, data);
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun 
initSocket(const unsigned int port)239*4882a593Smuzhiyun static int initSocket(const unsigned int port)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	int ret, fd_socket, val = 1;
242*4882a593Smuzhiyun 	struct sockaddr_in server_addr;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	/* create a socket */
245*4882a593Smuzhiyun 	fd_socket = socket(AF_INET, SOCK_STREAM, 0);
246*4882a593Smuzhiyun 	if (fd_socket < 0) {
247*4882a593Smuzhiyun 		printf("%s: create socket failed\n", __func__);
248*4882a593Smuzhiyun 		return -1;
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	/* set socket non-blocking */
252*4882a593Smuzhiyun 	//int flags;
253*4882a593Smuzhiyun 	//flags = fcntl(fd_socket, F_GETFL, 0);
254*4882a593Smuzhiyun 	//fcntl(sock, F_SETFL, flags | O_NONBLOCK);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	ret = setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));
257*4882a593Smuzhiyun 	if (ret < 0) {
258*4882a593Smuzhiyun 		printf("%s: setsockopt failed, ret: %d\n", __func__, ret);
259*4882a593Smuzhiyun 		return -2;
260*4882a593Smuzhiyun 	}
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	/* initialize server address */
263*4882a593Smuzhiyun 	bzero(&server_addr, sizeof(server_addr));
264*4882a593Smuzhiyun 	server_addr.sin_family = AF_INET;
265*4882a593Smuzhiyun 	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
266*4882a593Smuzhiyun 	server_addr.sin_port = htons(port);
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	/* bind with the local file */
269*4882a593Smuzhiyun 	ret = bind(fd_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
270*4882a593Smuzhiyun 	if (ret < 0) {
271*4882a593Smuzhiyun 		printf("%s: bind failed, ret: %d\n", __func__, ret);
272*4882a593Smuzhiyun 		close(fd_socket);
273*4882a593Smuzhiyun 		return -3;
274*4882a593Smuzhiyun 	}
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	/* listen */
277*4882a593Smuzhiyun 	ret = listen(fd_socket, 1);
278*4882a593Smuzhiyun 	if (ret < 0) {
279*4882a593Smuzhiyun 		printf("%s: listen failed, ret: %d\n", __func__, ret);
280*4882a593Smuzhiyun 		close(fd_socket);
281*4882a593Smuzhiyun 		return -4;
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	return fd_socket;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
sendWifiList(const int fd,const char * buf)287*4882a593Smuzhiyun static int sendWifiList(const int fd, const char* buf)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun 	char msg[MSG_BUFF_LEN] = {0};
290*4882a593Smuzhiyun 	char send_msg[MSG_BUFF_LEN] = {0};
291*4882a593Smuzhiyun 	size_t i, size = 0;
292*4882a593Smuzhiyun 	char *wifilist;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun scan_retry:
295*4882a593Smuzhiyun 	printf("[RK] RK_wifi_scan ...\n");
296*4882a593Smuzhiyun 	RK_wifi_scan();
297*4882a593Smuzhiyun 	usleep(800000);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	printf("[RK] RK_wifi_scan_r_sec ...\n");
300*4882a593Smuzhiyun 	wifilist = RK_wifi_scan_for_softap();
301*4882a593Smuzhiyun 	printf("[RK] RK_wifi_scan_r_sec end wifilist: %p\n", wifilist);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	if (wifilist == NULL)
304*4882a593Smuzhiyun 		goto scan_retry;
305*4882a593Smuzhiyun 	if (wifilist && (strlen(wifilist) < 3)) {
306*4882a593Smuzhiyun 		free(wifilist);
307*4882a593Smuzhiyun 		goto scan_retry;
308*4882a593Smuzhiyun 	}
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	strcpy(msg, "{\"type\":\"WifiList\", \"content\":");
311*4882a593Smuzhiyun 	strcat(msg, wifilist);
312*4882a593Smuzhiyun 	strcat(msg, "}");
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	snprintf(send_msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, strlen(msg), msg);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	printf("scan_r: %s\n", send_msg);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	if (send(fd, send_msg, sizeof(send_msg), 0) < 0) {
319*4882a593Smuzhiyun 		return false;
320*4882a593Smuzhiyun 	}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	free(wifilist);
323*4882a593Smuzhiyun 	return true;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
isWifiConnected(const int fd,const char * buf)326*4882a593Smuzhiyun static int isWifiConnected(const int fd, const char* buf)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	char msg[MSG_BUFF_LEN] = {0};
329*4882a593Smuzhiyun 	bool isConn = 0;
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	RK_WIFI_INFO_Connection_s info;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	if (!RK_wifi_running_getConnectionInfo(&info)) {
334*4882a593Smuzhiyun 		if (strncmp(info.wpa_state, "COMPLETED", 9) == 0)
335*4882a593Smuzhiyun 			isConn = 1;
336*4882a593Smuzhiyun 	}
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	memset(msg, 0, sizeof(msg));
339*4882a593Smuzhiyun 	snprintf(msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, 1, isConn ? "1" : "0");
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	m_isConnecting = false;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	if (send(fd, msg, sizeof(msg), 0) < 0) {
344*4882a593Smuzhiyun 		return false;
345*4882a593Smuzhiyun 	}
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	return true;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun static char softap_ssid[128];
351*4882a593Smuzhiyun static char softap_psk[128];
352*4882a593Smuzhiyun 
wifiSetup(const int fd,const char * buf)353*4882a593Smuzhiyun static bool wifiSetup(const int fd, const char* buf)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	char msg[MSG_BUFF_LEN] = {0};
356*4882a593Smuzhiyun 	char *str1, *str2;
357*4882a593Smuzhiyun 	char tmp[128];
358*4882a593Smuzhiyun 	int ret;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	printf("enter %s\n", __func__);
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	memset(msg, 0, sizeof(msg));
363*4882a593Smuzhiyun 	snprintf(msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, 0, "");
364*4882a593Smuzhiyun 	if (send(fd, msg, sizeof(msg), 0) < 0) {
365*4882a593Smuzhiyun 		return false;
366*4882a593Smuzhiyun 	}
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	if (m_isConnecting == true)
369*4882a593Smuzhiyun 		return false;
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	memset(softap_ssid, 0, 128);
372*4882a593Smuzhiyun 	memset(softap_psk, 0, 128);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	//{"ssid":"YHX","pwd":"rk123456789"}
375*4882a593Smuzhiyun 	str1 = strstr(buf, "\"ssid\"");
376*4882a593Smuzhiyun 	str2 = strstr(buf, "\"\,\"pwd\"");
377*4882a593Smuzhiyun 	strncpy(softap_ssid, str1 + 8, str2 - str1 - 8);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	str1 = strstr(buf, "\"pwd\"");
380*4882a593Smuzhiyun 	str2 = strstr(str1, "\"\}");
381*4882a593Smuzhiyun 	strncpy(softap_psk, str1 + 7, str2 - str1 - 7);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	printf("do connect ssid:\"%s\", psk:\"%s\", isConnecting:%d\n", softap_ssid, softap_psk, m_isConnecting);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	sendState(RK_SOFTAP_STATE_CONNECTTING, NULL);
386*4882a593Smuzhiyun 	m_state = RK_SOFTAP_STATE_CONNECTTING;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	system("wpa_cli -i wlan0 remove_network all");
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	ret = RK_wifi_connect(softap_ssid, softap_psk);
391*4882a593Smuzhiyun 	if (ret < 0) {
392*4882a593Smuzhiyun 		sendState(RK_SOFTAP_STATE_FAIL, NULL);
393*4882a593Smuzhiyun 		m_state = RK_SOFTAP_STATE_FAIL;
394*4882a593Smuzhiyun 		m_isConnecting = false;
395*4882a593Smuzhiyun 		return false;
396*4882a593Smuzhiyun 	}
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	m_isConnecting = true;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	printf("exit %s\n", __func__);
401*4882a593Smuzhiyun 	return true;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
doConnectResult(const int fd,const char * buf)404*4882a593Smuzhiyun static bool doConnectResult(const int fd, const char* buf)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun 	char msg[MSG_BUFF_LEN] = {0};
407*4882a593Smuzhiyun 	char result[2];
408*4882a593Smuzhiyun 	char *str;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	memset(msg, 0, sizeof(msg));
411*4882a593Smuzhiyun 	snprintf(msg, sizeof(msg), HTTP_RESPOSE_MESSAGE, 0, "");
412*4882a593Smuzhiyun 	if (send(fd, msg, sizeof(msg), 0) < 0) {
413*4882a593Smuzhiyun 		return false;
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	//{"result":"0"}
417*4882a593Smuzhiyun 	str = strstr(buf, "\"result\"");
418*4882a593Smuzhiyun 	strncpy(result, str + 10, 1);
419*4882a593Smuzhiyun 	printf("%s: %s", __func__, result);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (strncmp(result, "1", 1) == 0) { // connect success, disable ap
422*4882a593Smuzhiyun 		sendState(RK_SOFTAP_STATE_SUCCESS, NULL);
423*4882a593Smuzhiyun 		m_state = RK_SOFTAP_STATE_SUCCESS;
424*4882a593Smuzhiyun 		wifi_stop_hostapd();
425*4882a593Smuzhiyun 	} else {
426*4882a593Smuzhiyun 		sendState(RK_SOFTAP_STATE_FAIL, NULL);
427*4882a593Smuzhiyun 		m_state = RK_SOFTAP_STATE_FAIL;
428*4882a593Smuzhiyun 	}
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	return true;
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun 
handleRequest(const int fd_client)433*4882a593Smuzhiyun static void handleRequest(const int fd_client)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun 	size_t n;
436*4882a593Smuzhiyun 	char buf[2048] = {0};
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	n = recv(fd_client, buf, sizeof(buf), 0);
439*4882a593Smuzhiyun 	if (n <= 0) {
440*4882a593Smuzhiyun 		close(fd_client);
441*4882a593Smuzhiyun 		return;
442*4882a593Smuzhiyun 	}
443*4882a593Smuzhiyun 	buf[n] = '\0';
444*4882a593Smuzhiyun 	printf("TcpServer recv buf:\n[%s]\n", buf);
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	if (strstr(buf, REQUEST_WIFI_LIST)) {
447*4882a593Smuzhiyun 		sendWifiList(fd_client, buf);
448*4882a593Smuzhiyun 	} else if (strstr(buf, REQUEST_WIFI_SET_UP)) {
449*4882a593Smuzhiyun 		wifiSetup(fd_client, buf);
450*4882a593Smuzhiyun 	} else if (strstr(buf, REQUEST_IS_WIFI_CONNECTED)) {
451*4882a593Smuzhiyun 		isWifiConnected(fd_client, buf);
452*4882a593Smuzhiyun 	} else if (strstr(buf, REQUEST_POST_CONNECT_RESULT)) {
453*4882a593Smuzhiyun 		doConnectResult(fd_client, buf);
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	close(fd_client);
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun 
threadAccept(void * arg)459*4882a593Smuzhiyun static void *threadAccept(void *arg)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun 	int fd_client, port;
462*4882a593Smuzhiyun 	struct sockaddr_in addr_client;
463*4882a593Smuzhiyun 	socklen_t len_addr_client;
464*4882a593Smuzhiyun 	len_addr_client = sizeof(addr_client);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	prctl(PR_SET_NAME, "threadAccept");
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	port = *(int *)arg;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	printf("threadAccept port = %d\n", port);
471*4882a593Smuzhiyun 	fd_server = initSocket(port);
472*4882a593Smuzhiyun 	if (fd_server < 0) {
473*4882a593Smuzhiyun 		printf("TcpServer::threadAccept init tcp socket port %d fail. error:%d\n", port, fd_server);
474*4882a593Smuzhiyun 		goto end;
475*4882a593Smuzhiyun 	}
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	/* Accept connection all time */
478*4882a593Smuzhiyun 	while (1) {
479*4882a593Smuzhiyun 		printf("accept...\n");
480*4882a593Smuzhiyun 		fd_client = accept(fd_server, (struct sockaddr *)&addr_client, &len_addr_client);
481*4882a593Smuzhiyun 		printf("accept fd_client = %d\n", fd_client);
482*4882a593Smuzhiyun 		if (fd_client < 0)
483*4882a593Smuzhiyun 			goto end;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 		handleRequest(fd_client);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 		if (m_state == RK_SOFTAP_STATE_SUCCESS)
488*4882a593Smuzhiyun 			break;
489*4882a593Smuzhiyun 	}
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun end:
492*4882a593Smuzhiyun 	printf("Exit Tcp accept thread\n");
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	shutdown(fd_server, SHUT_RDWR);
495*4882a593Smuzhiyun 	close(fd_server);
496*4882a593Smuzhiyun 	fd_server = -1;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	return NULL;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
startTcpServer(void)501*4882a593Smuzhiyun static int startTcpServer(void)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun 	int ret;
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	m_port = SOCKET_PORT;
506*4882a593Smuzhiyun 	m_state = RK_SOFTAP_STATE_IDLE;
507*4882a593Smuzhiyun 	printf("startTcpServer m_port = %d\n", m_port);
508*4882a593Smuzhiyun 	ret = pthread_create(&m_thread, NULL, threadAccept, &m_port);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	return ret;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun 
stopTcpServer()513*4882a593Smuzhiyun static int stopTcpServer()
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun 	if (m_thread <= 0)
516*4882a593Smuzhiyun 		return 0;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	if (fd_server >= 0) {
519*4882a593Smuzhiyun 		shutdown(fd_server, SHUT_RDWR);
520*4882a593Smuzhiyun 		close(fd_server);
521*4882a593Smuzhiyun 		fd_server = -1;
522*4882a593Smuzhiyun 	}
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	if (0 != pthread_join(m_thread, NULL)) {
525*4882a593Smuzhiyun 		printf("stopTcpServer fail\n");
526*4882a593Smuzhiyun 		return -1;
527*4882a593Smuzhiyun 	}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	m_thread = 0;
530*4882a593Smuzhiyun 	printf("stopTcpServer success\n");
531*4882a593Smuzhiyun 	return 0;
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
RK_softap_start(char * name,RK_SOFTAP_SERVER_TYPE server_type)534*4882a593Smuzhiyun int RK_softap_start(char *name, RK_SOFTAP_SERVER_TYPE server_type)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun 	RK_wifi_enable(1);
537*4882a593Smuzhiyun 	wifi_start_hostapd(name, NULL, NULL);
538*4882a593Smuzhiyun 	startTcpServer();
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	return 0;
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun 
RK_softap_stop(void)543*4882a593Smuzhiyun int RK_softap_stop(void)
544*4882a593Smuzhiyun {
545*4882a593Smuzhiyun 	stopTcpServer();
546*4882a593Smuzhiyun 	wifi_stop_hostapd();
547*4882a593Smuzhiyun 	return 0;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 
RK_softap_register_callback(RK_SOFTAP_STATE_CALLBACK cb)551*4882a593Smuzhiyun int RK_softap_register_callback(RK_SOFTAP_STATE_CALLBACK cb) {
552*4882a593Smuzhiyun 	m_cb = cb;
553*4882a593Smuzhiyun 	return 0;
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun 
RK_softap_getState(RK_SOFTAP_STATE * pState)556*4882a593Smuzhiyun int RK_softap_getState(RK_SOFTAP_STATE *pState)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun 	return m_state;
559*4882a593Smuzhiyun }
560