天天看點

嵌入式 hi3518平台以太網網絡子產品設計包括重連機制和網線檢測機制

​​

<span style="font-family:Courier New;">  

#include <sys/types.h>    

#include <string.h>    

#include <stdlib.h>    

#include <sys/ioctl.h>    

#include <sys/stat.h>    

#include <stdio.h>    

#include <errno.h>    

#include <net/if.h>    

#include <sys/utsname.h>    

#include <limits.h>    

#include <ctype.h>       

#include <sys/socket.h>    

#include <arpa/inet.h>       

#include <linux/sockios.h>    

#include <sys/socket.h>     

#include <netinet/ip.h>     

#include <netinet/ip_icmp.h>     

#include <netdb.h>    

#include <netinet/in.h>  

#define JOSEPH_LOOP_INTERFACE           "lo"  

#define JOSEPH_ETH_INTERFACE            "eth0"  

#define JOSEPH_WIRLESS_INTERFACE        "wlan0"  

#define ETHTOOL_GLINK                   0x0000000a   /* Get link status (ethtool_value) */    

#define JSOEPH_NET_CHECK_PACKET_SIZE    4096     

#define JOSEPH_NET_CHECK_TIME           3000  

typedef struct Joseph_Net_Interface_Info  

{  

    int net_device_type;// 0 ~ eth0 ; 1 ~ wlan ;3 ~ ppp0  

    int net_device_priority;// 0 ~ eth0 ; 1 ~ wlan ;3 ~ ppp0  

    int net_device_status;//0 ~ down; 1 ~ up  

    int net_device_link_status;//0 ~ no ;1 ~ yes  

    char net_device_name[8];  

    char net_device_ip[16];  

    char net_device_mac_info[32];  

    char net_device_gw_info[16];  

    char net_device_mask_info[16];  

    char net_device_broadcast_info[16];  

}JOSEPH_NET_INTERFACE_INFO;  

typedef struct Joseph_Ethtool_Value {    

    unsigned int   cmd;    

    unsigned int   data;     

}JOSEPH_ETHTOOL_VALUE;  

enum Joseph_Net_Device_Type  

    JOSEPH_ETH = 0,  

    JOSEPH_WIFI = 1,  

    JOSEPH_3G = 2,  

}JOSEPH_NET_DEVICE_TYPE;  

unsigned short Joseph_Cal_Chksum(unsigned short *addr, int len)   

{    

    int nleft=len;    

    int sum=0;    

    unsigned short *w=addr;    

    unsigned short answer=0;      

    while(nleft > 1)   

    {    

      sum += *w++;    

      nleft -= 2;    

    }    

    if( nleft == 1)    

    {         

      *(unsigned char *)(&answer) = *(unsigned char *)w;    

      sum += answer;    

    sum = (sum >> 16) + (sum & 0xffff);    

    sum += (sum >> 16);    

    answer = ~sum;    

    return answer;    

}    

int Joseph_Ping( char *ips,char *srcip , int timeout)  

{        

    int n;  

    pid_t pid;    

    int maxfds = 0;    

    fd_set readfds;    

    struct ip *iph;    

    struct icmp *icmp;    

    struct timeval *tval;          

    struct sockaddr_in addr;        

    struct sockaddr_in from;  

    struct ifreq ifr;  

    bzero(&addr,sizeof(addr));  

    addr.sin_family = AF_INET;    

    addr.sin_addr.s_addr = inet_addr(ips);    

    int sockfd;    

    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);   

    if (sockfd < 0)     

    {      

      printf("ip:%s,socket error\n",ips);      

      return -1;      

    }      

    struct timeval timeo;  

    timeo.tv_sec = timeout / 1000;  

    timeo.tv_usec = timeout % 1000;    

#if 0  

    /*set src ip*/  

    bzero(&from,sizeof(from));  /* 設定Ip資訊 */  

    from.sin_family = AF_INET;    

    from.sin_addr.s_addr = inet_addr(srcip);      

    if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,(struct sockaddr *)&from, sizeof(from)) == -1)      

      printf("ip:%s,setsockopt error \n",srcip);       

      return ERROR;  

    bind(sockfd,(struct sockaddr *)&addr, sizeof(addr));  

#else  

    strcpy(ifr.ifr_name, srcip);  

    if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)  

    {  

        printf("can't bind to interface %s\n",ifr.ifr_name);  

    }  

#endif  

    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)) == -1)      

        printf("ip:%s,setsockopt error\n",ips);    

        return -1;      

    else  

        ;  

    char sendpacket[JSOEPH_NET_CHECK_PACKET_SIZE];      

    char recvpacket[JSOEPH_NET_CHECK_PACKET_SIZE];      

    memset(sendpacket, 0, sizeof(sendpacket));    

    pid = getpid();     

    icmp=(struct icmp*)sendpacket;   

    icmp->icmp_type = ICMP_ECHO;  

    icmp->icmp_code = 0;   

    icmp->icmp_cksum = 0;       

    icmp->icmp_seq = 0;      

    icmp->icmp_id = pid;     

    tval = (struct timeval *)icmp->icmp_data;        

    gettimeofday(tval,NULL);        

    icmp->icmp_cksum=Joseph_Cal_Chksum((unsigned short *)icmp,sizeof(struct icmp));  

    n = sendto(sockfd, (char *)&sendpacket, sizeof(struct icmp), 0, (struct sockaddr *)&addr, sizeof(addr));        

    if (n < 1)     

        printf("ip:%s,sendto error\n",ips);    

    while(1)   

      FD_ZERO(&readfds);  

      FD_SET(sockfd, &readfds);      

      maxfds = sockfd + 1;      

      n = select(maxfds, &readfds, NULL, NULL, &timeo);      

      if (n <= 0)       

      {      

          printf("ip:%s,Time out error\n",ips);      

          close(sockfd);      

          return -1;      

      }      

      memset(recvpacket, 0, sizeof(recvpacket));      

      int fromlen = sizeof(from);  

      n = recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen);      

      if (n < 1)  

      {     

          return -1;  

      char *from_ip = (char *)inet_ntoa(from.sin_addr);        

      if (strcmp(from_ip,ips) != 0)   

          printf("NowPingip:%s Fromip:%s\nNowPingip is not same to Fromip,so Joseph_Ping wrong!\n",ips,from_ip);       

          continue;    

      iph = (struct ip *)recvpacket;          

      icmp = (struct icmp *)(recvpacket + (iph->ip_hl << 2));  

      if (icmp->icmp_type == ICMP_ECHOREPLY && icmp->icmp_id == pid)  

          return 0;  

      else         

    }   

    return 0;  

}  

int Joseph_Check_Net_Status(char *if_name)    

    int Qy_Ret = 0;  

    if(strlen(if_name) <= 0)  

        Qy_Ret = -1;  

        return Qy_Ret;  

    char aPing[16]="202.108.22.5";  /* Joseph_Ping form ip  */  

    if(Joseph_Ping(aPing,if_name,JOSEPH_NET_CHECK_TIME) == 0)    

        printf("Network is Ok!\n");   

        Qy_Ret = 0;  

    else      

        printf("Network is Bad!\n");  

    return Qy_Ret;  

/*  

Author : kj  

Time : 2014-08-09  

Function :  

    get ip gw mac broadcast  

*/  

int Joseph_Get_Net_Device_Info(JOSEPH_NET_INTERFACE_INFO *Joseph_Net_Interface_Info_In)  

    int device_itertion = 0;  

    int Joseph_Net_Interface_Sfd = 0;  

    int Joseph_Net_Interface_exist = 0;  

    struct ifreq Joseph_Net_Ifr;  

    struct ifconf Joseph_Ifc;  

    struct sockaddr_in *sin = (struct sockaddr_in*)&Joseph_Net_Ifr.ifr_addr;  

    struct sockaddr_in *broadcast = (struct sockaddr_in*)&Joseph_Net_Ifr.ifr_broadaddr;  

    if(Joseph_Net_Interface_Info_In == NULL)  

    Joseph_Net_Interface_Sfd = socket(AF_INET,SOCK_DGRAM,0);  

    if(Joseph_Net_Interface_Sfd < 0){  

        perror("socket error");  

        return -1;  

    memset(&Joseph_Net_Ifr,0,sizeof(Joseph_Net_Ifr));  

    Joseph_Ifc.ifc_len = sizeof(Joseph_Net_Ifr);  

    Joseph_Ifc.ifc_buf = (caddr_t)&Joseph_Net_Ifr;  

    for(device_itertion = 1;device_itertion < 5;device_itertion++)  

        Joseph_Net_Ifr.ifr_ifindex = device_itertion;  

        Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFNAME,&Joseph_Net_Ifr);  

        if(Qy_Ret)  

        {  

            Joseph_Net_Interface_exist = 0;  

        }  

        else  

            if(strcmp(Joseph_Net_Ifr.ifr_name,Joseph_Net_Interface_Info_In->net_device_name) == 0)  

            {  

                printf("The %dst net device is : %s\n",Joseph_Net_Ifr.ifr_ifindex,Joseph_Net_Ifr.ifr_name);  

                Joseph_Net_Interface_exist = 1;  

                /*Judge card type of net device*/  

                Qy_Ret = ioctl (Joseph_Net_Interface_Sfd, SIOCGIFFLAGS,&Joseph_Net_Ifr);  

                if(!Qy_Ret)  

                {  

                    /*judge the status of net device*/  

                    if (Joseph_Net_Ifr.ifr_flags & IFF_UP)  

                    {  

                        puts("the interface status is UP");  

                    }  

                    else  

                        puts("the interface status is DOWN");  

                }  

                break;  

            }  

    if(Joseph_Net_Interface_exist == 0)  

        printf("%s:[%d] No Such Device of %s !\n",__FUNCTION__,__LINE__,Joseph_Net_Interface_Info_In->net_device_name);  

    /*get net device mac addr*/  

    Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFHWADDR,&Joseph_Net_Ifr);  

    if(!Qy_Ret)  

        sprintf(Joseph_Net_Interface_Info_In->net_device_mac_info,"%02x:%02x:%02x:%02x:%02x:%02x",\  

            (unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[0],\  

            (unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[1],\  

            (unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[2],\  

            (unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[3],\  

            (unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[4],\  

            (unsigned char)Joseph_Net_Ifr.ifr_hwaddr.sa_data[5]);  

        printf("Mac address is : %02x:%02x:%02x:%02x:%02x:%02x\n",\  

        printf("Mac address is : 00:00:00:00:00:00\n");  

    /*get net device ip */  

    memset(Joseph_Net_Interface_Info_In->net_device_ip,0,16);  

    Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFADDR,&Joseph_Net_Ifr);  

        inet_ntop(AF_INET,&sin->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_ip,16);  

        printf("IP address is : %s\n",Joseph_Net_Interface_Info_In->net_device_ip);  

    }else  

        printf("IP address is : 0.0.0.0\n");  

    /*get broadcast addr*/  

    memset(Joseph_Net_Interface_Info_In->net_device_broadcast_info,0,16);  

    Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFBRDADDR,&Joseph_Net_Ifr);  

        inet_ntop(AF_INET,&broadcast->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_broadcast_info,16);  

        printf("BROADCAST IP is : %s\n",Joseph_Net_Interface_Info_In->net_device_broadcast_info);  

        printf("BROADCAST IP is : 0.0.0.0\n");  

    /*get mask info*/  

    Qy_Ret = ioctl(Joseph_Net_Interface_Sfd,SIOCGIFNETMASK,&Joseph_Net_Ifr);  

    if (!Qy_Ret)      

        inet_ntop(AF_INET,&sin->sin_addr.s_addr,Joseph_Net_Interface_Info_In->net_device_mask_info,16);  

        printf("NetMask is : %s\n",Joseph_Net_Interface_Info_In->net_device_mask_info);   

/****************************************************************   

   return value:    

   -1 -- error , details can check errno    

   1  -- interface link up    

   0  -- interface link down.    

****************************************************************/  

int Joseph_Get_Netlink_Status(const char *if_name)    

    int skfd;    

    struct ifreq ifr;    

    JOSEPH_ETHTOOL_VALUE edata;    

    edata.cmd = ETHTOOL_GLINK;    

    edata.data = 0;    

    memset(&ifr, 0, sizeof(ifr));    

    strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1);    

    ifr.ifr_data = (char *)&edata;    

    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) == 0)    

        return -1;    

    if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1)    

       close(skfd);         

       return -1;    

    close(skfd);    

    return edata.data;    

int main(int argc,char *argv[])  

    JOSEPH_NET_INTERFACE_INFO Joseph_Net_Interface_Info;  

    memset(&Joseph_Net_Interface_Info,0,sizeof(JOSEPH_NET_INTERFACE_INFO));  

    if(argc < 2)  

    system("ifconfig eth0 up");  

    sleep(3);  

    strcpy(Joseph_Net_Interface_Info.net_device_name,argv[1]);  

    Qy_Ret = Joseph_Get_Netlink_Status(argv[1]);  

    if(Qy_Ret == 1)  

        printf("%s:[%d] The netlink is up !\n",__FUNCTION__,__LINE__);  

        printf("%s:[%d] The netlink is down , Begin go to wifi !\n",__FUNCTION__,__LINE__);  

NET_INIT:  

    /*after 5s , if no ip ,then killall udhcpc ,then go to wifi*/  

    system("killall -9 udhcpc");  

    system("udhcpc -i eth0");  

    Qy_Ret = Joseph_Check_Net_Status(argv[1]);  

    if(Qy_Ret == 0)  

        Joseph_Get_Net_Device_Info(&Joseph_Net_Interface_Info);       

NET_RUN:  

    while(1)  

        Qy_Ret = Joseph_Get_Netlink_Status(argv[1]);  

        if(Qy_Ret == 1)  

            printf("Net link status: %s\n", Qy_Ret == 1 ? "up" : "down");  

            Qy_Ret = Joseph_Check_Net_Status(argv[1]);  

            if(Qy_Ret < 0)  

                break;//do nothing  

            printf("%s:[%d] The netlink is down !\n",__FUNCTION__,__LINE__);      

        sleep(1);  

    goto NET_INIT;  

</span>  

繼續閱讀