aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--src/platform-info-apidef.h8
-rw-r--r--src/platform-info-binding.c22
-rw-r--r--src/platform-info-devices.c103
-rw-r--r--src/platform-info-devices.h3
4 files changed, 133 insertions, 3 deletions
diff --git a/src/platform-info-apidef.h b/src/platform-info-apidef.h
index c09da63..4dba262 100644
--- a/src/platform-info-apidef.h
+++ b/src/platform-info-apidef.h
@@ -5,6 +5,7 @@ static const struct afb_auth _afb_auths_platform_info[] = {
void afv_get(afb_req_t req);
void afv_set(afb_req_t req);
+ void afv_scan(afb_req_t req);
void afv_subscribe(afb_req_t req);
void afv_unsubscribe(afb_req_t req);
@@ -24,6 +25,13 @@ static const struct afb_verb_v3 _afb_verbs_platform_info[] = {
.session = AFB_SESSION_NONE
},
{
+ .verb = "scan",
+ .callback = afv_scan,
+ .auth = NULL,
+ .info = "Scan system devices",
+ .session = AFB_SESSION_NONE
+ },
+ {
.verb = "unsubscribe",
.callback = afv_unsubscribe,
.auth = NULL,
diff --git a/src/platform-info-binding.c b/src/platform-info-binding.c
index 4ae3c70..8aecdfe 100644
--- a/src/platform-info-binding.c
+++ b/src/platform-info-binding.c
@@ -172,17 +172,35 @@ afv_static_info(const char* dir) {
return static_info;
}
+void afv_scan(afb_req_t req) {
+ json_object* jres = NULL;
+ json_object* jfilter = NULL;
+ json_object* jmask = NULL;
+ json_object* jargs = afb_req_json(req);
+
+ if(json_object_is_type(jargs,json_type_object)) {
+ json_object_object_get_ex(jargs,"filter",&jfilter);
+ json_object_object_get_ex(jargs,"mask",&jmask);
+ }
+
+ jres = pinfo_device_scan(jfilter,jmask);
+
+ if(jres) {
+ afb_req_success(req,jres,"Scan success");
+ } else {
+ afb_req_fail(req,"failed","Scan failed");
+ }
+}
+
int init(afb_api_t api) {
// Initializing the platform_info binding object and associated it to
// the api
- AFB_DEBUG("init() ...");
pinfo_api_ctx_t *api_ctx = NULL;
int ret = PINFO_OK;
api_ctx = malloc(sizeof(*api_ctx));
if(api_ctx) {
- AFB_DEBUG("init() ... OK");
api_ctx->info = afv_static_info(PLATFORM_INFO_DIR);
AFB_API_DEBUG(api,"The API static data: %s",
json_object_to_json_string_ext(api_ctx->info, JSON_C_TO_STRING_PRETTY));
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;
+}
diff --git a/src/platform-info-devices.h b/src/platform-info-devices.h
index ad658f9..59944d6 100644
--- a/src/platform-info-devices.h
+++ b/src/platform-info-devices.h
@@ -45,6 +45,7 @@ typedef struct {
}pinfo_client_ctx_t;
-int pinfo_device_monitor(afb_req_t req);
+int pinfo_device_monitor(afb_req_t req);
+struct json_object* pinfo_device_scan(json_object *jfilter, json_object* jmask);
#endif