kobject_uevent_env 内核通知android有状态变化的一种方法

以下文字来源网络

[kernel ]

#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/semaphore.h>
#include <linux/mutex.h>
#include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/i2c.h>
#include <linux/input.h>
 

struct device *dev = NULL;
char * s_c[2];
static ssize_t send(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
{
s_c[0] = "song_hello";
s_c[1] = NULL;
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, s_c);
return count;
}
static DEVICE_ATTR(S, S_IRUGO|S_IWUSR, NULL, send);

static const struct attribute *song_event_attr[] = {
        &dev_attr_S.attr,
        NULL,
};

static const struct attribute_group song_event_attr_group = {
        .attrs = (struct attribute **) song_event_attr,
};

static struct class song_event_class = {
        .name =         "song_event",
        .owner =        THIS_MODULE,
};

static int __init song_uevent_init(void)
{
int ret = 0;
ret = class_register(&song_event_class);
if (ret < 0) {
printk(KERN_ERR "song_event: class_register fail\n");
return ret;
}

dev = device_create(&song_event_class, NULL, MKDEV(0, 0), NULL, "song_event");
if (dev) {
ret = sysfs_create_group(&dev->kobj, &song_event_attr_group);
if(ret < 0) {
printk(KERN_ERR "song_event:sysfs_create_group fail\r\n");
return ret;
}
} else {
printk(KERN_ERR "song_event:device_create fail\r\n");
ret = -1;
return ret;
}
return 0;
}

【用户空间】

#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

#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)
{
    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);
        } else if (!strncmp(msg, "PANEL_ALIVE=", 12)) {
            printf("yangchaofeng PANEL_ALIVE==%d\n",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);
}

int main()
{

    int device_fd = -1;
    char msg[UEVENT_MSG_LEN+2];
    int n;
    
    device_fd = open_luther_gliethttp_socket();
    while(1){
    
        while((n = recv(device_fd, msg, UEVENT_MSG_LEN, 0)) > 0){
            struct luther_gliethttp luther_gliethttp;
            
                if(n == UEVENT_MSG_LEN)
                continue;

            msg[n] = '\0';
            msg[n+1] = '\0';
            
            printf("-----------   msg=%s\n",msg);
            
            parse_event(msg, &luther_gliethttp);
            
            printf("-----------   msg=%s\n",msg);
        }
    }
}

[test]

/sys/devices/virtual/yang_event_class/yang_event_device # echo 1 > S

========================================================
change@/devices/virtual/yang_event_class/yang_event_device
ACTION=change
DEVPATH=/devices/virtual/yang_event_class/yang_event_device
SUBSYSTEM=yang_event_class
yang_hello=1
SEQNUM=3377
event { 'change', '/devices/virtual/yang_event_class/yang_event_device', 'yang_event_class', '', -1, -1 }
-----------   msg=change@/devices/virtual/yang_event_class/yang_event_device
========================================================

猜你喜欢

转载自blog.csdn.net/yangchaofeng001/article/details/81477945