UPnPsdk 0.1
Universal Plug and Play +, Software Development Kit
 
Loading...
Searching...
No Matches
service_table.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (c) 2000-2003 Intel Corporation
4 * All rights reserved.
5 * Copyright (c) 2012 France Telecom All rights reserved.
6 * Copyright (C) 2022+ GPL 3 and higher by Ingo Höft, <Ingo@Hoeft-online.de>
7 * Redistribution only with this Copyright remark. Last modified: 2024-03-02
8 k
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * - Neither name of Intel Corporation nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
29 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 ******************************************************************************/
34// Last compare with pupnp original source file on 2023-09-06, ver 1.14.18
46#include <service_table.hpp>
47
48#ifndef COMPA_INTERNAL_CONFIG_HPP
49#error "No or wrong config.hpp header file included."
50#endif
51
52#ifdef COMPA_HAVE_DEVICE_GENA
53namespace {
54
65 IXML_Node* node,
67 service_info** end,
69 char* URLBase) {
70 IXML_Node* serviceList = NULL;
71 IXML_Node* current_service = NULL;
72 IXML_Node* UDN = NULL;
73
74 IXML_Node* serviceType = NULL;
75 IXML_Node* serviceId = NULL;
76 IXML_Node* SCPDURL = NULL;
77 IXML_Node* controlURL = NULL;
78 IXML_Node* eventURL = NULL;
79 DOMString tempDOMString = NULL;
80 service_info* head = NULL;
81 service_info* current = NULL;
82 service_info* previous = NULL;
83 IXML_NodeList* serviceNodeList = NULL;
84 long unsigned int NumOfServices = 0lu;
85 long unsigned int i = 0lu;
86 int fail = 0;
87
88 if (getSubElement("UDN", node, &UDN) &&
89 getSubElement("serviceList", node, &serviceList)) {
90 serviceNodeList = ixmlElement_getElementsByTagName(
91 (IXML_Element*)serviceList, "service");
92 if (serviceNodeList) {
93 NumOfServices = ixmlNodeList_length(serviceNodeList);
94 for (i = 0lu; i < NumOfServices; i++) {
95 current_service = ixmlNodeList_item(serviceNodeList, i);
96 fail = 0;
97 if (current) {
98 current->next = (service_info*)malloc(sizeof(service_info));
99 previous = current;
100 current = current->next;
101 } else {
102 head = (service_info*)malloc(sizeof(service_info));
103 current = head;
104 }
105 if (!current) {
106 freeServiceList(head);
107 ixmlNodeList_free(serviceNodeList);
108 return NULL;
109 }
110 current->next = NULL;
111 current->controlURL = NULL;
112 current->eventURL = NULL;
113 current->serviceType = NULL;
114 current->serviceId = NULL;
115 current->SCPDURL = NULL;
116 current->active = 1;
117 current->subscriptionList = NULL;
118 current->TotalSubscriptions = 0;
119 if ((current->UDN = getElementValue(UDN)) == 0)
120 fail = 1;
121 if (!getSubElement("serviceType", current_service,
122 &serviceType) ||
123 ((current->serviceType = getElementValue(serviceType)) ==
124 0))
125 fail = 1;
126 if (!getSubElement("serviceId", current_service, &serviceId) ||
127 ((current->serviceId = getElementValue(serviceId)) == 0))
128 fail = 1;
129 if (!getSubElement("SCPDURL", current_service, &SCPDURL) ||
130 ((tempDOMString = getElementValue(SCPDURL)) == 0) ||
131 ((current->SCPDURL =
132 resolve_rel_url(URLBase, tempDOMString)) == 0))
133 fail = 1;
134 ixmlFreeDOMString(tempDOMString);
135 tempDOMString = NULL;
136 if (!(getSubElement("controlURL", current_service,
137 &controlURL)) ||
138 ((tempDOMString = getElementValue(controlURL)) == 0) ||
139 ((current->controlURL =
140 resolve_rel_url(URLBase, tempDOMString)) == 0)) {
141 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
142 "BAD OR MISSING CONTROL URL");
143 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
144 "CONTROL URL SET TO NULL IN "
145 "SERVICE INFO");
146 current->controlURL = NULL;
147 fail = 0;
148 }
149 ixmlFreeDOMString(tempDOMString);
150 tempDOMString = NULL;
151 if (!getSubElement("eventSubURL", current_service, &eventURL) ||
152 ((tempDOMString = getElementValue(eventURL)) == 0) ||
153 ((current->eventURL =
154 resolve_rel_url(URLBase, tempDOMString)) == 0)) {
155 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
156 "BAD OR MISSING EVENT URL");
157 UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
158 "EVENT URL SET TO NULL IN "
159 "SERVICE INFO");
160 current->eventURL = NULL;
161 fail = 0;
162 }
163 ixmlFreeDOMString(tempDOMString);
164 tempDOMString = NULL;
165 if (fail) {
166 freeServiceList(current);
167 if (previous)
168 previous->next = NULL;
169 else
170 head = NULL;
171 current = previous;
172 }
173 }
174 ixmlNodeList_free(serviceNodeList);
175 }
176 (*end) = current;
177 return head;
178 } else {
179 (*end) = NULL;
180 return NULL;
181 }
182}
183
194 IXML_Node* node,
196 char* URLBase,
198 service_info** out_end) {
199 service_info* head = NULL;
200 service_info* end = NULL;
201 service_info* next_end = NULL;
202 IXML_NodeList* deviceList = NULL;
203 IXML_Node* currentDevice = NULL;
204
205 long unsigned int NumOfDevices = 0lu;
206 long unsigned int i = 0lu;
207
208 (*out_end) = NULL;
209 deviceList =
211 if (deviceList) {
212 NumOfDevices = ixmlNodeList_length(deviceList);
213 for (i = 0lu; i < NumOfDevices; i++) {
214 currentDevice = ixmlNodeList_item(deviceList, i);
215 if (head) {
216 end->next = getServiceList(currentDevice, &next_end, URLBase);
217 if (next_end)
218 end = next_end;
219 } else {
220 head = getServiceList(currentDevice, &end, URLBase);
221 }
222 }
223 ixmlNodeList_free(deviceList);
224 }
225
226 (*out_end) = end;
227 return head;
228}
229
230} // anonymous namespace
231
232
234 int return_code = HTTP_SUCCESS;
235
236 memcpy(out->sid, in->sid, SID_SIZE);
237 out->sid[SID_SIZE] = 0;
239 out->expireTime = in->expireTime;
240 out->active = in->active;
241 return_code = copy_URL_list(&in->DeliveryURLs, &out->DeliveryURLs);
242 if (return_code != HTTP_SUCCESS) {
243 return return_code;
244 }
245 ListInit(&out->outgoing, 0, 0);
246 out->next = NULL;
247 return HTTP_SUCCESS;
248}
249
251 subscription* finger = service->subscriptionList;
252 subscription* previous = NULL;
253
254 while (finger) {
255 if (!strcmp(sid, finger->sid)) {
256 if (previous) {
257 previous->next = finger->next;
258 } else {
259 service->subscriptionList = finger->next;
260 }
261 finger->next = NULL;
262 freeSubscriptionList(finger);
263 finger = NULL;
264 service->TotalSubscriptions--;
265 } else {
266 previous = finger;
267 finger = finger->next;
268 }
269 }
270}
271
273 subscription* next = service->subscriptionList;
274 subscription* previous = NULL;
275 subscription* found = NULL;
276 time_t current_time;
277
278 while (next && !found) {
279 if (!strcmp(next->sid, sid))
280 found = next;
281 else {
282 previous = next;
283 next = next->next;
284 }
285 }
286 if (found) {
287 /* get the current_time */
288 time(&current_time);
289 if (found->expireTime && found->expireTime < current_time) {
290 if (previous) {
291 previous->next = found->next;
292 } else {
293 service->subscriptionList = found->next;
294 }
295 found->next = NULL;
297 found = NULL;
298 service->TotalSubscriptions--;
299 }
300 }
301 return found;
302}
303
305 subscription temp;
306 subscription* next = NULL;
307
308 temp.next = service->subscriptionList;
309 next = GetNextSubscription(service, &temp);
310 service->subscriptionList = temp.next;
311 /* service->subscriptionList = next; */
312
313 return next;
314}
315
317 subscription* current) {
318 time_t current_time;
319 subscription* next = NULL;
320 subscription* previous = NULL;
321 int notDone = 1;
322
323 /* get the current_time */
324 time(&current_time);
325 while (notDone && current) {
326 previous = current;
327 current = current->next;
328
329 if (!current) {
330 notDone = 0;
331 next = current;
332 } else if (current->expireTime && current->expireTime < current_time) {
333 previous->next = current->next;
334 current->next = NULL;
335 freeSubscriptionList(current);
336 current = previous;
337 service->TotalSubscriptions--;
338 } else if (current->active) {
339 notDone = 0;
340 next = current;
341 }
342 }
343 return next;
344}
345
347 if (sub) {
350 }
351}
352
354 subscription* next = NULL;
355
356 while (head) {
357 next = head->next;
358 freeSubscription(head);
359 free(head);
360 head = next;
361 }
362}
363
364service_info* FindServiceId(service_table* table, const char* serviceId,
365 const char* UDN) {
366 service_info* finger = NULL;
367
368 if (table) {
369 finger = table->serviceList;
370 while (finger) {
371 if (!strcmp(serviceId, finger->serviceId) &&
372 !strcmp(UDN, finger->UDN)) {
373 return finger;
374 }
375 finger = finger->next;
376 }
377 }
378
379 return NULL;
380}
381#endif // COMPA_HAVE_DEVICE_GENA
382
384 const char* eventURLPath) {
385 service_info* finger = NULL;
386 uri_type parsed_url;
387 uri_type parsed_url_in;
388
389 if (!table || !eventURLPath) {
390 return NULL;
391 }
392 if (parse_uri(eventURLPath, strlen(eventURLPath), &parsed_url_in) ==
393 HTTP_SUCCESS) {
394 finger = table->serviceList;
395 while (finger) {
396 if (finger->eventURL) {
397 if (parse_uri(finger->eventURL, strlen(finger->eventURL),
398 &parsed_url) == HTTP_SUCCESS) {
399 if (!token_cmp(&parsed_url.pathquery,
400 &parsed_url_in.pathquery)) {
401 return finger;
402 }
403 }
404 }
405 finger = finger->next;
406 }
407 }
408
409 return NULL;
410}
411
413 const char* controlURLPath) {
414 service_info* finger = NULL;
415 uri_type parsed_url;
416 uri_type parsed_url_in;
417
418 if (!table || !controlURLPath) {
419 return NULL;
420 }
421 if (parse_uri(controlURLPath, strlen(controlURLPath), &parsed_url_in) ==
422 HTTP_SUCCESS) {
423 finger = table->serviceList;
424 while (finger) {
425 if (finger->controlURL) {
426 if (parse_uri(finger->controlURL, strlen(finger->controlURL),
427 &parsed_url) == HTTP_SUCCESS) {
428 if (!token_cmp(&parsed_url.pathquery,
429 &parsed_url_in.pathquery)) {
430 return finger;
431 }
432 }
433 }
434 finger = finger->next;
435 }
436 }
437
438 return NULL;
439}
440
441#ifdef DEBUG
443 Dbg_Module module) {
444 if (service) {
445 if (service->serviceType) {
446 UpnpPrintf(level, module, __FILE__, __LINE__, "serviceType: %s\n",
447 service->serviceType);
448 }
449 if (service->serviceId) {
450 UpnpPrintf(level, module, __FILE__, __LINE__, "serviceId: %s\n",
451 service->serviceId);
452 }
453 if (service->SCPDURL) {
454 UpnpPrintf(level, module, __FILE__, __LINE__, "SCPDURL: %s\n",
455 service->SCPDURL);
456 }
457 if (service->controlURL) {
458 UpnpPrintf(level, module, __FILE__, __LINE__, "controlURL: %s\n",
459 service->controlURL);
460 }
461 if (service->eventURL) {
462 UpnpPrintf(level, module, __FILE__, __LINE__, "eventURL: %s\n",
463 service->eventURL);
464 }
465 if (service->UDN) {
466 UpnpPrintf(level, module, __FILE__, __LINE__, "UDN: %s\n\n",
467 service->UDN);
468 }
469 if (service->active) {
470 UpnpPrintf(level, module, __FILE__, __LINE__,
471 "Service is active\n");
472 } else {
473 UpnpPrintf(level, module, __FILE__, __LINE__,
474 "Service is inactive\n");
475 }
476 }
477}
478#endif
479
480#ifdef DEBUG
482 Dbg_Module module) {
483 while (service) {
484 if (service->serviceType) {
485 UpnpPrintf(level, module, __FILE__, __LINE__, "serviceType: %s\n",
486 service->serviceType);
487 }
488 if (service->serviceId) {
489 UpnpPrintf(level, module, __FILE__, __LINE__, "serviceId: %s\n",
490 service->serviceId);
491 }
492 if (service->SCPDURL) {
493 UpnpPrintf(level, module, __FILE__, __LINE__, "SCPDURL: %s\n",
494 service->SCPDURL);
495 }
496 if (service->controlURL) {
497 UpnpPrintf(level, module, __FILE__, __LINE__, "controlURL: %s\n",
498 service->controlURL);
499 }
500 if (service->eventURL) {
501 UpnpPrintf(level, module, __FILE__, __LINE__, "eventURL: %s\n",
502 service->eventURL);
503 }
504 if (service->UDN) {
505 UpnpPrintf(level, module, __FILE__, __LINE__, "UDN: %s\n\n",
506 service->UDN);
507 }
508 if (service->active) {
509 UpnpPrintf(level, module, __FILE__, __LINE__,
510 "Service is active\n");
511 } else {
512 UpnpPrintf(level, module, __FILE__, __LINE__,
513 "Service is inactive\n");
514 }
515 service = service->next;
516 }
517}
518#endif
519
520#ifdef DEBUG
522 Dbg_Module module) {
523 UpnpPrintf(level, module, __FILE__, __LINE__, "URL_BASE: %s\n",
524 table->URLBase);
525 UpnpPrintf(level, module, __FILE__, __LINE__, "Services: \n");
526 printServiceList(table->serviceList, level, module);
527}
528#endif
529
530#ifdef COMPA_HAVE_DEVICE_GENA
532 if (in) {
533 if (in->serviceType)
535
536 if (in->serviceId)
538
539 if (in->SCPDURL)
540 free(in->SCPDURL);
541
542 if (in->controlURL)
543 free(in->controlURL);
544
545 if (in->eventURL)
546 free(in->eventURL);
547
548 if (in->UDN)
550
551 if (in->subscriptionList)
553
554 in->TotalSubscriptions = 0;
555 free(in);
556 }
557}
558
560 service_info* next = NULL;
561
562 while (head) {
563 if (head->serviceType)
565 if (head->serviceId)
567 if (head->SCPDURL)
568 free(head->SCPDURL);
569 if (head->controlURL)
570 free(head->controlURL);
571 if (head->eventURL)
572 free(head->eventURL);
573 if (head->UDN)
574 ixmlFreeDOMString(head->UDN);
575 if (head->subscriptionList)
577
578 head->TotalSubscriptions = 0;
579 next = head->next;
580 free(head);
581 head = next;
582 }
583}
584
588 table->serviceList = NULL;
589 table->endServiceList = NULL;
590}
591
593 IXML_Node* root = NULL;
594 IXML_Node* currentUDN = NULL;
595 DOMString UDN = NULL;
596 IXML_NodeList* deviceList = NULL;
597 service_info* current_service = NULL;
598 service_info* start_search = NULL;
599 service_info* prev_service = NULL;
600 long unsigned int NumOfDevices = 0lu;
601 long unsigned int i = 0lu;
602
603 if (getSubElement("root", node, &root)) {
604 start_search = in->serviceList;
605 deviceList =
607 if (deviceList) {
608 NumOfDevices = ixmlNodeList_length(deviceList);
609 for (i = 0lu; i < NumOfDevices; i++) {
610 if ((start_search) &&
611 ((getSubElement("UDN", node, &currentUDN)) &&
612 ((UDN = getElementValue(currentUDN)) != 0))) {
613 current_service = start_search;
614 /* Services are put in the service table
615 * in the order in which they appear in
616 * the description document, therefore
617 * we go through the list only once to
618 * remove a particular root device */
619 while ((current_service) &&
620 (strcmp(current_service->UDN, UDN))) {
621 current_service = current_service->next;
622 if (current_service != NULL)
623 prev_service = current_service->next;
624 }
625 while ((current_service) &&
626 (!strcmp(current_service->UDN, UDN))) {
627 if (prev_service) {
628 prev_service->next = current_service->next;
629 } else {
630 in->serviceList = current_service->next;
631 }
632 if (current_service == in->endServiceList)
633 in->endServiceList = prev_service;
634 start_search = current_service->next;
635 freeService(current_service);
636 current_service = start_search;
637 }
639 UDN = NULL;
640 }
641 }
642
643 ixmlNodeList_free(deviceList);
644 }
645 }
646 return 1;
647}
648
650 const char* DefaultURLBase) {
651 IXML_Node* root = NULL;
652 IXML_Node* URLBase = NULL;
653 service_info* tempEnd = NULL;
654
655 if (in->URLBase) {
656 free(in->URLBase);
657 in->URLBase = NULL;
658 }
659 if (getSubElement("root", node, &root)) {
660 if (getSubElement("URLBase", root, &URLBase)) {
661 in->URLBase = getElementValue(URLBase);
662 } else {
663 if (DefaultURLBase) {
664 in->URLBase = ixmlCloneDOMString(DefaultURLBase);
665 } else {
666 in->URLBase = ixmlCloneDOMString("");
667 }
668 }
669 if ((in->endServiceList->next =
670 getAllServiceList(root, in->URLBase, &tempEnd))) {
671 in->endServiceList = tempEnd;
672 return 1;
673 }
674 }
675
676 return 0;
677}
678
680 const char* DefaultURLBase) {
681 IXML_Node* root = nullptr;
682 IXML_Node* URLBase = nullptr;
683
684 if (getSubElement("root", node, &root)) {
685 if (getSubElement("URLBase", root, &URLBase)) {
686 out->URLBase = getElementValue(URLBase);
687 } else {
688 if (DefaultURLBase) {
689 out->URLBase = ixmlCloneDOMString(DefaultURLBase);
690 } else {
691 out->URLBase = ixmlCloneDOMString("");
692 }
693 }
694 out->serviceList =
695 getAllServiceList(root, out->URLBase, &out->endServiceList);
696 if (out->serviceList) {
697 return 1;
698 }
699 }
700
701 return 0;
702}
703
706 const DOMString temp = NULL;
707
708 if (child && ixmlNode_getNodeType(child) == eTEXT_NODE) {
709 temp = ixmlNode_getNodeValue(child);
710
711 return ixmlCloneDOMString(temp);
712 } else {
713 return NULL;
714 }
715}
716
717int getSubElement(const char* element_name, IXML_Node* node, IXML_Node** out) {
718 const DOMString NodeName = NULL;
719 int found = 0;
721
722 (*out) = NULL;
723 while (child && !found) {
724 switch (ixmlNode_getNodeType(child)) {
725 case eELEMENT_NODE:
726 NodeName = ixmlNode_getNodeName(child);
727 if (!strcmp(NodeName, element_name)) {
728 (*out) = child;
729 found = 1;
730 return found;
731 }
732 break;
733 default:
734 break;
735 }
736 child = (IXML_Node*)ixmlNode_getNextSibling(child);
737 }
738
739 return found;
740}
741
742#endif // COMPA_HAVE_DEVICE_GENA
char Upnp_SID[44]
Holds the subscription identifier for a subscription between a client and a device.
Definition API.hpp:434
token pathquery
Member variable.
Definition uri.hpp:98
constexpr int HTTP_SUCCESS
Yet another success code.
Definition uri.hpp:70
Represents a URI used in parse_uri and elsewhere.
Definition uri.hpp:92
int ListInit(LinkedList *list, cmp_routine cmp_func, free_function free_func)
Initializes LinkedList. Must be called first and only once for List.
void freeSubscriptionQueuedEvents(subscription *sub)
???
Data structure common to all types of nodes.
Definition ixml.hpp:132
Data structure representing a list of nodes.
Definition ixml.hpp:193
Data structure representing an Element node.
Definition ixml.hpp:169
PUPNP_Api unsigned short ixmlNode_getNodeType(IXML_Node *nodeptr)
Retrieves the type of a Node. Note that not all possible return values are actually implemented.
Definition node.cpp:326
#define DOMString
The type of DOM strings.
Definition ixml.hpp:47
PUPNP_Api IXML_Node * ixmlNode_getNextSibling(IXML_Node *nodeptr)
Retrieves the sibling Node immediately following this Node.
Definition node.cpp:375
PUPNP_Api const DOMString ixmlNode_getNodeValue(IXML_Node *nodeptr)
Returns the value of the Node as a string.
Definition node.cpp:296
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.
Definition node.cpp:179
PUPNP_Api void ixmlFreeDOMString(DOMString buf)
Frees a DOMString.
Definition ixml.cpp:418
PUPNP_Api unsigned long ixmlNodeList_length(IXML_NodeList *nList)
Returns the number of Nodes in a NodeList.
Definition nodeList.cpp:116
PUPNP_Api void ixmlNodeList_free(IXML_NodeList *nList)
Frees a NodeList object.
Definition nodeList.cpp:129
PUPNP_Api DOMString ixmlCloneDOMString(const DOMString src)
Clones an existing DOMString.
Definition ixml.cpp:410
PUPNP_Api IXML_Node * ixmlNode_getFirstChild(IXML_Node *nodeptr)
Retrieves the first child Node of a Node.
Definition node.cpp:342
PUPNP_Api IXML_Node * ixmlNodeList_item(IXML_NodeList *nList, unsigned long index)
Retrieves a Node from a NodeList specified by a numerical index.
Definition nodeList.cpp:49
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...
Definition element.cpp:335
service_info * getAllServiceList(IXML_Node *node, char *URLBase, service_info **out_end)
Returns pointer to service info after getting the sub-elements of the service info.
service_info * getServiceList(IXML_Node *node, service_info **end, char *URLBase)
Returns pointer to service info after getting the sub-elements of the service info.
service_info * FindServiceControlURLPath(service_table *table, const char *controlURLPath)
Traverses the service table and finds the node whose control URL Path matches a known value.
void printService(service_info *service, Upnp_LogLevel level, Dbg_Module module)
prints information from the service passed into the function.
void printServiceTable(service_table *table, Upnp_LogLevel level, Dbg_Module module)
Prints the URL base of the table and information of each service from the service table.
int getSubElement(const char *element_name, IXML_Node *node, IXML_Node **out)
Traverses through a list of XML nodes to find the node with the known element name.
void printServiceList(service_info *service, Upnp_LogLevel level, Dbg_Module module)
Prints information of each service from the service table passed into the function.
subscription * GetFirstSubscription(service_info *service)
Gets pointer to the first subscription node in the service table.
subscription * GetSubscriptionSID(const Upnp_SID sid, service_info *service)
Return the subscription from the service table that matches const Upnp_SID sid value.
void freeService(service_info *in)
Free's memory allocated for the various components of the service entry in the service table.
int copy_subscription(subscription *in, subscription *out)
Makes a copy of the subscription.
void freeServiceTable(service_table *table)
Free's dynamic memory in table (does not free table, only memory within the structure).
int addServiceTable(IXML_Node *node, service_table *in, const char *DefaultURLBase)
Add Service to the table.
void freeServiceList(service_info *head)
Free's memory allocated for the various components of each service entry in the service table.
void freeSubscription(subscription *sub)
Free's the memory allocated for storing the URL of the subscription.
int removeServiceTable(IXML_Node *node, service_table *in)
Remove all services for a root device.
service_info * FindServiceEventURLPath(service_table *table, const char *eventURLPath)
Traverses the service table and finds the node whose event URL Path matches a known value.
void RemoveSubscriptionSID(Upnp_SID sid, service_info *service)
Remove the subscription from the service table and update it.
int getServiceTable(IXML_Node *node, service_table *out, const char *DefaultURLBase)
Retrieve service from the table.
void freeSubscriptionList(subscription *head)
Free's memory allocated for all the subscriptions in the service table.
subscription * GetNextSubscription(service_info *service, subscription *current)
Get current and valid subscription from the service table.
DOMString getElementValue(IXML_Node *node)
Returns the clone of the element value.
service_info * FindServiceId(service_table *table, const char *serviceId, const char *UDN)
Traverses through the service table to find a service.
Manage the UPnP Services of a UPnP Device if available.
int TotalSubscriptions
Part of Service information.
service_info * serviceList
Part of the service table.
URL_list DeliveryURLs
Part of subscription.
int active
Part of subscription.
char * eventURL
Part of Service information.
struct subscription * next
Part of subscription.
service_info * endServiceList
Part of the service table.
struct service_info * next
Part of Service information.
DOMString URLBase
Part of the service table.
Upnp_SID sid
Part of subscription.
subscription * subscriptionList
Part of Service information.
DOMString UDN
Part of Service information.
DOMString serviceId
Part of Service information.
LinkedList outgoing
List of queued events for this subscription.
DOMString serviceType
Part of Service information.
char * SCPDURL
Part of Service information.
int ToSendEventKey
Part of subscription.
#define SID_SIZE
???
time_t expireTime
Part of subscription.
int active
Part of Service information.
char * controlURL
Part of Service information.
device subscriptions
table of services
-brief Service information
enum Upnp_Module Dbg_Module
Only debug messages from this program module.
UPnPsdk_VIS void UpnpPrintf(Upnp_LogLevel DLevel, Dbg_Module Module, const char *DbgFileName, int DbgLineNo, const char *FmtStr,...)
Prints the debug statement.
enum Upnp_LogLevel_e Upnp_LogLevel
Upnp_LogLevel.
char * resolve_rel_url(char *base_url, char *rel_url)
Resolves a relative url with a base url.
Definition uri.cpp:605
int copy_URL_list(URL_list *in, URL_list *out)
Copies one URL_list into another.
Definition uri.cpp:431
int token_cmp(token *in1, token *in2)
Compares two tokens.
Definition uri.cpp:518
int parse_uri(const char *in, size_t max, uri_type *out)
Parses a uri as defined in RFC 2396 (explaining URIs).
Definition uri.cpp:733
void free_URL_list(URL_list *list)
Frees the memory associated with a URL_list.
Definition uri.cpp:480