19class DLNAControlPointMgr;
90 const char* searchTarget =
"ssdp:all", uint32_t minWaitMs = 3000,
91 uint32_t maxWaitMs = 60000) {
117 if (minWaitMs > maxWaitMs) minWaitMs = maxWaitMs;
118 search->
end_time = millis() + maxWaitMs;
126 uint64_t start = millis();
127 uint64_t minEnd = start + minWaitMs;
128 uint64_t maxEnd = start + maxWaitMs;
129 while (millis() < maxEnd) {
133 if (
devices.size() > 0 && millis() >= minEnd)
break;
139 if (
devices.size() > 0 && search !=
nullptr) {
144 "Control Point started with %d devices found",
153 for (
auto& device :
devices) device.clear();
178 a.name ? a.name :
"(null)", a.value.c_str());
186 "DLNAControlPointMgr::subscribeNotifications");
190 "HttpServer not defined - cannot subscribe to notifications");
200 "Service %s has no eventSubURL defined",
210 "Subscribed to service %s successfully",
218 int timoutSeconds = 60) {
222 "HttpServer not defined - cannot subscribe to notifications");
226 "DLNAControlPointMgr::subscribeNotifications");
229 char url_buffer[200] = {0};
230 char seconds_txt[80] = {0};
232 snprintf(seconds_txt, 80,
"Second-%d", timoutSeconds);
243 std::function<
void(
void*
reference,
const char* sid,
const char* varName,
244 const char* newValue)>
270 if (schedule !=
nullptr) {
307 if (result)
return result;
322 for (
auto& srv : dev.getServices()) {
323 if (srv == srv)
return dev;
333 if (dev.getDeviceURL() == location) {
335 "DLNAControlPointMgr::getDevice: Found device %s",
349 for (
auto& existing_device :
devices) {
350 if (dev.
getUDN() == existing_device.getUDN()) {
378 int rc = req.
get(url,
"text/xml");
388 int len = req.
read(buffer, 512);
390 xml.write(buffer, len);
399 for (
auto& existing_device :
devices) {
400 if (existing_device.getUDN() == new_device.
getUDN()) {
402 "Device '%s' already exists (skipping add)",
405 existing_device.setActive(
true);
440 std::function<void(
void*
reference,
const char* sid,
const char* varName,
441 const char* newValue)>
450 "DLNAControlPointMgr::attachHttpServer");
458 auto notifyHandler = [](
HttpServer* server,
const char* requestPath,
462 if (hl->contextCount > 0)
471 const char* sid = req.
get(
"SID");
488 server.
on(path,
T_POST, notifyHandler, ctx, 1);
502 if (!usn_c || *usn_c ==
'\0')
return false;
503 const char* sep = strstr(usn_c,
"::");
504 int udn_len = sep ? (int)(sep - usn_c) : (int)strlen(usn_c);
506 const char* known_udn = dev.getUDN();
507 if (known_udn && strncmp(known_udn, usn_c, udn_len) == 0 &&
508 (int)strlen(known_udn) == udn_len) {
519 select ?
"added" :
"filtered");
520 if (!select)
return false;
525 "Device '%s' already known (skip GET)",
526 existing ? existing->
getUDN() :
"<unknown>");
540 if (nts.
equals(
"ssdp:byebye")) {
543 if (nts.
equals(
"ssdp:alive")) {
552 "DLNAControlPointMgr::processMSearchReply");
560 const char* usn_c = data.
usn.
c_str();
561 if (usn_c && *usn_c) {
562 const char* sep = strstr(usn_c,
"::");
563 int udn_len = sep ? (int)(sep - usn_c) : (int)strlen(usn_c);
565 const char* known_udn = dev.getUDN();
566 if (known_udn && strncmp(known_udn, usn_c, udn_len) == 0 &&
567 (int)strlen(known_udn) == udn_len) {
569 "MSearchReply: device '%s' already known (skip GET)",
585 "DLNAControlPointMgr::parseAndDispatchEvent");
588 const char* xmlBuf = data.
xml.
c_str();
589 if (xmlBuf ==
nullptr || *xmlBuf ==
'\0')
return;
601 Str& ,
int ,
int ,
void* vref) {
602 CBRef* r =
static_cast<CBRef*
>(vref);
603 if (text.length() > 0 && r->self && r->self->eventCallback) {
604 const char* sid = r->data->subscription_id.c_str();
606 const char* namePtr = r->self->strings.add((
char*)nodeName.
c_str());
607 const char* valPtr = r->self->strings.add((
char*)text.c_str());
609 r->self->eventCallback(r->self->reference, sid, namePtr, valPtr);
629 for (
auto& srv : dev.getServices()) {
630 srv.is_active =
false;
631 if (usn.
endsWith(srv.service_type)) {
634 srv.is_active =
false;
664 "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
665 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"",
670 StrView namespace_str(ns, 200);
671 namespace_str =
"xmlns:u=\"%1\"";
693 if (action.getServiceType() !=
nullptr)
postAction(action);
715 action_str.add(action.
action);
716 action_str.add(
"\"");
719 char url_buffer[200] = {0};
737 const char* soapAction) {
764 xml_parser.
write(buffer, len);
765 while (xml_parser.
parse(outNodeName, outPath, outText, outAttributes)) {
767 if (!outNodeName.
equals(
"Result")) {
785 const char* buffer,
int len) {
787 StrView url_str{(
char*)buffer, len};
789 if (url_str ==
nullptr) {
Represents the result of invoking a DLNA service Action.
Definition: Action.h:42
void clear()
Definition: Action.h:55
void setValid(bool flag)
Definition: Action.h:48
Vector< Argument > arguments
Definition: Action.h:45
void addArgument(Argument arg)
Definition: Action.h:56
Represents a request to invoke a remote DLNA service action.
Definition: Action.h:79
Vector< Argument > arguments
Definition: Action.h:96
const char * getServiceType()
Definition: Action.h:99
DLNAServiceInfo * p_service
Definition: Action.h:94
const char * action
Definition: Action.h:95
DLNA Service: Action Argument.
Definition: Action.h:11
Str value
Definition: Action.h:19
const char * name
Definition: Action.h:18
Lightweight DLNA control point manager.
Definition: DLNAControlPointMgr.h:58
void setParseDevice(bool flag)
Requests the parsing of the device information.
Definition: DLNAControlPointMgr.h:69
bool begin(DLNAHttpRequest &http, IUDPService &udp, const char *searchTarget="ssdp:all", uint32_t minWaitMs=3000, uint32_t maxWaitMs=60000)
Start discovery by sending M-SEARCH requests and process replies.
Definition: DLNAControlPointMgr.h:89
HttpServer * p_http_server
Definition: DLNAControlPointMgr.h:437
size_t createXML(ActionRequest &action)
Definition: DLNAControlPointMgr.h:658
bool matches(const char *usn)
checks if the usn contains the search target
Definition: DLNAControlPointMgr.h:619
void * reference
Definition: DLNAControlPointMgr.h:439
void setHttpServer(HttpServer &server, int port=80)
Set HttpServer instance and register the notify handler.
Definition: DLNAControlPointMgr.h:253
static bool handleNotifyByebye(Str &usn)
Definition: DLNAControlPointMgr.h:493
bool isActive()
Checks if the scheduler is active.
Definition: DLNAControlPointMgr.h:420
bool loop()
Definition: DLNAControlPointMgr.h:262
void onNotification(std::function< void(void *reference, const char *sid, const char *varName, const char *newValue)> cb)
Register a callback that will be invoked for incoming event notification.
Definition: DLNAControlPointMgr.h:242
DLNAControlPointMgr(HttpServer &server, int port=80)
Constructor supporting Notifications.
Definition: DLNAControlPointMgr.h:64
const char * search_target
Definition: DLNAControlPointMgr.h:434
bool addDevice(Url url)
Adds the device from the device xml url if it does not already exist.
Definition: DLNAControlPointMgr.h:363
void setReference(void *ref)
Attach an opaque reference pointer (optional, for caller context)
Definition: DLNAControlPointMgr.h:250
ActionReply & getLastReply()
Definition: DLNAControlPointMgr.h:687
int http_server_port
Definition: DLNAControlPointMgr.h:438
ActionReply & postAction(ActionRequest &action)
Definition: DLNAControlPointMgr.h:698
static bool processMSearchReply(MSearchReplyCP &data)
Processes an M-SEARCH HTTP 200 reply and attempts to add the device.
Definition: DLNAControlPointMgr.h:550
static bool processDevice(NotifyReplyCP &data)
Definition: DLNAControlPointMgr.h:537
void buildActionBody(ActionRequest &action, StrPrint &out)
Build the SOAP XML request body for the action into out
Definition: DLNAControlPointMgr.h:728
static bool handleNotifyAlive(NotifyReplyCP &data)
Definition: DLNAControlPointMgr.h:516
DLNAHttpRequest * p_http
Definition: DLNAControlPointMgr.h:424
DLNADeviceInfo & getDevice(Url location)
Get a device for a Url.
Definition: DLNAControlPointMgr.h:330
void attachHttpServer(HttpServer &server)
Definition: DLNAControlPointMgr.h:448
bool subscribeNotifications(DLNADeviceInfo &device, int timeoutSeconds=60)
Subscribe to changes for all device services.
Definition: DLNAControlPointMgr.h:184
StringRegistry strings
Definition: DLNAControlPointMgr.h:435
DLNAControlPointMgr()
Default constructor w/o Notifications.
Definition: DLNAControlPointMgr.h:61
DLNADeviceInfo & getDevice(DLNAServiceInfo &service)
Provides the device for a service.
Definition: DLNAControlPointMgr.h:319
const char * getUrl(DLNADeviceInfo &device, const char *suffix, const char *buffer, int len)
Definition: DLNAControlPointMgr.h:784
DLNAServiceInfo & getService(const char *id)
Provide addess to the service information.
Definition: DLNAControlPointMgr.h:302
bool is_parse_device
Definition: DLNAControlPointMgr.h:432
ActionRequest & addAction(ActionRequest act)
Registers a method that will be called.
Definition: DLNAControlPointMgr.h:161
Scheduler scheduler
Definition: DLNAControlPointMgr.h:423
void parseAndDispatchEvent(NotifyReplyCP &data)
Parse the xml content of a NotifyReplyCP and dispatch each property.
Definition: DLNAControlPointMgr.h:583
IUDPService * p_udp
Definition: DLNAControlPointMgr.h:425
ActionReply reply
Definition: DLNAControlPointMgr.h:428
XMLPrinter xml
Definition: DLNAControlPointMgr.h:429
Url local_url
Definition: DLNAControlPointMgr.h:436
bool subscribeNotifications(DLNAServiceInfo &service, int timoutSeconds=60)
Subscribe to changes for defined device service.
Definition: DLNAControlPointMgr.h:217
std::function< void(void *reference, const char *sid, const char *varName, const char *newValue)> eventCallback
Definition: DLNAControlPointMgr.h:442
Vector< ActionRequest > actions
Definition: DLNAControlPointMgr.h:427
int msearch_repeat_ms
Definition: DLNAControlPointMgr.h:430
bool addDevice(DLNADeviceInfo dev)
Adds a new device.
Definition: DLNAControlPointMgr.h:346
void setActive(bool flag)
We can activate/deactivate the scheduler.
Definition: DLNAControlPointMgr.h:417
ActionReply & postAllActions()
Definition: DLNAControlPointMgr.h:689
bool processBye(Str &usn)
processes a bye-bye message
Definition: DLNAControlPointMgr.h:625
DLNADeviceInfo & getDevice(int deviceIdx=0)
Provides the device information by index.
Definition: DLNAControlPointMgr.h:313
static bool isUdnKnown(const char *usn_c, DLNADeviceInfo *&outDev)
Definition: DLNAControlPointMgr.h:500
bool is_active
Definition: DLNAControlPointMgr.h:431
void setLocalURL(Url url)
Defines the local url (needed for subscriptions)
Definition: DLNAControlPointMgr.h:72
ActionReply & processActionHttpPost(Url &post_url, StrPrint &requestBody, const char *soapAction)
Definition: DLNAControlPointMgr.h:736
Vector< DLNADeviceInfo > devices
Definition: DLNAControlPointMgr.h:426
DLNADeviceInfo NO_DEVICE
Definition: DLNAControlPointMgr.h:433
Vector< DLNADeviceInfo > & getDevices()
Definition: DLNAControlPointMgr.h:343
void end()
Stops the processing and releases the resources.
Definition: DLNAControlPointMgr.h:150
void setSearchRepeatMs(int repeatMs)
Sets the repeat interval for M-SEARCH requests (define before begin)
Definition: DLNAControlPointMgr.h:75
ActionReply & executeActions()
Executes all registered methods.
Definition: DLNAControlPointMgr.h:168
Translates DLNA UDP Requests to Schedule so that we can schedule a reply.
Definition: DLNAControlPointRequestParser.h:15
Schedule * parse(RequestData &req)
Definition: DLNAControlPointRequestParser.h:17
Device Attributes and generation of XML using urn:schemas-upnp-org:device-1-0. We could just return a...
Definition: DLNADeviceInfo.h:27
Vector< DLNAServiceInfo > & getServices()
Definition: DLNADeviceInfo.h:150
Url device_url
Definition: DLNADeviceInfo.h:195
void updateTimestamp()
Update the timestamp.
Definition: DLNADeviceInfo.h:180
const char * getUDN()
Provide the udn uuid.
Definition: DLNADeviceInfo.h:56
const char * getBaseURL()
Provides the base url.
Definition: DLNADeviceInfo.h:81
Url & getDeviceURL()
This method returns base url/device.xml.
Definition: DLNADeviceInfo.h:92
void setActive(bool flag)
Definition: DLNADeviceInfo.h:185
Attributes needed for the DLNA Service Definition.
Definition: DLNAServiceInfo.h:16
const char * control_url
Definition: DLNAServiceInfo.h:36
const char * event_sub_url
Definition: DLNAServiceInfo.h:37
Used to register and process callbacks.
Definition: HttpRequestHandlerLine.h:19
Simple API to process get, put, post, del http requests I tried to use Arduino HttpClient,...
Definition: HttpRequest.h:21
virtual HttpRequestHeader & request()
Definition: HttpRequest.h:118
virtual int subscribe(Url &url)
Definition: HttpRequest.h:91
Client * client()
Definition: HttpRequest.h:130
virtual int get(Url &url, const char *acceptMime=nullptr, const char *data=nullptr, int len=-1)
Definition: HttpRequest.h:77
virtual int post(Url &url, const char *mime, const char *data, int len=-1)
Definition: HttpRequest.h:61
virtual void stop()
Definition: HttpRequest.h:56
virtual int read(uint8_t *str, int len)
Definition: HttpRequest.h:97
A Simple Header only implementation of Http Server that allows the registration of callback functions...
Definition: HttpServer.h:24
bool begin(int port, const char *ssid, const char *password)
Definition: HttpServer.h:49
bool doLoop()
Legacy method: same as copy();.
Definition: HttpServer.h:404
void on(const char *url, TinyMethodID method, web_callback_fn fn, void *ctx[]=nullptr, int ctxCount=0)
register a generic handler
Definition: HttpServer.h:89
void replyOK()
write OK reply with 200 SUCCESS
Definition: HttpServer.h:363
Str contentStr()
converts the client content to a string
Definition: HttpServer.h:450
HttpRequestHeader & requestHeader()
provides the request header
Definition: HttpServer.h:380
void end()
stops the server_ptr
Definition: HttpServer.h:76
void replyNotFound()
write 404 reply
Definition: HttpServer.h:366
Abstract Interface for UDP API.
Definition: IUDPService.h:34
virtual RequestData receive()=0
virtual bool begin(int port)=0
void log(DlnaLogLevel current_level, const char *fmt...)
Print log message.
Definition: Logger.h:40
Processing at control point to handle a MSearchReply from the device.
Definition: Schedule.h:122
Str usn
Definition: Schedule.h:126
Str location
Definition: Schedule.h:125
Send MSearch request.
Definition: Schedule.h:39
Represents a notification/notify reply scheduled for control-point processing.
Definition: Schedule.h:163
Str xml
Definition: Schedule.h:171
Str subscription_id
Definition: Schedule.h:169
Str nts
Definition: Schedule.h:166
Scheduler which processes all due Schedules (to send out UDP replies)
Definition: Scheduler.h:15
bool isMSearchActive()
Returns true if there is any active schedule with name "MSearch".
Definition: Scheduler.h:59
void execute(IUDPService &udp)
Execute all due schedules.
Definition: Scheduler.h:25
void add(Schedule *schedule)
Add a schedule to the scheduler.
Definition: Scheduler.h:18
Print to a dynamic string.
Definition: StrPrint.h:12
const char * c_str()
Definition: StrPrint.h:38
size_t length()
Definition: StrPrint.h:40
A simple wrapper to provide string functions on char*. If the underlying char* is a const we do not a...
Definition: StrView.h:19
virtual void add(int value)
adds a int value
Definition: StrView.h:129
virtual bool isEmpty()
checks if the string is empty
Definition: StrView.h:383
virtual const char * c_str()
provides the string value as const char*
Definition: StrView.h:376
virtual bool startsWith(const char *str)
checks if the string starts with the indicated substring
Definition: StrView.h:184
virtual bool endsWith(const char *str)
checks if the string ends with the indicated substring
Definition: StrView.h:192
virtual bool replace(const char *toReplace, const int replaced)
Replaces the first instance of toReplace with replaced.
Definition: StrView.h:395
virtual bool equals(const char *str)
checks if the string equals indicated parameter string
Definition: StrView.h:178
virtual bool contains(const char *str)
checks if the string contains a substring
Definition: StrView.h:285
String implementation which keeps the data on the heap. We grow the allocated memory only if the copy...
Definition: Str.h:22
const char * c_str()
provides the string value as const char*
Definition: Str.h:187
Make sure that a string is stored only once.
Definition: StringRegistry.h:9
const char * add(char *in)
adds a string
Definition: StringRegistry.h:12
URL parser which breaks a full url string up into its individual parts.
Definition: Url.h:18
int port()
Definition: Url.h:50
const char * host()
Definition: Url.h:45
const char * protocol()
Definition: Url.h:46
const char * url()
Definition: Url.h:43
const char * path()
Definition: Url.h:44
Vector implementation which provides the most important methods as defined by std::vector....
Definition: Vector.h:21
Parses an DLNA device xml string to fill the DLNADevice data structure.
Definition: XMLDeviceParser.h:17
void parse(DLNADeviceInfo &result, StringRegistry &strings, const char *xmlStr)
Definition: XMLDeviceParser.h:19
Helper that implements a Print interface to accumulate XML data and then parse it using XMLParser.
Definition: XMLParserPrint.h:12
size_t write(uint8_t ch) override
Definition: XMLParserPrint.h:21
void setExpandEncoded(bool flag)
Forward expand-entities setting to the underlying XMLParser.
Definition: XMLParserPrint.h:28
bool parse(Str &outNodeName, Vector< Str > &outPath, Str &outText, Str &outAttributes)
Definition: XMLParserPrint.h:30
Lightweight streaming XML parser.
Definition: XMLParser.h:27
void setReference(void *ref)
Attach an opaque user pointer to the parser instance.
Definition: XMLParser.h:60
void parse()
Parse the previously set XML buffer and invoke the callback.
Definition: XMLParser.h:90
Definition: Allocator.h:6
@ T_POST
Definition: HttpHeader.h:39
DLNAControlPointMgr * selfDLNAControlPoint
Definition: DLNAControlPointMgr.h:20
LoggerClass DlnaLogger
Definition: Logger.cpp:5
Provides information of the received UDP which consists of the (xml) data and the peer address and po...
Definition: IUDPService.h:23
An individual Schedule (to send out UDP messages)
Definition: Schedule.h:17
uint64_t end_time
Definition: Schedule.h:24
bool active
Definition: Schedule.h:26
virtual const char * name()
Definition: Schedule.h:30
uint32_t repeat_ms
Definition: Schedule.h:22
Functions to efficiently output XML. XML data contains a lot of redundancy so it is more memory effic...
Definition: XMLPrinter.h:31
size_t printNodeBegin(const char *node, const char *attributes=nullptr, const char *ns=nullptr)
Definition: XMLPrinter.h:97
size_t printNode(XMLNode node)
Definition: XMLPrinter.h:43
size_t printNodeEnd(const char *node, const char *ns=nullptr)
Definition: XMLPrinter.h:122
void setOutput(Print &output)
Defines the output.
Definition: XMLPrinter.h:36
size_t printXMLHeader()
Definition: XMLPrinter.h:38