46template <
typename ClientType>
104 uint64_t now = millis();
129 uint64_t
end = millis() + 2000;
130 while (millis() <
end) {
156 uint64_t now = millis();
160 if (count > 0) rc =
true;
169 if (count > 0) rc =
true;
198 if (schedule !=
nullptr) {
222 if (
p_device_info ==
nullptr || requestPath ==
nullptr)
return nullptr;
233 std::function<
size_t(Print&,
void*)> changeWriter,
234 void* ref)
override {
242 "addChange: No service info available for %s",
246 mgr.addChange(serviceInfo, changeWriter, ref);
278 const char* requestPath,
282 auto start = millis();
292 bool is_attribute =
false;
293 bool is_action =
false;
299 auto* pClient = client.
client();
302 if (clen_str !=
nullptr) {
303 char* endptr =
nullptr;
304 long val = strtol(clen_str, &endptr, 10);
307 if (endptr != clen_str && val >= 0) remaining = (int)val;
309 while (remaining != 0) {
310 size_t chunk = remaining < 0 || (size_t)remaining >
sizeof(buffer)
313 size_t len = pClient->readBytes(buffer, chunk);
315 if (remaining > 0) remaining -= (int)len;
316 xp.
write((
const uint8_t*)buffer, len);
318 while (xp.
parse(outNodeName, outPath, outText, outAttributes)) {
320 const char* argName = outNodeName.
c_str();
334 if (outNodeName.
endsWith(
"Envelope")) {
356 Print& out,
const char* replyName,
const char* serviceId,
357 std::function<
size_t(Print&,
void*)> valuesWriter =
nullptr,
358 void* ref =
nullptr) {
364 "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"");
367 xp.
printf(
"<u:%s xmlns:u=\"urn:schemas-upnp-org:service:%s:1\">\n",
368 replyName, serviceId);
373 result += valuesWriter(out, ref);
376 result += xp.
printf(
"</u:%s>\n", replyName);
386 const char* sink =
"") {
388 return printReplyXML(out,
"GetProtocolInfoResponse",
"ConnectionManager",
389 [source, sink](Print& o,
void* ref) ->
size_t {
392 written += o.print(
"<Source>");
393 written += o.print(
StrView(source).c_str());
394 written += o.print(
"</Source>");
395 written += o.print(
"<Sink>");
396 written += o.print(
StrView(sink).c_str());
397 written += o.print(
"</Sink>");
406 [ids](Print& o,
void* ref) ->
size_t {
411 written += o.print(
"<CurrentConnectionIDs>");
412 written += o.print(
StrView(ids ? ids :
"0").c_str());
413 written += o.print(
"</CurrentConnectionIDs>");
419 const char* protocolInfo,
420 const char* connectionID,
421 const char* direction) {
424 out,
"GetCurrentConnectionInfoResponse",
"ConnectionManager",
425 [protocolInfo, connectionID, direction](Print& o,
void* ref) ->
size_t {
430 written += o.print(
"<RcsID>0</RcsID>");
431 written += o.print(
"<AVTransportID>0</AVTransportID>");
432 written += o.print(
"<ProtocolInfo>");
433 written += o.print(
StrView(protocolInfo).c_str());
434 written += o.print(
"</ProtocolInfo>");
435 written += o.print(
"<PeerConnectionManager></PeerConnectionManager>");
436 written += o.print(
"<PeerConnectionID>");
437 written += o.print(
StrView(connectionID).c_str());
438 written += o.print(
"</PeerConnectionID>");
439 written += o.print(
"<Direction>");
440 written += o.print(
StrView(direction).c_str());
441 written += o.print(
"</Direction>");
442 written += o.print(
"<Status>OK</Status>");
449 const char* requestPath,
451 bool& is_subscribe) {
454 is_subscribe =
false;
468 client->
replyError(501,
"Unsupported Method");
480 "Subscriptions: active=%d pending=%d / Scheduler: size=%d "
487 (
unsigned)ESP.getFreeHeap(), (
unsigned)ESP.getFreePsram());
536 static uint64_t last_mem_log = 0;
537 const uint64_t MEM_LOG_INTERVAL_MS = 10000;
538 uint64_t now = millis();
539 if (runImmediately ||
540 (uint64_t)(now - last_mem_log) >= MEM_LOG_INTERVAL_MS) {
572 postAlive1->
time = millis() + 100;
581 bool has_error =
false;
613 "Service validation failed - missing URLs/callbacks");
633 if (!
StrView(device_path).isEmpty()) {
646 (
const uint8_t*)icon.icon_data, icon.icon_size);
649 (
const uint8_t*)icon.icon_data, icon.icon_size);
657 "Skipping service registration due to validation failure");
677 const char* requestPath,
682 assert(device_xml !=
nullptr);
683 if (device_xml !=
nullptr) {
689 [](Print& out,
void* ref) ->
size_t {
692 200,
"SUCCESS", device_xml);
701 const char* requestPath,
705 assert(device !=
nullptr);
707 assert(svc !=
nullptr);
710 return device->getSubscriptionMgr().processSubscribeRequest(*server, *svc,
716 const char* requestPath,
720 assert(device !=
nullptr);
722 assert(svc !=
nullptr);
725 return device->getSubscriptionMgr().processUnsubscribeRequest(*server, *svc,
Represents a request to invoke a remote DLNA service action.
Definition: Action.h:104
void addArgument(Argument arg)
Definition: Action.h:113
void setAction(const char *act)
Definition: Action.h:155
const char * getAction()
Definition: Action.h:157
Device Attributes and generation of XML using urn:schemas-upnp-org:device-1-0. We could just return a...
Definition: DLNADeviceInfo.h:28
Vector< DLNAServiceInfo > & getServices()
Provides all service definitions.
Definition: DLNADeviceInfo.h:212
DLNAServiceInfo & getService(const char *id)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:190
void setSubscriptionActive(bool flag)
Definition: DLNADeviceInfo.h:285
const char * getUDN()
Provide the udn uuid.
Definition: DLNADeviceInfo.h:92
const char * getBaseURL()
Provides the base url.
Definition: DLNADeviceInfo.h:122
Url & getDeviceURL()
This method returns base url/device.xml.
Definition: DLNADeviceInfo.h:133
virtual void setupServices(IHttpServer &server, IUDPService &udp)
to be implemented by subclasses
Definition: DLNADeviceInfo.h:317
DLNAServiceInfo & getServiceByAbbrev(const char *abbrev)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:200
const char * getDeviceType()
Definition: DLNADeviceInfo.h:86
Vector< Icon > & getIcons()
Provides all icons.
Definition: DLNADeviceInfo.h:246
Translates DLNA UDP Requests to Schedule so that we can schedule a reply.
Definition: DLNADeviceRequestParser.h:15
Schedule * parse(DLNADeviceInfo &device, RequestData &req)
Definition: DLNADeviceRequestParser.h:20
void addMSearchST(const char *accept)
Definition: DLNADeviceRequestParser.h:18
Setup of a Basic DLNA Device service. The device registers itself to the network and answers to the D...
Definition: DLNADevice.h:47
void * reference
Definition: DLNADevice.h:506
void setSchedulerIntervalMs(uint32_t ms)
Set scheduler interval in milliseconds.
Definition: DLNADevice.h:515
uint64_t next_subscriptions_timeout_ms
Definition: DLNADevice.h:505
int loopUDPMessages()
Process incoming UDP and execute scheduled replies.
Definition: DLNADevice.h:192
void * getReference() override
Gets the reference pointer.
Definition: DLNADevice.h:476
static void deviceXMLCallback(IClientHandler &client, IHttpServer *server, const char *requestPath, HttpRequestHandlerLine *hl)
callback to provide device XML
Definition: DLNADevice.h:676
bool is_active
Definition: DLNADevice.h:492
void setDeviceInfo(DLNADeviceInfo &device)
Definition: DLNADevice.h:508
uint64_t subscriptions_interval_ms
Definition: DLNADevice.h:502
void end() override
Stops the processing and releases the resources.
Definition: DLNADevice.h:119
void setReference(void *ref) override
Sets a reference pointer that can be used to associate application.
Definition: DLNADevice.h:473
void setSubscriptionsIntervalMs(uint32_t ms)
Set subscription publish interval in milliseconds.
Definition: DLNADevice.h:523
DLNAServiceInfo * getServiceByEventPath(const char *requestPath) override
Definition: DLNADevice.h:220
static size_t printReplyXML(Print &out, const char *replyName, const char *serviceId, std::function< size_t(Print &, void *)> valuesWriter=nullptr, void *ref=nullptr)
Builds a standard SOAP reply envelope.
Definition: DLNADevice.h:355
uint32_t getSchedulerIntervalMs() const
Get scheduler interval in milliseconds.
Definition: DLNADevice.h:518
static bool handleUnsubscribe(IClientHandler *client, IHttpServer *server, const char *requestPath, HttpRequestHandlerLine *hl)
Handle UNSUBSCRIBE requests.
Definition: DLNADevice.h:715
DLNAServiceInfo & getServiceByAbbrev(const char *abbrev) override
Get Service by subscription ns abbrev.
Definition: DLNADevice.h:213
static void parseActionRequest(IHttpServer *server, IClientHandler &client, const char *requestPath, HttpRequestHandlerLine *hl, ActionRequest &action)
Parses the SOAP content of a DLNA action request.
Definition: DLNADevice.h:277
bool setupScheduler()
Schedule PostAlive messages.
Definition: DLNADevice.h:564
uint64_t next_scheduler_timeout_ms
Definition: DLNADevice.h:504
IUDPService * p_udp
Definition: DLNADevice.h:499
void logScheduledStatus(bool runImmediately=false)
Definition: DLNADevice.h:535
bool begin(DLNADeviceInfo &device, IUDPService &udp, IHttpServer &server) override
start the
Definition: DLNADevice.h:54
int loopPublishSubscriptions()
Publish pending subscription notifications.
Definition: DLNADevice.h:180
static size_t replyGetCurrentConnectionInfo(Print &out, const char *protocolInfo, const char *connectionID, const char *direction)
Definition: DLNADevice.h:418
IHttpServer * p_server
Definition: DLNADevice.h:500
Scheduler scheduler
Definition: DLNADevice.h:495
uint32_t post_alive_repeat_ms
Definition: DLNADevice.h:494
DLNAServiceInfo & getService(const char *id) override
Provide addess to the service information.
Definition: DLNADevice.h:208
bool loop(int loopAction=RUN_ALL) override
Definition: DLNADevice.h:142
DLNADeviceInfo * p_device_info
Definition: DLNADevice.h:498
bool validateServiceInfo(const DLNAServiceInfo &service)
Validates that all required service URLs and callbacks are defined.
Definition: DLNADevice.h:579
void setPostAliveRepeatMs(uint32_t ms) override
Definition: DLNADevice.h:260
DLNADeviceRequestParser parser
Definition: DLNADevice.h:497
static size_t replyGetProtocolInfo(Print &out, const char *source="", const char *sink="")
Definition: DLNADevice.h:385
SubscriptionMgrDevice< ClientType > subscription_mgr
Definition: DLNADevice.h:496
void logStatus()
Definition: DLNADevice.h:478
virtual bool setupDLNAServer(IHttpServer &srv)
set up Web Server to handle Service Addresses
Definition: DLNADevice.h:620
static bool handleSubscription(IHttpServer *server, IClientHandler *client, const char *requestPath, HttpRequestHandlerLine *hl, bool &is_subscribe)
Static handler for SUBSCRIBE/UNSUBSCRIBE requests on service event URLs.
Definition: DLNADevice.h:448
uint32_t getSubscriptionsIntervalMs() const
Get subscription publish interval in milliseconds.
Definition: DLNADevice.h:528
bool setupParser()
Definition: DLNADevice.h:549
DLNADeviceInfo & getDeviceInfo() override
Provides the device.
Definition: DLNADevice.h:250
bool isSchedulerActive() override
Checks if the scheduler is active.
Definition: DLNADevice.h:256
bool loopServer() override
Process http server loop.
Definition: DLNADevice.h:183
ISubscriptionMgrDevice & getSubscriptionMgr() override
Get subscription manager for event handling.
Definition: DLNADevice.h:114
static size_t replyGetCurrentConnectionIDs(Print &out, const char *ids)
Definition: DLNADevice.h:402
void setSubscriptionsActive(bool flag) override
Enable or disable subscription notifications: call before begin.
Definition: DLNADevice.h:263
uint64_t scheduler_interval_ms
Definition: DLNADevice.h:501
bool isSubscriptionsActive() const override
Check if subscription notifications are active.
Definition: DLNADevice.h:272
void setSchedulerActive(bool flag) override
We can activate/deactivate the scheduler.
Definition: DLNADevice.h:253
static bool handleSubscribe(IClientHandler *client, IHttpServer *server, const char *requestPath, HttpRequestHandlerLine *hl)
Handle SUBSCRIBE requests.
Definition: DLNADevice.h:700
DLNADevice()
Definition: DLNADevice.h:49
bool is_subscriptions_active
Definition: DLNADevice.h:493
void addChange(const char *serviceAbbrev, std::function< size_t(Print &, void *)> changeWriter, void *ref) override
Record a state variable change for subscription notifications.
Definition: DLNADevice.h:232
Attributes needed for the DLNA Service Definition.
Definition: DLNAServiceInfo.h:18
http_callback control_cb
Definition: DLNAServiceInfo.h:44
http_callback scp_cb
Definition: DLNAServiceInfo.h:43
Str event_sub_url
Definition: DLNAServiceInfo.h:41
Str scpd_url
Definition: DLNAServiceInfo.h:39
http_callback event_sub_cb
Definition: DLNAServiceInfo.h:45
Str control_url
Definition: DLNAServiceInfo.h:40
Used to register and process callbacks.
Definition: HttpRequestHandlerLine.h:12
void ** context
Definition: HttpRequestHandlerLine.h:37
Definition: IHttpServer.h:19
virtual HttpRequestHeader & requestHeader()=0
virtual void replyNotFound()=0
virtual void reply(const char *contentType, Stream &inputStream, int size, int status=200, const char *msg=SUCCESS)=0
virtual void replyError(int err, const char *msg="Internal Server Error")=0
virtual Client * client()=0
Abstract interface for DLNA device functionality.
Definition: IDevice.h:30
Abstract interface for HTTP server functionality.
Definition: IHttpServer.h:50
virtual void * getReference()=0
virtual bool doLoop()=0
Process server loop.
virtual void on(const char *url, TinyMethodID method, web_callback_fn fn, void *ctx[]=nullptr, int ctxCount=0)=0
virtual void setReference(void *reference)=0
virtual void rewrite(const char *from, const char *to)=0
Abstract interface for UPnP event subscription management.
Definition: ISubscriptionMgrDevice.h:27
virtual void setSubscriptionsActive(bool flag)=0
Enable/disable subscription processing.
virtual void end()=0
Cleanup and stop subscription manager.
Abstract Interface for UDP API.
Definition: IUDPService.h:33
virtual RequestData receive()=0
Receive incoming UDP data and peer information.
virtual bool begin(int port)=0
Initialize UDP service on specified port.
Information about the icon.
Definition: Icon.h:10
Send out PostAlive messages: Repeated every 5 seconds.
Definition: Schedule.h:282
Send out ByeBye message.
Definition: Schedule.h:356
Scheduler which processes all due Schedules (to send out UDP replies)
Definition: Scheduler.h:15
int execute(IUDPService &udp)
Execute all due schedules.
Definition: Scheduler.h:30
void setActive(bool flag)
Definition: Scheduler.h:81
bool isActive()
Definition: Scheduler.h:83
int size()
Number of queued schedules.
Definition: Scheduler.h:79
void add(Schedule *schedule)
Add a schedule to the scheduler.
Definition: Scheduler.h:18
A simple wrapper to provide string functions on char*. If the underlying char* is a const we do not a...
Definition: StrView.h:18
virtual bool equals(const char *str)
checks if the string equals indicated parameter string
Definition: StrView.h:177
virtual bool contains(const char *str)
checks if the string contains a substring
Definition: StrView.h:284
Heap-backed string utility used throughout tiny_dlna.
Definition: Str.h:27
bool endsWith(const char *suffix) const
True if ends with suffix (case-sensitive)
Definition: Str.h:175
const char * c_str() const
C-string pointer to internal buffer.
Definition: Str.h:88
Manages UPnP event subscriptions and queued notifications for a DLNA device.
Definition: SubscriptionMgrDevice.h:91
URL parser which breaks a full url string up into its individual parts.
Definition: Url.h:18
const char * path()
Definition: Url.h:40
Lightweight wrapper around std::vector with Arduino-friendly helpers and a pluggable allocator.
Definition: Vector.h:39
static void unEscape(Str &str)
Expands the predefined XML entities (< > " ' &)
Definition: XMLAttributeParser.h:203
Helper class that implements a Print interface to accumulate XML data and then parse it using XMLPars...
Definition: XMLParserPrint.h:16
size_t write(uint8_t ch) override
Writes a single byte to the buffer (Print interface)
Definition: XMLParserPrint.h:32
void end()
Resets the internal buffer.
Definition: XMLParserPrint.h:87
bool parse(Str &outNodeName, Vector< Str > &outPath, Str &outText, Str &outAttributes)
Parses the accumulated XML data and returns results via output parameters.
Definition: XMLParserPrint.h:59
#define DLNA_MAX_URL_LEN
app-wide max URL length
Definition: dlna_config.h:61
#define XML_PARSER_BUFFER_SIZE
Define XML parse buffer size.
Definition: dlna_config.h:41
#define DLNA_LOOP_DELAY_MS
Define delay in ms for main DLNA loop.
Definition: dlna_config.h:5
#define DLNA_RUN_SCHEDULER_EVERY_MS
Define scheduler run interval in ms.
Definition: dlna_config.h:10
#define DLNA_RUN_SUBSCRIPTIONS_EVERY_MS
Define subscription publish interval in ms.
Definition: dlna_config.h:15
Definition: Allocator.h:13
@ RUN_UDP
Definition: IDevice.h:18
@ RUN_SERVER
Definition: IDevice.h:18
@ RUN_ALL
Definition: IDevice.h:18
@ RUN_SUBSCRIPTIONS
Definition: IDevice.h:18
@ T_UNSUBSCRIBE
Definition: HttpHeader.h:46
@ T_SUBSCRIBE
Definition: HttpHeader.h:47
@ T_GET
Definition: HttpHeader.h:37
@ T_POST
Definition: HttpHeader.h:39
void(* web_callback_fn)(IClientHandler &client, IHttpServer *server, const char *requestPath, HttpRequestHandlerLine *handlerLine)
Definition: IHttpServer.h:40
Provides information of the received UDP which consists of the (xml) data and the peer address and po...
Definition: IUDPService.h:22
An individual Schedule (to send out UDP messages)
Definition: Schedule.h:18
uint64_t time
Definition: Schedule.h:21
uint32_t repeat_ms
Definition: Schedule.h:23
Functions to efficiently output XML. XML data contains a lot of redundancy so it is more memory effic...
Definition: XMLPrinter.h:56
size_t printNodeBegin(const char *node, const char *attributes=nullptr, const char *ns=nullptr)
Prints the beginning of an XML node.
Definition: XMLPrinter.h:314
size_t printf(const char *fmt,...)
printf-style helper that formats into an internal buffer and writes to the configured Print output.
Definition: XMLPrinter.h:248
size_t printNodeEnd(const char *node, const char *ns=nullptr)
Prints the end of an XML node.
Definition: XMLPrinter.h:352