41#include <httpreadwrite.hpp>
83 int send_callback = 0;
89 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA SUB EXPIRED");
94 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA AUTO RENEW");
109 if (
GetHandleInfo(arg->handle, &handle_info) != HND_CLIENT) {
114 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
"HANDLE IS VALID");
117 callback_fun = handle_info->
Callback;
118 cookie = handle_info->
Cookie;
147 memset(&job, 0,
sizeof(job));
155 if (RenewEvent == NULL) {
166 memset(arg, 0,
sizeof(
job_arg));
176 arg->handle = client_handle;
177 arg->Event = RenewEvent;
186 &job, SHORT_TERM, &(arg->eventId));
221 if (return_code != 0) {
232 HTTPMETHOD_UNSUBSCRIBE, &dest_url,
236 if (return_code != 0) {
244 &dest_url, request.
buf, request.
length, HTTPMETHOD_UNSUBSCRIBE,
247 if (return_code != 0) {
279 char timeout_str[25];
288 if (timeout == NULL) {
289 timeout = &local_timeout;
292 memset(timeout_str, 0,
sizeof(timeout_str));
293 strncpy(timeout_str,
"infinite",
sizeof(timeout_str) - 1);
295 rc = snprintf(timeout_str,
sizeof(timeout_str),
"%d",
298 rc = snprintf(timeout_str,
sizeof(timeout_str),
"%d", *timeout);
300 if (rc < 0 || (
unsigned int)rc >=
sizeof(timeout_str))
306 if (return_code != 0) {
320 HTTPMETHOD_SUBSCRIBE, &dest_url,
322 "TIMEOUT: Second-", timeout_str);
326 struct sockaddr_in6* DestAddr6 =
334 HTTPMETHOD_SUBSCRIBE, &dest_url,
"CALLBACK: <http://[",
335 (IN6_IS_ADDR_LINKLOCAL(&DestAddr6->sin6_addr) ||
340 (IN6_IS_ADDR_LINKLOCAL(&DestAddr6->sin6_addr) ||
344 "/>",
"NT: upnp:event",
"TIMEOUT: Second-", timeout_str);
352 HTTPMETHOD_SUBSCRIBE, &dest_url,
"CALLBACK: <http://",
gIF_IPV4,
353 ":",
LOCAL_PORT_V4,
"/>",
"NT: upnp:event",
"TIMEOUT: Second-",
357 if (return_code != 0) {
363 request.
length, HTTPMETHOD_SUBSCRIBE,
367 if (return_code != 0) {
382 timeout_hdr.
length == 0) {
416 pthread_mutexattr_t attr;
418 int ret = pthread_mutexattr_init(&attr);
421 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
423 pthread_mutexattr_destroy(&attr);
440 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
458 if (return_code == 0) {
481 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
498 if (return_code == 0) {
504 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
530 memset(temp_sid, 0,
sizeof(temp_sid));
531 memset(temp_sid2, 0,
sizeof(temp_sid2));
533 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA SUBSCRIBE BEGIN");
540 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
544 UPnPsdk_LOGCRIT(
"MSG1099")
"POSIX thread mutex lock fails with "
545 << (ret == EINVAL ?
"EINVAL" :
"EDEADLK") <<
".\n";
553 UPnPsdk_LOGCRIT(
"MSG1138")
"POSIX thread mutex lock fails with "
554 << (ret == EINVAL ?
"EINVAL" :
"EDEADLK") <<
".\n";
555 return_code =
gena_subscribe(PublisherURL, TimeOut, NULL, ActualSID);
558 UpnpPrintf(UPNP_CRITICAL, GENA, __FILE__, __LINE__,
559 "SUBSCRIBE FAILED in transfer error code: %d "
565 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
573 rc = snprintf(temp_sid2,
sizeof(temp_sid2),
"uuid:%s", temp_sid);
574 if (rc < 0 || (
unsigned int)rc >=
sizeof(temp_sid2)) {
584 if (newSubscription == NULL) {
608 UPnPsdk_LOGCRIT(
"MSG1139")
"POSIX thread mutex unlock fails with "
609 << (ret == EINVAL ?
"EINVAL" :
"EPERM") <<
".\n";
626 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
645 tempJob.free_func(tempJob.arg);
648 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
649 "REMOVED AUTO RENEW EVENT");
662 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
716 int err_ret = HTTP_PRECONDITION_FAILED;
746 memptr_cmp(&nts_hdr,
"upnp:propchange") != 0) {
769 for (client_handle = client_handle_start; client_handle <
NUM_HANDLE;
774 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
798 "MSG1140")
"POSIX thread mutex lock fails with "
799 << (ret == EINVAL ?
"EINVAL" :
"EDEADLK") <<
".\n";
804 if (
GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
808 "MSG1141")
"POSIX thread mutex unlock fails with "
809 << (ret == EINVAL ?
"EINVAL" :
"EPERM") <<
".\n";
820 "MSG1142")
"POSIX thread mutex unlock fails with "
821 << (ret == EINVAL ?
"EINVAL" :
"EPERM") <<
".\n";
829 "MSG1143")
"POSIX thread mutex unlock fails with "
830 << (ret == EINVAL ?
"EINVAL" :
"EPERM") <<
".\n";
848 cookie = handle_info->
Cookie;
enum Upnp_EventType_e Upnp_EventType
Old C stile quirks to make a symbol protected. Look at Upnp_EventType_e.
@ UPNP_EVENT_AUTORENEWAL_FAILED
@ UPNP_EVENT_SUBSCRIPTION_EXPIRED
int(* Upnp_FunPtr)(Upnp_EventType EventType, const void *Event, void *Cookie)
char Upnp_SID[44]
Holds the subscription identifier for a subscription between a client and a device.
int UpnpClient_Handle
Returned when a control point application registers with UpnpRegisterClient().
int http_RequestAndResponse(uri_type *destination, const char *request, size_t request_length, http_method_t req_method, int timeout_secs, http_parser_t *response)
Initiates socket, connects to the remote host, sends a request and waits for the response from the re...
int http_FixStrUrl(const char *urlstr, size_t urlstrlen, uri_type *fixed_url)
Parses URL and then validates URL.
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.
http_message_t msg
entire raw message
memptr entity
message body(entity).
#define HDR_NT
Type of a HTTP header.
#define HDR_NTS
Type of a HTTP header.
membuffer msg
entire raw message.
#define HDR_SEQ
Type of a HTTP header.
#define HDR_TIMEOUT
Type of a HTTP header.
#define HDR_SID
Type of a HTTP header.
Structure of an HTTP parser object.
Structure of an HTTP message.
#define HTTP_DEFAULT_TIMEOUT
hostport_type hostport
Member variable.
size_t size
Size of the buffer.
sockaddr_storage IPaddress
Network socket address.
Represents a URI used in parse_uri and elsewhere.
Buffer used in parsinghttp messages, urls, etc. Generally this simply holds a pointer into a larger a...
int GenlibClientSubscription_set_RenewEventId(GenlibClientSubscription *p, int n)
int GenlibClientSubscription_set_ActualSID(GenlibClientSubscription *p, const UpnpString *s)
int GenlibClientSubscription_set_Next(GenlibClientSubscription *p, GenlibClientSubscription *n)
int GenlibClientSubscription_set_EventURL(GenlibClientSubscription *p, const UpnpString *s)
const UpnpString * GenlibClientSubscription_get_ActualSID(const GenlibClientSubscription *p)
GenlibClientSubscription * GenlibClientSubscription_new()
int GenlibClientSubscription_set_SID(GenlibClientSubscription *p, const UpnpString *s)
int GenlibClientSubscription_assign(GenlibClientSubscription *p, const GenlibClientSubscription *q)
const UpnpString * GenlibClientSubscription_get_EventURL(const GenlibClientSubscription *p)
const UpnpString * GenlibClientSubscription_get_SID(const GenlibClientSubscription *p)
int GenlibClientSubscription_get_RenewEventId(const GenlibClientSubscription *p)
void GenlibClientSubscription_delete(GenlibClientSubscription *q)
Genlib Client subscription.
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.
int TimerThreadRemove(TimerThread *timer, int id, ThreadPoolJob *out)
Removes an event from the timer Q.
@ REL_SEC
seconds from current time.
PUPNP_Api int UpnpEventSubscribe_set_ErrCode(UpnpEventSubscribe *p, int n)
PUPNP_Api UpnpEventSubscribe * UpnpEventSubscribe_new(void)
PUPNP_Api int UpnpEventSubscribe_set_SID(UpnpEventSubscribe *p, const UpnpString *s)
PUPNP_Api const UpnpString * UpnpEventSubscribe_get_SID(const UpnpEventSubscribe *p)
PUPNP_Api int UpnpEventSubscribe_get_TimeOut(const UpnpEventSubscribe *p)
PUPNP_Api int UpnpEventSubscribe_set_TimeOut(UpnpEventSubscribe *p, int n)
PUPNP_Api void UpnpEventSubscribe_delete(UpnpEventSubscribe *p)
PUPNP_Api int UpnpEventSubscribe_set_PublisherUrl(UpnpEventSubscribe *p, const UpnpString *s)
PUPNP_Api UpnpEvent * UpnpEvent_new(void)
PUPNP_Api int UpnpEvent_set_EventKey(UpnpEvent *p, int n)
PUPNP_Api int UpnpEvent_set_ChangedVariables(UpnpEvent *p, IXML_Document *n)
PUPNP_Api int UpnpEvent_set_SID(UpnpEvent *p, const UpnpString *s)
PUPNP_Api void UpnpEvent_delete(UpnpEvent *p)
void free_client_subscription(GenlibClientSubscription *sub)
Free memory allocated for client subscription data.
GenlibClientSubscription * GetClientSubClientSID(GenlibClientSubscription *head, const UpnpString *sid)
Return the client subscription from the client table that matches const Upnp_SID sid subscrition id v...
void RemoveClientSubClientSID(GenlibClientSubscription **head, const UpnpString *sid)
Remove the client subscription matching the subscritpion id represented by the const Upnp_SID sid par...
void freeClientSubList(GenlibClientSubscription *list)
Free the client subscription table.
GenlibClientSubscription * GetClientSubActualSID(GenlibClientSubscription *head, token *sid)
Returns the client subscription from the client subscription table that has the matching token *sid b...
#define AUTO_RENEW_TIME
The AUTO_RENEW_TIME is the time, in seconds, before a subscription expires that the SDK automatically...
#define CP_MINIMUM_SUBSCRIPTION_TIME
The CP_MINIMUM_SUBSCRIPTION_TIME is the minimum subscription time allowed for a control point using t...
Manage Eventing with GENA, the General Event Notification Architecture.
#define GENA_E_BAD_HANDLE
void error_respond(SOCKINFO *info, int error_code, http_message_t *hmsg)
Sends an error message to the control point in the case of incorrect GENA requests.
int clientSubscribeMutexInit()
Initialize the client subsribe mutex.
int genaUnregisterClient(UpnpClient_Handle client_handle)
Unsubcribes all the outstanding subscriptions and cleans the subscription list.
void gena_process_notification_event(SOCKINFO *info, http_message_t *event)
This function processes NOTIFY events that are sent by devices.
int genaUnSubscribe(UpnpClient_Handle client_handle, const UpnpString *in_sid)
Unsubscribes a SID.
int genaSubscribe(UpnpClient_Handle client_handle, const UpnpString *PublisherURL, int *TimeOut, UpnpString *out_sid)
This function subscribes to a PublisherURL (also mentioned as EventURL in some places).
int clientSubscribeMutexDestroy()
Destroy the client subsribe mutex.
int genaRenewSubscription(UpnpClient_Handle client_handle, const UpnpString *in_sid, int *TimeOut)
Renews a SID.
Internal implementation of the class UpnpString.
PUPNP_Api int UpnpString_set_StringN(UpnpString *p, const char *s, size_t n)
Sets the string from a pointer to char using a maximum of N chars.
PUPNP_Api int UpnpString_set_String(UpnpString *p, const char *s)
Sets the string from a pointer to char.
PUPNP_Api size_t UpnpString_get_Length(const UpnpString *p)
Returns the length of the string.
PUPNP_Api UpnpString * UpnpString_new(void)
Constructor.
PUPNP_Api const char * UpnpString_get_String(const UpnpString *p)
Returns the pointer to char.
PUPNP_Api void UpnpString_delete(UpnpString *p)
Destructor.
PUPNP_Api void UpnpString_assign(UpnpString *p, const UpnpString *q)
Assignment operator.
PUPNP_Api void UpnpString_clear(UpnpString *p)
Clears the string, sets its size to zero.
Data structure representing the DOM Document.
PUPNP_Api int ixmlParseBufferEx(const char *buffer, IXML_Document **doc)
Parses an XML text buffer converting it into an IXML DOM representation.
PUPNP_Api void ixmlDocument_free(IXML_Document *doc)
Frees a Document object and all Nodes associated with it.
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 httpmsg_destroy(http_message_t *msg)
Free memory allocated for the http message.
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,...
void membuffer_destroy(membuffer *m)
Free's memory allocated for membuffer* m.
void membuffer_init(membuffer *m)
Wrapper to membuffer_initialize().
int memptr_cmp_nocase(memptr *m, const char *s)
Compares characters of 2 strings irrespective of the case for a specific count of bytes.
size_t size_inc
used to increase size; MUST be > 0; (read/write).
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).
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_SUCCESS
The operation completed successfully.
#define UPNP_E_SUBSCRIBE_UNACCEPTED
A subscription request was rejected from the remote side.
#define UPNP_E_OUTOF_MEMORY
Not enough resources are currently available to complete the operation.
#define UPNP_E_UNSUBSCRIBE_UNACCEPTED
An unsubscribe request was rejected from the remote side.
#define UPNP_E_BAD_RESPONSE
The response received from the remote side of a connection is not correct for the protocol.
void GenaAutoRenewSubscription(void *input)
This is a thread function to send the renewal just before the subscription times out.
void free_subscribe_arg(job_arg *arg)
Free memory associated with job's argument.
int ScheduleGenaAutoRenew(int client_handle, int TimeOut, GenlibClientSubscription *sub)
Schedules a job to renew the subscription just before time out.
int gena_subscribe(const UpnpString *url, int *timeout, const UpnpString *renewal_sid, UpnpString *sid)
Subscribes or renew subscription.
pthread_mutex_t ctrlpntSubscribe_mutex
Mutex to synchronize the subscription handling at the control point side.
int gena_unsubscribe(const UpnpString *url, const UpnpString *sid, http_parser_t *response)
Sends the UNSUBCRIBE gena request and recieves the response from the device and returns it as a param...
Additional socket information for connections and ssl.
in_port_t LOCAL_PORT_V6_ULA_GUA
IPv6 ULA or GUA port for the mini-server.
Upnp_Handle_Type GetHandleInfo(UpnpClient_Handle Hnd, Handle_Info **HndInfo)
Get handle information.
char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN]
Static buffer to contain interface IPv6 unique-local or globally-unique address (ULA or GUA)....
in_port_t LOCAL_PORT_V6
IPv6 LLA port for the mini-server.
in_port_t LOCAL_PORT_V4
local IPv4 port for the mini-server
char gIF_IPV4[INET_ADDRSTRLEN]
Static buffer to contain interface IPv4 address. (extern'ed in upnp.h)
TimerThread gTimerThread
Global timer thread.
char gIF_IPV6[INET6_ADDRSTRLEN]
Static buffer to contain interface IPv6 link-local address (LLA). (extern'ed in upnp....
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.
GenlibClientSubscription * ClientSubList
Client subscription list.
#define HandleUnlock()
HandleUnlock.
Upnp_FunPtr Callback
Callback function pointer.
constexpr int NUM_HANDLE
Maximal number of available UPnP Unit handles.
#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.
void upnp_uuid_unpack(uuid_upnp *u, char *out)
Unpack a UUID.
int uuid_create(uuid_upnp *uid)
Generate a UUID.