45#include <httpreadwrite.hpp>
48#include <webserver.hpp>
50#include <umock/sys_socket.hpp>
52#ifndef COMPA_INTERNAL_CONFIG_HPP
53#error "No or wrong config.hpp header file included."
91 struct sockaddr* DestAddr,
98 socklen_t socklen =
sizeof(
struct sockaddr_storage);
100 struct in_addr replyAddr;
103#ifdef UPNP_ENABLE_IPV6
106 char buf_ntop[INET6_ADDRSTRLEN];
110 !inet_pton(AF_INET,
gIF_IPV4, &replyAddr)) {
115 umock::sys_socket_h.socket((
int)DestAddr->sa_family, SOCK_DGRAM, 0);
116 if (ReplySock == INVALID_SOCKET) {
118 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
119 "SSDP_LIB: New Request Handler:"
120 "Error in socket(): %s\n",
126 switch (DestAddr->sa_family) {
128 inet_ntop(AF_INET, &((
struct sockaddr_in*)DestAddr)->sin_addr, buf_ntop,
130 umock::sys_socket_h.setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
131 (
char*)&replyAddr,
sizeof(replyAddr));
132 umock::sys_socket_h.setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
133 (
char*)&ttl,
sizeof(
int));
134 socklen =
sizeof(
struct sockaddr_in);
136#ifdef UPNP_ENABLE_IPV6
138 inet_ntop(AF_INET6, &((
struct sockaddr_in6*)DestAddr)->sin6_addr,
139 buf_ntop,
sizeof(buf_ntop));
140 umock::sys_socket_h.setsockopt(ReplySock, IPPROTO_IPV6,
143 umock::sys_socket_h.setsockopt(ReplySock, IPPROTO_IPV6,
144 IPV6_MULTICAST_HOPS, (
char*)&hops,
149 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
150 "Invalid destination address specified.");
152 goto end_NewRequestHandler;
155 for (Index = 0; Index < NumPacket; Index++) {
157 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
158 ">>> SSDP SEND to %s >>>\n%s\n", buf_ntop,
159 *(RqPacket + Index));
160 rc = sendto(ReplySock, *(RqPacket + Index),
161 (SIZEP_T)strlen(*(RqPacket + Index)), 0, DestAddr,
165 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
166 "SSDP_LIB: New Request Handler:"
167 "Error in socket(): %s\n",
170 goto end_NewRequestHandler;
174end_NewRequestHandler:
175 umock::unistd_h.CLOSE_SOCKET_P(ReplySock);
193 while (url[i] !=
'[' && url[i] !=
'\0') {
196 if (url[i] ==
'\0') {
202 while (url[i] !=
'\0' && url[i] !=
']') {
207 if (url[i] ==
'\0') {
229 char address[INET6_ADDRSTRLEN];
230 struct in6_addr v6_addr;
233 inet_pton(AF_INET6, address, &v6_addr);
234 return !IN6_IS_ADDR_LINKLOCAL(&v6_addr);
267 int RegistrationState) {
279 if (PowerState > 0) {
280#ifdef COMPA_HAVE_OPTION_SSDP
297 HTTP_OK,
"CACHE-CONTROL: max-age=", duration,
298 "EXT:",
"LOCATION: ", location,
299 "OPT: ",
"\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
301 "USN: ", usn,
"Powerstate: ", PowerState,
302 "SleepPeriod: ", SleepPeriod,
303 "RegistrationState: ", RegistrationState);
318 HTTP_OK,
"CACHE-CONTROL: max-age=", duration,
319 "EXT:",
"LOCATION: ", location,
"ST: ", nt,
"USN: ", usn,
320 "Powerstate: ", PowerState,
"SleepPeriod: ", SleepPeriod,
321 "RegistrationState: ", RegistrationState);
324#ifdef COMPA_HAVE_OPTION_SSDP
338 HTTP_OK,
"CACHE-CONTROL: max-age=", duration,
339 "EXT:",
"LOCATION: ", location,
340 "OPT: ",
"\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
354 HTTP_OK,
"CACHE-CONTROL: max-age=", duration,
355 "EXT:",
"LOCATION: ", location,
"ST: ", nt,
"USN: ", usn);
363 const char* host = NULL;
372 switch (AddressFamily) {
382 if (PowerState > 0) {
383#ifdef COMPA_HAVE_OPTION_SSDP
400 HTTPMETHOD_NOTIFY,
"*", (
size_t)1,
"HOST: ", host,
":",
401 SSDP_PORT,
"CACHE-CONTROL: max-age=", duration,
402 "LOCATION: ", location,
403 "OPT: ",
"\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
406 "SleepPeriod: ", SleepPeriod,
407 "RegistrationState: ", RegistrationState);
422 HTTPMETHOD_NOTIFY,
"*", (
size_t)1,
"HOST: ", host,
":",
423 SSDP_PORT,
"CACHE-CONTROL: max-age=", duration,
424 "LOCATION: ", location,
"NT: ", nt,
"NTS: ", nts,
"USN: ", usn,
425 "Powerstate: ", PowerState,
"SleepPeriod: ", SleepPeriod,
426 "RegistrationState: ", RegistrationState);
429#ifdef COMPA_HAVE_OPTION_SSDP
443 HTTPMETHOD_NOTIFY,
"*", (
size_t)1,
"HOST: ", host,
":",
444 SSDP_PORT,
"CACHE-CONTROL: max-age=", duration,
445 "LOCATION: ", location,
446 "OPT: ",
"\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
460 HTTPMETHOD_NOTIFY,
"*", (
size_t)1,
"HOST: ", host,
":",
461 SSDP_PORT,
"CACHE-CONTROL: max-age=", duration,
462 "LOCATION: ", location,
"NT: ", nt,
"NTS: ", nts,
"USN: ", usn);
482 struct sockaddr_storage* dest_addr) {
483 constexpr int MX_FUDGE_FACTOR{10};
496 memset(&job, 0,
sizeof(job));
500 memptr_cmp(&hdr_value,
"\"ssdp:discover\"") != 0)
510 save_char = hdr_value.
buf[hdr_value.
length];
514 hdr_value.
buf[hdr_value.
length] = save_char;
532 maxAge = dev_info->
MaxAge;
535 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"MAX-AGE = %d\n",
537 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"MX = %d\n",
539 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"DeviceType = %s\n",
541 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"DeviceUuid = %s\n",
543 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"ServiceType = %s\n",
546 if (threadArg == NULL)
548 threadArg->
handle = handle;
550 threadArg->
event = event;
551 threadArg->
MaxAge = maxAge;
560 mx -= std::max(1, mx / MX_FUDGE_FACTOR);
563 replyTime = rand() % mx;
573 struct sockaddr_storage __ss;
574 struct sockaddr_in* DestAddr4 = (
struct sockaddr_in*)&__ss;
575 struct sockaddr_in6* DestAddr6 = (
struct sockaddr_in6*)&__ss;
582 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
583 "In function DeviceAdvertisement\n");
584 memset(&__ss, 0,
sizeof(__ss));
585 switch (AddressFamily) {
587 DestAddr4->sin_family = (sa_family_t)AF_INET;
588 inet_pton(AF_INET,
SSDP_IP, &DestAddr4->sin_addr);
592 DestAddr6->sin6_family = (sa_family_t)AF_INET6;
596 &DestAddr6->sin6_addr);
601 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
602 "Invalid device address family.\n");
609 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::upnp:rootdevice", Udn);
610 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
613 Location,
Duration, &msgs[0], AddressFamily,
614 PowerState, SleepPeriod, RegistrationState);
618 &msgs[1], AddressFamily, PowerState, SleepPeriod,
620 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, DevType);
621 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
624 Duration, &msgs[2], AddressFamily, PowerState,
625 SleepPeriod, RegistrationState);
627 if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) {
649int SendReply(
struct sockaddr* DestAddr,
char* DevType,
int RootDev,
char* Udn,
650 char* Location,
int Duration,
int ByType,
int PowerState,
651 int SleepPeriod,
int RegistrationState) {
665 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::upnp:rootdevice", Udn);
666 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
669 Duration, &msgs[0], (
int)DestAddr->sa_family,
670 PowerState, SleepPeriod, RegistrationState);
678 &msgs[0], (
int)DestAddr->sa_family, PowerState,
679 SleepPeriod, RegistrationState);
681 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, DevType);
682 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
685 Duration, &msgs[0], (
int)DestAddr->sa_family,
686 PowerState, SleepPeriod, RegistrationState);
690 for (i = 0; i < num_msgs; i++) {
691 if (msgs[i] == NULL) {
699 for (i = 0; i < num_msgs; i++) {
707int DeviceReply(
struct sockaddr* DestAddr,
char* DevType,
int RootDev,
708 char* Udn,
char* Location,
int Duration,
int PowerState,
709 int SleepPeriod,
int RegistrationState) {
720 memset(Mil_Nt, 0,
sizeof(Mil_Nt));
721 strncpy(Mil_Nt,
"upnp:rootdevice",
sizeof(Mil_Nt) - 1);
722 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::upnp:rootdevice", Udn);
723 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
726 &szReq[0], (
int)DestAddr->sa_family, PowerState,
727 SleepPeriod, RegistrationState);
729 rc = snprintf(Mil_Nt,
sizeof(Mil_Nt),
"%s", Udn);
730 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Nt))
732 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s", Udn);
733 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
736 &szReq[1], (
int)DestAddr->sa_family, PowerState,
737 SleepPeriod, RegistrationState);
738 rc = snprintf(Mil_Nt,
sizeof(Mil_Nt),
"%s", DevType);
739 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Nt))
741 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, DevType);
742 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
745 &szReq[2], (
int)DestAddr->sa_family, PowerState,
746 SleepPeriod, RegistrationState);
748 if ((RootDev && szReq[0] == NULL) || szReq[1] == NULL || szReq[2] == NULL) {
768 int Duration,
int AddressFamily,
int PowerState,
769 int SleepPeriod,
int RegistrationState) {
773 struct sockaddr_storage __ss;
774 struct sockaddr_in* DestAddr4 = (
struct sockaddr_in*)&__ss;
775 struct sockaddr_in6* DestAddr6 = (
struct sockaddr_in6*)&__ss;
778 memset(&__ss, 0,
sizeof(__ss));
780 switch (AddressFamily) {
782 DestAddr4->sin_family = (sa_family_t)AddressFamily;
783 inet_pton(AF_INET,
SSDP_IP, &DestAddr4->sin_addr);
787 DestAddr6->sin6_family = (sa_family_t)AddressFamily;
791 &DestAddr6->sin6_addr);
796 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
797 "Invalid device address family.\n");
799 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, ServType);
800 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
805 Duration, &szReq[0], AddressFamily, PowerState,
806 SleepPeriod, RegistrationState);
807 if (szReq[0] == NULL) {
819 char* Location,
int Duration,
int PowerState,
int SleepPeriod,
820 int RegistrationState) {
827 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, ServType);
828 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
831 &szReq[0], (
int)DestAddr->sa_family, PowerState,
832 SleepPeriod, RegistrationState);
833 if (szReq[0] == NULL)
844 int AddressFamily,
int PowerState,
int SleepPeriod,
845 int RegistrationState) {
848 struct sockaddr_storage __ss;
849 struct sockaddr_in* DestAddr4 = (
struct sockaddr_in*)&__ss;
850 struct sockaddr_in6* DestAddr6 = (
struct sockaddr_in6*)&__ss;
854 memset(&__ss, 0,
sizeof(__ss));
856 switch (AddressFamily) {
858 DestAddr4->sin_family = (sa_family_t)AddressFamily;
859 inet_pton(AF_INET,
SSDP_IP, &DestAddr4->sin_addr);
863 DestAddr6->sin6_family = (sa_family_t)AddressFamily;
867 &DestAddr6->sin6_addr);
872 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
873 "Invalid device address family.\n");
876 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, ServType);
877 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
882 &szReq[0], AddressFamily, PowerState, SleepPeriod,
884 if (szReq[0] == NULL)
895 int Duration,
int AddressFamily,
int PowerState,
896 int SleepPeriod,
int RegistrationState) {
897 struct sockaddr_storage __ss;
898 struct sockaddr_in* DestAddr4 = (
struct sockaddr_in*)&__ss;
899 struct sockaddr_in6* DestAddr6 = (
struct sockaddr_in6*)&__ss;
908 memset(&__ss, 0,
sizeof(__ss));
909 switch (AddressFamily) {
911 DestAddr4->sin_family = (sa_family_t)AddressFamily;
912 inet_pton(AF_INET,
SSDP_IP, &DestAddr4->sin_addr);
916 DestAddr6->sin6_family = (sa_family_t)AddressFamily;
920 &DestAddr6->sin6_addr);
925 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
926 "Invalid device address family.\n");
930 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::upnp:rootdevice", Udn);
931 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
934 Location,
Duration, &msgs[0], AddressFamily,
935 PowerState, SleepPeriod, RegistrationState);
937 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
938 "In function DeviceShutdown\n");
941 &msgs[1], AddressFamily, PowerState, SleepPeriod,
943 rc = snprintf(Mil_Usn,
sizeof(Mil_Usn),
"%s::%s", Udn, DevType);
944 if (rc < 0 || (
unsigned int)rc >=
sizeof(Mil_Usn))
947 &msgs[2], AddressFamily, PowerState, SleepPeriod,
950 if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) {
974 char* DeviceType,
char* DeviceUDN,
char* ServiceType,
976 constexpr char SERVICELIST_STR[] =
"serviceList";
994 memset(UDNstr, 0,
sizeof(UDNstr));
995 memset(devType, 0,
sizeof(devType));
996 memset(servType, 0,
sizeof(servType));
999 "Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag);
1007 defaultExp = SInfo->
MaxAge;
1009 while (NumCopy == 0 || (AdFlag && NumCopy <
NUM_SSDP_COPY)) {
1011 std::this_thread::sleep_for(std::chrono::milliseconds(
SSDP_PAUSE));
1013 for (i = 0lu;; i++) {
1014 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1015 "Entering new device list with i = %lu\n\n", i);
1018 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1019 "Exiting new device list with i = "
1025 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1026 "Extracting device type once for %s\n", dbgStr);
1032 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1033 "Extracting UDN for %s\n", dbgStr);
1034 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1035 "Extracting device type\n");
1042 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1043 "Extracting device type \n");
1047 strncpy(devType, tmpStr,
sizeof(devType) - 1);
1048 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1049 "Extracting device type = %s\n", devType);
1051 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1052 "TempNode is NULL\n");
1055 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1056 "Extracting UDN for %s\n", dbgStr);
1061 UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
1062 "UDN not found!\n");
1067 UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
1068 "UDN not found!\n");
1073 UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
1074 "UDN not found!\n");
1079 UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
1080 "UDN not found!\n");
1083 strncpy(UDNstr, tmpStr,
sizeof(UDNstr) - 1);
1084 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1085 "Sending UDNStr = %s \n", UDNstr);
1101 switch (SearchType) {
1116 if (DeviceUDN && strlen(DeviceUDN) != (
size_t)0) {
1117 if (strcasecmp(DeviceUDN, UDNstr)) {
1118 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1119 "DeviceUDN=%s and search UDN=%s DID NOT match\n",
1122 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1123 "DeviceUDN=%s and search UDN=%s MATCH\n",
1136 if (!strncasecmp(DeviceType, devType, strlen(DeviceType) - (
size_t)2)) {
1137 if (atoi(strrchr(DeviceType,
':') + 1)
1138 < atoi(&devType[strlen(devType) - (
size_t)1])) {
1142 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1143 "DeviceType=%s and search devType=%s MATCH\n",
1144 devType, DeviceType);
1150 }
else if (atoi(strrchr(DeviceType,
':') + 1)
1151 == atoi(&devType[strlen(devType) - (
size_t)1])) {
1152 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1153 "DeviceType=%s and search devType=%s MATCH\n",
1154 devType, DeviceType);
1161 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1162 "DeviceType=%s and search devType=%s DID NOT MATCH\n",
1163 devType, DeviceType);
1166 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1167 "DeviceType=%s and search devType=%s DID NOT MATCH\n",
1168 devType, DeviceType);
1179 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1180 "Sending service Advertisement\n");
1188 if (!strncmp(dbgStr, SERVICELIST_STR,
sizeof SERVICELIST_STR)) {
1201 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1202 "Service not found 3\n");
1205 for (j = 0lu;; j++) {
1214 UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
1215 "ServiceType not found \n");
1229 strncpy(servType, tmpStr,
sizeof(servType) - 1);
1230 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1231 "ServiceType = %s\n", servType);
1235 UDNstr, servType, SInfo->
DescURL, Exp,
1246 switch (SearchType) {
1256 if (!strncasecmp(ServiceType, servType, strlen(ServiceType) - (
size_t)2)) {
1257 if (atoi(strrchr(ServiceType,
':') + 1) <
1258 atoi(&servType[strlen(servType) - (
size_t)1])) {
1262 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1263 "ServiceType=%s and search servType=%s MATCH\n",
1264 ServiceType, servType);
1270 }
else if (atoi(strrchr (ServiceType,
':') + 1) ==
1271 atoi(&servType[strlen(servType) - (
size_t)1])) {
1272 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1273 "ServiceType=%s and search servType=%s MATCH\n",
1274 ServiceType, servType);
1281 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1282 "ServiceType=%s and search servType=%s DID NOT MATCH\n",
1283 ServiceType, servType);
1286 UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
1287 "ServiceType=%s and search servType=%s DID NOT MATCH\n",
1288 ServiceType, servType);
1308 UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
1309 "Exiting AdvertiseAndReply.\n");
int UpnpDevice_Handle
Returned when a device application registers with UpnpRegisterRootDevice(),UpnpRegisterRootDevice2(),...
int http_MakeMessage(membuffer *buf, int http_major_version, int http_minor_version, const char *fmt,...)
Generate an HTTP message based on the format that is specified in the input parameters.
#define HDR_MX
Type of a HTTP header.
#define HDR_ST
Type of a HTTP header.
#define HDR_MAN
Type of a HTTP header.
Structure of an HTTP message.
#define X_USER_AGENT
Can be overwritten by configure CFLAGS argument.
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func)
Sets the jobs free function.
int TPJobInit(ThreadPoolJob *job, UPnPsdk::start_routine func, void *arg)
Initializes thread pool job.
void(* free_routine)(void *arg)
int TimerThreadSchedule(TimerThread *timer, time_t timeout, TimeoutType type, ThreadPoolJob *job, Duration duration, int *id)
Schedules an event to run at a specified time.
@ REL_SEC
seconds from current time.
#define NUM_SSDP_COPY
This configuration parameter determines how many copies of each SSDP advertisement and search packets...
#define SSDP_PAUSE
This configuration parameter determines the pause between identical SSDP advertisement and search pac...
int ssdp_request_type(char *cmd, SsdpEvent *Evt)
Starts filling the SSDP event structure based upon the request received.
int AdvertiseAndReply(int AdFlag, UpnpDevice_Handle Hnd, enum SsdpSearchType SearchType, struct sockaddr *DestAddr, char *DeviceType, char *DeviceUDN, char *ServiceType, int Exp)
Sends SSDP advertisements, replies and shutdown messages.
Data structure common to all types of nodes.
Data structure representing a list of nodes.
Data structure representing an Element node.
#define DOMString
The type of DOM strings.
PUPNP_Api IXML_Node * ixmlNode_getNextSibling(IXML_Node *nodeptr)
Retrieves the sibling Node immediately following this Node.
PUPNP_Api const DOMString ixmlNode_getNodeValue(IXML_Node *nodeptr)
Returns the value of the Node as a string.
PUPNP_Api const DOMString ixmlNode_getNodeName(IXML_Node *nodeptr)
Returns the name of the Node, depending on what type of Node it is, in a read-only string.
PUPNP_Api void ixmlNodeList_free(IXML_NodeList *nList)
Frees a NodeList object.
PUPNP_Api IXML_Node * ixmlNode_getFirstChild(IXML_Node *nodeptr)
Retrieves the first child Node of a Node.
PUPNP_Api IXML_Node * ixmlNodeList_item(IXML_NodeList *nList, unsigned long index)
Retrieves a Node from a NodeList specified by a numerical index.
PUPNP_Api IXML_NodeList * ixmlElement_getElementsByTagName(IXML_Element *element, const DOMString tagName)
Returns a NodeList of all descendant Elements with a given tag name, in the order in which they are e...
http_header_t * httpmsg_find_hdr(http_message_t *msg, int header_name_id, memptr *value)
Finds header from a list, with the given 'name_id'.
int raw_to_int(memptr *raw_value, int base)
Converts raw character data to integer value.
int memptr_cmp(memptr *m, const char *s)
Compares characters of strings passed for number of bytes. If equal for the number of bytes,...
void membuffer_destroy(membuffer *m)
Free's memory allocated for membuffer* m.
void membuffer_init(membuffer *m)
Wrapper to membuffer_initialize().
char * membuffer_detach(membuffer *m)
Detaches current buffer and returns it. The caller must free the returned buffer using free()....
size_t size_inc
used to increase size; MUST be > 0; (read/write).
size_t length
length of memory (read-only).
char * buf
start of memory (read/write).
pointer to a chunk of memory.
Maintains a block of dynamically allocated memory.
#define UPNP_E_NETWORK_ERROR
A network error occurred.
#define UPNP_E_INVALID_HANDLE
The handle passed to a function is not a recognized as a valid handle.
#define UPNP_E_SUCCESS
The operation completed successfully.
#define UPNP_E_OUTOF_SOCKET
The SDK cannot create any more sockets.
#define UPNP_E_OUTOF_MEMORY
Not enough resources are currently available to complete the operation.
#define UPNP_E_SOCKET_WRITE
An error happened while writing to a socket.
#define UPNP_E_INVALID_PARAM
One or more of the parameters passed to the function is not valid.
int NewRequestHandler(struct sockaddr *DestAddr, int NumPacket, char **RqPacket)
Works as a request handler which passes the HTTP request string to multicast channel.
int extractIPv6address(char *url, char *address)
Extract IPv6 address.
constexpr int MSGTYPE_REPLY
Message type.
constexpr int MSGTYPE_SHUTDOWN
Message type.
void CreateServicePacket(int msg_type, const char *nt, char *usn, char *location, int duration, char **packet, int AddressFamily, int PowerState, int SleepPeriod, int RegistrationState)
Creates a HTTP request packet.
constexpr int MSGTYPE_ADVERTISEMENT
Message type.
int isUrlV6UlaGua(char *descdocUrl)
Test if a Url contains an ULA or GUA IPv6 address.
#define SSDP_PORT
constant
struct sockaddr_storage dest_addr
part of search reply
char UDN[LINE_SIZE]
Part of SSDP Event.
int Mx
Part of SSDP Event.
constexpr size_t ERROR_BUFFER_LEN
Size of the errorBuffer variable, passed to the strerror_r() function.
#define SSDP_IPV6_SITELOCAL
constant
UpnpDevice_Handle handle
part of search reply
char ServiceType[LINE_SIZE]
Part of SSDP Event.
#define SSDP_IPV6_LINKLOCAL
constant
char DeviceType[LINE_SIZE]
Part of SSDP Event.
int MaxAge
part of search reply
enum SsdpSearchType RequestType
Part of SSDP Event.
SsdpEvent event
part of search reply
SsdpSearchType
Enumeration to define all different types of ssdp searches.
@ SSDP_DEVICEUDN
Part of SType.
@ SSDP_DEVICETYPE
Part of SType.
@ SSDP_ROOTDEVICE
Part of SType.
@ SSDP_SERVICE
Part of SType.
Structure to store the SSDP information.
int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev, char *Udn, char *Location, int Duration, int PowerState, int SleepPeriod, int RegistrationState)
Creates the reply packet and send it to the Control Point address.
int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location, int Duration, int AddressFamily, int PowerState, int SleepPeriod, int RegistrationState)
Creates the device advertisement request.
int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *Location, int Duration, int AddressFamily, int PowerState, int SleepPeriod, int RegistrationState)
Creates a HTTP device shutdown request packet and send it to the multicast channel through RequestHan...
void ssdp_handle_device_request(http_message_t *hmsg, struct sockaddr_storage *dest_addr)
Handles the search request.
void advertiseAndReplyThread(void *data)
Wrapper function to reply the search request coming from the control point.
int ServiceAdvertisement(char *Udn, char *ServType, char *Location, int Duration, int AddressFamily, int PowerState, int SleepPeriod, int RegistrationState)
Creates the advertisement packet and send it to the multicast channel.
int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration, int AddressFamily, int PowerState, int SleepPeriod, int RegistrationState)
Creates a HTTP service shutdown request packet and sends it to the multicast channel through RequestH...
int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev, char *Udn, char *Location, int Duration, int ByType, int PowerState, int SleepPeriod, int RegistrationState)
Creates the reply packet and send it to the Control Point addesss.
int ServiceReply(struct sockaddr *DestAddr, char *ServType, char *Udn, char *Location, int Duration, int PowerState, int SleepPeriod, int RegistrationState)
Creates the advertisement packet and send it to the multicast channel.
Manage "Step 1: Discovery" of the UPnP+™ specification for UPnP Devices with SSDP.
Upnp_Handle_Type GetHandleInfo(UpnpClient_Handle Hnd, Handle_Info **HndInfo)
Get handle information.
Upnp_SID gUpnpSdkNLSuuid
Global variable used in discovery notifications.
Upnp_Handle_Type GetDeviceHandleInfo(UpnpDevice_Handle start, int AddressFamily, UpnpDevice_Handle *device_handle_out, struct Handle_Info **HndInfo)
Retrieves the device handle and information of the first device of the address family specified....
char gIF_IPV4[INET_ADDRSTRLEN]
Static buffer to contain interface IPv4 address. (extern'ed in upnp.h)
TimerThread gTimerThread
Global timer thread.
unsigned gIF_INDEX
Contains network interface index of the link local address gIF_IPV6 that is used as its scope_id.
Inititalize the compatible library before it can be used.
#define HandleLock()
HandleLock.
#define DEFAULT_MAXAGE
DEFAULT_MAXAGE.
int SleepPeriod
Sleep Period as defined by UPnP Low Power.
char LowerDescURL[LINE_SIZE]
URL for the use of SSDP when answering to legacy CPs (CP searching for a v1 when the device is v2).
int RegistrationState
Registration State as defined by UPnP Low Power.
char DescURL[LINE_SIZE]
URL for the use of SSDP.
#define HandleUnlock()
HandleUnlock.
int PowerState
Power State as defined by UPnP Low Power.
IXML_NodeList * DeviceList
List of devices in the description document.
int MaxAge
Advertisement timeout.
int DeviceAf
Address family: AF_INET6 or AF_INET.
#define HandleReadLock()
HandleReadLock.
Data to be stored in handle table for Handle Info.
UPnPsdk_VIS void UpnpPrintf(Upnp_LogLevel DLevel, Dbg_Module Module, const char *DbgFileName, int DbgLineNo, const char *FmtStr,...)
Prints the debug statement.