WiFi scanresult to wait for scan_finished or 30sec timeout

This commit is contained in:
suvendhu 2022-01-21 16:43:41 +05:30 committed by Amin Ben Ramdhane
parent a6c13758fe
commit 74b65edade
5 changed files with 168 additions and 1 deletions

View file

@ -5353,9 +5353,22 @@ static int operate_WiFi_NeighboringWiFiDiagnostic(char *refparam, struct dmctx *
char *signal_strength[2] = {0};
char *radio_name = dmjson_get_value(radios, 1, "name");
if (!DM_STRLEN(radio_name))
continue;
snprintf(object, sizeof(object), "wifi.radio.%s", radio_name);
struct blob_buf bb;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
blobmsg_add_string(&bb, "radio", radio_name);
blobmsg_add_string(&bb, "action", "scan_finished");
dmubus_call_set(object, "scan", UBUS_ARGS{0}, 0);
sleep(2); // Wait for results to get populated in scanresults
dmubus_register_event_blocking("wifi.radio", 30, bb.head);
blob_buf_free(&bb);
dmubus_call(object, "scanresults", UBUS_ARGS{0}, 0, &scan_res);
if (!scan_res)

View file

@ -1746,3 +1746,83 @@ char *get_ipv6(char *interface_name)
return (*ipstr) ? dmstrdup(ipstr) : "";
}
static bool validate_blob_dataval(struct blob_attr *src_attr, struct blob_attr *dst_attr)
{
if (!src_attr || !dst_attr)
return false;
int src_type = blob_id(src_attr);
int dst_type = blob_id(dst_attr);
if (src_type != dst_type)
return false;
void *src_val = blobmsg_data(src_attr);
void *dst_val = blobmsg_data(dst_attr);
switch (src_type) {
case BLOBMSG_TYPE_STRING:
if (src_val == NULL && dst_val == NULL)
return true;
if (src_val && dst_val && strcmp((char *)src_val, (char*)dst_val) == 0)
return true;
break;
default:
break;
}
return false;
}
/*********************************************************************//**
**
** validate_blob_message
**
** This API is to validate the 'src' blob message against 'dst' blob message. It
** validates the attributes(key:value pair) present in 'src' are also exist in 'dst'.
** 'dst' may have more attributes than 'src'.
**
** NOTE: currently we only support string type value in key:val i.e if the attribute
** in 'src' blob message is other than of type string (like array, table etc) this
** API will return false.
**
** \param src - blob message to validate
** \param dst - blob message against which the validation is performed
**
** \return true: if all key:value pairs in 'src' are present in 'dst'
** false: otherwise
**
**************************************************************************/
bool validate_blob_message(struct blob_attr *src, struct blob_attr *dst)
{
if (!src || !dst)
return false;
size_t src_len = (size_t)blobmsg_data_len(src);
size_t dst_len = (size_t)blobmsg_data_len(dst);
if (dst_len < src_len)
return false;
bool res = true;
struct blob_attr *src_attr, *dst_attr;
__blob_for_each_attr(src_attr, blobmsg_data(src), src_len) {
bool matched = false;
__blob_for_each_attr(dst_attr, blobmsg_data(dst), dst_len) {
if (strcmp(blobmsg_name(src_attr), blobmsg_name(dst_attr)) != 0) {
continue;
}
matched = validate_blob_dataval(src_attr, dst_attr);
break;
}
if (matched == false) {
res = false;
break;
}
}
return res;
}

View file

@ -289,4 +289,5 @@ int check_browse_section(struct uci_section *s, void *data);
int parse_proc_intf6_line(const char *line, const char *device, char *ipstr, size_t str_len);
char *ioctl_get_ipv4(char *interface_name);
char *get_ipv6(char *interface_name);
bool validate_blob_message(struct blob_attr *src, struct blob_attr *dst);
#endif

View file

@ -206,6 +206,78 @@ int dmubus_call_set(char *obj, char *method, struct ubus_arg u_args[], int u_arg
return rc;
}
struct dmubus_event_data {
struct uloop_timeout tm;
struct ubus_event_handler ev;
struct blob_attr *ev_msg;
};
static void dmubus_receive_event(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg)
{
struct dmubus_event_data *data = container_of(ev, struct dmubus_event_data, ev);
if (!msg)
return;
if (validate_blob_message(data->ev_msg, msg) == true) {
uloop_end();
}
return;
}
static void dmubus_listen_timeout(struct uloop_timeout *timeout)
{
uloop_end();
}
/*********************************************************************//**
**
** dmubus_register_event_blocking
**
** This API is to wait for the specified event to arrive on ubus or the timeout
** whichever is earlier
**
** NOTE: since this is a blocking call so it should only be called from DM_ASYNC
** operations.
**
** \param event - event to be listened on ubus
** \param timeout - max time (seconds) to wait for the event
** \param type - event type for which the process need to wait
**
** E.G: event: wifi.radio, type: {"radio":"wl1","action":"scan_finished"}
**
**************************************************************************/
void dmubus_register_event_blocking(char *event, int timeout, struct blob_attr *type)
{
struct ubus_context *ctx = ubus_connect(NULL);
if (!ctx)
return;
struct dmubus_event_data data = {
.tm.cb = dmubus_listen_timeout,
.ev.cb = dmubus_receive_event,
.ev_msg = type,
};
uloop_init();
ubus_add_uloop(ctx);
int ret = ubus_register_event_handler(ctx, &data.ev, event);
if (ret)
goto end;
uloop_timeout_set(&data.tm, timeout * 1000);
uloop_run();
uloop_done();
ubus_unregister_event_handler(ctx, &data.ev);
end:
ubus_free(ctx);
return;
}
static inline json_object *ubus_call_req(char *obj, char *method, struct blob_attr *attr)
{
__dm_ubus_call(obj, method, attr);

View file

@ -28,5 +28,6 @@ void dmubus_configure(struct ubus_context *ctx);
void dmubus_update_cached_entries();
void dmubus_clean_endlife_entries();
void dmubus_set_caching_time(int seconds);
void dmubus_register_event_blocking(char *event, int timeout, struct blob_attr *type);
#endif