#include #include #include #include #include #include #include #include #include #include #include "elog.h" #include "sys.h" #include "upgrade.h" #include "paras.h" #include "cfg.h" #include "file.h" #include "lock.h" #include "qrc.h" #include "thread.h" #include "shell.h" #include "common.h" #include "sqlite_handle.h" #include "language_hashmap.h" #include "wifi.h" #if (CHIP_TYPE != CHIP_T113s) #include #endif #if 1 #define LOGE log_e #define LOGW log_w #define LOGD log_d #else #define LOGD printf #define LOGW printf #define LOGE printf #endif //#define USE_BASH #define USE_FILE //#define USE_API #define DFLT_NIC "eth0" //#define FILE_NET "/root/interfaces" #define FILE_NET "/etc/network/interfaces" #define FILE_DNS "/etc/dnsmasq.conf" static int net_check(void); static int get_pid(char *proc); static int get_net(NetworkInfo_t *para, int ipv); static int set_net(NetworkInfo_t *para, int ipv); static void nic_restart(void) { NetworkInfo_t info; char *p=getLocalIpAddress(DFLT_NIC); if(p==NULL) { system("ifdown eth0;ifup eth0;sleep 2"); } } static int is_mac_fixed(void) { const char *path="/usr/bin/docker"; if(access(path,0)==0) { //docker存在则是老版镜像,每次重启mac不固定, 为随机值 return 0; } return 1; } static void nic_set_mac(void) { #if(CHIP_TYPE == CHIP_T113i) //if(is_mac_fixed()) return; //如果是t113i新版镜像,mac地址跟id绑定,不需要写固定值进去 #endif system("ip link set dev eth0 address `cat /sys/class/addr_mgt/addr_eth`"); } //////////////////////////////////////////////////////////////////// int sys_reboot(void) { int r=0; r = system("reboot"); if(r) { LOGE("sys_reboot failed!\n"); return -1; } return r; } #include "upgrade.h" int sys_set_factory(void) { int r=0; char dir[200],src[400],dst[400]; GlobalDeviceManager *dm=&__globalDeviceManage; sqlite_deinit(dm->db, &dm->dbThreadlock); sys_get_path(dir, ""); LOGD("___ curdir: %s\n", dir); snprintf(src, sizeof(src), "%s/%s", dir, DATABASE_BAK_NAME); snprintf(dst, sizeof(dst), "%s/%s", dir, DATABASE_NAME); LOGD("__1__ file_copy from %s to %s\n", src, dst); r = file_copy(dst, src); if(0) { r = paras_reset(); } else { snprintf(src, sizeof(src), "%s/%s", dir, INI_FILE_BAK_NAME); snprintf(dst, sizeof(dst), "%s/%s", dir, INI_FILE_NAME); LOGD("__2__ file_copy from %s to %s\n", src, dst); r = file_copy(dst, src); } #if 0 r = set_net(&DFLT_PARAS.dev._network_info, IP_V4); if(r) { LOGE("____ set_net failed\n"); return -1; } #endif LOGD("____ exit smartPDU now ...\n"); exit(0); return r; } int sys_get_path(char *path, char *name) { int r,n; char *p,tmp[500]; pid_t pid = getpid(); snprintf(tmp, sizeof(tmp), "/proc/%d/exe", pid); n = readlink(tmp, path, sizeof(tmp)); if(n>0 && n1) { *p = 0; if(name && strlen(name)>0) { strcat(path, "/"); strcat(path, name); } } return 0; } return -1; } //////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include void print_net(char*s, NetworkInfo_t *p) { LOGD("__%s__net.mode: %d\n", s, p->mode); LOGD("__%s__net.addr: %s\n", s, p->ip_address); LOGD("__%s__net.mask: %s\n", s, p->mask); LOGD("__%s__net.gateway: %s\n", s, p->gateway); LOGD("__%s__net.dns1: %s\n", s, p->dns1); LOGD("__%s__net.dns2: %s\n", s, p->dns2); } void print_modbus(char*s, ModbusInfo_t *p) { LOGD("__%s__mbus.mode: %d\n", s, p->mode); LOGD("__%s__mbus.addr: %d\n", s, p->addr); LOGD("__%s__mbus.baud: %d\n", s, p->baudrate); LOGD("__%s__mbus.path: %s\n", s, p->path); } static int set_ipaddr(int family, const char* iface, const char* addr, const char* netmask) { struct ifreq ifr; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; int fd = socket(family, SOCK_DGRAM, 0); if (fd < 0) { LOGD("socket SOCK_DGRAM failed\n"); return -1; } strcpy(ifr.ifr_name, iface); sin = (struct sockaddr_in*)&ifr.ifr_addr; sin6 = (struct sockaddr_in6*)&ifr.ifr_addr; if(family==AF_INET) { sin->sin_family = family; sin->sin_port = 0; inet_pton(family, addr, &sin->sin_addr); if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { LOGD("ioctl SIOCSIFADDR \n"); close(fd); return -1; } sin->sin_family = family; inet_pton(family, netmask, &sin->sin_addr); if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) { LOGD("ioctl SIOCSIFNETMASK \n"); close(fd); return -1; } } else { sin6->sin6_family = family; sin6->sin6_port = 0; inet_pton(family, addr, &sin6->sin6_addr); if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { LOGD("ioctl SIOCSIFADDR \n"); close(fd); return -1; } sin6->sin6_family = family; inet_pton(family, netmask, &sin6->sin6_addr); if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) { LOGD("ioctl SIOCSIFNETMASK \n"); close(fd); return -1; } } close(fd); return 0; } static int get_ipaddr(int family, char *iface, char *addr, char *netmask) { int r=-1; struct ifaddrs *ifap, *ifa; if (getifaddrs(&ifap) == -1) { LOGE("___getifaddrs() error\n"); return -1; } for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr != NULL && ifa->ifa_addr->sa_family == family) { if(family==AF_INET) { struct sockaddr_in *sa,*msk; sa = (struct sockaddr_in *) ifa->ifa_addr; msk = (struct sockaddr_in *) ifa->ifa_netmask; if(addr) { char *p = (char*)inet_ntop(family, &sa->sin_addr, addr, INET6_ADDRSTRLEN); if(p && strcmp(p, "127.0.0.1") && strcmp(p, "172.17.0.1")) { printf("___addr4: %s\n", addr); r = 0; } } if(netmask) { inet_ntop(family, &msk->sin_addr, netmask, INET6_ADDRSTRLEN); //printf("___netmask4: %s\n", netmask); } if(r==0) break; } else { struct sockaddr_in6 *sa,*msk; sa = (struct sockaddr_in6 *) ifa->ifa_addr; msk = (struct sockaddr_in6 *) ifa->ifa_netmask; if(addr) { char *p = (char*)inet_ntop(family, &sa->sin6_addr, addr, INET6_ADDRSTRLEN); if(p && strcmp(p, "::1")) { printf("___addr6: %s\n", addr); r = 0; } } if(netmask) { inet_ntop(family, &msk->sin6_addr, netmask, INET6_ADDRSTRLEN); //printf("___netmask6: %s\n", netmask); } if(r==0) break; } } } freeifaddrs(ifap); return r; } static int set_gateway(int family, const char* gateway) { struct rtentry rt; int fd; fd = socket(family, SOCK_DGRAM, 0); if (fd < 0) { LOGE("socket SOCK_DGRAM failed\n"); return -1; } memset(&rt, 0, sizeof(rt)); if(family==AF_INET) { struct sockaddr_in* sin; sin = (struct sockaddr_in*)&rt.rt_gateway; sin->sin_family = family; sin->sin_port = 0; inet_pton(family, gateway, &sin->sin_addr); sin = (struct sockaddr_in*)&rt.rt_dst; sin->sin_family = family; sin->sin_addr.s_addr = 0; } else { struct sockaddr_in6* sin; sin = (struct sockaddr_in6*)&rt.rt_gateway; sin->sin6_family = family; sin->sin6_port = 0; inet_pton(family, gateway, &sin->sin6_addr); sin = (struct sockaddr_in6*)&rt.rt_dst; sin->sin6_family = family; //sin->sin6_addr.s_addr[0] = 0; } rt.rt_flags = RTF_GATEWAY; if (ioctl(fd, SIOCADDRT, &rt) < 0) { LOGE("ioctl SIOCADDRT failed\n"); close(fd); return -1; } close(fd); return 0; } static int get_gateway(int family, const char* gateway) { #if 0 int sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sockfd == -1) { log_e("set_gateway, socket AF_NETLINK error\n"); return -1; } struct sockaddr_nl sa; memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { log_e("set_gateway, bind error\n"); return -1; } struct nlreq req; memset(&req, 0, sizeof(req)); req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); req.hdr.nlmsg_type = RTM_GETROUTE; req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; req.msg.rtm_family = family; req.msg.rtm_table = RT_TABLE_MAIN; req.msg.rtm_protocol = RTPROT_UNSPEC; req.msg.rtm_scope = RT_SCOPE_UNIVERSE; req.msg.rtm_type = RTN_UNICAST; struct iovec iov; memset(&iov, 0, sizeof(iov)); iov.iov_base = &req; iov.iov_len = req.hdr.nlmsg_len; struct msghdr msg; memset(&msg, 0, sizeof(msg)); msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &iov; msg.msg_iovlen = 1; char buf[BUFSIZE]; memset(buf, 0, sizeof(buf)); struct nlmsghdr *hdr; int len; if (sendmsg(sockfd, &msg, 0) == -1) { log_e("set_gateway, sendmsg error\n"); return -1; } while ((len = recv(sockfd, buf, sizeof(buf), 0)) > 0) { for (hdr = (struct nlmsghdr *) buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) { if (hdr->nlmsg_type == NLMSG_DONE) { goto finish; } if (hdr->nlmsg_type == NLMSG_ERROR) { log_e("set_gateway, NLMSG_ERROR\n"); return -1; } struct rtmsg *rt = (struct rtmsg *) NLMSG_DATA(hdr); if (rt->rtm_family != family || rt->rtm_table != RT_TABLE_MAIN || rt->rtm_type != RTN_UNICAST) { continue; } struct rtattr *attr; int attrlen; for (attr = (struct rtattr *) RTM_RTA(rt), attrlen = RTM_PAYLOAD(hdr); RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) { if (attr->rta_type == RTA_GATEWAY) { char gw_addr[INET_ADDRSTRLEN]; struct in_addr addr; memcpy(&addr, RTA_DATA(attr), sizeof(addr)); if (inet_ntop(family, &addr, gateway, INET6_ADDRSTRLEN) == NULL) { log_e("set_gateway, inet_ntop error\n"); continue; } printf("Gateway address: %s\n", gw_addr); log_i("set_gateway, Gateway address: %s\n"); goto finish; } } } } finish: close(sockfd); #endif return 0; } static int set_dhcp(int on) { if(on) { system("killall udhcpc && udhcpc –i eth0 –s /usr/share/udhcpc/default.script &"); } else { system("killall udhcpc"); } return 0; } static int is_number(char *str) { while (*str) { if (!isdigit(*str)) { return 0; } str++; } return 1; } static int ip_check(char* addr) { int flag=IP_ERR; struct in_addr addr4; struct in6_addr addr6; if (inet_pton(AF_INET, addr, &addr4) == 1) { flag = IP_V4; } else if (inet_pton(AF_INET6, addr, &addr6) == 1) { flag = IP_V6; } if(flag==IP_ERR) { LOGE("____ wrong ip addr: %s\n", addr); } return flag; } static int is_ipv6_prefix(char *ss) { if(is_number(ss)) { int val = atoi(ss); if(val>1 && val<128) { return 1; } } return 0; } /////////////////////////////////////////////// typedef struct { char lo[1000]; char e0[1000]; char e1[1000]; }interface_t; typedef uint32_t u32; #define XLEN(a,b) ((u32)(a)-(u32)(b)) typedef struct { char *ptr; int len; }nic_t; static int get_nic(char *nbuf, int nlen, char *nic, char *fbuf, int flen) { int r,xlen; char tmp[20]; char *p1,*p2; char *fend=fbuf+flen-1; sprintf(tmp, "auto %s", nic); p1 = strstr(fbuf, tmp); if(!p1) { return -1; } p2 = strstr(p1+1, "auto"); if(!p2 || p2>fend) { p2 = fend; } xlen = XLEN(p2,p1); memcpy(nbuf, p1, xlen); nbuf[xlen] = 0; return 0; } static int get_ip(char *nbuf, char *token, char *ipaddr, int ipv) { int cnt=0; char *p,*p1,*p2; char *pbuf=NULL; if(ipv==IP_V4) { pbuf = strstr(nbuf, "inet"); } else { pbuf = strstr(nbuf, "inet6"); } if(pbuf==NULL) { LOGE("___get_ip, not found inet or inet6\n"); return -1; } p = strstr(pbuf, token); if(p) { p += strlen(token); while(isspace(*p)) p++; p1 = p; while(!isspace(*p)) p++; p2 = p; for(p=p1; pdns1); int chk2=ip_check(para->dns2); if( chk1==IP_ERR && chk2==IP_ERR) { LOGE("___ dns1 and dns2 are all wrong!\n"); return -1; } memset(buf, 0, sizeof(buf)); strcpy(buf, "interface=eth0\nno-hosts\nno-resolv\n\n"); if(chk1) { sprintf(tmp, "server=%s\n", para->dns1); strcat(buf, tmp); } if(chk2) { sprintf(tmp, "server=%s\n", para->dns2); strcat(buf, tmp); } r = file_save(FILE_DNS, buf, strlen(buf))+1; if(r==0) { system("killall dnsmasq; /usr/sbin/dnsmasq &"); } return r; } static int get_net(NetworkInfo_t *para, int ipv) { int r; char *p=NULL; interface_t intf; buf_t fbuf; r = file_load(FILE_NET, &fbuf); if(r) { return -1; } memset(&intf, 0, sizeof(intf)); get_nic(intf.lo, sizeof(intf.lo), "lo", fbuf.buf, fbuf.dlen); get_nic(intf.e0, sizeof(intf.e0), "eth0", fbuf.buf, fbuf.dlen); get_nic(intf.e1, sizeof(intf.e1), "eth1", fbuf.buf, fbuf.dlen); p = strstr(intf.e0, (ipv==IP_V4)?"inet":"inet6"); if(p==NULL) { LOGE("___get_ipv%d, %s not found!\n", (ipv==IP_V4)?4:6, (ipv==IP_V4)?"inet":"inet6"); free(fbuf.buf); return -1; } if(strstr(p, "dhcp")) { para->mode = 0; } else if(strstr(p, "static")) { para->mode = 1; } else { LOGE("___get_net, dhcp/static not found!\n"); free(fbuf.buf); return -1; } get_ip(p, "address", para->ip_address, ipv); get_ip(p, "netmask", para->mask, ipv); get_ip(p, "gateway", para->gateway, ipv); free(fbuf.buf); r = file_load(FILE_DNS, &fbuf); if(r) { return -1; } get_dns(fbuf.buf, para->dns1, para->dns2); return 0; } static int nw_check(NetworkInfo_t *para, int ipv) { if(ipv==IP_V4) { if((ip_check(para->ip_address)!=IP_V4) || (ip_check(para->mask)!=IP_V4) || (ip_check(para->gateway)!=IP_V4)) { return -1; } } else { if((ip_check(para->ip_address)!=IP_V6) || (!is_ipv6_prefix(para->mask)) || (ip_check(para->gateway)!=IP_V6)) { return -1; } } return 0; } static int set_net(NetworkInfo_t *para, int ipv) { int r,ipv2; char *p1,*p2,*p3,*p4; int flen=100*1000; NetworkInfo_t info4,info6,*info; get_net(&info4, IP_V4); get_net(&info6, IP_V6); info = ((ipv==IP_V4)?&info4:&info6); if(para->mode<2 && para->mode!=info->mode) { info->mode = para->mode; } ipv2 = ip_check(para->ip_address); if((ipv==ipv2) && strcmp(para->ip_address, info->ip_address)) { strcpy(info->ip_address, para->ip_address); } if(ipv==IP_V4) { ipv2 = ip_check(para->mask); } else { ipv2=is_ipv6_prefix(para->mask)?IP_V6:IP_ERR; } if((ipv==ipv2) && strcmp(para->mask, info->mask)) { strcpy(info->mask, para->mask); } ipv2 = ip_check(para->gateway); if((ipv==ipv2) && strcmp(para->gateway, info->gateway)) { strcpy(info->gateway, para->gateway); } char *fbuf=malloc(flen); if(!fbuf) { LOGE("___ malloc %d failed\n", flen); return -1; } #if 0 file_load(FILE_NET, fbuf); get_nic(pNet->lo, sizeof(pNet->lo), "lo", fbuf, flen); get_nic(pNet->e1, sizeof(pNet->e1), "eth1", fbuf, flen); snprintf(pNet->e0, sizeof(pNet->e0), "auto eth0\niface eth0 inet %s\n address %s\n netmask %s\n gateway %s\n\n", info4.mode?"static":"dhcp", info4.ip_address, info4.mask, info4.gateway); strcpy(fbuf, pNet->lo); strcat(fbuf, pNet->e0); strcat(fbuf, pNet->e1); #else char *lo="auto lo\niface lo inet loopback\n\n"; char *eth1="auto eth1\niface eth1 inet dhcp\npre-up /etc/network/nfs_check\nwait-delay 5\nhostname $(hostname)\n"; char eth0[1000]; int chk4=nw_check(&info4, IP_V4); int chk6=nw_check(&info6, IP_V6); char temp[400]; strcpy(eth0, "auto eth0\n"); if(chk4==0) { sprintf(temp, "iface eth0 inet %s\n address %s\n netmask %s\n gateway %s\n\n", (info4.mode==IP_STATIC)?"static":"dhcp", info4.ip_address, info4.mask, info4.gateway); strcat(eth0, temp); } if(chk6==0) { sprintf(temp, "iface eth0 inet6 %s\n address %s\n netmask %s\n gateway %s\n\n", (info6.mode==IP_STATIC)?"static":"dhcp", info6.ip_address, info6.mask, info6.gateway); strcat(eth0, temp); } sprintf(fbuf, "%s%s%s", lo, eth0, eth1); #endif //LOGD("___interfaces___:\n%s", fbuf); r = file_save(FILE_NET, fbuf, strlen(fbuf)); free(fbuf); return r; } ////////////////////////////////////////////////////////////////////////////// int sys_set_net(NetworkInfo_t *para, int ipVersion) { int r,ipv; #ifdef USE_BASH char cmd[200]; snprintf(cmd, sizeof(cmd), "ip addr flush dev %s", DFLT_NIC); r = system(cmd); if(r) { LOGE("set ipaddr failed\n"); return -1; } snprintf(cmd, sizeof(cmd), "ip addr add %s/%s dev %s", para->ip_address, para->mask, DFLT_NIC); r = system(cmd); if(r) { LOGE("set netmask %s failed\n", para->mask); return -1; } snprintf(cmd, sizeof(cmd), "ip route add default via %s dev %s", para->gateway, DFLT_NIC); r = system(cmd); if(r) { LOGE("set gateway %s failed\n", para->gateway); return -1; } snprintf(cmd, sizeof(cmd), "ip link set dev %s up", DFLT_NIC); r = system(cmd); if(r) { LOGE("restart %s failed\n", DFLT_NIC); return -1; } #elif defined USE_FILE NetworkInfo_t para2; r = get_net(¶2, ipVersion); if(r==0) { if(memcmp(para, ¶2, sizeof(NetworkInfo_t))==0) { LOGW("%s NetworkInfo is same, no need to set\n", DFLT_NIC); return -1; } set_dns(para); r = set_net(para, ipVersion); if(r==0) { //system("ip addr flush dev eth0"); //sprintf(eth0, "ip link set dev eth0 %s/%d && ip link set eth0 up && ip link set eth0 down", info->ip_address, info->netmask); //system(eth0); sys_reboot(); //nic_restart(DFLT_NIC); exit(0); } } else { LOGE("get_net failed\n"); } #elif defined USE_API if(para->mode==IP_DHCP) { r = set_dhcp(1); } else { set_dhcp(0); int family=(ipv==IP_V4)?AF_INET:AF_INET6; r = set_ipaddr(family, "eth0", para->ip_address, para->mask); if(r) { LOGE("set_ipaddr failed\n"); return r; } r = set_gateway(family, para->gateway); if(r) { LOGE("set_gateway failed\n"); return r; } r = set_dns(family, "eth0", para->dns1, para->dns2); if(r) { LOGE("set_dns failed\n"); return r; } } #endif return r; } int sys_get_net(NetworkInfo_t *para, int ipVersion) { int r; int family=AF_INET; #ifdef USE_BASH #elif defined USE_FILE r = get_net(para, ipVersion); #elif defined USE_API r = get_ipaddr(family, DFLT_NIC, para->ip_address, para->mask); if(r) { LOGE("set_ipaddr failed\n"); return r; } r = get_gateway(family, para->gateway); if(r) { LOGE("set_gateway failed\n"); return r; } r = get_dns(family, DFLT_NIC, para->dns1, para->dns2); if(r) { LOGE("set_dns failed\n"); return r; } #endif return r; } int sys_is_running(char *prog) { FILE *fp; int pid=0; char buf[20]={0}; char command[200]; snprintf(command, sizeof(command), "ps -ef | grep -v grep | grep -w -c %s", prog); fp = popen(command, "r"); if (fp == NULL) { LOGE("execute %s failed: %s", command, strerror(errno)); return 0; } if (fgets(buf, sizeof(buf), fp)) { pid = atoi(buf); } pclose(fp); return (pid)?1:0; } int sys_get_disk_ava_MB(char *path) { int r; struct statvfs st; r = statvfs(path, &st); if(r) { return -1; } int avaMB = (st.f_frsize*st.f_bavail)/(1024*1024); //int freeMB = (st.f_frsize*st.f_bfree)/(1024*1024); //printf("____ava: %dMB, free %dMB\n", avaMB, freeMB); LOGD("___ RomAvailable rom: %dMB\n", avaMB); return avaMB; } int sys_get_mem_ava_MB(void) { int r; long v1=0,v2=0; char buf[32]; struct sysinfo info; #if 0 r = sysinfo(&info); if(r) { return -1; } value = (info.freeram*info.mem_unit)/(1014*1024); #else FILE *fp = fopen("/proc/meminfo", "r"); if(!fp) { return -1; } fscanf(fp, "MemTotal: %s kB\n", buf); fscanf(fp, "MemFree: %s kB\n", buf); v1 = atol(buf); fscanf(fp, "MemAvailable: %s kB\n", buf); v2 = atol(buf); fclose(fp); LOGD("___MemFree: %ldkB, MemAvailable: %ldkB\n", v1, v2); v2 /= 1024; #endif return v2; } int sys_get_mac(char *mac, int maclen) { int sock; struct ifreq ifr; if(!mac || maclen<6) { return -1; } sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1){ return -1; } strcpy(ifr.ifr_name, "eth0"); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0){ close(sock); return -1; } close(sock); uint8_t *p = (uint8_t*)ifr.ifr_hwaddr.sa_data; snprintf(mac, maclen, "%02x%02x%02x%02x%02x%02x", p[0], p[1], p[2], p[3], p[4], p[5]); return 0; } int sys_get_chip_id(int *id) { int sock; struct ifreq ifr; if(!id) { return -1; } sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1){ return -1; } strcpy(ifr.ifr_name, "eth0"); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0){ close(sock); return -1; } close(sock); *id = *((int*)ifr.ifr_hwaddr.sa_data); return 0; } int sys_ip_check(char *ip) { return ip_check(ip); } /////////////////////////////////////////////////////////////////////// #define MAX_BUFFER_SIZE 4096 static void* plug_thread(void *arg) { int nlSock; struct sockaddr_nl srcAddr; struct nlmsghdr *nlMsg; char buffer[MAX_BUFFER_SIZE]; int plug_in=0,plug_out=0; thread_handle_t *h=(thread_handle_t*)arg; printf("___plug_thread start\n"); nlSock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (nlSock < 0) { printf("Failed to create Netlink socket"); goto quit; } memset(&srcAddr, 0, sizeof(srcAddr)); srcAddr.nl_family = AF_NETLINK; srcAddr.nl_groups = RTMGRP_LINK | RTMGRP_NOTIFY; if (bind(nlSock, (struct sockaddr *)&srcAddr, sizeof(srcAddr)) < 0) { perror("Failed to bind Netlink socket"); close(nlSock); goto quit; } int flags = fcntl(nlSock, F_GETFL, 0); fcntl(nlSock, F_SETFL, flags | O_NONBLOCK); while (h->quit==0) { fd_set readSet; FD_ZERO(&readSet); FD_SET(nlSock, &readSet); // 设置超时时间为 1 秒 struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; // 监视 Netlink Socket 的可读状态 int result = select(nlSock + 1, &readSet, NULL, NULL, &timeout); if (result == -1) { perror("Failed to select"); goto quit; } else if (result == 0) { // 超时,没有新数据到达 //printf("Timeout\n"); continue; } if (FD_ISSET(nlSock, &readSet)) { // 接收消息 int bytesRead = recv(nlSock, buffer, MAX_BUFFER_SIZE, 0); if (bytesRead < 0) { perror("Failed to receive message from Netlink socket"); close(nlSock); goto quit; } // 遍历接收到的消息,获取到Netlink的消息头。 nlMsg = (struct nlmsghdr *)buffer; while (NLMSG_OK(nlMsg, bytesRead)) { if (nlMsg->nlmsg_type == NLMSG_DONE) { break; } if (nlMsg->nlmsg_type == RTM_NEWLINK || nlMsg->nlmsg_type == RTM_DELLINK) { //NLMSG_DATA()获取完整的ifinfomsg结构体的指针 //根据消息头nlMsg获取到其后面的数据部分ifinfomsg结构体的指针 struct ifinfomsg *ifInfo = (struct ifinfomsg *)NLMSG_DATA(nlMsg); if (ifInfo->ifi_family == AF_UNSPEC) { //获取路由信息的属性,以及消息负载的长度,通过这两个参数来判断本次的数据是否有效 struct rtattr *attribute = IFLA_RTA(ifInfo); int attributeLen = IFLA_PAYLOAD(nlMsg); while (RTA_OK(attribute, attributeLen)) { char *ifaceName = (char *)RTA_DATA(attribute); if ((attribute->rta_type == IFLA_IFNAME) && (strcmp(ifaceName, "eth0")==0)) { //printf("____Interface: %s \n", ifaceName); if((ifInfo->ifi_flags & IFF_LOWER_UP)) { if(plug_in==0) { system("ifup eth0"); printf("____eth0 plug in\n"); plug_in = 1; plug_out = 0; } } else { if(plug_out==0) { system("ifdown eth0"); printf("____eth0 plug out\n"); plug_in = 0; plug_out = 1; } } } attribute = RTA_NEXT(attribute, attributeLen); } } } nlMsg = NLMSG_NEXT(nlMsg, bytesRead); } } } close(nlSock); quit: printf("___plug_thread exit\n"); pthread_exit(NULL); } /////////////////////////////////////////////////////////// //#define RAM_DEBUG //#define ROM_DEBUG #ifdef RAM_DEBUG #define RAM_THRD 50 #define RAM_PERIOD 1 #else #if(CHIP_TYPE == CHIP_T113s) #define RAM_THRD 20 #define RAM_PERIOD 30 #else #define RAM_THRD 50 #define RAM_PERIOD 60 #endif #endif #ifdef ROM_DEBUG #define ROM_THRD 50 #define ROM_PERIOD 1 #else #if(CHIP_TYPE == CHIP_T113s) #define ROM_THRD 30 #define ROM_PERIOD 40 #else #define ROM_THRD 50 #define ROM_PERIOD 60 #endif #endif static void mem_check(void) { int avaMB,flag=0; static uint32_t mem_cnt=0; mem_cnt++; if(mem_cnt%RAM_PERIOD==0) { avaMB = sys_get_mem_ava_MB(); if(avaMB /dev/null", TMP_DIR); return system(cmd); } static void send_by_mail(struct tm *tm, char *dir) { int r=-1; char temp[200],sub[100]; char tmp1[100],tmp2[100]; char path[1024]; GlobalDeviceManager *dm=&__globalDeviceManage; ProductInfo_t *prod=&dm->_globalDevInfo.product; static time_t sended_id=0; time_t from,to; get_range(tm, &from, &to, 1); if(sended_id != from) { path[0] = 0; get_time_str2(tmp1,sizeof(tmp1),from); get_time_str2(tmp2,sizeof(tmp2),to); sprintf(temp, "%s/log_run_%s_%s.txt", dir, tmp1, tmp2); r = dev_log_xport(0, from, to, temp); if(r==0) { strcat(path, temp);strcat(path, ";"); } sprintf(temp, "%s/log_opr_%s_%s.txt", dir, tmp1, tmp2); r = dev_log_xport(1, from, to, temp); if(r==0) { strcat(path, temp);strcat(path, ";"); } sprintf(temp, "%s/power_%s_%s.csv", dir, tmp1, tmp2); r = dev_power_xport(from, to, temp); if(r==0) { strcat(path, temp);strcat(path, ";"); } if(r==0) { sprintf(sub, "%s %d power and log data", prod->name, prod->id); r = mail_send(sub, NULL, path); if(r==0) { tmp_remove(); sended_id = from; } } } } static void send_check(void) { static int file_flag=0; static uint32_t send_cnt=0; send_cnt++; if(send_cnt%SEND_PERIOD==0) { struct tm *tm=get_curtime(); if(tm->tm_hour==0) { send_by_mail(tm, TMP_DIR); file_flag = 1; } else if(tm->tm_hour==1 && file_flag) { tmp_remove(); file_flag = 0; } } } //https://blog.csdn.net/weixin_47604497/article/details/136913868 #include static int wdog_fd=-1; static int wdog_is_en(void) { GlobalDeviceManager *dm=&__globalDeviceManage; MiscInfo_t *misc=&dm->_globalDevInfo.misc; return misc->watchdog; } static int wdog_init(void) { int r=0; if(wdog_is_en()) { char *path="/dev/watchdog"; if(wdog_fd<0) { wdog_fd = open(path, O_RDWR); //O_WRONLY if(wdog_fd<0) { printf("___ %s open failed\n", path); return -1; } } #if 0 int i,option,timeout; struct watchdog_info info; option = WDIOS_DISABLECARD; r = ioctl(wdog_fd, WDIOC_SETOPTIONS, &option); r = ioctl(wdog_fd, WDIOC_GETSUPPORT, &info); if(r<0) { printf("___ %s getsupport failed\n", path); return -1; } printf("___ watchdog options: 0x%x\n", info.options&WDIOC_SETTIMEOUT); timeout = 100; r = ioctl(wdog_fd, WDIOC_SETTIMEOUT, &timeout); if(r) { printf("______set__________ wdog set timeout: %d failed, errno: %d\n", timeout, errno); } option = WDIOS_ENABLECARD; r = ioctl(wdog_fd, WDIOC_SETOPTIONS, &option); #endif } return r; } static int wdog_feed(void) { int r=0; if(wdog_is_en()) { r = ioctl(wdog_fd, WDIOC_KEEPALIVE, 0); //int t1=200,t2=0; //r = ioctl(wdog_fd, WDIOC_SETTIMEOUT, &t1); //printf("______set__________ wdog timeout: %d, errno: %d\n", r, errno); //r = ioctl(wdog_fd, WDIOC_GETTIMEOUT, &t2); //printf("________________ wdog timeout: %d\n", t2); } return r; } static void sig_handler(int signo) { printf("sigint_handler, signo: %d\n", signo); //wdog_enable(0); } static void sig_init(void) { signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGKILL, sig_handler); } static void* polling_thread(void *arg) { thread_handle_t *h=(thread_handle_t*)arg; wdog_init(); tmp_create(); while(h->quit==0) { net_check(); wdog_feed(); mem_check(); send_check(); sleep(1); } pthread_exit(NULL); } static char *str_get(char *buf, char *tok, char *dst, int dstlen) { int n=0; char *t=dst,*p=strstr(buf,tok); if(!p) { return NULL; } while((*p)!=':') { if((*p)=='\r' || (*p)=='\n') { return NULL; } p++; } p++; while((*p)!='"') { if((*p)=='\r' || (*p)=='\n') { return NULL; } p++; } p++; while((*p)!='"') { if((*p)=='\r' || (*p)=='\n') { return NULL; } *dst++ = *p++; n++; if(n>=dstlen-1) { LOGE("str_get %s, dst buf length %d is too small!\n", tok, dstlen); return NULL; } } *dst = 0; return t; } int sys_get_prod(GlobalDeviceInfo *info) { int r; char *p,*tok; buf_t fbuf; char path[100]={0}; r = file_load(INFO_FILE_PATH, &fbuf); if(r) { return -1; } tok = "product_name"; p = str_get(fbuf.buf, tok, info->product.pname, sizeof(info->product.pname)); if(p) LOGD("___%s:%s\n", tok, p); tok = "product_sn"; p = str_get(fbuf.buf, tok, info->product.pnumber, sizeof( info->product.pnumber)); if(p) LOGD("___%s:%s\n", tok, p); #if 0 tok = "device_name"; p = str_get(fbuf.buf, tok, info->product.name, sizeof( info->product.name)); if(p) LOGD("___%s:%s\n", tok, p); #endif tok = "device_no"; p = str_get(fbuf.buf, tok, info->product.number, sizeof(info->product.number)); if (p) LOGD("___%s:%s\n", tok, p); tok = "device_date"; p = str_get(fbuf.buf, tok, info->product.date, sizeof(info->product.date)); if(p) LOGD("___%s:%s\n", tok, p); tok = "device_batch"; p = str_get(fbuf.buf, tok, info->product.batch, sizeof(info->product.batch)); if(p) LOGD("___%s:%s\n", tok, p); tok = "service_name"; p = str_get(fbuf.buf, tok, info->service.name, sizeof(info->service.name)); if(p) LOGD("___%s:%s\n", tok, p); tok = "service_site"; p = str_get(fbuf.buf, tok, info->service.site, sizeof(info->service.site)); if(p) LOGD("___%s:%s\n", tok, p); tok = "service_mail"; p = str_get(fbuf.buf, tok, info->service.mail, sizeof(info->service.mail)); if(p) LOGD("___%s:%s\n", tok, p); tok = "service_address"; p = str_get(fbuf.buf, tok, info->service.addr, sizeof(info->service.addr)); if(p) LOGD("___%s:%s\n", tok, p); tok = "service_telephone"; p = str_get(fbuf.buf, tok, info->service.tele, sizeof(info->service.tele)); if(p) LOGD("___%s:%s\n", tok, p); sys_get_path(path, "../web/img/shdh.png"); r = qrc_to_png(info->service.tele, path); sys_get_path(path, "../web/img/sbh.png"); r = qrc_to_png(info->product.number, path); free(fbuf.buf); return 0; } int sys_chmod(void) { DIR *dir; char path[200]; struct stat st; struct dirent *entry; sys_get_path(path, NULL); dir = opendir(path); if(!dir) { return -1; } chdir(path); while ((entry=readdir(dir))) { lstat(entry->d_name, &st); if(S_ISDIR(st.st_mode)) { continue; } chmod(entry->d_name, S_IRWXG); } closedir(dir); return 0; } int sys_get_ip_ver(char *addr) { return ip_check(addr); } static int net_check(void) { int r,pid; char tmp[200]; char ipaddr[64],mask[64]; NetworkInfo_t net4,net6; static uint32_t dhcp_cnt=0; if(dhcp_cnt%10==0) { printf("__ dhcp check\n"); r = get_net(&net4, IP_V4); if(r==0) { r = get_ipaddr(AF_INET, DFLT_NIC, ipaddr, mask); if(r) { if(net4.mode==IP_DHCP) { #if 0 pid = get_pid("udhcpc"); printf("___udhcpc pid: %d\n", pid); if(pid>=0) { kill(pid, SIGUSR2); } #else system("killall udhcpc; udhcpc"); #endif } else { sprintf(tmp, "ifconfig %s %s up", DFLT_NIC, ipaddr); system(tmp); } } } r = get_net(&net6, IP_V6); if(r==0) { r = get_ipaddr(AF_INET6, DFLT_NIC, ipaddr, mask); if(r) { if(net6.mode==IP_DHCP) { pid = get_pid("udhcpc6"); printf("___udhcpc6 pid: %d\n", pid); if(pid>=0) { kill(pid, SIGUSR2); } } else { sprintf(tmp, "ip addr add %s/%s dev %s", ipaddr, mask, DFLT_NIC); system(tmp); sprintf(tmp, "ip link set dev %s up", DFLT_NIC); system(tmp); } } } } dhcp_cnt++; return 0; } static void net_init(void) { nic_set_mac(); } static int get_pid(char *proc) { DIR *dir; int pid=-1; struct dirent *entry; dir = opendir("/proc"); if (!dir) { return -1; } while ((entry = readdir(dir))) { if (entry->d_type != DT_DIR || !isdigit(entry->d_name[0])) { continue; } char path[500]; snprintf(path, sizeof(path), "/proc/%s/cmdline", entry->d_name); FILE *f = fopen(path, "r"); if (f) { char cmd[64]; if (fgets(cmd, sizeof(cmd), f) && strstr(cmd, proc)) { pid = atoi(entry->d_name); break; } fclose(f); } } closedir(dir); return pid; } int sys_kill(char *proc) { int status; int pid=get_pid(proc); if(pid<0) { return -1; } kill(pid, SIGKILL); waitpid(pid, &status, 0); return 0; } int sys_restart_app(void) { #if (CHIP_TYPE == CHIP_T113s) return system("reboot -f"); #else return system("/etc/init.d/S90PDUApp restart"); #endif } #if (CHIP_TYPE != CHIP_T113s) #include "ui.h" #endif int sys_init(void) { initLogger(); lock_s_init(); paras_init(); sys_chmod(); init_hash_table(); net_init(); #if (CHIP_TYPE != CHIP_T113s) ui_init(); #endif thread_start(THREAD_ID_POLLING, polling_thread, NULL); return 0; }