#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#define MAX_RECV_SIZE 1024
static int Init_USB_Monitor( void )
{
// 本函数返回值
int iResult = 0;
// 接收内核发来的消息缓冲区大小
const unsigned int uiRecvBuffSize = MAX_RECV_SIZE;
// 套接字地址
struct sockaddr_nl snl;
// 套接字文件描述符
int sfd = -1;
// 1.添写套接字地址
snl.nl_family = AF_NETLINK;
snl.nl_pad = 0;
// 如果希望内核处理消息或多播消息,就把该字段设置为 0,
// 否则设置为处理消息的进程ID。
snl.nl_pid = getpid();
snl.nl_groups = 1;
// 2.创建套接字
// NETLINK_KOBJECT_UEVENT - 内核消息到用户空间,出现在 Linux 2.6.10
sfd = socket( PF_NETLINK, // 使用 netlink
SOCK_DGRAM, // 使用不连续不可信赖的数据包连接
NETLINK_KOBJECT_UEVENT );
// 如果 创建套接字失败 的话,则
if ( -1 == sfd )
{
return -1;
}
// 3.设置套接字接收缓冲区大小
setsockopt( sfd,
SOL_SOCKET, // 存取 socket 层
SO_RCVBUF, // 设置接收缓冲区大小
&uiRecvBuffSize,
sizeof( uiRecvBuffSize ) );
// 4.将套接字加入指定的多播组
iResult = bind( sfd,
(struct sockaddr*)&snl,
sizeof( snl ) );
// 如果 将套接字加入指定的多播组失败 的话,则
if ( -1 == iResult )
{
return -2;
}
return sfd;
}
int USB_Monitoring(int fd)
{
// 接收内核发来的消息字符串
char caKernelMsgBuff[MAX_RECV_SIZE];
if(fd <= 0)
{
return -1;
}
// 接收内核消息
recv(fd, &caKernelMsgBuff, sizeof( caKernelMsgBuff ), 0);
printf( "Kernel Message:\n%s\n", caKernelMsgBuff );
#if 0
// USB 设备的插入时,会出现以 add@/devices/ 开头,含 usb 的字符串
if( 0 == memcmp( caKernelMsgBuff,
"add@",
4 )
&&
NULL != strstr( caKernelMsgBuff,
"usb" ) )
{
printf( "Add USB Device\n" );
//break;
}
// USB 设备的拔除时,会出现以 remove@/devices/ 开头,含 usb 的字符串
if( 0 == memcmp( caKernelMsgBuff,
"remove@",
7 )
&&
NULL != strstr( caKernelMsgBuff,
"usb" ) )
{
printf( "Remove USB Device\n" );
//break;
}
#endif
return 0;
}
int main(int argc, char* argv[])
{
int fd = Init_USB_Monitor();
while(1)
{
USB_Monitoring(fd);
}
if (fd > 0)
{
close(fd);
fd = -1;
}
return 0;
}
Linux USB设备热插拔检测
最新推荐文章于 2024-09-02 21:32:13 发布