UPnP Low Power support

Adding two new functions (UpnpSendAdvertisementLowPower and
UpnpUnRegisterRootDeviceLowPower) which can be used to specify values
for the three SSDP headers defined by UPnP Low Power. Those headers are
Powerstate, SleepPeriod and RegistrationState.
(cherry picked from commit 98e4f938d63226bcb623dd7d9cd1855482318534)
This commit is contained in:
Fabrice Fontaine 2011-10-31 10:07:29 +01:00 committed by Marcelo Roberto Jimenez
parent c86d963abe
commit 4b82bb7baf
7 changed files with 294 additions and 48 deletions

View File

@ -255,6 +255,15 @@ Version 1.8.0
Version 1.6.14 Version 1.6.14
******************************************************************************* *******************************************************************************
2011-10-31 Fabrice Fontaine <fabrice.fontaine(at)orange.com>
UPnP Low Power Support.
Adding two new functions (UpnpSendAdvertisementLowPower and
UpnpUnRegisterRootDeviceLowPower) which can be used to specify values
for the three SSDP headers defined by UPnP Low Power. Those headers are
Powerstate, SleepPeriod and RegistrationState.
2011-10-24 Fabrice Fontaine <fabrice.fontaine(at)orange.com> 2011-10-24 Fabrice Fontaine <fabrice.fontaine(at)orange.com>
Bug fix in IN6_IS_ADDR_GLOBAL. Bug fix in IN6_IS_ADDR_GLOBAL.

View File

@ -5,6 +5,7 @@
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
* Copyright (C) 2011 France Telecom All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -917,6 +918,35 @@ EXPORT_SPEC int UpnpUnRegisterRootDevice(
/*! [in] The handle of the root device instance to unregister. */ /*! [in] The handle of the root device instance to unregister. */
UpnpDevice_Handle Hnd); UpnpDevice_Handle Hnd);
/*!
* \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
* message automatically.
*
* This is a synchronous call and generates no callbacks. Once this call
* returns, the SDK will no longer generate callbacks to the application.
*
* This function allow a device to specify the SSDP extensions defined by UPnP
* Low Power.
*
* \return An integer representing one of the following:
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
* \li \c UPNP_E_INVALID_HANDLE: The handle is not a valid device handle.
*/
EXPORT_SPEC int UpnpUnRegisterRootDeviceLowPower(
/*! [in] The handle of the root device instance to unregister. */
UpnpDevice_Handle Hnd,
/*! PowerState as defined by UPnP Low Power. */
int PowerState,
/*! SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/*! RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Registers a control point application with the UPnP Library. * \brief Registers a control point application with the UPnP Library.
* *
@ -1071,6 +1101,36 @@ EXPORT_SPEC int UpnpSendAdvertisement(
/*! The expiration age, in seconds, of the announcements. */ /*! The expiration age, in seconds, of the announcements. */
int Exp); int Exp);
/*!
* \brief Sends out the discovery announcements for all devices and services
* for a device.
*
* Each announcement is made with the same expiration time.
*
* This is a synchronous call.
*
* This function allow a device to specify the SSDP extensions defined by UPnP
* Low Power.
*
* \return An integer representing one of the following:
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
* \li \c UPNP_E_INVALID_HANDLE: The handle is not a valid
* device handle.
* \li \c UPNP_E_OUTOF_MEMORY: There are insufficient resources to
* send future advertisements.
*/
EXPORT_SPEC int UpnpSendAdvertisementLowPower(
/*! The device handle for which to send out the announcements. */
UpnpDevice_Handle Hnd,
/*! The expiration age, in seconds, of the announcements. */
int Exp,
/*! PowerState as defined by UPnP Low Power. */
int PowerState,
/*! SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/*! RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/* @} Discovery */ /* @} Discovery */
/****************************************************************************** /******************************************************************************

View File

@ -2,6 +2,7 @@
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
* Copyright (C) 2011 France Telecom All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -1205,6 +1206,14 @@ exit_function:
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd) int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
{
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Inside UpnpUnRegisterRootDevice\n");
return UpnpUnRegisterRootDeviceLowPower(Hnd, -1, -1, -1);
}
int UpnpUnRegisterRootDeviceLowPower(UpnpDevice_Handle Hnd, int PowerState,
int SleepPeriod, int RegistrationState)
{ {
int retVal = 0; int retVal = 0;
struct Handle_Info *HInfo = NULL; struct Handle_Info *HInfo = NULL;
@ -1212,7 +1221,7 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
if (UpnpSdkInit != 1) if (UpnpSdkInit != 1)
return UPNP_E_FINISH; return UPNP_E_FINISH;
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Inside UpnpUnRegisterRootDevice\n"); "Inside UpnpUnRegisterRootDeviceLowPower\n");
#if EXCLUDE_GENA == 0 #if EXCLUDE_GENA == 0
if (genaUnregisterDevice(Hnd) != UPNP_E_SUCCESS) if (genaUnregisterDevice(Hnd) != UPNP_E_SUCCESS)
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -1223,6 +1232,11 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
} }
HInfo->PowerState = PowerState;
if( SleepPeriod < 0 )
SleepPeriod = -1;
HInfo->SleepPeriod = SleepPeriod;
HInfo->RegistrationState = RegistrationState;
HandleUnlock(); HandleUnlock();
#if EXCLUDE_SSDP == 0 #if EXCLUDE_SSDP == 0
@ -1254,7 +1268,7 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
HandleUnlock(); HandleUnlock();
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Exiting UpnpUnRegisterRootDevice\n"); "Exiting UpnpUnRegisterRootDeviceLowPower\n");
return retVal; return retVal;
} }
@ -1583,6 +1597,14 @@ static int GetDescDocumentAndURL(
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
#if EXCLUDE_SSDP == 0 #if EXCLUDE_SSDP == 0
int UpnpSendAdvertisement(UpnpDevice_Handle Hnd, int Exp) int UpnpSendAdvertisement(UpnpDevice_Handle Hnd, int Exp)
{
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSendAdvertisement \n");
return UpnpSendAdvertisementLowPower (Hnd, Exp, -1, -1, -1);
}
int UpnpSendAdvertisementLowPower(UpnpDevice_Handle Hnd, int Exp,
int PowerState, int SleepPeriod, int RegistrationState)
{ {
struct Handle_Info *SInfo = NULL; struct Handle_Info *SInfo = NULL;
int retVal = 0, int retVal = 0,
@ -1595,7 +1617,7 @@ int UpnpSendAdvertisement(UpnpDevice_Handle Hnd, int Exp)
} }
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSendAdvertisement \n" ); "Inside UpnpSendAdvertisementLowPower \n" );
HandleLock(); HandleLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
@ -1605,6 +1627,11 @@ int UpnpSendAdvertisement(UpnpDevice_Handle Hnd, int Exp)
if( Exp < 1 ) if( Exp < 1 )
Exp = DEFAULT_MAXAGE; Exp = DEFAULT_MAXAGE;
SInfo->MaxAge = Exp; SInfo->MaxAge = Exp;
SInfo->PowerState = PowerState;
if( SleepPeriod < 0 )
SleepPeriod = -1;
SInfo->SleepPeriod = SleepPeriod;
SInfo->RegistrationState = RegistrationState;
HandleUnlock(); HandleUnlock();
retVal = AdvertiseAndReply( 1, Hnd, 0, ( struct sockaddr * )NULL, retVal = AdvertiseAndReply( 1, Hnd, 0, ( struct sockaddr * )NULL,
( char * )NULL, ( char * )NULL, ( char * )NULL, ( char * )NULL,
@ -1665,7 +1692,7 @@ int UpnpSendAdvertisement(UpnpDevice_Handle Hnd, int Exp)
HandleUnlock(); HandleUnlock();
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Exiting UpnpSendAdvertisement \n" ); "Exiting UpnpSendAdvertisementLowPower \n" );
return retVal; return retVal;

View File

@ -5,6 +5,7 @@
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
* Copyright (C) 2011 France Telecom All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -353,7 +354,13 @@ int DeviceAdvertisement(
/* [in] Service duration in sec. */ /* [in] Service duration in sec. */
int Duration, int Duration,
/* [in] Device address family. */ /* [in] Device address family. */
int AddressFamily); int AddressFamily,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Creates the reply packet based on the input parameter, and send it * \brief Creates the reply packet based on the input parameter, and send it
@ -375,7 +382,13 @@ int SendReply(
/* [in] Life time of this device. */ /* [in] Life time of this device. */
int Duration, int Duration,
/* [in] . */ /* [in] . */
int ByType ); int ByType,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Creates the reply packet based on the input parameter, and send it * \brief Creates the reply packet based on the input parameter, and send it
@ -395,7 +408,13 @@ int DeviceReply(
/* [in] Location of Device description document. */ /* [in] Location of Device description document. */
char *Location, char *Location,
/* [in] Life time of this device. */ /* [in] Life time of this device. */
int Duration); int Duration,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Creates the advertisement packet based on the input parameter, * \brief Creates the advertisement packet based on the input parameter,
@ -413,7 +432,13 @@ int ServiceAdvertisement(
/* [in] Life time of this device. */ /* [in] Life time of this device. */
int Duration, int Duration,
/* [in] Device address family. */ /* [in] Device address family. */
int AddressFamily); int AddressFamily,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Creates the advertisement packet based on the input parameter, * \brief Creates the advertisement packet based on the input parameter,
@ -431,7 +456,13 @@ int ServiceReply(
/* [in] Location of Device description document. */ /* [in] Location of Device description document. */
char *Location, char *Location,
/* [in] Life time of this device. */ /* [in] Life time of this device. */
int Duration); int Duration,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Creates a HTTP service shutdown request packet and sends it to the * \brief Creates a HTTP service shutdown request packet and sends it to the
@ -449,7 +480,13 @@ int ServiceShutdown(
/* [in] Service duration in sec. */ /* [in] Service duration in sec. */
int Duration, int Duration,
/* [in] Device address family. */ /* [in] Device address family. */
int AddressFamily); int AddressFamily,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/*! /*!
* \brief Creates a HTTP device shutdown request packet and send it to the * \brief Creates a HTTP device shutdown request packet and send it to the
@ -471,7 +508,13 @@ int DeviceShutdown(
/* [in] Device duration in sec. */ /* [in] Device duration in sec. */
int Duration, int Duration,
/* [in] Device address family. */ /* [in] Device address family. */
int AddressFamily); int AddressFamily,
/* [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/* [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/* [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState);
/* @} SSDP Device Functions */ /* @} SSDP Device Functions */

View File

@ -2,6 +2,7 @@
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
* Copyright (C) 2011 France Telecom All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -87,6 +88,12 @@ struct Handle_Info
char DescXML[LINE_SIZE]; char DescXML[LINE_SIZE];
/* Advertisement timeout */ /* Advertisement timeout */
int MaxAge; int MaxAge;
/* Power State as defined by UPnP Low Power. */
int PowerState;
/* Sleep Period as defined by UPnP Low Power. */
int SleepPeriod;
/* Registration State as defined by UPnP Low Power. */
int RegistrationState;
/*! Description parsed in terms of DOM document. */ /*! Description parsed in terms of DOM document. */
IXML_Document *DescDocument; IXML_Document *DescDocument;
/*! List of devices in the description document. */ /*! List of devices in the description document. */

View File

@ -2,6 +2,7 @@
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
* Copyright (C) 2011 France Telecom All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -313,7 +314,13 @@ static void CreateServicePacket(
/*! [out] Output buffer filled with HTTP statement. */ /*! [out] Output buffer filled with HTTP statement. */
char **packet, char **packet,
/*! [in] Address family of the HTTP request. */ /*! [in] Address family of the HTTP request. */
int AddressFamily) int AddressFamily,
/*! [in] PowerState as defined by UPnP Low Power. */
int PowerState,
/*! [in] SleepPeriod as defined by UPnP Low Power. */
int SleepPeriod,
/*! [in] RegistrationState as defined by UPnP Low Power. */
int RegistrationState)
{ {
int ret_code; int ret_code;
const char *nts; const char *nts;
@ -326,6 +333,22 @@ static void CreateServicePacket(
buf.size_inc = 30; buf.size_inc = 30;
*packet = NULL; *packet = NULL;
if (msg_type == MSGTYPE_REPLY) { if (msg_type == MSGTYPE_REPLY) {
if (PowerState > 0) {
ret_code = http_MakeMessage(&buf, 1, 1,
"R" "sdc" "D" "sc" "ssc" "ssc" "ssc"
"S" "Xc" "ssc" "ssc"
"sdc" "sdc" "sdcc", HTTP_OK,
"CACHE-CONTROL: max-age=", duration,
"EXT:", "LOCATION: ", location,
"OPT: ",
"\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
"01-NLS: ", gUpnpSdkNLSuuid,
X_USER_AGENT, "ST: ", nt, "USN: ",
usn, "Powerstate: ", PowerState,
"SleepPeriod: ", SleepPeriod,
"RegistrationState: ",
RegistrationState);
} else {
ret_code = http_MakeMessage(&buf, 1, 1, ret_code = http_MakeMessage(&buf, 1, 1,
"R" "sdc" "D" "sc" "ssc" "ssc" "ssc" "R" "sdc" "D" "sc" "ssc" "ssc" "ssc"
"S" "Xc" "ssc" "sscc", HTTP_OK, "S" "Xc" "ssc" "sscc", HTTP_OK,
@ -336,6 +359,7 @@ static void CreateServicePacket(
"01-NLS: ", gUpnpSdkNLSuuid, "01-NLS: ", gUpnpSdkNLSuuid,
X_USER_AGENT, "ST: ", nt, "USN: ", X_USER_AGENT, "ST: ", nt, "USN: ",
usn); usn);
}
if (ret_code != 0) { if (ret_code != 0) {
return; return;
} }
@ -358,6 +382,23 @@ static void CreateServicePacket(
else else
host = "[" SSDP_IPV6_LINKLOCAL "]"; host = "[" SSDP_IPV6_LINKLOCAL "]";
} }
if (PowerState > 0) {
ret_code = http_MakeMessage(&buf, 1, 1,
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc"
"ssc" "ssc" "S" "Xc" "ssc"
"sdc" "sdc" "sdcc",
HTTPMETHOD_NOTIFY, "*", (size_t) 1,
"HOST: ", host, ":", SSDP_PORT,
"CACHE-CONTROL: max-age=", duration,
"LOCATION: ", location, "OPT: ",
"\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
"01-NLS: ", gUpnpSdkNLSuuid, "NT: ",
nt, "NTS: ", nts, X_USER_AGENT,
"USN: ", usn, "Powerstate: ",
PowerState, "SleepPeriod: ",
SleepPeriod, "RegistrationState: ",
RegistrationState);
} else {
ret_code = http_MakeMessage(&buf, 1, 1, ret_code = http_MakeMessage(&buf, 1, 1,
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "Q" "sssdc" "sdc" "ssc" "ssc" "ssc"
"ssc" "ssc" "S" "Xc" "sscc", "ssc" "ssc" "S" "Xc" "sscc",
@ -369,6 +410,7 @@ static void CreateServicePacket(
"01-NLS: ", gUpnpSdkNLSuuid, "NT: ", "01-NLS: ", gUpnpSdkNLSuuid, "NT: ",
nt, "NTS: ", nts, X_USER_AGENT, nt, "NTS: ", nts, X_USER_AGENT,
"USN: ", usn); "USN: ", usn);
}
if (ret_code) if (ret_code)
return; return;
} else } else
@ -382,7 +424,8 @@ static void CreateServicePacket(
} }
int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location, int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location,
int Duration, int AddressFamily) int Duration, int AddressFamily, int PowerState,
int SleepPeriod, int RegistrationState)
{ {
struct sockaddr_storage __ss; struct sockaddr_storage __ss;
struct sockaddr_in *DestAddr4 = (struct sockaddr_in *)&__ss; struct sockaddr_in *DestAddr4 = (struct sockaddr_in *)&__ss;
@ -419,14 +462,17 @@ int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location,
sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn); sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn);
CreateServicePacket(MSGTYPE_ADVERTISEMENT, "upnp:rootdevice", CreateServicePacket(MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
Mil_Usn, Location, Duration, &msgs[0], Mil_Usn, Location, Duration, &msgs[0],
AddressFamily); AddressFamily, PowerState, SleepPeriod,
RegistrationState);
} }
/* both root and sub-devices need to send these two messages */ /* both root and sub-devices need to send these two messages */
CreateServicePacket(MSGTYPE_ADVERTISEMENT, Udn, Udn, CreateServicePacket(MSGTYPE_ADVERTISEMENT, Udn, Udn,
Location, Duration, &msgs[1], AddressFamily); Location, Duration, &msgs[1], AddressFamily,
PowerState, SleepPeriod, RegistrationState);
sprintf(Mil_Usn, "%s::%s", Udn, DevType); sprintf(Mil_Usn, "%s::%s", Udn, DevType);
CreateServicePacket(MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn, CreateServicePacket(MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
Location, Duration, &msgs[2], AddressFamily); Location, Duration, &msgs[2], AddressFamily,
PowerState, SleepPeriod, RegistrationState);
/* check error */ /* check error */
if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) { if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) {
free(msgs[0]); free(msgs[0]);
@ -454,7 +500,8 @@ int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location,
} }
int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev, int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
char *Udn, char *Location, int Duration, int ByType) char *Udn, char *Location, int Duration, int ByType,
int PowerState, int SleepPeriod, int RegistrationState)
{ {
int ret_code; int ret_code;
char *msgs[2]; char *msgs[2];
@ -471,7 +518,8 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn); sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn);
CreateServicePacket(MSGTYPE_REPLY, "upnp:rootdevice", CreateServicePacket(MSGTYPE_REPLY, "upnp:rootdevice",
Mil_Usn, Location, Duration, &msgs[0], Mil_Usn, Location, Duration, &msgs[0],
DestAddr->sa_family); DestAddr->sa_family, PowerState,
SleepPeriod, RegistrationState);
} else { } else {
/* two msgs for embedded devices */ /* two msgs for embedded devices */
num_msgs = 1; num_msgs = 1;
@ -480,12 +528,14 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
if (!ByType) { if (!ByType) {
CreateServicePacket(MSGTYPE_REPLY, Udn, Udn, Location, CreateServicePacket(MSGTYPE_REPLY, Udn, Udn, Location,
Duration, &msgs[0], Duration, &msgs[0],
DestAddr->sa_family); DestAddr->sa_family, PowerState,
SleepPeriod, RegistrationState);
} else { } else {
sprintf(Mil_Usn, "%s::%s", Udn, DevType); sprintf(Mil_Usn, "%s::%s", Udn, DevType);
CreateServicePacket(MSGTYPE_REPLY, DevType, Mil_Usn, CreateServicePacket(MSGTYPE_REPLY, DevType, Mil_Usn,
Location, Duration, &msgs[0], Location, Duration, &msgs[0],
DestAddr->sa_family); DestAddr->sa_family, PowerState,
SleepPeriod, RegistrationState);
} }
} }
/* check error */ /* check error */
@ -506,7 +556,8 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
} }
int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev, int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
char *Udn, char *Location, int Duration) char *Udn, char *Location, int Duration, int PowerState,
int SleepPeriod, int RegistrationState)
{ {
char *szReq[3], Mil_Nt[LINE_SIZE], Mil_Usn[LINE_SIZE]; char *szReq[3], Mil_Nt[LINE_SIZE], Mil_Usn[LINE_SIZE];
int RetVal; int RetVal;
@ -521,16 +572,19 @@ int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn); sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn);
CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn, CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
Location, Duration, &szReq[0], Location, Duration, &szReq[0],
DestAddr->sa_family); DestAddr->sa_family, PowerState,
SleepPeriod, RegistrationState);
} }
sprintf(Mil_Nt, "%s", Udn); sprintf(Mil_Nt, "%s", Udn);
sprintf(Mil_Usn, "%s", Udn); sprintf(Mil_Usn, "%s", Udn);
CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn, CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
Location, Duration, &szReq[1], DestAddr->sa_family); Location, Duration, &szReq[1], DestAddr->sa_family,
PowerState, SleepPeriod, RegistrationState);
sprintf(Mil_Nt, "%s", DevType); sprintf(Mil_Nt, "%s", DevType);
sprintf(Mil_Usn, "%s::%s", Udn, DevType); sprintf(Mil_Usn, "%s::%s", Udn, DevType);
CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn, CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
Location, Duration, &szReq[2], DestAddr->sa_family); Location, Duration, &szReq[2], DestAddr->sa_family,
PowerState, SleepPeriod, RegistrationState);
/* check error */ /* check error */
if ((RootDev && szReq[0] == NULL) || if ((RootDev && szReq[0] == NULL) ||
szReq[1] == NULL || szReq[2] == NULL) { szReq[1] == NULL || szReq[2] == NULL) {
@ -554,7 +608,8 @@ int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev,
} }
int ServiceAdvertisement(char *Udn, char *ServType, char *Location, int ServiceAdvertisement(char *Udn, char *ServType, char *Location,
int Duration, int AddressFamily) int Duration, int AddressFamily, int PowerState,
int SleepPeriod, int RegistrationState)
{ {
char Mil_Usn[LINE_SIZE]; char Mil_Usn[LINE_SIZE];
char *szReq[1]; char *szReq[1];
@ -583,7 +638,8 @@ int ServiceAdvertisement(char *Udn, char *ServType, char *Location,
/* CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn, /* CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
* Server,Location,Duration); */ * Server,Location,Duration); */
CreateServicePacket(MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn, CreateServicePacket(MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
Location, Duration, &szReq[0], AddressFamily); Location, Duration, &szReq[0], AddressFamily,
PowerState, SleepPeriod, RegistrationState);
if (szReq[0] == NULL) { if (szReq[0] == NULL) {
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
@ -594,7 +650,8 @@ int ServiceAdvertisement(char *Udn, char *ServType, char *Location,
} }
int ServiceReply(struct sockaddr *DestAddr, char *ServType, char *Udn, int ServiceReply(struct sockaddr *DestAddr, char *ServType, char *Udn,
char *Location, int Duration) char *Location, int Duration, int PowerState, int SleepPeriod,
int RegistrationState)
{ {
char Mil_Usn[LINE_SIZE]; char Mil_Usn[LINE_SIZE];
char *szReq[1]; char *szReq[1];
@ -603,7 +660,8 @@ int ServiceReply(struct sockaddr *DestAddr, char *ServType, char *Udn,
szReq[0] = NULL; szReq[0] = NULL;
sprintf(Mil_Usn, "%s::%s", Udn, ServType); sprintf(Mil_Usn, "%s::%s", Udn, ServType);
CreateServicePacket(MSGTYPE_REPLY, ServType, Mil_Usn, CreateServicePacket(MSGTYPE_REPLY, ServType, Mil_Usn,
Location, Duration, &szReq[0], DestAddr->sa_family); Location, Duration, &szReq[0], DestAddr->sa_family,
PowerState, SleepPeriod, RegistrationState);
if (szReq[0] == NULL) if (szReq[0] == NULL)
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
RetVal = NewRequestHandler(DestAddr, 1, szReq); RetVal = NewRequestHandler(DestAddr, 1, szReq);
@ -613,7 +671,8 @@ int ServiceReply(struct sockaddr *DestAddr, char *ServType, char *Udn,
} }
int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration, int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration,
int AddressFamily) int AddressFamily, int PowerState, int SleepPeriod,
int RegistrationState)
{ {
char Mil_Usn[LINE_SIZE]; char Mil_Usn[LINE_SIZE];
char *szReq[1]; char *szReq[1];
@ -643,7 +702,8 @@ int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration,
/* CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn, /* CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
* Server,Location,Duration); */ * Server,Location,Duration); */
CreateServicePacket(MSGTYPE_SHUTDOWN, ServType, Mil_Usn, CreateServicePacket(MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
Location, Duration, &szReq[0], AddressFamily); Location, Duration, &szReq[0], AddressFamily,
PowerState, SleepPeriod, RegistrationState);
if (szReq[0] == NULL) if (szReq[0] == NULL)
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
RetVal = NewRequestHandler((struct sockaddr *)&__ss, 1, szReq); RetVal = NewRequestHandler((struct sockaddr *)&__ss, 1, szReq);
@ -653,7 +713,8 @@ int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration,
} }
int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server, int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server,
char *Location, int Duration, int AddressFamily) char *Location, int Duration, int AddressFamily,
int PowerState, int SleepPeriod, int RegistrationState)
{ {
struct sockaddr_storage __ss; struct sockaddr_storage __ss;
struct sockaddr_in *DestAddr4 = (struct sockaddr_in *)&__ss; struct sockaddr_in *DestAddr4 = (struct sockaddr_in *)&__ss;
@ -686,16 +747,19 @@ int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server,
sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn); sprintf(Mil_Usn, "%s::upnp:rootdevice", Udn);
CreateServicePacket(MSGTYPE_SHUTDOWN, "upnp:rootdevice", CreateServicePacket(MSGTYPE_SHUTDOWN, "upnp:rootdevice",
Mil_Usn, Location, Duration, &msgs[0], Mil_Usn, Location, Duration, &msgs[0],
AddressFamily); AddressFamily, PowerState, SleepPeriod,
RegistrationState);
} }
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
"In function DeviceShutdown\n"); "In function DeviceShutdown\n");
/* both root and sub-devices need to send these two messages */ /* both root and sub-devices need to send these two messages */
CreateServicePacket(MSGTYPE_SHUTDOWN, Udn, Udn, CreateServicePacket(MSGTYPE_SHUTDOWN, Udn, Udn,
Location, Duration, &msgs[1], AddressFamily); Location, Duration, &msgs[1], AddressFamily,
PowerState, SleepPeriod, RegistrationState);
sprintf(Mil_Usn, "%s::%s", Udn, DevType); sprintf(Mil_Usn, "%s::%s", Udn, DevType);
CreateServicePacket(MSGTYPE_SHUTDOWN, DevType, Mil_Usn, CreateServicePacket(MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
Location, Duration, &msgs[2], AddressFamily); Location, Duration, &msgs[2], AddressFamily,
PowerState, SleepPeriod, RegistrationState);
/* check error */ /* check error */
if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) { if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) {
free(msgs[0]); free(msgs[0]);

View File

@ -2,6 +2,7 @@
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
* Copyright (C) 2011 France Telecom All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -205,26 +206,37 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
DeviceAdvertisement(devType, i == 0, DeviceAdvertisement(devType, i == 0,
UDNstr, UDNstr,
SInfo->DescURL, Exp, SInfo->DescURL, Exp,
SInfo->DeviceAf); SInfo->DeviceAf,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} else { } else {
/* AdFlag == -1 */ /* AdFlag == -1 */
DeviceShutdown(devType, i == 0, UDNstr, DeviceShutdown(devType, i == 0, UDNstr,
SERVER, SInfo->DescURL, SERVER, SInfo->DescURL,
Exp, SInfo->DeviceAf); Exp, SInfo->DeviceAf,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} }
} else { } else {
switch (SearchType) { switch (SearchType) {
case SSDP_ALL: case SSDP_ALL:
DeviceReply(DestAddr, devType, i == 0, DeviceReply(DestAddr, devType, i == 0,
UDNstr, SInfo->DescURL, UDNstr, SInfo->DescURL,
defaultExp); defaultExp, SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
break; break;
case SSDP_ROOTDEVICE: case SSDP_ROOTDEVICE:
if (i == 0) { if (i == 0) {
SendReply(DestAddr, devType, 1, SendReply(DestAddr, devType, 1,
UDNstr, UDNstr,
SInfo->DescURL, SInfo->DescURL,
defaultExp, 0); defaultExp, 0,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} }
break; break;
case SSDP_DEVICEUDN: { case SSDP_DEVICEUDN: {
@ -238,7 +250,10 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"DeviceUDN=%s and search UDN=%s MATCH\n", "DeviceUDN=%s and search UDN=%s MATCH\n",
UDNstr, DeviceUDN); UDNstr, DeviceUDN);
SendReply(DestAddr, devType, 0, UDNstr, SInfo->DescURL, defaultExp, 0); SendReply(DestAddr, devType, 0, UDNstr, SInfo->DescURL, defaultExp, 0,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
break; break;
} }
} }
@ -254,14 +269,20 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
"DeviceType=%s and search devType=%s MATCH\n", "DeviceType=%s and search devType=%s MATCH\n",
devType, DeviceType); devType, DeviceType);
SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->LowerDescURL, SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->LowerDescURL,
defaultExp, 1); defaultExp, 1,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} else if (atoi(strrchr(DeviceType, ':') + 1) } else if (atoi(strrchr(DeviceType, ':') + 1)
== atoi(&devType[strlen(devType) - 1])) { == atoi(&devType[strlen(devType) - 1])) {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"DeviceType=%s and search devType=%s MATCH\n", "DeviceType=%s and search devType=%s MATCH\n",
devType, DeviceType); devType, DeviceType);
SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->DescURL, SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->DescURL,
defaultExp, 1); defaultExp, 1,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} else { } else {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"DeviceType=%s and search devType=%s DID NOT MATCH\n", "DeviceType=%s and search devType=%s DID NOT MATCH\n",
@ -337,12 +358,18 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
if (AdFlag == 1) { if (AdFlag == 1) {
ServiceAdvertisement(UDNstr, ServiceAdvertisement(UDNstr,
servType, SInfo->DescURL, servType, SInfo->DescURL,
Exp, SInfo->DeviceAf); Exp, SInfo->DeviceAf,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} else { } else {
/* AdFlag == -1 */ /* AdFlag == -1 */
ServiceShutdown(UDNstr, ServiceShutdown(UDNstr,
servType, SInfo->DescURL, servType, SInfo->DescURL,
Exp, SInfo->DeviceAf); Exp, SInfo->DeviceAf,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} }
} else { } else {
switch (SearchType) { switch (SearchType) {
@ -350,7 +377,10 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
ServiceReply(DestAddr, servType, ServiceReply(DestAddr, servType,
UDNstr, UDNstr,
SInfo->DescURL, SInfo->DescURL,
defaultExp); defaultExp,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
break; break;
case SSDP_SERVICE: case SSDP_SERVICE:
if (ServiceType) { if (ServiceType) {
@ -364,14 +394,20 @@ int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd,
"ServiceType=%s and search servType=%s MATCH\n", "ServiceType=%s and search servType=%s MATCH\n",
ServiceType, servType); ServiceType, servType);
SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->LowerDescURL, SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->LowerDescURL,
defaultExp, 1); defaultExp, 1,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} else if (atoi(strrchr (ServiceType, ':') + 1) == } else if (atoi(strrchr (ServiceType, ':') + 1) ==
atoi(&servType[strlen(servType) - 1])) { atoi(&servType[strlen(servType) - 1])) {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"ServiceType=%s and search servType=%s MATCH\n", "ServiceType=%s and search servType=%s MATCH\n",
ServiceType, servType); ServiceType, servType);
SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->DescURL, SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->DescURL,
defaultExp, 1); defaultExp, 1,
SInfo->PowerState,
SInfo->SleepPeriod,
SInfo->RegistrationState);
} else { } else {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"ServiceType=%s and search servType=%s DID NOT MATCH\n", "ServiceType=%s and search servType=%s DID NOT MATCH\n",