前言
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机制详解