应用层接收 uevent 消息

        Uevent是一种在内核空间和用户空间之间通信的机制,主要用于热插拔事件(hotplug)。常用的电量通知、usb拔插通知、耳机拔插通知等都可以使用uevent。它的好处是使用简单方便,稳定性也很好。

下面贴出示例代码:

****************************************************************************************************************

#include
#include
#include
#include
#include
#include
#include

#define UEVENT_MSG_LEN 4096
struct luther_gliethttp {
    const char *action;
    const char *path;
    const char *subsystem;
    const char *firmware;
    int major;
    int minor;
};
static int open_luther_gliethttp_socket(void);
static void parse_event(const char *msg, struct luther_gliethttp *luther_gliethttp);

void *uevent_thread(void* data)
{
    int device_fd = -1;
    char msg[UEVENT_MSG_LEN+2];
    int n;
struct luther_gliethttp luther_gliethttp;
int brun  =1;

    device_fd = open_luther_gliethttp_socket();
    printf("--dxp-- uevent device_fd = %d\n", device_fd);

    while(brun){
   if((n = recv(device_fd, msg, UEVENT_MSG_LEN, 0)) > 0) {
      
printf("---- uevent len = %d\n", n);        
       msg[n] = '\0';
       msg[n+1] = '\0';
       parse_event(msg, &luther_gliethttp);
   }
    usleep(1000*10);
    }
    close(device_fd);
}


static int open_luther_gliethttp_socket(void)
{
    struct sockaddr_nl addr;
    int sz = 64*1024;
    int s;

    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_pid = getpid();
    addr.nl_groups = 0xffffffff;

    s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
    if (s < 0)
        return -1;

    setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));
    if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        close(s);
        return -1;
    }

    return s;
}


static void parse_event(const char *msg, struct luther_gliethttp *luther_gliethttp)
{
    luther_gliethttp->action = "";
    luther_gliethttp->path = "";
    luther_gliethttp->subsystem = "";
    luther_gliethttp->firmware = "";
    luther_gliethttp->major = -1;
    luther_gliethttp->minor = -1;

    printf("========================================================\n");
    while (*msg) {
        printf("%s\n", msg);
        if (!strncmp(msg, "ACTION=", 7)) {
            msg += 7;
            luther_gliethttp->action = msg;
        } else if (!strncmp(msg, "DEVPATH=", 8)) {
            msg += 8;
            luther_gliethttp->path = msg;
        } else if (!strncmp(msg, "SUBSYSTEM=", 10)) {
            msg += 10;
            luther_gliethttp->subsystem = msg;
        } else if (!strncmp(msg, "FIRMWARE=", 9)) {
            msg += 9;
            luther_gliethttp->firmware = msg;
        } else if (!strncmp(msg, "MAJOR=", 6)) {
            msg += 6;
            luther_gliethttp->major = atoi(msg);
        } else if (!strncmp(msg, "MINOR=", 6)) {
            msg += 6;
            luther_gliethttp->minor = atoi(msg);
        }

        while(*msg++);
    }

    printf("event { '%s', '%s', '%s', '%s', %d, %d }\n",
                    luther_gliethttp->action, luther_gliethttp->path, luther_gliethttp->subsystem,
                    luther_gliethttp->firmware, luther_gliethttp->major, luther_gliethttp->minor);
}

*****************************************************************************************

外部接口只有一个:void *uevent_thread(void* data),这是一个线程,具体uevent解析是在函数parse_event(),当然这里只有打印,可根据具体应用场景加上相应的解析逻辑代码。

你可能感兴趣的:(linux编程)