New UpnpRegisterRootDevice4 for legacy CPs.
Add a new UpnpRegisterRootDevice4 which allow user to specify a
description URL to be returned for legacy CPs (for example, CPs
searching for a v1 when the device is v2). Most of those CPs does not
work if they found a v2 in the XML description, so this new function is
only used to solve interoperability issues.
(cherry picked from commit 11f9a2bafe
)
This commit is contained in:
parent
bbe6d49b46
commit
daec6a0321
10
ChangeLog
10
ChangeLog
@ -255,6 +255,16 @@ Version 1.8.0
|
||||
Version 1.6.13
|
||||
*******************************************************************************
|
||||
|
||||
2011-03-15 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
|
||||
|
||||
New UpnpRegisterRootDevice4 for legacy CPs.
|
||||
|
||||
Add a new UpnpRegisterRootDevice4 which allow user to specify a
|
||||
description URL to be returned for legacy CPs (for example, CPs
|
||||
searching for a v1 when the device is v2). Most of those CPs does not
|
||||
work if they found a v2 in the XML description, so this new function is
|
||||
only used to solve interoperability issues.
|
||||
|
||||
2011-03-08 Iain Denniston <iain.denniston(at)gmail.com>
|
||||
Fix for memory leak.
|
||||
|
||||
|
@ -128,8 +128,9 @@
|
||||
#define UPNP_E_BUFFER_TOO_SMALL -106
|
||||
|
||||
/*!
|
||||
* \brief The description document passed to \b UpnpRegisterRootDevice or
|
||||
* \b UpnpRegisterRootDevice2 is invalid.
|
||||
* \brief The description document passed to \b UpnpRegisterRootDevice,
|
||||
* \b UpnpRegisterRootDevice2 \b UpnpRegisterRootDevice3 or
|
||||
* \b UpnpRegisterRootDevice4 is invalid.
|
||||
*/
|
||||
#define UPNP_E_INVALID_DESC -107
|
||||
|
||||
@ -418,7 +419,8 @@ typedef int UpnpClient_Handle;
|
||||
|
||||
/*!
|
||||
* \brief Returned when a device application registers with
|
||||
* \b UpnpRegisterRootDevice or \b UpnpRegisterRootDevice2.
|
||||
* \b UpnpRegisterRootDevice, \b UpnpRegisterRootDevice2,
|
||||
* \b UpnpRegisterRootDevice3 or \b UpnpRegisterRootDevice4.
|
||||
*
|
||||
* Device handles can only be used with functions that operate with a device
|
||||
* handle.
|
||||
@ -840,8 +842,62 @@ EXPORT_SPEC int UpnpRegisterRootDevice3(
|
||||
const int AddressFamily);
|
||||
|
||||
/*!
|
||||
* \brief Unregisters a root device registered with \b UpnpRegisterRootDevice or
|
||||
* \b UpnpRegisterRootDevice2.
|
||||
* \brief Registers a device application for a specific address family with
|
||||
* the UPnP library. This function can also be used to specify a dedicated
|
||||
* description URL to be returned for legacy CPs.
|
||||
*
|
||||
* A device application cannot make any other API calls until it registers
|
||||
* using this function. Device applications can also register as control
|
||||
* points (see \b UpnpRegisterClient to get a control point handle to perform
|
||||
* control point functionality).
|
||||
*
|
||||
* This is synchronous and does not generate any callbacks. Callbacks can occur
|
||||
* as soon as this function returns.
|
||||
*
|
||||
* \return An integer representing one of the following:
|
||||
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||
* \li \c UPNP_E_FINISH: The SDK is already terminated or
|
||||
* is not initialized.
|
||||
* \li \c UPNP_E_INVALID_DESC: The description document was not
|
||||
* a valid device description.
|
||||
* \li \c UPNP_E_INVALID_URL: The URL for the description document
|
||||
* is not valid.
|
||||
* \li \c UPNP_E_INVALID_PARAM: Either \b Callback or \b Hnd
|
||||
* is not a valid pointer or \b DescURL is \c NULL.
|
||||
* \li \c UPNP_E_NETWORK_ERROR: A network error occurred.
|
||||
* \li \c UPNP_E_SOCKET_WRITE: An error or timeout occurred writing
|
||||
* to a socket.
|
||||
* \li \c UPNP_E_SOCKET_READ: An error or timeout occurred reading
|
||||
* from a socket.
|
||||
* \li \c UPNP_E_SOCKET_BIND: An error occurred binding a socket.
|
||||
* \li \c UPNP_E_SOCKET_CONNECT: An error occurred connecting the
|
||||
* socket.
|
||||
* \li \c UPNP_E_OUTOF_SOCKET: Too many sockets are currently
|
||||
* allocated.
|
||||
* \li \c UPNP_E_OUTOF_MEMORY: There are insufficient resources to
|
||||
* register this root device.
|
||||
*/
|
||||
EXPORT_SPEC int UpnpRegisterRootDevice4(
|
||||
/*! [in] Pointer to a string containing the description URL for this root
|
||||
* device instance. */
|
||||
const char *DescUrl,
|
||||
/*! [in] Pointer to the callback function for receiving asynchronous events. */
|
||||
Upnp_FunPtr Callback,
|
||||
/*! [in] Pointer to user data returned with the callback function when invoked. */
|
||||
const void *Cookie,
|
||||
/*! [out] Pointer to a variable to store the new device handle. */
|
||||
UpnpDevice_Handle *Hnd,
|
||||
/*! [in] Address family of this device. Can be AF_INET for an IPv4 device, or
|
||||
* AF_INET6 for an IPv6 device. Defaults to AF_INET. */
|
||||
const int AddressFamily,
|
||||
/*! [in] Pointer to a string containing the description URL to be returned for
|
||||
* legacy CPs for this root device instance. */
|
||||
const char *LowerDescUrl);
|
||||
|
||||
/*!
|
||||
* \brief Unregisters a root device registered with \b UpnpRegisterRootDevice,
|
||||
* \b UpnpRegisterRootDevice2, \b UpnpRegisterRootDevice3 or
|
||||
* \b UpnpRegisterRootDevice4.
|
||||
*
|
||||
* After this call, the \b UpnpDevice_Handle is no longer valid. For all
|
||||
* advertisements that have not yet expired, the SDK sends a device unavailable
|
||||
|
@ -790,6 +790,10 @@ int UpnpRegisterRootDevice(
|
||||
HInfo->aliasInstalled = 0;
|
||||
HInfo->HType = HND_DEVICE;
|
||||
strcpy(HInfo->DescURL, DescUrl);
|
||||
strcpy(HInfo->LowerDescURL, DescUrl);
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"Following Root Device URL will be used when answering to legacy CPs %s\n",
|
||||
HInfo->LowerDescURL);
|
||||
HInfo->Callback = Fun;
|
||||
HInfo->Cookie = (void *)Cookie;
|
||||
HInfo->MaxAge = DEFAULT_MAXAGE;
|
||||
@ -952,6 +956,10 @@ int UpnpRegisterRootDevice2(
|
||||
goto exit_function;
|
||||
}
|
||||
|
||||
strcpy(HInfo->LowerDescURL, HInfo->DescURL);
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"Following Root Device URL will be used when answering to legacy CPs %s\n",
|
||||
HInfo->LowerDescURL);
|
||||
HInfo->aliasInstalled = config_baseURL != 0;
|
||||
HInfo->HType = HND_DEVICE;
|
||||
HInfo->Callback = Fun;
|
||||
@ -1034,6 +1042,23 @@ int UpnpRegisterRootDevice3(
|
||||
const void *Cookie,
|
||||
UpnpDevice_Handle *Hnd,
|
||||
const int AddressFamily)
|
||||
{
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"Inside UpnpRegisterRootDevice3\n");
|
||||
return UpnpRegisterRootDevice4(DescUrl, Fun, Cookie, Hnd,
|
||||
AddressFamily, NULL);
|
||||
}
|
||||
#endif /* INCLUDE_DEVICE_APIS */
|
||||
|
||||
|
||||
#ifdef INCLUDE_DEVICE_APIS
|
||||
int UpnpRegisterRootDevice4(
|
||||
const char *DescUrl,
|
||||
Upnp_FunPtr Fun,
|
||||
const void *Cookie,
|
||||
UpnpDevice_Handle *Hnd,
|
||||
const int AddressFamily,
|
||||
const char *LowerDescUrl)
|
||||
{
|
||||
struct Handle_Info *HInfo;
|
||||
int retVal = 0;
|
||||
@ -1043,7 +1068,7 @@ int UpnpRegisterRootDevice3(
|
||||
HandleLock();
|
||||
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"Inside UpnpRegisterRootDevice3\n");
|
||||
"Inside UpnpRegisterRootDevice4\n");
|
||||
if (UpnpSdkInit != 1) {
|
||||
retVal = UPNP_E_FINISH;
|
||||
goto exit_function;
|
||||
@ -1087,6 +1112,13 @@ int UpnpRegisterRootDevice3(
|
||||
HInfo->aliasInstalled = 0;
|
||||
HInfo->HType = HND_DEVICE;
|
||||
strcpy(HInfo->DescURL, DescUrl);
|
||||
if (LowerDescUrl == NULL)
|
||||
strcpy(HInfo->LowerDescURL, DescUrl);
|
||||
else
|
||||
strcpy(HInfo->LowerDescURL, LowerDescUrl);
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"Following Root Device URL will be used when answering to legacy CPs %s\n",
|
||||
HInfo->LowerDescURL);
|
||||
HInfo->Callback = Fun;
|
||||
HInfo->Cookie = (void *)Cookie;
|
||||
HInfo->MaxAge = DEFAULT_MAXAGE;
|
||||
@ -1109,8 +1141,8 @@ int UpnpRegisterRootDevice3(
|
||||
goto exit_function;
|
||||
}
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"UpnpRegisterRootDevice3: Valid Description\n"
|
||||
"UpnpRegisterRootDevice3: DescURL : %s\n",
|
||||
"UpnpRegisterRootDevice4: Valid Description\n"
|
||||
"UpnpRegisterRootDevice4: DescURL : %s\n",
|
||||
HInfo->DescURL);
|
||||
|
||||
HInfo->DeviceList = ixmlDocument_getElementsByTagName(
|
||||
@ -1122,7 +1154,7 @@ int UpnpRegisterRootDevice3(
|
||||
ixmlDocument_free(HInfo->DescDocument);
|
||||
FreeHandle(*Hnd);
|
||||
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
|
||||
"UpnpRegisterRootDevice3: No devices found for RootDevice\n");
|
||||
"UpnpRegisterRootDevice4: No devices found for RootDevice\n");
|
||||
retVal = UPNP_E_INVALID_DESC;
|
||||
goto exit_function;
|
||||
}
|
||||
@ -1131,26 +1163,26 @@ int UpnpRegisterRootDevice3(
|
||||
HInfo->DescDocument, "serviceList" );
|
||||
if (!HInfo->ServiceList) {
|
||||
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
|
||||
"UpnpRegisterRootDevice3: No services found for RootDevice\n");
|
||||
"UpnpRegisterRootDevice4: No services found for RootDevice\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* GENA SET UP
|
||||
*/
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"UpnpRegisterRootDevice3: Gena Check\n" );
|
||||
"UpnpRegisterRootDevice4: Gena Check\n" );
|
||||
hasServiceTable = getServiceTable(
|
||||
(IXML_Node *)HInfo->DescDocument,
|
||||
&HInfo->ServiceTable,
|
||||
HInfo->DescURL);
|
||||
if (hasServiceTable) {
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"UpnpRegisterRootDevice3: GENA Service Table \n"
|
||||
"UpnpRegisterRootDevice4: GENA Service Table \n"
|
||||
"Here are the known services: \n" );
|
||||
printServiceTable(&HInfo->ServiceTable, UPNP_ALL, API);
|
||||
} else {
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"\nUpnpRegisterRootDevice3: Empty service table\n");
|
||||
"\nUpnpRegisterRootDevice4: Empty service table\n");
|
||||
}
|
||||
|
||||
if (AddressFamily == AF_INET) {
|
||||
@ -1163,7 +1195,7 @@ int UpnpRegisterRootDevice3(
|
||||
|
||||
exit_function:
|
||||
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||
"Exiting RegisterRootDevice3, return value == %d\n", retVal);
|
||||
"Exiting RegisterRootDevice4, return value == %d\n", retVal);
|
||||
HandleUnlock();
|
||||
|
||||
return retVal;
|
||||
|
@ -80,6 +80,9 @@ struct Handle_Info
|
||||
#ifdef INCLUDE_DEVICE_APIS
|
||||
/*! URL for the use of SSDP. */
|
||||
char DescURL[LINE_SIZE];
|
||||
/*! URL for the use of SSDP when answering to legacy CPs (CP searching
|
||||
* for a v1 when the device is v2). */
|
||||
char LowerDescURL[LINE_SIZE];
|
||||
/*! XML file path for device description. */
|
||||
char DescXML[LINE_SIZE];
|
||||
/* Advertisement timeout */
|
||||
|
@ -366,10 +366,13 @@ static int check_soap_body(
|
||||
if (actionNode) {
|
||||
ns = ixmlNode_getNamespaceURI(actionNode);
|
||||
name = ixmlNode_getLocalName(actionNode);
|
||||
/* Don't check version number, to accept a
|
||||
* request comming on a v1 service when
|
||||
* publishing a v2 service */
|
||||
if (name &&
|
||||
ns &&
|
||||
!strcmp(actionName, name) &&
|
||||
!strcmp(urn, ns))
|
||||
!strncmp(urn, ns, strlen (urn) - 2))
|
||||
ret_code = UPNP_E_SUCCESS;
|
||||
}
|
||||
}
|
||||
@ -440,7 +443,9 @@ static int check_soap_action_header(
|
||||
return ret_code;
|
||||
}
|
||||
snprintf(ns_compare, tempSize, "\"%s", urn);
|
||||
if (strcmp(temp_header_value, ns_compare))
|
||||
/* Don't check version number, to accept a request comming on a v1
|
||||
* service when publishing a v2 service */
|
||||
if (strncmp(temp_header_value, ns_compare, strlen(ns_compare) - 2))
|
||||
ret_code = UPNP_E_INVALID_ACTION;
|
||||
else {
|
||||
ret_code = UPNP_E_SUCCESS;
|
||||
|
@ -245,10 +245,18 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
|
||||
}
|
||||
case SSDP_DEVICETYPE: {
|
||||
if (!strncasecmp(DeviceType, devType, strlen(DeviceType) - 2)) {
|
||||
if (atoi(&DeviceType[strlen(DeviceType)
|
||||
- 1]) <= atoi(&devType[strlen(devType) - 1])) {
|
||||
if (atoi(strrchr(DeviceType, ':') + 1)
|
||||
< atoi(&devType[strlen(devType) - 1])) {
|
||||
/* the requested version is lower than the device version
|
||||
* must reply with the lower version number */
|
||||
* must reply with the lower version number and the lower
|
||||
* description URL */
|
||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
|
||||
"DeviceType=%s and search devType=%s MATCH\n",
|
||||
devType, DeviceType);
|
||||
SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->LowerDescURL,
|
||||
defaultExp, 1);
|
||||
} else if (atoi(strrchr(DeviceType, ':') + 1)
|
||||
== atoi(&devType[strlen(devType) - 1])) {
|
||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
|
||||
"DeviceType=%s and search devType=%s MATCH\n",
|
||||
devType, DeviceType);
|
||||
@ -347,10 +355,18 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
|
||||
case SSDP_SERVICE:
|
||||
if (ServiceType) {
|
||||
if (!strncasecmp(ServiceType, servType, strlen(ServiceType) - 2)) {
|
||||
if (atoi(&ServiceType[strlen(ServiceType) - 1]) <=
|
||||
if (atoi(strrchr(ServiceType, ':') + 1) <
|
||||
atoi(&servType[strlen(servType) - 1])) {
|
||||
/* the requested version is lower than the service version
|
||||
* must reply with the lower version number */
|
||||
* must reply with the lower version number and the lower
|
||||
* description URL */
|
||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
|
||||
"ServiceType=%s and search servType=%s MATCH\n",
|
||||
ServiceType, servType);
|
||||
SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->LowerDescURL,
|
||||
defaultExp, 1);
|
||||
} else if (atoi(strrchr (ServiceType, ':') + 1) ==
|
||||
atoi(&servType[strlen(servType) - 1])) {
|
||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
|
||||
"ServiceType=%s and search servType=%s MATCH\n",
|
||||
ServiceType, servType);
|
||||
|
Loading…
Reference in New Issue
Block a user