display announced services in ubus call umdns browse
authorMohd Husaam Mehdi <h.mehdi@gxgroup.eu>
Mon, 5 Feb 2024 14:56:24 +0000 (20:26 +0530)
committerJohn Crispin <john@phrozen.org>
Wed, 11 Dec 2024 14:06:53 +0000 (15:06 +0100)
This commit adds logic to display details of services announced by
umdns.

Signed-off-by: Mohd Husaam <husaam.mehdi@iopsys.eu>
(minor changes to the original PR)
Signed-off-by: John Crispin <john@phrozen.org>
service.c
service.h
ubus.c

index b693b3127b4cf54f08e49cb2df6d4d9550d5495b..21bdc7bee6771c181516836f2343fc2115e47a01 100644 (file)
--- a/service.c
+++ b/service.c
@@ -22,9 +22,7 @@
 #include <time.h>
 
 #include <libubus.h>
-#include <libubox/vlist.h>
 #include <libubox/uloop.h>
-#include <libubox/avl-cmp.h>
 #include <libubox/blobmsg_json.h>
 
 #include "ubus.h"
@@ -43,20 +41,6 @@ enum {
        __SERVICE_MAX,
 };
 
-struct service {
-       struct vlist_node node;
-
-       time_t t;
-
-       const char *id;
-       const char *instance;
-       const char *service;
-       const uint8_t *txt;
-       int txt_len;
-       int port;
-       int active;
-};
-
 static const struct blobmsg_policy service_policy[__SERVICE_MAX] = {
        [SERVICE_INSTANCE] = { .name = "instance", .type = BLOBMSG_TYPE_STRING },
        [SERVICE_SERVICE] = { .name = "service", .type = BLOBMSG_TYPE_STRING },
@@ -65,16 +49,12 @@ static const struct blobmsg_policy service_policy[__SERVICE_MAX] = {
        [SERVICE_HOSTNAME] = { .name = "hostname", .type = BLOBMSG_TYPE_STRING },
 };
 
-static void
-service_update(struct vlist_tree *tree, struct vlist_node *node_new,
-              struct vlist_node *node_old);
-
 static void
 hostname_update(struct vlist_tree *tree, struct vlist_node *node_new,
                struct vlist_node *node_old);
 
 static struct blob_buf b;
-static VLIST_TREE(services, avl_strcmp, service_update, false, false);
+VLIST_TREE(announced_services, avl_strcmp, service_update, false, false);
 VLIST_TREE(hostnames, avl_strcmp, hostname_update, false, false);
 static int service_init_announce;
 
@@ -168,7 +148,7 @@ service_reply(struct interface *iface, struct sockaddr *to, const char *instance
 {
        struct service *s;
 
-       vlist_for_each_element(&services, s, node) {
+       vlist_for_each_element(&announced_services, s, node) {
                if (instance && strcmp(s->instance, instance))
                        continue;
                if (service_domain && strcmp(s->service, service_domain))
@@ -182,7 +162,7 @@ service_announce_services(struct interface *iface, struct sockaddr *to, int ttl)
 {
        struct service *s;
 
-       vlist_for_each_element(&services, s, node) {
+       vlist_for_each_element(&announced_services, s, node) {
                s->t = 0;
                if (ttl) {
                        dns_init_answer();
@@ -193,7 +173,7 @@ service_announce_services(struct interface *iface, struct sockaddr *to, int ttl)
        }
 }
 
-static void
+void
 service_update(struct vlist_tree *tree, struct vlist_node *node_new,
               struct vlist_node *node_old)
 {
@@ -315,7 +295,7 @@ service_load_blob(struct blob_attr *b)
                        d_txt += len;
                }
 
-       vlist_add(&services, &s->node, s->id);
+       vlist_add(&announced_services, &s->node, s->id);
 }
 
 static void
@@ -348,7 +328,7 @@ service_init_cb(struct ubus_request *req, int type, struct blob_attr *msg)
 
        get_hostname();
 
-       vlist_update(&services);
+       vlist_update(&announced_services);
        vlist_update(&hostnames);
        service_load("/etc/umdns/*");
 
@@ -393,7 +373,7 @@ service_init_cb(struct ubus_request *req, int type, struct blob_attr *msg)
                        }
                }
        }
-       vlist_flush(&services);
+       vlist_flush(&announced_services);
        vlist_flush(&hostnames);
 }
 
@@ -409,6 +389,6 @@ service_init(int announce)
 void
 service_cleanup(void)
 {
-       vlist_flush(&services);
+       vlist_flush(&announced_services);
        blob_buf_free(&b);
 }
index 9dea1f62b9026e6f2197f2e6ee050c94cb729aea..ea2a6ed287f96be63f20cb0f1f1dcbbc7b506a3b 100644 (file)
--- a/service.h
+++ b/service.h
 #ifndef _SERVICE_H__
 #define _SERVICE_H__
 
+#include <libubox/vlist.h>
+#include <libubox/avl-cmp.h>
+
+struct service {
+       struct vlist_node node;
+
+       time_t t;
+
+       const char *id;
+       const char *instance;
+       const char *service;
+       const uint8_t *txt;
+       int txt_len;
+       int port;
+       int active;
+};
+
 struct hostname {
        struct vlist_node node;
 
        const char *hostname;
 };
 extern struct vlist_tree hostnames;
+extern struct vlist_tree announced_services;
 
 extern void service_init(int announce);
 extern void service_cleanup(void);
 extern void service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl);
 extern void service_announce_services(struct interface *iface, struct sockaddr *to, int ttl);
+extern void service_update(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old);
 
 #endif
diff --git a/ubus.c b/ubus.c
index 69912784784b80e3bb01bd233a8379a8554b8969..3dbaeaa7742eef14fb6f6172bbc3185de9c07fb8 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -15,6 +15,7 @@
 #include <arpa/inet.h>
 
 #include <stdio.h>
+#include <ctype.h>
 
 #include <libubus.h>
 #include <libubox/vlist.h>
@@ -48,6 +49,80 @@ umdns_update(struct ubus_context *ctx, struct ubus_object *obj,
        return 0;
 }
 
+static int
+umdns_announcements(struct ubus_context *ctx, struct ubus_object *obj,
+                       struct ubus_request_data *req, const char *method,
+                       struct blob_attr *msg)
+{
+       struct service *s;
+       void *c1 = NULL, *c2 = NULL;
+
+       blob_buf_init(&b, 0);
+       vlist_for_each_element(&announced_services, s, node) {
+               // is something there?
+               if (!s->id || !strlen(s->id))
+                       continue;
+
+               if (!s->service || !strlen(s->service))
+                       continue;
+
+               if (!s->port)
+                       continue;
+
+               if (!c1) {
+                       c1 = blobmsg_open_table(&b, (const char *) s->service);
+               }
+
+               c2 = blobmsg_open_table(&b, s->id);
+
+               blobmsg_add_u32(&b, "port", s->port);
+
+               // check if there are any text entries
+               if (s->txt_len) {
+                       void *c_txt = NULL;
+                       int i;
+
+                       // this string will hold text records
+                       char *txt_str = (char *) calloc(s->txt_len, sizeof(char));
+
+                       // we get some weird characters like \u000b, so get don't copy them
+                       for (i=0; i<s->txt_len; i++) {
+                               if ((ispunct(s->txt[i])) || (isalnum(s->txt[i])))
+                                       txt_str[i] = (char) s->txt[i];
+                               else
+                                       txt_str[i] = ' ';
+                       }
+
+                       txt_str[s->txt_len] = '\0';
+
+                       // a table of txt json objects
+                       c_txt = blobmsg_open_array(&b, "txt");
+
+                       // split based on space and add each token to output
+                       char *pch = NULL, *pchr = NULL;
+
+                       for (pch = strtok_r(txt_str, " ", &pchr); pch != NULL; pch = strtok_r(NULL, " ", &pchr)) {
+                               // add it to array
+                               blobmsg_add_string(&b, "txt", pch);
+                       }
+
+                       // close the array
+                       blobmsg_close_array(&b, c_txt);
+
+                       // free the calloced memory
+                       free(txt_str);
+               }
+
+               blobmsg_close_table(&b, c2);
+               blobmsg_close_table(&b, c1);
+               c1 = NULL;
+       }
+
+       ubus_send_reply(ctx, req, b.head);
+
+       return UBUS_STATUS_OK;
+}
+
 enum {
        BROWSE_SERVICE,
        BROWSE_ARRAY,
@@ -83,6 +158,7 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
                address = blobmsg_get_bool(data[BROWSE_ADDRESS]);
 
        blob_buf_init(&b, 0);
+
        avl_for_each_element(&services, s, avl) {
                const char *hostname = buffer;
                char *local;
@@ -116,6 +192,7 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
                        c1 = NULL;
                }
        }
+
        ubus_send_reply(ctx, req, b.head);
 
        return UBUS_STATUS_OK;
@@ -270,6 +347,7 @@ static const struct ubus_method umdns_methods[] = {
        UBUS_METHOD("query", umdns_query, query_policy),
        UBUS_METHOD("fetch", umdns_query, query_policy),
        UBUS_METHOD("browse", umdns_browse, browse_policy),
+       UBUS_METHOD_NOARG("announcements", umdns_announcements),
        UBUS_METHOD_NOARG("update", umdns_update),
        UBUS_METHOD("hosts", umdns_hosts, hosts_policy),
        UBUS_METHOD_NOARG("reload", umdns_reload),