47#ifndef COMPA_SSDP_COMMON_HPP
48#error "No or wrong ssdp_common.hpp header file included."
50#ifndef COMPA_INTERNAL_CONFIG_HPP
51#error "No or wrong config.hpp header file included."
54#include <umock/sys_socket.hpp>
55#include <umock/pupnp_sock.hpp>
57#include <umock/winsock2.hpp>
111 (
memptr_cmp(&hdr_value,
"239.255.255.250:1900") != 0 &&
112 memptr_cmp(&hdr_value,
"[FF02::C]:1900") != 0 &&
113 memptr_cmp(&hdr_value,
"[ff02::c]:1900") != 0 &&
114 memptr_cmp(&hdr_value,
"[FF05::C]:1900") != 0 &&
115 memptr_cmp(&hdr_value,
"[ff05::c]:1900") != 0)) {
116 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
117 "Invalid HOST header from SSDP message\n");
148 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
149 "SSDP recvd bad msg code = %u\n", status);
155 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
156 "SSDP recvd bad msg code = %u\n", status);
188#ifdef COMPA_HAVE_CTRLPT_SSDP
192#ifdef COMPA_HAVE_DEVICE_SSDP
215 UPnPsdk_LOGINFO(
"MSG1075")
"Executing...\n";
217 u_char ttl = (u_char)4;
218 ip_mreq ssdpMcastAddr;
219 sockaddr_storage __ss;
220 sockaddr_in* ssdpAddr4 = (
struct sockaddr_in*)&__ss;
225 *ssdpSock = umock::sys_socket_h.socket(AF_INET, SOCK_DGRAM, 0);
226 if (*ssdpSock == INVALID_SOCKET) {
228 UPnPsdk_LOGCRIT(
"MSG1076")
"Error in socket(): "
233 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_REUSEADDR,
234 (
char*)&onOff,
sizeof(onOff));
237 UPnPsdk_LOGCRIT(
"MSG1077")
"Error in setsockopt() SO_REUSEADDR: "
242#if (defined(BSD) && !defined(__GNU__)) || defined(__APPLE__)
244 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_REUSEPORT,
245 (
char*)&onOff,
sizeof(onOff));
248 UPnPsdk_LOGCRIT(
"MSG1078")
"Error in setsockopt() SO_REUSEP: "
254 memset(&__ss, 0,
sizeof(__ss));
255 ssdpAddr4->sin_family = (sa_family_t)AF_INET;
256 ssdpAddr4->sin_addr.s_addr = htonl(INADDR_ANY);
258 ret = umock::sys_socket_h.bind(*ssdpSock, (sockaddr*)ssdpAddr4,
262 UPnPsdk_LOGCRIT(
"MSG1079")
"Error in bind(), addr="
263 << INADDR_ANY <<
", port=" <<
SSDP_PORT <<
": "
279 memset((
void*)&ssdpMcastAddr, 0,
sizeof ssdpMcastAddr);
280 inet_pton(AF_INET,
gIF_IPV4, &ssdpMcastAddr.imr_interface);
281 inet_pton(AF_INET,
SSDP_IP, &ssdpMcastAddr.imr_multiaddr);
282 ret = umock::sys_socket_h.setsockopt(
283 *ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
char*)&ssdpMcastAddr,
284 sizeof(
struct ip_mreq));
287 UPnPsdk_LOGCRIT(
"MSG1080")
"Error in setsockopt() IP_ADD_MEMBERSHIP "
288 "(join multicast group): "
294 memset((
void*)&addr, 0,
sizeof(
struct in_addr));
295 inet_pton(AF_INET,
gIF_IPV4, &addr);
296 ret = umock::sys_socket_h.setsockopt(*ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
297 (
char*)&addr,
sizeof addr);
300 UPnPsdk_LOGINFO(
"MSG1081")
"Error in setsockopt() IP_MULTICAST_IF (set "
301 "multicast interface): "
306 umock::sys_socket_h.setsockopt(*ssdpSock, IPPROTO_IP, IP_MULTICAST_TTL,
307 (
const char*)&ttl,
sizeof(ttl));
309 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_BROADCAST,
310 (
char*)&onOff,
sizeof(onOff));
314 "MSG1082")
"Error in setsockopt() SO_BROADCAST (set broadcast): "
323 umock::unistd_h.CLOSE_SOCKET_P(*ssdpSock);
329#if defined(COMPA_HAVE_CTRLPT_SSDP) || defined(DOXYGEN_RUN)
340 SOCKET* ssdpReqSock) {
341 UPnPsdk_LOGINFO(
"MSG1071")
"Executing...\n";
345 *ssdpReqSock = umock::sys_socket_h.socket(AF_INET, SOCK_DGRAM, 0);
346 if (*ssdpReqSock == INVALID_SOCKET) {
348 UPnPsdk_LOGCRIT(
"MSG1072")
"Error in socket(): "
352 umock::sys_socket_h.setsockopt(*ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
353 (
const char*)&ttl,
sizeof(ttl));
355 int ret = umock::pupnp_sock.sock_make_no_blocking(*ssdpReqSock);
356 if (ret == SOCKET_ERROR)
358 UPnPsdk_LOGCRIT(
"MSG1090")
"SSDP Request Socket "
360 <<
" failed to set \"no blocking\" but continue...\n";
366#ifdef UPNP_ENABLE_IPV6
377 SOCKET* ssdpReqSock) {
378 UPnPsdk_LOGINFO(
"MSG1073")
"Executing...\n";
382 *ssdpReqSock = umock::sys_socket_h.socket(AF_INET6, SOCK_DGRAM, 0);
383 if (*ssdpReqSock == INVALID_SOCKET) {
385 UPnPsdk_LOGCRIT(
"MSG1074")
"Error in socket(): "
392 umock::sys_socket_h.setsockopt(*ssdpReqSock, IPPROTO_IPV6,
393 IPV6_MULTICAST_HOPS, &hops,
sizeof(hops));
395 umock::pupnp_sock.sock_make_no_blocking(*ssdpReqSock);
402#ifdef UPNP_ENABLE_IPV6
417 UPnPsdk_LOGINFO(
"MSG1083")
"Executing...\n";
419 ipv6_mreq ssdpMcastAddr;
420 sockaddr_storage __ss;
421 sockaddr_in6* ssdpAddr6 = (
struct sockaddr_in6*)&__ss;
425 *ssdpSock = umock::sys_socket_h.socket(AF_INET6, SOCK_DGRAM, 0);
426 if (*ssdpSock == INVALID_SOCKET) {
428 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
429 "Error in socket(): %s\n", errorBuffer);
434 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_REUSEADDR,
435 (
char*)&onOff,
sizeof(onOff));
438 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
439 "Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer);
443#if (defined(BSD) && !defined(__GNU__)) || defined(__APPLE__)
445 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_REUSEPORT,
446 (
char*)&onOff,
sizeof(onOff));
449 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
450 "Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer);
456 ret = umock::sys_socket_h.setsockopt(*ssdpSock, IPPROTO_IPV6, IPV6_V6ONLY,
457 (
char*)&onOff,
sizeof(onOff));
460 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
461 "Error in setsockopt() IPV6_V6ONLY: %s\n", errorBuffer);
465 memset(&__ss, 0,
sizeof(__ss));
466 ssdpAddr6->sin6_family = (sa_family_t)AF_INET6;
467 ssdpAddr6->sin6_addr = in6addr_any;
472 ret = umock::sys_socket_h.bind(*ssdpSock, (
struct sockaddr*)ssdpAddr6,
477 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
478 "Error in bind(), addr=%s, index=%u, port=%d: %s\n",
483 int wsa_err = umock::winsock2_h.WSAGetLastError();
484 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
485 "Error in bind(), addr=%s, index=%u, port=%d: %d\n",
491 memset((
void*)&ssdpMcastAddr, 0,
sizeof(ssdpMcastAddr));
492 ssdpMcastAddr.ipv6mr_interface =
gIF_INDEX;
494 ret = umock::sys_socket_h.setsockopt(*ssdpSock, IPPROTO_IPV6,
495 IPV6_JOIN_GROUP, (
char*)&ssdpMcastAddr,
496 sizeof(ssdpMcastAddr));
499 uint32_t* p = (uint32_t*)&ssdpMcastAddr.ipv6mr_multiaddr;
500 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
501 "Error in setsockopt() IPV6_JOIN_GROUP (join multicast "
503 "SSDP_IPV6_LINKLOCAL = %s,\n"
504 "ipv6mr_interface = %u,\n"
505 "ipv6mr_multiaddr[0,1,2,3] = "
506 "0x%08X:0x%08X:0x%08X:0x%08X\n"
509 ssdpMcastAddr.ipv6mr_interface, p[0], p[1], p[2], p[3],
515 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_BROADCAST,
516 (
char*)&onOff,
sizeof(onOff));
519 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
520 "Error in setsockopt() SO_BROADCAST (set broadcast): "
530 umock::unistd_h.CLOSE_SOCKET_P(*ssdpSock);
537#ifdef UPNP_ENABLE_IPV6
552 UPnPsdk_LOGINFO(
"MSG1084")
"Executing...\n";
554 ipv6_mreq ssdpMcastAddr;
558 *ssdpSock = umock::sys_socket_h.socket(AF_INET6, SOCK_DGRAM, 0);
559 if (*ssdpSock == INVALID_SOCKET) {
561 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
562 "Error in socket(): %s\n", errorBuffer);
567 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_REUSEADDR,
568 (
char*)&onOff,
sizeof(onOff));
571 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
572 "Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer);
576#if (defined(BSD) && !defined(__GNU__)) || defined(__APPLE__)
578 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_REUSEPORT,
579 (
char*)&onOff,
sizeof(onOff));
582 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
583 "Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer);
589 ret = umock::sys_socket_h.setsockopt(*ssdpSock, IPPROTO_IPV6, IPV6_V6ONLY,
590 (
char*)&onOff,
sizeof(onOff));
593 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
594 "Error in setsockopt() IPV6_V6ONLY: %s\n", errorBuffer);
601 saddr.sin6.sin6_family = AF_INET6;
602 saddr.sin6.sin6_addr = in6addr_any;
607 umock::sys_socket_h.bind(*ssdpSock, &saddr.sa,
sizeof(saddr.sin6));
610 UPnPsdk_LOGERR(
"MSG1134")
"in ::bind() with addr=\"[::]:"
611 <<
SSDP_PORT <<
"\": (" << serrObj <<
") "
617 memset((
void*)&ssdpMcastAddr, 0,
sizeof(ssdpMcastAddr));
618 ssdpMcastAddr.ipv6mr_interface =
gIF_INDEX;
621 ret = umock::sys_socket_h.setsockopt(*ssdpSock, IPPROTO_IPV6,
622 IPV6_JOIN_GROUP, (
char*)&ssdpMcastAddr,
623 sizeof(ssdpMcastAddr));
626 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
627 "Error in setsockopt() IPV6_JOIN_GROUP (join multicast "
634 ret = umock::sys_socket_h.setsockopt(*ssdpSock, SOL_SOCKET, SO_BROADCAST,
635 (
char*)&onOff,
sizeof(onOff));
638 UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
639 "Error in setsockopt() SO_BROADCAST (set broadcast): "
649 umock::unistd_h.CLOSE_SOCKET_P(*ssdpSock);
662 char* TempPtr = NULL;
667 int CommandFound = 0;
668 size_t n = (size_t)0;
670 if (strstr(cmd,
"uuid:schemas") != NULL) {
671 ptr1 = strstr(cmd,
":device");
673 ptr2 = strstr(ptr1 + 1,
":");
677 ptr3 = strstr(ptr2 + 1,
":");
681 if (strlen(
"uuid:") + strlen(ptr3 + 1) >=
sizeof Evt->
UDN)
683 snprintf(Evt->
UDN,
sizeof Evt->
UDN,
"uuid:%s", ptr3 + 1);
686 ptr1 = strstr(cmd,
":");
688 n = (size_t)ptr3 - (
size_t)ptr1;
689 n = n >=
sizeof TempBuf ?
sizeof TempBuf - 1 : n;
690 strncpy(TempBuf, ptr1, n);
692 if (strlen(
"urn") + strlen(TempBuf) >=
sizeof(Evt->
DeviceType))
700 if ((TempPtr = strstr(cmd,
"uuid")) != NULL) {
701 if ((Ptr = strstr(cmd,
"::")) != NULL) {
702 n = (size_t)Ptr - (
size_t)TempPtr;
703 n = n >=
sizeof Evt->
UDN ?
sizeof Evt->
UDN - 1 : n;
704 strncpy(Evt->
UDN, TempPtr, n);
707 memset(Evt->
UDN, 0,
sizeof(Evt->
UDN));
708 strncpy(Evt->
UDN, TempPtr,
sizeof Evt->
UDN - 1);
712 if (strstr(cmd,
"urn:") != NULL && strstr(cmd,
":service:") != NULL) {
713 if ((TempPtr = strstr(cmd,
"urn")) != NULL) {
719 if (strstr(cmd,
"urn:") != NULL && strstr(cmd,
":device:") != NULL) {
720 if ((TempPtr = strstr(cmd,
"urn")) != NULL) {
726 if ((TempPtr = strstr(cmd,
"::upnp:rootdevice")) != NULL) {
728 if (TempPtr != cmd) {
729 n = (size_t)TempPtr - (
size_t)cmd;
730 n = n >=
sizeof Evt->
UDN ?
sizeof Evt->
UDN - 1 : n;
731 strncpy(Evt->
UDN, cmd, n);
736 if (CommandFound == 0)
743 if (strstr(cmd,
":all"))
745 if (strstr(cmd,
":rootdevice"))
747 if (strstr(cmd,
"uuid:"))
749 if (strstr(cmd,
"urn:") && strstr(cmd,
":device:"))
751 if (strstr(cmd,
"urn:") && strstr(cmd,
":service:"))
770 TRACE(
"Executing readFromSSDPSocket()")
773 char* requestBuf = staticBuf;
780#ifdef COMPA_HAVE_CTRLPT_SSDP
797 struct sockaddr_storage __ss;
798 socklen_t socklen =
sizeof(__ss);
799 ssize_t byteReceived = umock::sys_socket_h.recvfrom(
800 socket, requestBuf,
BUFSIZE - 1, 0,
reinterpret_cast<sockaddr*
>(&__ss),
802 if (byteReceived > 0) {
803 requestBuf[byteReceived] =
'\0';
804 char ntop_buf[INET6_ADDRSTRLEN];
806 switch (__ss.ss_family) {
808 inet_ntop(AF_INET, &((
struct sockaddr_in*)&__ss)->sin_addr,
809 ntop_buf,
sizeof(ntop_buf));
812 inet_ntop(AF_INET6, &((
struct sockaddr_in6*)&__ss)->sin6_addr,
813 ntop_buf,
sizeof(ntop_buf));
816 memset(ntop_buf, 0,
sizeof(ntop_buf));
817 strncpy(ntop_buf,
"<Invalid address family>",
sizeof(ntop_buf) - 1);
820 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
821 "\nStart of received response ----------------------------------------------------\n"
823 "End of received response ------------------------------------------------------\n"
824 "From host %s\n", requestBuf, ntop_buf);
828 if (data !=
nullptr) {
833 memcpy(&data->
dest_addr, &__ss,
sizeof(__ss));
847 return (byteReceived < 0) ? -1 : 0;
853 UPnPsdk_LOGINFO(
"MSG1057")
"Executing...\n";
855#if defined(COMPA_HAVE_CTRLPT_SSDP) || defined(DOXYGEN_RUN)
868#ifdef UPNP_ENABLE_IPV6
885#ifdef COMPA_HAVE_CTRLPT_SSDP
893#ifdef UPNP_ENABLE_IPV6
898 umock::unistd_h.CLOSE_SOCKET_P(out->
ssdpSock4);
899#ifdef COMPA_HAVE_CTRLPT_SSDP
910 umock::unistd_h.CLOSE_SOCKET_P(out->
ssdpSock4);
911 umock::unistd_h.CLOSE_SOCKET_P(out->
ssdpSock6);
912#ifdef COMPA_HAVE_CTRLPT_SSDP
http_message_t msg
entire raw message
uri_type uri
Type of a uri, e.g. absolute, relative, etc.
http_method_t method
Http method of an outgoing request.
http_method_t
Method in a HTTP request.
membuffer msg
entire raw message.
#define HDR_HOST
Type of a HTTP header.
http_method_t request_method
Http method of an incoming response.
parse_status_t
Status of parsing.
int valid_ssdp_notify_hack
read-only; this is set to 1 if a NOTIFY request has no content-length. used to read valid sspd notify...
Structure of an HTTP parser object.
Structure of an HTTP message.
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
Adds a job to the thread pool.
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func)
Sets the jobs free function.
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority)
Sets the priority of the threadpool job.
int TPJobInit(ThreadPoolJob *job, UPnPsdk::start_routine func, void *arg)
Initializes thread pool job.
@ Relative
The URI is relative, means it hasn't a 'scheme' component.
size_t size
Size of the buffer.
token pathquery
Member variable.
uriType type
Member variable.
Class for portable handling of network socket errors.
void catch_error()
Catch error for later use.
std::string error_str() const
Get human readable error description of the catched error.
int unique_service_name(char *cmd, SsdpEvent *Evt)
Fills the fields of the event structure like DeviceType, Device UDN and Service Type.
void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, sockaddr_storage *dest_addr, int timeout)
This function handles the ssdp messages from the devices.
Helpful union of the different socket address structures.
parse_status_t parser_parse(http_parser_t *parser)
The parser function.
void parser_request_init(http_parser_t *parser)
Initializes parser object for a request.
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'.
void parser_response_init(http_parser_t *parser, http_method_t request_method)
Initializes parser object for a response.
void httpmsg_destroy(http_message_t *msg)
Free memory allocated for the http message.
int memptr_cmp(memptr *m, const char *s)
Compares characters of strings passed for number of bytes. If equal for the number of bytes,...
int membuffer_set_size(membuffer *m, size_t new_length)
Increases or decreases buffer cap so that at least 'new_length' bytes can be stored.
size_t length
length of buffer without terminating null byte (read-only).
char * buf
mem buffer; must not write beyond buf[length-1] (read/write).
pointer to a chunk of memory.
#define UPNP_E_SOCKET_ERROR
Generic socket error code for conditions not covered by other error codes.
#define UPNP_E_NETWORK_ERROR
A network error occurred.
#define UPNP_E_SOCKET_BIND
The SDK had a problem binding a socket to a network interface.
#define UPNP_E_SUCCESS
The operation completed successfully.
#define UPNP_E_OUTOF_SOCKET
The SDK cannot create any more sockets.
SOCKET ssdpSock4
IPv4 SSDP datagram Socket for incoming advertisments and search requests.
SOCKET ssdpReqSock6
IPv6 SSDP socket for sending search requests and receiving search replies.
SOCKET ssdpReqSock4
IPv4 SSDP socket for sending search requests and receiving search replies.
SOCKET ssdpSock6
IPv6 LLA SSDP Socket for incoming advertisments and search requests.
SOCKET ssdpSock6UlaGua
IPv6 ULA or GUA SSDP Socket for incoming advertisments and search requests.
Provides sockets for all network communications.
int create_ssdp_sock_v6(SOCKET *ssdpSock)
Create an SSDP IPv6 socket.
void free_ssdp_event_handler_data(void *the_data)
Frees the ssdp request.
int create_ssdp_sock_v4(SOCKET *ssdpSock)
Create an SSDP IPv4 socket.
int start_event_handler(void *Data)
Parses the message and dispatches it to a handler which handles the ssdp request msg.
void ssdp_event_handler_thread(void *the_data)
This function is a thread that handles SSDP requests.
int valid_ssdp_msg(http_message_t *hmsg)
Does some quick checking of the ssdp msg.
int create_ssdp_sock_v6_ula_gua(SOCKET *ssdpSock)
Create an SSDP IPv6 ULA_GUA socket.
int create_ssdp_sock_reqv6(SOCKET *ssdpReqSock)
Creates the SSDP IPv6 socket to be used by the control point.
int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock)
Creates the SSDP IPv4 socket to be used by the control point.
int ssdp_request_type(char *cmd, SsdpEvent *Evt)
Starts filling the SSDP event structure based upon the request received.
int get_ssdp_sockets(MiniServerSockArray *out)
Creates the IPv4 and IPv6 ssdp sockets required by the control point and device operation.
SsdpSearchType ssdp_request_type1(char *cmd)
This function figures out the type of the SSDP search in the request.
int readFromSSDPSocket(SOCKET socket)
This function reads the data from the ssdp socket.
#define SSDP_PORT
constant
sockaddr_storage dest_addr
destination socket address
char UDN[LINE_SIZE]
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
char ServiceType[LINE_SIZE]
Part of SSDP Event.
int ErrCode
Part of SSDP Event.
#define SSDP_IPV6_LINKLOCAL
constant
char DeviceType[LINE_SIZE]
Part of SSDP Event.
#define E_HTTP_SYNTEX
error code
http_parser_t parser
parser
SOCKET gSsdpReqSocket6
If control point API is compiled in, this is the global IPv6 socket for it.
enum SsdpSearchType RequestType
Part of SSDP Event.
#define NO_ERROR_FOUND
error code
SOCKET gSsdpReqSocket4
If control point API is compiled in, this is the global IPv4 socket for it.
SsdpSearchType
Enumeration to define all different types of ssdp searches.
@ SSDP_SERROR
Unknown search command.
@ 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.
Manage "Step 1: Discovery" of the UPnP+™ specification for Control Points with SSDP.
Manage "Step 1: Discovery" of the UPnP+™ specification for UPnP Devices with SSDP.
void ssdp_handle_device_request(http_message_t *hmsg, struct sockaddr_storage *dest_addr)
Handles the search request.
char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN]
IPv6 GUA buffer to contain interface IPv6 global-unicast address.
ThreadPool gRecvThreadPool
Receive thread pool.
char gIF_IPV4[INET_ADDRSTRLEN]
IPv4 buffer to contain interface address. (extern'ed in upnp.h)
char gIF_NAME[LINE_SIZE]
Buffer to contain used network interface name. (extern'ed in upnp.h)
unsigned gIF_INDEX
Index/scope-id from the used network interface.
char gIF_IPV6[INET6_ADDRSTRLEN]
IPv6 LLA buffer to contain interface address. (extern'ed in upnp.h)
Inititalize the compatible library before it can be used.
UPnPsdk_VIS void UpnpPrintf(Upnp_LogLevel DLevel, Dbg_Module Module, const char *DbgFileName, int DbgLineNo, const char *FmtStr,...)
Prints the debug statement.