48#include <umock/sys_socket.hpp>
50#ifndef COMPA_INTERNAL_CONFIG_HPP
51#error "No or wrong config.hpp header file included."
100 const char* command =
"M-SEARCH * HTTP/1.1\r\n";
101 const char* man =
"MAN: \"ssdp:discover\"\r\n";
103 memset(TempBuf, 0,
sizeof(TempBuf));
104 if (RqstBufSize <= strlen(command))
106 strcpy(RqstBuf, command);
108 switch (AddressFamily) {
110 rc = snprintf(TempBuf,
sizeof(TempBuf),
"HOST: %s:%d\r\n",
SSDP_IP,
114 rc = snprintf(TempBuf,
sizeof(TempBuf),
"HOST: [%s]:%d\r\n",
120 if (rc < 0 || (
unsigned int)rc >=
sizeof(TempBuf))
123 if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
125 strcat(RqstBuf, TempBuf);
127 if (RqstBufSize <= strlen(RqstBuf) + strlen(man))
129 strcat(RqstBuf, man);
132 rc = snprintf(TempBuf,
sizeof(TempBuf),
"MX: %d\r\n", Mx);
133 if (rc < 0 || (
unsigned int)rc >=
sizeof(TempBuf))
135 if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
137 strcat(RqstBuf, TempBuf);
140 if (SearchTarget != NULL) {
141 rc = snprintf(TempBuf,
sizeof(TempBuf),
"ST: %s\r\n", SearchTarget);
142 if (rc < 0 || (
unsigned int)rc >=
sizeof(TempBuf))
144 if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
146 strcat(RqstBuf, TempBuf);
148 if (RqstBufSize <= strlen(RqstBuf) + strlen(
"\r\n"))
150 strcat(RqstBuf,
"\r\n");
166#ifdef UPNP_ENABLE_IPV6
180 const char* command =
"M-SEARCH * HTTP/1.1\r\n";
181 const char* man =
"MAN: \"ssdp:discover\"\r\n";
183 memset(TempBuf, 0,
sizeof(TempBuf));
184 if (RqstBufSize <= strlen(command))
186 strcpy(RqstBuf, command);
187 switch (AddressFamily) {
189 rc = snprintf(TempBuf,
sizeof(TempBuf),
"HOST: %s:%d\r\n",
SSDP_IP,
193 rc = snprintf(TempBuf,
sizeof(TempBuf),
"HOST: [%s]:%d\r\n",
199 if (rc < 0 || (
unsigned int)rc >=
sizeof(TempBuf))
202 if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
204 strcat(RqstBuf, TempBuf);
206 if (RqstBufSize <= strlen(RqstBuf) + strlen(man))
208 strcat(RqstBuf, man);
211 rc = snprintf(TempBuf,
sizeof(TempBuf),
"MX: %d\r\n", Mx);
212 if (rc < 0 || (
unsigned int)rc >=
sizeof(TempBuf))
214 if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
216 strcat(RqstBuf, TempBuf);
219 rc = snprintf(TempBuf,
sizeof(TempBuf),
"ST: %s\r\n", SearchTarget);
220 if (rc < 0 || (
unsigned int)rc >=
sizeof(TempBuf))
222 if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
224 strcat(RqstBuf, TempBuf);
226 if (RqstBufSize <= strlen(RqstBuf) + strlen(
"\r\n"))
228 strcat(RqstBuf,
"\r\n");
259 ctrlpt_callback = ctrlpt_info->
Callback;
261 while (node != NULL) {
286 struct sockaddr_storage* dest_addr,
int timeout) {
316 goto end_ssdp_handle_ctrlpt_msg;
321 for (handle = handle_start; handle <
NUM_HANDLE; handle++) {
330 ctrlpt_callback = ctrlpt_info->
Callback;
331 ctrlpt_cookie = ctrlpt_info->
Cookie;
336 goto end_ssdp_handle_ctrlpt_msg;
348 goto end_ssdp_handle_ctrlpt_msg;
371 event.DeviceType[0] =
'\0';
372 event.ServiceType[0] =
'\0';
375 save_char = hdr_value.
buf[hdr_value.
length];
378 hdr_value.
buf[hdr_value.
length] = save_char;
382 save_char = hdr_value.
buf[hdr_value.
length];
385 hdr_value.
buf[hdr_value.
length] = save_char;
387 if (nt_found || usn_found) {
397 goto end_ssdp_handle_ctrlpt_msg;
399 if (
memptr_cmp(&hdr_value,
"ssdp:alive") == 0) {
401 }
else if (
memptr_cmp(&hdr_value,
"ssdp:byebye") == 0) {
405 goto end_ssdp_handle_ctrlpt_msg;
409 if (!nt_found || !usn_found) {
411 goto end_ssdp_handle_ctrlpt_msg;
419 if (!nt_found || !usn_found ||
423 goto end_ssdp_handle_ctrlpt_msg;
428 for (handle = handle_start; handle <
NUM_HANDLE; handle++) {
437 ctrlpt_callback = ctrlpt_info->
Callback;
438 ctrlpt_cookie = ctrlpt_info->
Cookie;
441 ctrlpt_callback(event_type, param, ctrlpt_cookie);
448 save_char = hdr_value.
buf[hdr_value.
length];
451 hdr_value.
buf[hdr_value.
length] = save_char;
456 !usn_found || !st_found) {
458 goto end_ssdp_handle_ctrlpt_msg;
461 for (handle = handle_start; handle <
NUM_HANDLE; handle++) {
470 ctrlpt_callback = ctrlpt_info->
Callback;
471 ctrlpt_cookie = ctrlpt_info->
Cookie;
477 while (node != NULL) {
493 size_t m = std::min(hdr_value.
length,
500 size_t m = std::min(hdr_value.
length,
513 if (threadData != NULL) {
519 memset(&job, 0,
sizeof(job));
540end_ssdp_handle_ctrlpt_msg:
550#ifdef UPNP_ENABLE_IPV6
554 struct sockaddr_storage __ss_v4;
555#ifdef UPNP_ENABLE_IPV6
556 struct sockaddr_storage __ss_v6;
558 struct sockaddr_in* destAddr4 = (
struct sockaddr_in*)&__ss_v4;
559#ifdef UPNP_ENABLE_IPV6
560 struct sockaddr_in6* destAddr6 = (
struct sockaddr_in6*)&__ss_v6;
565 int timeTillRead = 0;
568 struct in_addr addrv4;
576 !inet_pton(AF_INET,
gIF_IPV4, &addrv4)) {
580 memset(&job, 0,
sizeof(job));
585 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
"Inside SearchByTarget\n");
595#ifdef UPNP_ENABLE_IPV6
601 ReqBufv6UlaGua,
sizeof(ReqBufv6UlaGua), timeTillRead, St, AF_INET6);
606 memset(&__ss_v4, 0,
sizeof(__ss_v4));
607 destAddr4->sin_family = (sa_family_t)AF_INET;
608 inet_pton(AF_INET,
SSDP_IP, &destAddr4->sin_addr);
611#ifdef UPNP_ENABLE_IPV6
612 memset(&__ss_v6, 0,
sizeof(__ss_v6));
613 destAddr6->sin6_family = (sa_family_t)AF_INET6;
647 IP_MULTICAST_IF, (
char*)&addrv4,
652#ifdef UPNP_ENABLE_IPV6
661 ret = umock::sys_socket_h.select((
int)max_fd + 1, NULL, &wrSet, NULL, NULL);
664 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
665 "SSDP_LIB: Error in select(): %s\n", errorBuffer);
667#ifdef UPNP_ENABLE_IPV6
672#ifdef UPNP_ENABLE_IPV6
678 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
679 ">>> SSDP SEND M-SEARCH >>>\n%s\n", ReqBufv6UlaGua);
681 (SIZEP_T)strlen(ReqBufv6UlaGua), 0,
682 (
struct sockaddr*)&__ss_v6,
683 (SIZEP_T)
sizeof(
struct sockaddr_in6));
685 std::this_thread::sleep_for(std::chrono::milliseconds(
SSDP_PAUSE));
690 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
691 ">>> SSDP SEND M-SEARCH >>>\n%s\n", ReqBufv6);
693 (
struct sockaddr*)&__ss_v6,
694 (SIZEP_T)
sizeof(
struct sockaddr_in6));
696 std::this_thread::sleep_for(std::chrono::milliseconds(
SSDP_PAUSE));
704 UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
705 ">>> SSDP SEND M-SEARCH >>>\n%s\n", ReqBufv4);
707 (SIZEP_T)strlen(ReqBufv4), 0,
708 (
struct sockaddr*)&__ss_v4,
709 (SIZEP_T)
sizeof(
struct sockaddr_in));
711 std::this_thread::sleep_for(std::chrono::milliseconds(
SSDP_PAUSE));
enum Upnp_EventType_e Upnp_EventType
Old C stile quirks to make a symbol protected. Look at Upnp_EventType_e.
@ UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE
@ UPNP_DISCOVERY_ADVERTISEMENT_ALIVE
@ UPNP_DISCOVERY_SEARCH_TIMEOUT
int(* Upnp_FunPtr)(Upnp_EventType EventType, const void *Event, void *Cookie)
#define UPNP_E_BUFFER_TOO_SMALL
The operation completed successfully.
int is_request
If 1, msg is a request, else response.
#define HDR_USN
Type of a HTTP header.
#define HDR_DATE
Type of a HTTP header.
#define HDR_NT
Type of a HTTP header.
#define HDR_NTS
Type of a HTTP header.
#define HDR_EXT
Type of a HTTP header.
#define HDR_SERVER
Type of a HTTP header.
#define HDR_ST
Type of a HTTP header.
#define HDR_CACHE_CONTROL
Type of a HTTP header.
#define HDR_LOCATION
Type of a HTTP header.
#define HDR_USER_AGENT
Type of a HTTP header.
Structure of an HTTP message.
void * ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)
Removes a node from the list. The memory for the node is freed.
ListNode * ListNext(LinkedList *list, ListNode *node)
Returns the next item in the list.
ListNode * ListHead(LinkedList *list)
Returns the head of the list.
ListNode * ListAddTail(LinkedList *list, void *item)
Adds a node to the tail of the list. Node gets added immediately before list.tail.
Linked list node. Stores generic item and pointers to next and prev.
void SSDPResultData_Callback(const SSDPResultData *p)
SSDP result data callback function.
SSDPResultData object declararion.
int SSDPResultData_set_Cookie(SSDPResultData *p, void *n)
SSDPResultData_set_Cookie.
int SSDPResultData_set_CtrlptCallback(SSDPResultData *p, Upnp_FunPtr n)
SSDPResultData_set_CtrlptCallback.
void SSDPResultData_delete(SSDPResultData *q)
Destructor.
int SSDPResultData_set_Param(SSDPResultData *p, const UpnpDiscovery *s)
SSDPResultData_set_Param.
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.
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.
PUPNP_Api int UpnpDiscovery_strcpy_DeviceType(UpnpDiscovery *p, const char *s)
PUPNP_Api void UpnpDiscovery_delete(UpnpDiscovery *p)
PUPNP_Api int UpnpDiscovery_strncpy_Location(UpnpDiscovery *p, const char *s, size_t n)
PUPNP_Api UpnpDiscovery * UpnpDiscovery_new(void)
PUPNP_Api int UpnpDiscovery_strcpy_ServiceType(UpnpDiscovery *p, const char *s)
PUPNP_Api int UpnpDiscovery_set_ErrCode(UpnpDiscovery *p, int n)
PUPNP_Api int UpnpDiscovery_strcpy_DeviceID(UpnpDiscovery *p, const char *s)
PUPNP_Api int UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, const struct sockaddr_storage *buf)
PUPNP_Api int UpnpDiscovery_get_Expires(const UpnpDiscovery *p)
PUPNP_Api const UpnpString * UpnpDiscovery_get_Location(const UpnpDiscovery *p)
PUPNP_Api int UpnpDiscovery_set_Expires(UpnpDiscovery *p, int n)
PUPNP_Api int UpnpDiscovery_strncpy_Ext(UpnpDiscovery *p, const char *s, size_t n)
PUPNP_Api int UpnpDiscovery_strncpy_Os(UpnpDiscovery *p, const char *s, size_t n)
PUPNP_Api int UpnpDiscovery_strcpy_Date(UpnpDiscovery *p, const char *s)
#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...
#define MAX_SEARCH_TIME
The MAX_SEARCH_TIME is the maximum time allowed for an SSDP search by a control point....
#define MIN_SEARCH_TIME
The MIN_SEARCH_TIME is the minimumm time allowed for an SSDP search by a control point....
"protected" structure, addressable with typedef
int ssdp_request_type(char *cmd, SsdpEvent *Evt)
Starts filling the SSDP event structure based upon the request received.
SsdpSearchType ssdp_request_type1(char *cmd)
This function figures out the type of the SSDP search in the request.
SSDPResultData * SSDPResultData_new(void)
Constructor.
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, struct sockaddr_storage *dest_addr, int timeout)
This function handles the ssdp messages from the devices.
PUPNP_Api size_t UpnpString_get_Length(const UpnpString *p)
Returns the length of the string.
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'.
parse_status_t matchstr(char *str, size_t slen, const char *fmt,...)
Matches a variable parameter list with a string and takes actions based on the data type specified.
int memptr_cmp(memptr *m, const char *s)
Compares characters of strings passed for number of bytes. If equal for the number of bytes,...
size_t length
length of memory without terminating '\0' (read-only).
char * buf
start of memory (read/write).
pointer to a chunk of memory.
#define UPNP_E_INVALID_ARGUMENT
One or more of the parameters passed to a function is invalid.
#define UPNP_E_SUCCESS
The operation completed successfully.
#define UPNP_E_INVALID_PARAM
One or more of the parameters passed to the function is not valid.
#define UPNP_E_INTERNAL_ERROR
Generic error code for internal conditions not covered by other error codes.
int CreateClientRequestPacketUlaGua(char *RqstBuf, size_t RqstBufSize, int Mx, char *SearchTarget, int AddressFamily)
Creates a HTTP search request packet for IPv6 UlaGua depending on the input parameter.
int CreateClientRequestPacket(char *RqstBuf, size_t RqstBufSize, int Mx, char *SearchTarget, int AddressFamily)
Creates a HTTP search request packet depending on the input parameter.
void send_search_result(void *data)
Sends a callback to the control point application with a SEARCH result.
void searchExpired(void *arg)
Remove search Target from list and call client back.
#define SSDP_PORT
constant
#define COMMAND_LEN
constant
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 timeoutEventId
timeout event id
#define SSDP_IPV6_LINKLOCAL
constant
char DeviceType[LINE_SIZE]
Part of SSDP Event.
SOCKET gSsdpReqSocket6
If control point API is compiled in, this is the global IPv6 socket for it.
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.
SSDP search exp argument.
int SearchByTarget(int Hnd, int Mx, char *St, void *Cookie)
Creates and send the search request for a specific URL.
Manage "Step 1: Discovery" of the UPnP+™ specification for Control Points with SSDP.
int timeoutEventId
part of search argument
enum SsdpSearchType requestType
part of search argument
void * cookie
part of search argument
char * searchTarget
part of search argument
Upnp_Handle_Type GetHandleInfo(UpnpClient_Handle Hnd, Handle_Info **HndInfo)
Get handle information.
ThreadPool gRecvThreadPool
Receive thread pool.
char gIF_IPV4[INET_ADDRSTRLEN]
IPv4 buffer to contain interface address. (extern'ed in upnp.h)
TimerThread gTimerThread
Global timer thread.
unsigned gIF_INDEX
Index/scope-id from the used network interface.
Upnp_Handle_Type GetClientHandleInfo(UpnpClient_Handle *client_handle_out, struct Handle_Info **HndInfo)
Get client handle info.
Inititalize the compatible library before it can be used.
#define HandleLock()
HandleLock.
#define HandleUnlock()
HandleUnlock.
Upnp_FunPtr Callback
Callback function pointer.
constexpr int NUM_HANDLE
Maximal number of available UPnP Unit handles.
LinkedList SsdpSearchList
Active SSDP searches.
#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.