diff --git a/ssdpd/Makefile b/ssdpd/Makefile index 37e315014..c207b7efd 100644 --- a/ssdpd/Makefile +++ b/ssdpd/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ssdpd -PKG_VERSION:=1.0.3 +PKG_VERSION:=1.0.4 LOCAL_DEV:=0 ifneq ($(LOCAL_DEV),1) @@ -45,8 +45,6 @@ endef endif define Package/ssdpd/install - $(INSTALL_DIR) $(1)/etc/upnp - $(INSTALL_DIR) $(1)/etc/upnp/description $(INSTALL_DIR) $(1)/etc/config $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_DIR) $(1)/usr/sbin diff --git a/ssdpd/files/etc/init.d/ssdpd b/ssdpd/files/etc/init.d/ssdpd index 10eb25f6b..8a9460125 100755 --- a/ssdpd/files/etc/init.d/ssdpd +++ b/ssdpd/files/etc/init.d/ssdpd @@ -34,6 +34,8 @@ configure_ssdp() [ ${enabled} -eq 0 ] && return 0 + mkdir -p /tmp/ssdp/description/ + procd_set_param command ${PROG} if [ ${ipv6_enabled} -eq 1 ]; then diff --git a/ssdpd/patches/012-ubus-runner-thread-hook b/ssdpd/patches/012-ubus-runner-thread-hook index badd26f6f..dc4893b79 100644 --- a/ssdpd/patches/012-ubus-runner-thread-hook +++ b/ssdpd/patches/012-ubus-runner-thread-hook @@ -72,7 +72,223 @@ } --- a/minissdpd/ssdpd.c +++ b/minissdpd/ssdpd.c -@@ -624,3 +624,8 @@ end: +@@ -39,10 +39,9 @@ struct desc_list_elt { + struct list_head list; + char *url; + char *desc_path; +- bool is_device_desc; + }; + +-#define UPNP_DESC_PATH "/etc/upnp/description" ++#define UPNP_DESC_PATH "/tmp/ssdp/description" + #define UPNP_DISCOVER_TIMEOUT (30 * 1000) + + #ifndef MIN +@@ -282,6 +281,21 @@ static bool is_desc_exist(const char *de + return false; + } + ++static bool is_device_exist(const char *dev_url) ++{ ++ struct UPNPDev *dev = NULL; ++ ++ if (!dev_url) ++ return false; ++ ++ list_for_each_entry(dev, &dev_list, list) { ++ if (strcmp(dev->descURL, dev_url) == 0) ++ return true; ++ } ++ ++ return false; ++} ++ + static void get_desc_name(const char *desc_url, char *str, size_t len) + { + if (!desc_url || !str || len == 0) +@@ -297,7 +311,7 @@ static void get_desc_name(const char *de + } + } + +-static void add_desc_to_desc_list(const char *desc_path, const char *url, int is_device_desc) ++static void add_desc_to_desc_list(const char *desc_path, const char *url) + { + struct desc_list_elt *desc_elt; + +@@ -306,7 +320,6 @@ static void add_desc_to_desc_list(const + + desc_elt->desc_path = strdup(desc_path); + desc_elt->url = strdup(url); +- desc_elt->is_device_desc = is_device_desc; + } + + static void free_all_desc_list(void) +@@ -324,10 +337,12 @@ static void free_all_desc_list(void) + + static void __upnp_discover_devices(void) + { ++ struct desc_list_elt *desc_elt = NULL; ++ struct desc_list_elt *desc_elt_tmp = NULL; + struct UPNPDev *dev = NULL; + char desc_name[128] = {0}; + char file_path[256] = {0}; +- int res = 0, is_device_desc = 0; ++ int res = 0; + + /* + * Discover devices +@@ -349,13 +364,26 @@ static void __upnp_discover_devices(void + + get_desc_name(dev->descURL, desc_name, sizeof(desc_name)); + snprintf(file_path, sizeof(file_path), "%s/%s", UPNP_DESC_PATH, desc_name); +- is_device_desc = (dev->usn && strstr(dev->usn, ":service:")) ? 0 : 1; + + // Download Description + download_file(file_path, dev->descURL); + + // Add description to descriptions list +- add_desc_to_desc_list(file_path, dev->descURL, is_device_desc); ++ add_desc_to_desc_list(file_path, dev->descURL); ++ } ++ ++ /* ++ * Remove unused descriptions ++ */ ++ list_for_each_entry_safe(desc_elt, desc_elt_tmp, &desc_list, list) { ++ ++ if (is_device_exist(desc_elt->url)) ++ continue; ++ ++ free(desc_elt->desc_path); ++ free(desc_elt->url); ++ free(desc_elt); ++ list_del(&desc_elt->list); + } + + end: +@@ -371,15 +399,27 @@ static int upnp_discovery_res(struct ubu + memset(&bb,0,sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + ++ void *root_devices_array = blobmsg_open_array(&bb, "root_devices"); ++ list_for_each_entry_reverse(dev, &dev_list, list) { ++ // Parse root device ++ if (dev->st && strstr(dev->st, ":rootdevice") != NULL) { ++ void *device_obj = blobmsg_open_table(&bb, NULL); ++ blobmsg_add_string(&bb, "descurl", dev->descURL); ++ blobmsg_add_string(&bb, "st", dev->st); ++ blobmsg_add_string(&bb, "usn", dev->usn); ++ blobmsg_close_table(&bb, device_obj); ++ } ++ } ++ blobmsg_close_array(&bb, root_devices_array); ++ + void *devices_array = blobmsg_open_array(&bb, "devices"); + list_for_each_entry_reverse(dev, &dev_list, list) { +- // Parse Root device and devices +- if ((dev->st && strstr(dev->st, ":rootdevice") != NULL) || (dev->usn && strstr(dev->usn, ":device:") != NULL)) { ++ // Parse devices ++ if (dev->usn && strstr(dev->usn, ":device:") != NULL) { + void *device_obj = blobmsg_open_table(&bb, NULL); + blobmsg_add_string(&bb, "descurl", dev->descURL); + blobmsg_add_string(&bb, "st", dev->st); + blobmsg_add_string(&bb, "usn", dev->usn); +- blobmsg_add_string(&bb, "is_root_device", dev->st && strstr(dev->st, ":rootdevice") ? "1" : "0"); + blobmsg_close_table(&bb, device_obj); + } + } +@@ -472,7 +512,7 @@ static void fill_device_instances(struct + blobmsg_close_table(bb, device_obj); + } + +-static void fill_service_element(struct blob_buf *bb, mxml_node_t *service) ++static void fill_service_instances(struct blob_buf *bb, mxml_node_t *service) + { + mxml_node_t *b = service; + void *service_obj = NULL; +@@ -525,6 +565,32 @@ static void fill_service_element(struct + blobmsg_close_table(bb, service_obj); + } + ++static void fill_device_service_instances(struct blob_buf *bb, bool is_device) ++{ ++ struct desc_list_elt *desc_elt = NULL; ++ ++ list_for_each_entry(desc_elt, &desc_list, list) { ++ ++ FILE *fp = fopen(desc_elt->desc_path, "r"); ++ if (!fp) ++ continue; ++ ++ mxml_node_t *tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK); ++ fclose(fp); ++ ++ if (tree) { ++ mxml_node_t *node = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND); ++ ++ if (is_device) ++ fill_device_instances(bb, node); ++ else ++ fill_service_instances(bb, node); ++ ++ mxmlDelete(tree); ++ } ++ } ++} ++ + static int upnp_description_res(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), + struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg __attribute__((unused))) + { +@@ -534,39 +600,25 @@ static int upnp_description_res(struct u + memset(&bb,0,sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + ++ // Descriptions Array + void *desc_array = blobmsg_open_array(&bb, "descriptions"); + list_for_each_entry(desc_elt, &desc_list, list) { + void *device_obj = blobmsg_open_table(&bb, NULL); + blobmsg_add_string(&bb, "desc_url", desc_elt->url); +- blobmsg_add_u32(&bb, "is_device_desc", desc_elt->is_device_desc); + blobmsg_close_table(&bb, device_obj); + + } + blobmsg_close_array(&bb, desc_array); + +- list_for_each_entry(desc_elt, &desc_list, list) { +- +- FILE *fp = fopen(desc_elt->desc_path, "r"); +- if (!fp) +- continue; +- +- mxml_node_t *tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK); +- fclose(fp); +- +- if (tree) { +- void *devices_array = blobmsg_open_array(&bb, "devices"); +- mxml_node_t *device = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND); +- fill_device_instances(&bb, device); +- blobmsg_close_array(&bb, devices_array); +- +- void *services_array = blobmsg_open_array(&bb, "services"); +- mxml_node_t *service = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND); +- fill_service_element(&bb, service); +- blobmsg_close_array(&bb, services_array); ++ // Devices Array ++ void *devices_array = blobmsg_open_array(&bb, "devices"); ++ fill_device_service_instances(&bb, true); ++ blobmsg_close_array(&bb, devices_array); + +- mxmlDelete(tree); +- } +- } ++ // Services Array ++ void *services_array = blobmsg_open_array(&bb, "services"); ++ fill_device_service_instances(&bb, false); ++ blobmsg_close_array(&bb, services_array); + + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); +@@ -624,3 +676,8 @@ end: uloop_done(); ubus_free(ctx); }