diff options
author | Farshid Monhaseri <monhaseri.f@gmail.com> | 2020-11-10 14:20:08 +0330 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2020-11-10 15:04:30 +0000 |
commit | 980b0dbc25e1b423562b87bc402c09329c039212 (patch) | |
tree | bf579d7e5125e9926b1da9f3afdd58c861af3ea8 /src/platform-info-devices.c | |
parent | 172db50c33beeb53f8e75c115699179be880b960 (diff) |
Add 'scan' verb for runtime device scan
Changes:
- Add 'scan' verb so client can pass 'filter'(udev rules in JSON
format) and 'mask' (desired data fields mask) arguments.
'filter' & 'mask' can include 'properties' and 'attributes' sub-
fields so their key & values act as parameters for device scanning
and mask the scanned devices properties & attributes when service
report back. The 'filter' argument can contain an additional field
with 'tags' key and JSON array value hence the tags will match for
device scanning too.
Bug-AGL: SPEC-3512
Signed-off-by: Farshid Monhaseri <monhaseri.f@gmail.com>
Change-Id: I83e91ec4405a8144e1ee813633c4895214b5b9df
Diffstat (limited to 'src/platform-info-devices.c')
-rw-r--r-- | src/platform-info-devices.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/platform-info-devices.c b/src/platform-info-devices.c index 89796f1..785423b 100644 --- a/src/platform-info-devices.c +++ b/src/platform-info-devices.c @@ -34,6 +34,7 @@ static void pinfo_device_monitor_detect(pinfo_client_ctx_t* ctx, struct static json_object* pinfo_device_udevice_to_jdevice(struct udev_device* udevice, struct json_object* jmask); static void pinfo_device_jdev_destructor(json_object* jdevice, void* udevice); static int pinfo_device_filter_monitoring(pinfo_client_ctx_t* ctx); +static void pinfo_device_filter_scan(struct udev_enumerate* udev_enum, struct json_object* jfilter); static json_object* pinfo_device_udevice_to_jlist( struct udev_device* udevice, struct udev_list_entry*(*udevice_elist)(struct udev_device*), @@ -395,3 +396,105 @@ pinfo_device_monitor_loop(pinfo_client_ctx_t* ctx) { } return NULL; } + +static void +pinfo_device_filter_scan(struct udev_enumerate* udev_enum, json_object* jfilter) { + if(udev_enum && jfilter) { + if(json_object_is_type(jfilter,json_type_object)) { + json_object* jval = NULL; + + if(json_object_object_get_ex(jfilter,"tags",&jval)) { + if(json_object_is_type(jval,json_type_array)) { + int tag_idx = 0; + const int tags_count = json_object_array_length(jval); + + if(tags_count > 0) { + json_object* jtag = NULL; + + for(jtag = json_object_array_get_idx(jval,0); + jtag && tag_idx < tags_count; + jtag = json_object_array_get_idx(jtag,++tag_idx)) { + udev_enumerate_add_match_tag(udev_enum,json_object_get_string(jtag)); + } + } else { + //Empty json array for tags array + } + } else if(json_object_is_type(jval,json_type_string)) { + udev_enumerate_add_match_tag(udev_enum,json_object_get_string(jval)); + } else { + AFB_WARNING("Client passed invalid value for 'tags' field,\ + the value type should be a json array with json string items\ + or a json string, avoid the tags filtering"); + } + } + + if(json_object_object_get_ex(jfilter,"properties",&jval) && + json_object_is_type(jval,json_type_object)) { + if(json_object_object_length(jval) > 0) { + json_object_object_foreach(jval,key,value) { + udev_enumerate_add_match_property(udev_enum,key,json_object_get_string(value)); + } + } + } + + if(json_object_object_get_ex(jfilter,"attributes",&jval) && + json_object_is_type(jval,json_type_object)) { + if(json_object_object_length(jval) > 0) { + json_object_object_foreach(jval,key,value) { + udev_enumerate_add_match_sysattr(udev_enum,key,json_object_get_string(value)); + } + } + } + } + } +} + +json_object* +pinfo_device_scan(json_object *jfilter, json_object* jmask) { + json_object* jdevs_arr = NULL; + struct udev* udev_ctx = NULL; + + udev_ctx = udev_new(); + jdevs_arr = json_object_new_array(); + + if(udev_ctx) { + struct udev_enumerate *dev_enum = NULL; + + dev_enum = udev_enumerate_new(udev_ctx); + if(dev_enum) { + struct udev_list_entry *dev_elist = NULL; + struct udev_list_entry *dev_elist_head = NULL; + pinfo_device_filter_scan(dev_enum,jfilter); + + udev_enumerate_scan_devices(dev_enum); + dev_elist = udev_enumerate_get_list_entry(dev_enum); + if(dev_elist) { + struct udev_device *udevice = NULL; + struct json_object *jdevice = NULL; + int udev_num = 0; + int jdev_num = 0; + + udev_list_entry_foreach(dev_elist_head,dev_elist) { + const char* path = udev_list_entry_get_name(dev_elist_head); + udev_num++; + udevice = udev_device_new_from_syspath((struct udev*)udev_ctx,path); + jdevice = pinfo_device_udevice_to_jdevice(udevice,jmask); + if(jdevice) { + json_object_array_add(jdevs_arr,jdevice); + jdev_num++; + } else { + udev_device_unref(udevice); + } + } + AFB_INFO("[SCAN]: %d device detected, %d device info reported back.",udev_num,jdev_num); + } else { + AFB_WARNING("No device found or enumeration failed"); + } + } else { + AFB_DEBUG("Unable to allocate enumeration object."); + } + udev_enumerate_unref(dev_enum); + } + + return jdevs_arr; +} |