summaryrefslogtreecommitdiffstats
path: root/src/platform-info-devices.c
diff options
context:
space:
mode:
authorFarshid Monhaseri <monhaseri.f@gmail.com>2020-11-10 14:20:08 +0330
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2020-11-10 15:04:30 +0000
commit980b0dbc25e1b423562b87bc402c09329c039212 (patch)
treebf579d7e5125e9926b1da9f3afdd58c861af3ea8 /src/platform-info-devices.c
parent172db50c33beeb53f8e75c115699179be880b960 (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.c103
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;
+}