netlink加异步套接字select函数捕获USB插拔事件


前言

Linux中使用udev来管理热插拔,使用netlink监听udev的消息可以为用户空间提供管理策略,通过解析消息中的字符串来完成控制逻辑。

USB的热插拔应用广泛,比如U盘、手机、USB网卡等等,netlink捕获消息后,解析消息中的字符串可以进一步识别是哪种设备,从而在用户空间完成逻辑控制


一、整体框架

  socket   s;   
  .....   
  fd_set   set;   
  while(1)   
  {       
        FD_ZERO(&set);//将你的套接字集合清空   
        FD_SET(s,&set);//加入你感兴趣的套接字到集合,这里是一个读数据的套接字s   
        select(0,&set,NULL,NULL,NULL);//检查套接字是否可读, 很多情况下就是是否有数据(注意,只是说很多情况),这里select是否出错没有写   
        if(FD_ISSET(s,&set)   //检查s是否在这个集合里面【因为select将更新这个集合,把其中不可读的套接字去掉,只保留符合条件的套接字在这个集合里面   
        {11
                recv(s,...); 
        }   
        //do   something   here 
  }

二、示例代码

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <linux/netlink.h>

#define UEVENT_BUFFER_SIZE 2048

int main(void)
{
  char buf[UEVENT_BUFFER_SIZE] = { 0 };
  struct sockaddr_nl netlink;
  fd_set fds;
  int hotplug_sock, rcvlen, ret;
  int buffersize = 2048;
  struct timeval tv;
  
  hotplug_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
  memset(&netlink, 0, sizeof(netlink));
  netlink.nl_family = AF_NETLINK;
  netlink.nl_pid = getpid();
  netlink.nl_groups = 1; /* receive broadcast message*/

  setsockopt(hotplug_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
  bind(hotplug_sock, (struct sockaddr*)&netlink, sizeof(netlink));
  FD_ZERO(&fds);
  FD_SET(hotplug_sock , &fds);
  while (1) {
	  memset(buf, 0, sizeof(buf));
	  ret = select(hotplug_sock + 1, &fds, NULL, NULL, &tv);
      if(ret < 0)
          continue;
      if(!(ret > 0 && FD_ISSET(hotplug_sock , &fds)))
          continue;
     /* receive data */
      rcvlen = recv(hotplug_sock, &buf, sizeof(buf), 0);
      if (rcvlen > 0) {
        /*You can do something here to make the program more perfect!!!*/
        printf("%s\n", buf);
      		if(strstr(buf, "add@")){
      			//printf("%s\n", buf);
      		}else if(strstr(buf, "remove@")){
      			printf("%s\n", buf);
      			system("echo 0 > /sys/bus/i2c/drivers/e52241/0-0011/set_en");
      			sleep(1);
      			system("echo 1 > /sys/bus/i2c/drivers/e52241/0-0011/set_en");
      		}
      }
    }

    close(hotplug_sock);
    return 0;
}

三、相关知识

异步套接字基础:select函数:
异步套接字基础:select函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
【一文搞懂】FD_SET的使用

netlink相关知识:
Android:内核与用户层通信之netlink
Linux 下使用 NetLink 检测设备的热插拔
linux netlink机制详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值