Пример #1
0
static int
upnp_device_advlist_init(UPNP_CONTEXT *context)
{
	int i;
	int size;
	UPNP_INTERFACE *ifp = context->focus_ifp;
	UPNP_ADVERTISE *src, *dst;
	char new_uuid[64];
	char old_uuid[64];

	/* Count advertise_table size */
	for (i = 0; ifp->device->advertise_table[i].name; i++)
		;

	size = (i + 1) * sizeof(UPNP_ADVERTISE);
	ifp->advlist = (UPNP_ADVERTISE *)malloc(size);
	if (ifp->advlist == NULL)
		return -1;

	memcpy(ifp->advlist, ifp->device->advertise_table, size);

	/* Renew UUIDs of this ifp */
	for (src = ifp->advlist; src->name; src++) {
		if (src->type != ADVERTISE_ROOTDEVICE &&
			src->type != ADVERTISE_DEVICE)
			continue;

		/* Generate interface uuid for this device */
		strcpy(old_uuid, src->uuid);
		upnp_gen_uuid(new_uuid, src->name, (unsigned char *)ifp->mac);

		/* Sync to device/services with this UUID */
		for (dst = ifp->advlist; dst->name; dst++) {
			if (strcmp(dst->uuid, old_uuid) == 0) {
				strncpy(dst->uuid, new_uuid, sizeof(dst->uuid));
				dst->uuid[sizeof(dst->uuid)-1] = '\0';
			}
		}
	}

	return 0;
}
Пример #2
0
/* Give a unique uuid to this rootdevice */
int
upnp_device_renew_uuid(UPNP_CONTEXT *context, UPNP_DEVICE *device)
{
	char *s, *p;
	char deviceType[256];
	char serviceType[256];
	char new_uuid[64];

	UPNP_DESCRIPTION *desc;

	/* Find root device */
	for (desc = device->description_table; desc; desc++) {
		if (strcmp(device->root_device_xml, desc->name+1) == 0)
			break;
	}
	if (desc == 0) {
		upnp_syslog(LOG_ERR, "Root device can not find it's xml.");
		return -1;
	}

	/*
	 * Update UUID of the root device xml
	 * for each AP/router. By using the MAC address
	 * and the value between <deviceType>...</deviceType>, we can
	 * generate a unique UUID.
	 */
	for (p = desc->xml; *p != 0; p++) {
		/* Search for <deviceType> */
		if (strncmp(p, DEVICE_BTAG, strlen(DEVICE_BTAG)) == 0) {

			p += strlen(DEVICE_BTAG);

			/* Find the balanced </deviceType> */
			s = strstr(p, DEVICE_ETAG);
			if (s == 0 || (s-p) > sizeof(deviceType)-1) {
				upnp_syslog(LOG_ERR,
					"Parse format:<deviceType>...</deviceType> error.\n");
				return -1;
			}

			/* Save deviceType */
			memcpy(deviceType, p, s-p);
			deviceType[s-p] = '\0';
			p = s + strlen(DEVICE_ETAG);
		}

		/*
		 * For example,
		 * <deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>
		 * the value between <UDN>...</UDN> is the UUID we have to replace.
		 * The UUID format is such as, uuid:eb9ab5b2-981c-4401-a20e-b7bcde359dbb.
		 * By generate the same UUID size, we don't have to do memory ajustment.
		 */
		if (strncmp(p, UDN_BTAG, strlen(UDN_BTAG)) == 0) {

			p += strlen(UDN_BTAG);

			/* Find the balanced </UDN> */
			s = strstr(p, UDN_ETAG);
			if (s == 0 || (s-p) > sizeof(deviceType)-1) {
				upnp_syslog(LOG_ERR, "Parse format:<UDN>...</UDN> error.\n");
				return -1;
			}

			p += 5; /* "uuid:" is 5 char */
			if ((s-p) != 36) {
				upnp_syslog(LOG_ERR, "UUID length is not 36.\n");
				return -1;
			}

			/* Replace uuid */
			upnp_gen_uuid(new_uuid, deviceType);

			memcpy(p, new_uuid, 36);  /* uuid is 36 characters. */
			p = p + 36;				  /* 46 = 10 + 36 */

			/*
			 * Afert the UUID of device in description XML is changed,
			 * we have to sync this new UUID to the advertisement table.
			 */
			sync_advertise_uuid(device, new_uuid, deviceType);
		}

		/*
		 * The SSDP broadcasts not only the device information but
		 * also all the services of this device, which shares the
		 * UUID of that device.
		 * As a result, we have to find out all the <serviceType>'s
		 * of this <deviceType>, and sync the device UUID to the
		 * advertisement table
		 */
		if (strncmp(p, SERVICE_BTAG, strlen(SERVICE_BTAG)) == 0) {

			p += strlen(SERVICE_BTAG);

			/* Find the balanced </serviceType> */
			s = strstr(p, SERVICE_ETAG);
			if (s == 0 || (s-p) > sizeof(serviceType)-1) {
				upnp_syslog(LOG_ERR,
					"Parse format:<serviceType>...</serviceType> error.\n");
				return -1;
			}

			/* Save serviceType */
			strncpy(serviceType, p, s-p);
			serviceType[s-p] = '\0';
			p = s + strlen(SERVICE_ETAG);

			/*
			 * Found a <serviceType>...</serviceType>.
			 * For example,
			 * <serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1
			 * </serviceType>
			 * is the service of
			 * <deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1
			 * </deviceType>.
			 * We have to search the
			 * "urn:schemas-upnp-org:service:Layer3Forwarding:1"
			 * in the advertisement table, and replace its UUID with the UUID of
			 * "urn:schemas-upnp-org:device:InternetGatewayDevice:1".
			 */
			sync_advertise_uuid(device, new_uuid, serviceType);
		}
	}

	return 0;
}