Monday, 2 June 2014

Reading UEVENTS in Linux UserSpace {Android}

ueventd
    ⚬ ueventd creates and 'poll' netlink socket.
        ueventd_main [init/ueventd.c]

    ⚬ read kernel event message -> parse -> handle
        handle_device_event [init/devices.c]
            -> device_changed [init/init.c]
                -> queue_device_triggers [init/init_parser.c]
                            |
            +---------------+
            |
            v
        : search action list to know what to do for this event.
          searching action which name is device-added/removed-[device node].
          [device node] is from 'DEVPATH' variable of uevent message.

    ⚬ action list : list declared at [init_parser.c]
        • builtin action (added by 'queue_builtin_action [init/init_parser.c]')
            ex. property_init, wait_for_coldboot_done etc.
        • from script (added by 'parse_action [init/init_parser.c]')
            section "on device-added-[device path] / on device-removed-[device path]"
            ex.
                [init.rc]
                on device-added-/dev/block/mmcblk0p18
                    exec /system/bin/sh /system/bin/hello_mmc.shother daemons (ex usbd)
    ⚬ create and 'poll' netlink socket.
 
 The following code below in the device driver sends a UEVENT to the 
 udev to create nodes.
 
/* seend uevents to udev, so it'll create the /dev node*/
  class_device_create(memory_class, NULL, dev_num, NULL, "memory%d", 1);
 
Sample Code for capturing the UEVENTS
 
#include <stdio.h>

  #include <stdlib.h>
  #include <string.h>
  #include <sys/poll.h>
  #include <sys/socket.h>
  #include <sys/types.h>
  #include <unistd.h>
  #include <linux/types.h>
  #include <linux/netlink.h>

  void die(char *s)
  {
 write(2,s,strlen(s));
 exit(1);
  }

  int main(int argc, char *argv[])
  {
 struct sockaddr_nl nls;
 struct pollfd pfd;
 char buf[512];

 // Open hotplug event netlink socket
 memset(&nls,0,sizeof(struct sockaddr_nl));
 nls.nl_family = AF_NETLINK;
 nls.nl_pid = getpid();
 nls.nl_groups = -1;
 pfd.events = POLLIN;
 pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
 if (pfd.fd==-1)
  die("Not root\n");

 // Listen to netlink socket
 if (bind(pfd.fd, (void *)&nls, sizeof(struct sockaddr_nl)))
  die("Bind failed\n");

 while (-1!=poll(&pfd, 1, -1)) {
  int i, len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
  if (len == -1) die("recv\n");
  // Print the data to stdout.
  i = 0;
  while (i<len) {
   printf("%s\n", buf+i);
   i += strlen(buf+i)+1;
  }
 }
 die("poll\n");
 // Dear gcc: shut up.
 return 0;
  } 
 
 


Print from the above code:
 
add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
SUBSYSTEM=usb
MAJOR=189
MINOR=1
DEVNAME=bus/usb/001/002
DEVTYPE=usb_device
PRODUCT=4e8/6860/216
TYPE=0/0/0
BUSNUM=001
DEVNUM=002
SEQNUM=2112
libudev
����(


(


X 

w��'��




 
 UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/001/002
DEVTYPE=usb_device
PRODUCT=4e8/6860/216
TYPE=0/0/0
BUSNUM=001
DEVNUM=002
SEQNUM=2112
MAJOR=189
MINOR=1
ID_MTP_DEVICE=1
ID_MEDIA_PLAYER=samsung_galaxy-s2
DEVLINKS=/dev/libmtp-1-1
ID_VENDOR=unknown
ID_VENDOR_ENC=unknown
ID_VENDOR_ID=04e8
ID_MODEL=AOSP_on_Maguro
ID_MODEL_ENC=AOSP\x20on\x20Maguro
ID_MODEL_ID=6860
ID_REVISION=0216
ID_SERIAL=unknow�A{��
add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/255/0
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFiscFFip00
SEQNUM=2113
add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/66/1
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFisc42ip01
SEQNUM=2114
libudev
����(


(





w��� Ge







UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/66/1
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFisc42ip01
SEQNUM=2114
libudev
����(


(





w��� Ge







UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
SUBSYSTEM=usb
DEVTYPE=usb_interface
PRODUCT=4e8/6860/216
TYPE=0/0/0
INTERFACE=255/255/0
MODALIAS=usb:v04E8p6860d0216dc00dsc00dp00icFFiscFFip00
SEQNUM=2113 
 
Device Model and Vendor ID and Product ID

ID_MTP_DEVICE=1
ID_MEDIA_PLAYER=samsung_galaxy-s2
DEVLINKS=/dev/libmtp-1-1
ID_VENDOR=unknown
ID_VENDOR_ENC=unknown
ID_VENDOR_ID=04e8
ID_MODEL=AOSP_on_Maguro
ID_MODEL_ENC=AOSP\x20on\x20Maguro
ID_MODEL_ID=6860
ID_REVISION=0216

  

1 comment:

  1. thanks, this sample code save my life.

    BTW, the messes such as

    'libudev ����('

    was generated by udev.

    sudo service udev stop
    udev stop/waiting

    world is more clear.

    ReplyDelete