Linux C程序如何检测WIFI无线USB网卡是否可用?

简介: 最新做一个WIFI应用项目。如何检测WIFI USB设备是否插上了呢?特此共享。       第一种方法,采用读取文件的方式。在linux下,任何一种设备都可看成文件。通过分析相关文件信息,可得知WIFI设备是否存在;代码示例如下:     static void WIFI_Enum_Devi...

最新做一个WIFI应用项目。如何检测WIFI USB设备是否插上了呢?特此共享。

      第一种方法,采用读取文件的方式。在linux下,任何一种设备都可看成文件。通过分析相关文件信息,可得知WIFI设备是否存在;代码示例如下:

   

static void WIFI_Enum_Device(void)
{
    char  buff[1024];
    FILE * fh;

 

    /* Check if /proc/net/wireless is available */
    fh = fopen(PROC_NET_WIRELESS, "r");


    if(fh != NULL)
    {
        /* Success : use data from /proc/net/wireless */

        /* Eat 2 lines of header */
        fgets(buff, sizeof(buff), fh);
        fgets(buff, sizeof(buff), fh);

        /* Read each device line */
        while(fgets(buff, sizeof(buff), fh))
        {
            char name[IFNAMSIZ + 1];
            char *s;

            /* Skip empty or almost empty lines. It seems that in some
            * cases fgets return a line with only a newline. */
            if((buff[0] == '\0') || (buff[1] == '\0'))
                continue;

            /* Extract interface name */
            s = WIFI_Get_DeviceName(name, sizeof(name), buff);

            if(!s)
            {
            /* Failed to parse, complain and continue */
#ifndef IW_RESTRIC_ENUM
                fprintf(stderr, "Cannot parse " PROC_NET_DEV "\n");
#else
                fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");
#endif
            }
            else
                /* Got it, save the name about this interface */

            {//we always use the first detected device when doing first time detecting
                if(s_DeviceCount == 0)
                {
                    if(strcmp(s_Deviceinfo.DeviceName,name))
                    {
                        memset((char *)&s_Deviceinfo, 0, sizeof(DeviceInfo_t));

                        memcpy(s_Deviceinfo.DeviceName,name,IFNAMSIZ);
                    }
                    if(strlen(s_SavedDevice) == 0)//this is the first detected device when doing first time detecting, we save it
                        memcpy(s_SavedDevice,name,IFNAMSIZ);
                }
                else
                {//there is more than one device, we should use the first detected
                    if(!strcmp(s_SavedDevice,name))
                    {
                        memset((char *)&s_Deviceinfo, 0, sizeof(DeviceInfo_t));

                        memcpy(s_Deviceinfo.DeviceName,name,IFNAMSIZ);
                    }
                }
                s_DeviceCount++;
            }
        }

        fclose(fh);
    }
   
}

 

static char* WIFI_Get_DeviceName(char * name, /* Where to store the name */
       int nsize, /* Size of name buffer */
       char * buf) /* Current position in buffer */
{
    char * end;

    /* Skip leading spaces */
    while(isspace(*buf))
        buf++;

#ifndef IW_RESTRIC_ENUM
    /* Get name up to the last ':'. Aliases may contain ':' in them,
    * but the last one should be the separator */
    end = strrchr(buf, ':');
#else
    /* Get name up to ": "
    * Note : we compare to ": " to make sure to process aliased interfaces
    * properly. Doesn't work on /proc/net/dev, because it doesn't guarantee
    * a ' ' after the ':'*/
    end = strstr(buf, ": ");
#endif

    /* Not found ??? To big ??? */
    if((end == NULL) || (((end - buf) + 1) > nsize))
        return(NULL);

    /* Copy */
    memcpy(name, buf, (end - buf));
    name[end - buf] = '\0';

    /* Return value currently unused, just make sure it's non-NULL */
    return(end);
}

 

RETURN_TYPE APP_WIFI_DetectDevice(void)
{
    char command[50] = {'\0'};
    s_DeviceCount = 0;  //reset count
    WIFI_Enum_Device();
    s_LastDeviceCount = s_DeviceCount;
    if(s_DeviceCount > 0)
    {
        sprintf(command,"ifconfig %s up",s_Deviceinfo.DeviceName);
        system(command);  //boot up the device firstly
        return SYS_NOERROR;
    }
    else
        return SYS_FAILED;        
}

      第二种方法,利用linux ioctl函数读取I/O接口的相关信息。

 

/*****************************************************************************
*  Name        : trid_char * APP_NetLink_GetIFFLAGS(char *NetDev )
*  Description : Get net interface IFFLAGS
*  Params      : NetDev
*  Returns     : the string of the NetDev
*  Author/date : Danny.Hu /2011.11.16
*****************************************************************************/
RETURN_TYPE APP_NetLink_GetIFFlags( trid_char *NetDev )
{
    int fd = -1;
    int InterfaceFlags;
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, NetDev);
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) 
    {
        printf("Cannot get control socket\n");
        close(fd);
        return SYS_FAILED;
    }
    else if( 0!=(ioctl(fd, SIOCGIFFLAGS, (char*)&ifr)) )
    {
       printf("Cannot get Network Interface Flags!\n");
       close(fd);
       return SYS_FAILED;
    }
    
    InterfaceFlags = ifr.ifr_flags; 
    
    printf("<");
    if ( InterfaceFlags & IFF_UP)                        printf("Network %s is UP, ", NetDev);
    if ( InterfaceFlags & IFF_BROADCAST)     printf("Network %s is BCAST, ", NetDev);
    if ( InterfaceFlags & IFF_MULTICAST)      printf("Network %s is MCAST, ", NetDev);
    if ( InterfaceFlags & IFF_LOOPBACK)       printf("Network %s is LOOP, ", NetDev);
    if ( InterfaceFlags & IFF_POINTOPOINT)   printf("Network %s is P2P, ", NetDev);
    printf(">\n");
    close(fd);
    return  SYS_NOERROR;
}

目录
相关文章
|
1月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
|
2月前
|
网络协议 Linux
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
145 2
|
2月前
|
Linux Python
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
47 2
|
9天前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
18 5
|
1月前
|
Linux 编译器 C语言
Linux内核对GCC版本的检测
Linux内核对GCC版本的检测
|
2月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
|
2月前
|
Linux Windows Python
最新 Windows\Linux 后台运行程序注解
本文介绍了在Windows和Linux系统后台运行程序的方法,包括Linux系统中使用nohup命令和ps命令查看进程,以及Windows系统中通过编写bat文件和使用PowerShell启动隐藏窗口的程序,确保即使退出命令行界面程序也继续在后台运行。
|
2月前
|
存储 安全 Linux
【Azure 应用服务】App Service For Linux 怎么安装Composer,怎么安装PHP扩展,怎么来修改站点根路径启动程序?
【Azure 应用服务】App Service For Linux 怎么安装Composer,怎么安装PHP扩展,怎么来修改站点根路径启动程序?
|
2月前
|
监控 Shell Linux
在Linux中,如何使用shell脚本检测磁盘使用率?
在Linux中,如何使用shell脚本检测磁盘使用率?
|
2月前
|
网络协议 Ubuntu Linux
在Linux中,如何将本地80端口的请求转发到8080端口,当前主机IP为192.168.16.1,其中本地网卡eth0。
在Linux中,如何将本地80端口的请求转发到8080端口,当前主机IP为192.168.16.1,其中本地网卡eth0。
下一篇
无影云桌面