linux下应用程序检测usb口热插拔事件

1. 简介

usb口的检测在linux中可以通过mdev/udev热插拔机制来检测,相应的,我们只需要更改配置文件中规则即可,但是实际中,有的时候应用程序就是需要知道事件发生了,并做一些动作,该如何做呢?使用 netlink 的方式。

 

2. 程序

#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <errno.h>
#include <sys/socket.h>

/* Kernel Netlink */
int CUSBListener_initSock()
{
    const int buffersize = UEVENT_BUFFER_SIZE;
    int ret;
    int on = 1;

    struct sockaddr_nl snl;
    bzero(&snl, sizeof(struct sockaddr_nl));
    snl.nl_family = AF_NETLINK;
    snl.nl_pid = getpid();
    //snl.nl_groups = 1|RTNLGRP_LINK;
    //snl.nl_groups = 1;
    snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;

    int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
    if (s == -1)
    {
		return -1;
    }
    if (setsockopt(s, SOL_SOCKET, /*SO_RCVBUFFORCE*/ SO_RCVBUF, &buffersize, sizeof(buffersize)) < 0)
    {
		perror("setsockopet error\n");
		return -1;
    }
    if((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))<0)
    {
		perror("setsockopet error\n");
		return -1;
    }

    ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
    if (ret < 0)
    {
		return -2;
    }
    return s;
}

void CUSBListener_onUSB(const char *msg)
{
    if (!memcmp(msg, "add@", 4))
    {
		// 识别 U盘
		if (!memcmp(&msg[strlen(msg)-5], "/sd", 3)) {
			printf("Found U Disk\n");
			printf("%s\n",&msg[strlen(msg) - 5]);
		} else
		// 识别 GPIB
		if (!memcmp(&msg[strlen(msg)-9], "/usbgpib", 8)) {
			printf("USB_GPIB connected\n");
			system("mknod /dev/usbgpib0 c 180 176"); // 手动创建设备节点
		}
    } else
    if (!memcmp(msg,"remove@",7))
    {
		if (!memcmp(&msg[strlen(msg) - 5],"/sd",3)) {
			printf("remove U Disk\n");
			printf("%s\n",&msg[strlen(msg) - 5]);
		} else
		if (!memcmp(&msg[strlen(msg)-9], "/usbgpib", 8)) {
			printf("USB_GPIB disconnected\n");
			system("rm /dev/usbgpib0"); // 删除设备节点
		}
    }
}

/* listener for USB Event message*/
void CUSBListener_run()
{
    char buf[UEVENT_BUFFER_SIZE * 2] = {0};

    int sock = CUSBListener_initSock();

    while(sock > 0)
    {
		/* Netlink message buffer */
		int b = recv(sock, &buf, sizeof(buf),0);
		if(b > 0)
		{
			//printf("%s\n", buf);
			CUSBListener_onUSB(buf);
		}
    }
    perror("Create Netlink failed:" );
}

 

3. 接收到的内核的报文内容

当由设备插入时,这里是一个U盘和一个GPIB设备,内核发送的报文内容如下

插入

——————

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/scsi_host/host6

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/scsi_disk/6:0:0:0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/scsi_device/6:0:0:0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/scsi_generic/sg0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/bsg/6:0:0:0

add@/devices/virtual/bdi/8:0

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/block/sda

add@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/block/sda/sda1

Found U Disk

/sda1

add@/devices/virtual/bdi/8:1-fuseblk

add@/devices/virtual/bdi/0:28

add@/devices/virtual/bdi/0:29

add@/devices/virtual/bdi/0:30

——————

 

删除

——————

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/bsg/6:0:0:0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/scsi_generic/sg0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/scsi_device/6:0:0:0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/scsi_disk/6:0:0:0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/block/sda/sda1

remove U Disk

/sda1

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0/block/sda

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0/6:0:0:0

remove@/devices/virtual/bdi/8:0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/target6:0:0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6/scsi_host/host6

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host6

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4/1-1.4:1.0

remove@/devices/platform/fe3c0000.usb/usb1/1-1/1-1.4

remove@/devices/virtual/bdi/0:28

remove@/devices/virtual/bdi/0:29

remove@/devices/virtual/bdi/0:30

remove@/devices/virtual/bdi/8:1-fuseblk

——————

 

其中红色部分是我打印出来的

 

GPIB的实验

插入

——————

add@/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.11.auto/usb3/3-1

add@/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.11.auto/usb3/3-1/3-1:1.0

add@/class/usbmisc

add@/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.11.auto/usb3/3-1/3-1:1.0/usbmisc/usbgpib0

——————

删除

——————

add@/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.11.auto/usb3/3-1

add@/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.11.auto/usb3/3-1/3-1:1.0

add@/class/usbmisc

add@/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.11.auto/usb3/3-1/3-1:1.0/usbmisc/usbgpib0

——————

 

4. 参考

https://gist.github.com/userid/9edfae91647479de3e5790fbbdba36c2

https://blog.csdn.net/u010727765/article/details/79538101

 

 

 

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值