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