Advertisement
stream13

udev_notificator

Jun 24th, 2015
428
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.97 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stddef.h>
  6. #include <errno.h>
  7. #include <sys/time.h> //debug -> remove me
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <stdbool.h>
  12.  
  13. #include <libudev.h>
  14.  
  15. #define ADD_FILTER "add"
  16. #define REMOVE_FILTER "remove"
  17. #define SUBSYSTEM_FILTER "block"
  18. #define DEVTYPE_FILTER "disk"
  19. #define ATTR_FILTER "ID_MODEL"
  20. #define SD_ATTR_VALUE "SD_MMC"
  21. #define ATTR_ADDED_DISK "UDISKS_PARTITION_TABLE" // attribute is available for "change" event when SD card is added (n/a when removed)
  22.  
  23. static bool isDeviceSD(struct udev_device *device); //checks if device is SD card (MMC)
  24. static bool isDevPresent(struct udev *device); //checks if device is present (SD + added)
  25. static bool isDeviceAdded(struct udev_device *device); //checks if device is added (presence of attribute ATTR_ADDED_DISK)
  26. static void print_device(struct udev_device *device, const char *source); //for debugging -> remove me
  27. static bool s_bSD_present;
  28.  
  29. int main(){
  30.     struct udev *udev;
  31.     struct udev_monitor *udev_monitor = NULL;
  32.     fd_set readfds;
  33.  
  34.     struct udev_list_entry* t_list_entry = 0;
  35.     struct udev_list_entry* t_model_entry = 0;
  36.     struct udev_list_entry* t_added_disk_entry = 0;
  37.  
  38.     s_bSD_present = false;
  39.  
  40.     udev = udev_new();
  41.     if (udev == NULL){
  42.         printf("udev_new FAILED \n");
  43.         return 1;
  44.     }
  45.  
  46.     if( isDevPresent(udev) ){
  47.         s_bSD_present = true;
  48.         printf("+++SD is plugged in \n");
  49.     }else{
  50.         printf("---SD is not plugged in \n");
  51.     }
  52.  
  53.     udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
  54.     if (udev_monitor == NULL) {
  55.         printf("udev_monitor_new_from_netlink FAILED \n");
  56.         return 1;
  57.     }
  58.  
  59.     //add some filters
  60.     if( udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, SUBSYSTEM_FILTER, DEVTYPE_FILTER) < 0 ){
  61.         printf("udev_monitor_filter_add_match_subsystem_devtype FAILED \n");
  62.         return 1;
  63.     }
  64.  
  65.     if (udev_monitor_enable_receiving(udev_monitor) < 0){
  66.         printf("udev_monitor_enable_receiving FAILED \n");
  67.         return 1;
  68.     }
  69.  
  70.     while (1) {
  71.         printf("Polling for new data... \n");
  72.  
  73.         int fdcount = 0;
  74.  
  75.         FD_ZERO(&readfds);
  76.  
  77.         if (udev_monitor != NULL){
  78.             FD_SET(udev_monitor_get_fd(udev_monitor), &readfds);
  79.         }
  80.  
  81.         fdcount = select(udev_monitor_get_fd(udev_monitor)+1, &readfds, NULL, NULL, NULL);
  82.         if (fdcount < 0){
  83.             if (errno != EINTR)
  84.                 printf("Error receiving uevent message\n");
  85.             continue;
  86.         }
  87.  
  88.         if ((udev_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(udev_monitor), &readfds)){
  89.             struct udev_device *device;
  90.  
  91.             device = udev_monitor_receive_device(udev_monitor);
  92.             if (device == NULL)
  93.                 continue;
  94.  
  95.             // My modifications
  96.             t_list_entry = udev_device_get_properties_list_entry(device);
  97.             t_model_entry = udev_list_entry_get_by_name(t_list_entry, ATTR_FILTER);
  98.             t_added_disk_entry = udev_list_entry_get_by_name(t_list_entry,/* "DEVNAME" */ ATTR_ADDED_DISK);
  99.  
  100.             print_device(device, "UDEV");
  101. //          if( 0 != t_model_entry ){
  102. //              const char* szModelValue = udev_list_entry_get_value(t_model_entry);
  103. //              printf("[%s]%s\n",
  104. //                     (t_added_disk_entry != 0 ? "Inserted" : "Removed"),
  105. //                     (szModelValue == NULL ? "Unknown device" : szModelValue)
  106. //                     );
  107.  
  108. //          }
  109.  
  110.             //check presence
  111. //          if( isDeviceSD(device) && isDeviceAdded(device) ){
  112. //              if(!s_bSD_present){ //guard for double "change" events
  113. //                  s_bSD_present = true;
  114. //                  printf("+++SD has been plugged in \n");
  115. //              }
  116. //          }else{
  117. //              if(s_bSD_present){ //not needed -> just keeping consistency
  118. //                  s_bSD_present = false;
  119. //                  printf("---SD has been removed \n");
  120. //              }
  121. //          }
  122.  
  123.             udev_device_unref(device);
  124.         }
  125.     }
  126.  
  127.     return 0;
  128. }
  129.  
  130. static bool isDeviceSD(struct udev_device *device)
  131. {
  132.     bool retVal = false;
  133.     struct udev_list_entry *list_entry = 0;
  134.     struct udev_list_entry* model_entry = 0;
  135.  
  136.     list_entry = udev_device_get_properties_list_entry(device);
  137.     model_entry = udev_list_entry_get_by_name(list_entry, ATTR_FILTER);
  138.     if( 0 != model_entry ){
  139.         const char* szModelValue = udev_list_entry_get_value(model_entry);
  140.         if( strcmp( szModelValue, SD_ATTR_VALUE) == 0 ){
  141.             //printf("Device is SD \n");
  142.             retVal = true;
  143.             //print_device(device, "UDEV");
  144.         }
  145.     }
  146.     return retVal;
  147. }
  148.  
  149. static bool isDeviceAdded(struct udev_device *device){
  150.     bool retVal = false;
  151.     struct udev_list_entry *list_entry = 0;
  152.     struct udev_list_entry* added_disk_entry = 0;
  153.  
  154.  
  155.     list_entry = udev_device_get_properties_list_entry(device);
  156.     added_disk_entry = udev_list_entry_get_by_name(list_entry,/* "DEVNAME" */ ATTR_ADDED_DISK);
  157.     if( 0 != added_disk_entry ){
  158.         retVal = true;
  159.     }
  160.     return retVal;
  161. }
  162.  
  163.  
  164. static bool isDevPresent(struct udev *device){
  165.     bool retVal = false;
  166.     struct udev_enumerate *enumerate;
  167.     struct udev_list_entry *devices, *dev_list_entry;
  168.  
  169.     enumerate = udev_enumerate_new(device);
  170.     udev_enumerate_add_match_subsystem(enumerate, SUBSYSTEM_FILTER);
  171.     udev_enumerate_scan_devices(enumerate);
  172.     devices = udev_enumerate_get_list_entry(enumerate);
  173.  
  174.     udev_list_entry_foreach(dev_list_entry, devices){
  175.         struct udev_device *dev;
  176.         const char* dev_path = udev_list_entry_get_name(dev_list_entry);
  177.         dev = udev_device_new_from_syspath(device, dev_path);
  178.  
  179.         if( isDeviceSD(dev) && isDeviceAdded(dev) ){
  180.             retVal = true;
  181.             udev_device_unref(dev);
  182.             break;
  183.         }
  184.  
  185.         udev_device_unref(dev);
  186.     }
  187.     udev_enumerate_unref(enumerate);
  188.  
  189.     return retVal;
  190. }
  191.  
  192.  
  193. static void print_device(struct udev_device *device, const char *source){
  194.     struct timeval tv;
  195.     struct timezone tz;
  196.  
  197.     gettimeofday(&tv, &tz);
  198.     printf("%-6s[%llu.%06u] %-8s %s (%s)\n",
  199.     source,
  200.     (unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec,
  201.     udev_device_get_action(device),
  202.     udev_device_get_devpath(device),
  203.     udev_device_get_subsystem(device));
  204.  
  205.     struct udev_list_entry *list_entry;
  206.  
  207.     udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
  208.         printf("%s=%s\n",
  209.         udev_list_entry_get_name(list_entry),
  210.         udev_list_entry_get_value(list_entry));
  211.     printf("\n");
  212.  
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement