blob: ff3af085d1fb4518759db0ea8f6aad4c9b497817 [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001/*************************************************************
2Description:
3 C file for network control.
4Author:
5 LiuBin
6Date:
7 2019/7/24 17:13:06
8*************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <unistd.h>
12#include <sys/un.h>
13#include <sys/socket.h>
14#include <netinet/in.h>
15#include <arpa/inet.h>
16#include <errno.h>
17#include <linux/netlink.h>
18#include <linux/rtnetlink.h>
19#include <linux/route.h>
20#include <cutils/properties.h>
21#include <telephony/ril.h>
22
23#include "mbtk_type.h"
24#include "mbtk_net_control.h"
25#include "mbtk_task.h"
26#include "mbtk_utils.h"
27#include "mbtk_str.h"
28
29#ifdef LOG_TAG
30#undef LOG_TAG
31#endif
32#define LOG_TAG "mbtk_net_control"
33#include "mbtk_log.h"
34
35/*************************************************************
36 Constants and Macros
37*************************************************************/
38#define NET_CONTROL_BUF_SIZE 1024
39#ifndef INFTIM
40#define INFTIM (-1) /* infinite poll timeout */
41#endif
42#define MBTK_NET_PING_HOST "223.5.5.5"
43#define MBTK_NET_PING_IP "180.97.33.107" // IP for www.baidu.com
44
45// #define MBTK_NET_MONITOR_SUPPORT
46
47/*************************************************************
48 Variables:local
49*************************************************************/
50static char net_interface[20];
51static char net_ip[20];
52static mbtk_net_state_t net_state = MBTK_NET_STATE_OFF;
53static bool net_control_thread_running = FALSE;
54
55#ifdef MBTK_NET_MONITOR_SUPPORT
56static pthread_t net_control_thread_id = -1;
57static int net_control_fd = -1;
58#endif
59
60/*************************************************************
61 Variables:public
62*************************************************************/
63
64
65/*************************************************************
66 Local Function Declaration
67*************************************************************/
68
69
70/*************************************************************
71 Local Function Definitions
72*************************************************************/
73// Test network connected?
74// ping www.baidu.com
75static bool net_connected(const char *inf)
76{
77 char cmd[100];
78 char cmd_rsp[100];
79
80 // IP get now, ping www.baidu.com
81 memset(cmd,0,100);
82 snprintf(cmd,100,
83 "ping -I %s -c1 -s0 -w1000 %s | grep \"8 bytes from \"",
84 inf,
85 MBTK_NET_PING_HOST);
86 if(!mbtk_cmd_line(cmd,cmd_rsp,100))
87 {
88 LOGE("ping www.baidu.com cmd error.");
89 return FALSE;
90 }
91
92 LOGI("cmd_rsp:%s",cmd_rsp);
93 // ping www.baidu.com success.
94 if(str_startwith(cmd_rsp, "8 bytes from "))
95 {
96 return TRUE;
97 }
98#if 0
99 else if(str_contains(cmd_rsp, "unknown host"))
100 {
101 // DNS error,ping IP angin.
102 memset(cmd,0,100);
103 snprintf(cmd,100,
104 "ping -I %s -c1 -s0 -w1000 %s | grep \"8 bytes from \"",
105 inf,
106 MBTK_NET_PING_IP);
107 if(!mbtk_cmd_line(cmd,cmd_rsp,100))
108 {
109 LOGW("ping www.baidu.com IP cmd error.");
110 return FALSE;
111 }
112
113 if(str_startwith(cmd_rsp, "8 bytes from "))
114 {
115 return TRUE;
116 }
117 else
118 {
119 LOGW("Network unconnected.(ping baidu IP fail)");
120 return FALSE;
121 }
122 }
123#endif
124 else
125 {
126 LOGW("Network unconnected.(ping baidu host fail)");
127 return FALSE;
128 }
129
130 LOGW("ifconfig cmd fail.");
131 return FALSE;
132}
133
134#ifdef MBTK_NET_MONITOR_SUPPORT
135static int net_control_netlink_init()
136{
137 struct sockaddr_nl sa;
138 int len = 2048;
139
140 net_control_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
141 if(net_control_fd < 0)
142 {
143 LOGE("socket() fail.[%d]",errno);
144 return -1;
145 }
146
147 if(setsockopt(net_control_fd,
148 SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)) < 0)
149 {
150 LOGE("setsockopt() fail.[%d]",errno);
151 return -1;
152 }
153
154 bzero(&sa, sizeof(sa));
155 sa.nl_family = AF_NETLINK;
156 sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE /*| RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE*/;
157 if(bind(net_control_fd,
158 (struct sockaddr *) &sa, sizeof(sa)) < 0)
159 {
160 LOGE("bind() fail.[%d]",errno);
161 return -1;
162 }
163
164 return 0;
165}
166
167static void net_control_if_change(struct nlmsghdr *nh)
168{
169 struct rtattr *tb[IFLA_MAX + 1];
170 struct ifinfomsg *ifinfo;
171 bzero(tb, sizeof(tb));
172 if(nh == NULL)
173 {
174 LOGE("mbtk_net_if_change() nh == NULL");
175 return;
176 }
177
178 ifinfo = NLMSG_DATA(nh);
179 if(ifinfo == NULL)
180 {
181 LOGE("mbtk_net_if_change() ifinfo == NULL");
182 return;
183 }
184
185 LOGD("nlmsghdr:%d,%d,%d,%d,%d\n",nh->nlmsg_len,
186 nh->nlmsg_type,
187 nh->nlmsg_flags,
188 nh->nlmsg_seq,
189 nh->nlmsg_pid);
190
191 LOGD("ifinfomsg:%d,%d,%d,%d,%d,%d\n",ifinfo->ifi_family,
192 ifinfo->__ifi_pad,
193 ifinfo->ifi_type,
194 ifinfo->ifi_index,
195 ifinfo->ifi_flags,
196 ifinfo->ifi_change);
197
198 if((ifinfo->ifi_flags & IFF_RUNNING)
199 && (ifinfo->ifi_flags & IFF_LOWER_UP))
200 {
201 LOGD("Wired inserted.");
202 }
203 else
204 {
205 LOGD("Wired not insert.");
206 }
207}
208
209static void net_control_addr_change(struct nlmsghdr *nh)
210{
211 if(nh == NULL)
212 {
213 LOGE("mbtk_net_if_change() nh == NULL");
214 return;
215 }
216
217 if(nh->nlmsg_type==RTM_NEWADDR)
218 {
219 LOGD("New addr...");
220 }
221 else
222 {
223 LOGD("Del addr...");
224 }
225}
226
227static void* net_control_monitor_run(void *arg)
228{
229 LOGI("net_control_monitor_run start.");
230 if(net_control_netlink_init() < 0)
231 {
232 LOGE("mbtk_net_monitor_run() fail.");
233 return ((void*)0);
234 }
235
236 fd_set rd_set;
237 struct timeval timeout;
238 int select_r;
239 int read_r;
240 struct sockaddr_nl sa;
241 struct nlmsghdr *nh;
242 char buff[NET_CONTROL_BUF_SIZE];
243
244 while (net_control_thread_running)
245 {
246 FD_ZERO(&rd_set);
247 FD_SET(net_control_fd, &rd_set);
248 timeout.tv_sec = 5;
249 timeout.tv_usec = 0;
250 select_r = select(net_control_fd + 1, &rd_set, NULL, NULL, &timeout);
251 if (select_r < 0)
252 {
253 perror("select");
254 }
255 else if (select_r > 0)
256 {
257 if (FD_ISSET(net_control_fd, &rd_set))
258 {
259 read_r = read(net_control_fd, buff, NET_CONTROL_BUF_SIZE);
260 LOGI("Net change:read len:%d",read_r);
261
262 int i;
263 for(i = 0; i < 32 && i < read_r; i++)
264 LOGI("data:%x",buff[i]);
265
266 for (nh = (struct nlmsghdr *) buff; NLMSG_OK(nh, read_r); nh = NLMSG_NEXT(nh, read_r))
267 {
268 LOGI("msg_type:%d",nh->nlmsg_type);
269 switch (nh->nlmsg_type)
270 {
271 default:
272 LOGI("nh->nlmsg_type = %d\n", nh->nlmsg_type);
273 break;
274 case NLMSG_DONE:
275 case NLMSG_ERROR:
276 break;
277 case RTM_NEWLINK:
278 case RTM_DELLINK:
279 net_control_if_change(nh);
280 break;
281 case RTM_NEWADDR:
282 case RTM_DELADDR:
283 net_control_addr_change(nh);
284 break;
285 case RTM_NEWROUTE:
286 case RTM_DELROUTE:
287 //print_rtmsg(nh);
288 break;
289 }
290
291 }
292 }
293 }
294 }
295
296 LOGD("mbtk_net_monitor_run exist ...");
297
298 return ((void*)0);
299}
300
301static mbtk_task_info net_control_thread =
302{
303 .task_id = &net_control_thread_id,
304 .thread_run = net_control_monitor_run,
305 .args = NULL
306};
307#endif
308
309static int net_control_interface_init()
310{
311 // seth_ltex
312 int i = 0;
313 int size = 0;
314 char result[NET_CONTROL_BUF_SIZE];
315 char cmd[100];
316 int index = 0;
317 while(i <= 7)
318 {
319 size = snprintf(cmd, 100,"ifconfig ccinet%d", i);
320 cmd[size] = '\0';
321 memset(result,0x0,NET_CONTROL_BUF_SIZE);
322 if(mbtk_cmd_line(cmd, result, NET_CONTROL_BUF_SIZE))
323 {
324 index = str_indexof(result,"inet addr:");
325 if(index > 0)
326 {
327 size = snprintf(net_interface, 20,"ccinet%d", i);
328 net_interface[size] = '\0';
329
330 memcpy(net_ip,result + index + 10,20);
331
332 char *ptr = net_ip;
333 while(*ptr && *ptr != ' ')
334 {
335 ptr++;
336 }
337 *ptr = '\0';
338 break;
339 }
340 }
341 i++;
342 }
343
344 LOGI("Interface : %s, IP : %s",net_interface,net_ip);
345 if(index )
346 {
347 return 0;
348 }
349 else{
350 return -1;
351 }
352}
353
354static int net_control_init()
355{
356// if(net_control_thread_running)
357// {
358// LOGD("Network control has inited.");
359// return 0;
360// }
361
362 memset(net_ip,0x0,20);
363 memset(net_interface,0x0,20);
364 if( net_control_interface_init())
365 return -1;
366 net_control_thread_running = TRUE;
367
368#ifdef MBTK_NET_MONITOR_SUPPORT
369 if(mbtk_task_start(&net_control_thread))
370 {
371 LOGE("Create thread fail.");
372 net_control_thread_id = -1;
373 net_control_thread_running = FALSE;
374 return -1;
375 }
376#endif
377 LOGI("net_control_init() success.");
378 return 0;
379}
380
381static int net_control_state_change(bool enable)
382{
383 int size;
384 char result[NET_CONTROL_BUF_SIZE];
385 char cmd[100];
386 if(enable)
387 {
388 // ifconfig seth_lte1 up
389 // ip route add default via 10.94.251.205 dev seth_lte1
390 size = snprintf(cmd,100,"ifconfig %s up",net_interface);
391 cmd[size] = '\0';
392
393 if(mbtk_cmd_line(cmd, result, NET_CONTROL_BUF_SIZE))
394 {
395 size = snprintf(cmd,100,"ip route add default via %s dev %s",net_ip,net_interface);
396 cmd[size] = '\0';
397
398 if(mbtk_cmd_line(cmd, result, NET_CONTROL_BUF_SIZE))
399 {
400 net_state = MBTK_NET_STATE_CONN;
401 return 0;
402 }
403 }
404 }
405 else
406 {
407 // ifconfig seth_lte1 down
408 size = snprintf(cmd,100,"ifconfig %s down",net_interface);
409 cmd[size] = '\0';
410
411 if(mbtk_cmd_line(cmd, result, NET_CONTROL_BUF_SIZE))
412 {
413 net_state = MBTK_NET_STATE_OFF;
414 return 0;
415 }
416 }
417
418 return -1;
419}
420
421/*************************************************************
422 Public Function Definitions
423*************************************************************/
424/*=============================================
425FUNCTION
426 mbtk_net_state_get()
427
428DESCRIPTION
429 Get network state.
430
431DEPENDENCIES
432 None
433
434PARAMETERS
435 None
436
437RETURN VALUE
438 Current network state.
439
440SIDE EFFECTS
441 None
442=============================================*/
443mbtk_net_state_t mbtk_net_state_get()
444{
445 net_control_init();
446
447 net_state = MBTK_NET_STATE_OFF;
448 if(strlen(net_ip) > 0)
449 {
450 if(net_connected(net_interface))
451 net_state = MBTK_NET_STATE_CONN;
452 }
453
454 LOGI("[GET]Net state:%d",net_state);
455
456 if(net_state == MBTK_NET_STATE_CONN)
457 {
458 char value[PROPERTY_VALUE_MAX] = {0};
459 if (property_get("persist.mbtk.netstate", value, "0,0") > 0 && strcmp(value,"0,0")) {
460 int regStatus = 0, gprsState = 0;
461 char *ptr = value;
462 regStatus = atoi(ptr);
463 if((ptr = strstr(ptr, ",")))
464 {
465 gprsState = atoi(ptr + 1);
466 }
467
468 LOGI("regStatus : %d, gprsState : %d", regStatus, gprsState);
469 if(regStatus != 1 && regStatus != 5) // Not Home/Roaming Network.
470 {
471 net_state = MBTK_NET_STATE_CONN_UNKNOWN;
472 }
473 else
474 {
475 if (gprsState == RADIO_TECH_LTE || gprsState == RADIO_TECH_LTEP)
476 {
477 net_state = MBTK_NET_STATE_CONN_4G;
478 }
479 else if ((gprsState == RADIO_TECH_GPRS) || (gprsState == RADIO_TECH_EDGE) || (gprsState == RADIO_TECH_GSM))
480 {
481 net_state = MBTK_NET_STATE_CONN_2G;
482 } else if((gprsState == RADIO_TECH_UMTS) || (gprsState == RADIO_TECH_HSDPA)
483 || (gprsState == RADIO_TECH_HSUPA) || (gprsState == RADIO_TECH_HSPA)) {
484 net_state = MBTK_NET_STATE_CONN_3G;
485 } else {
486 net_state = MBTK_NET_STATE_CONN_UNKNOWN;
487 }
488 }
489 }
490 else
491 {
492 LOGE("property_get persist.mbtk.netstate fail.");
493 net_state = MBTK_NET_STATE_CONN_UNKNOWN;
494 goto end;
495 }
496 }
497
498end:
499 return net_state;
500}
501
502/*=============================================
503FUNCTION
504 mbtk_net_enable()
505
506DESCRIPTION
507 Set network state.
508
509DEPENDENCIES
510 None
511
512PARAMETERS
513 enable
514 TRUE : Enable network.
515 FALSE: Diable network.
516
517RETURN VALUE
518 0 : Success
519 -1: Fail
520
521SIDE EFFECTS
522 None
523=============================================*/
524int mbtk_net_enable(bool enable)
525{
526 if( net_control_init())
527 return -1;
528
529 int result = net_control_state_change(enable);
530
531 LOGI("[SET]Net state:%d",net_state);
532
533 return result;
534}
535