22template <
typename ClientType>
55 std::function<size_t(Print&,
void*)>
writer;
90template <
typename ClientType>
131 const char* sid =
nullptr,
132 uint32_t timeoutSec = 1800)
override {
142 if (
StrView(callbackUrl).isEmpty()) {
145 "subscribe: missing CALLBACK header for new subscription");
153 if (!renewed.
isEmpty())
return renewed;
158 if (
StrView(callbackUrl).isEmpty()) {
160 "subscribe: missing CALLBACK header for new subscription");
166 snprintf(buffer,
sizeof(buffer),
"uuid:%lu", millis());
174 s->
expires_at = millis() + (uint64_t)timeoutSec * 1000ULL;
178 auto existing_sub = *it;
179 if (existing_sub->service == &service &&
183 "subscribe: found existing subscription for service "
184 "'%s' and callback '%s', renewing SID '%s'",
186 StrView(callbackUrl).
c_str(), existing_sub->sid.c_str());
188 existing_sub->timeout_sec = timeoutSec;
189 existing_sub->expires_at = millis() + (uint64_t)timeoutSec * 1000ULL;
190 return existing_sub->sid;
217 if (pit->p_subscription == s) {
251 std::function<
size_t(Print&,
void*)> changeWriter,
252 void* ref)
override {
260 if (sub->
service != &service)
continue;
306 "pending notification dropped: missing subscription");
313 snprintf(seqBuf,
sizeof(seqBuf),
"%d", pn.
seq);
337 "dropping notify to %s after %d errors with rc=%d %s",
338 cbUrl.
url(), it->error_count, rc,
350 "Published: %d notifications, %d remaining (for %d subscriptions)",
404 uint64_t now = millis();
426 const char* callbackUrl, uint32_t timeoutSec) {
433 ex->
expires_at = millis() + (uint64_t)timeoutSec * 1000ULL;
470 const char* service_abbrev =
475 written += out.println(
"<?xml version=\"1.0\"?>");
476 written += out.println(
478 "xmlns:e=\"urn:schemas-upnp-org:metadata-1-0/events\">");
479 written += out.println(
"<e:property>");
480 written += out.println(
"<LastChange>");
483 out_esc.print(
"<Event xmlns=\"urn:schemas-upnp-org:metadata-1-0/");
484 written += out_esc.print(service_abbrev);
485 written += out_esc.print(
"/\">");
486 written += out_esc.print(
"<InstanceID val=\"");
487 written += out_esc.print(instance_id);
488 written += out_esc.print(
"\">");
492 written += out_esc.print(
"</InstanceID>");
493 written += out_esc.print(
"</Event>");
495 written += out.println();
496 written += out.println(
"</LastChange>");
497 written += out.println(
"</e:property>");
498 written += out.println(
"</e:propertyset>");
516 const char* callbackHeader =
518 const char* timeoutHeader =
520 const char* sidHeader =
525 callbackHeader ? callbackHeader :
"null");
527 timeoutHeader ? timeoutHeader :
"null");
529 sidHeader ? sidHeader :
"null");
533 if (callbackHeader) {
534 cbStr = callbackHeader;
550 uint32_t tsec = 1800;
551 if (timeoutHeader &&
StrView(timeoutHeader).startsWith(
"Second-")) {
552 tsec = atoi(timeoutHeader + 7);
556 const char* callbackPtr = cbStr.
c_str();
557 const char* sidPtr = sidStr.
c_str();
559 Str sid =
subscribe(service, callbackPtr, sidPtr, tsec);
562 "subscribe request rejected (missing data)");
615 "handleUnsubscribeRequest: failed for SID %s",
616 sid ? sid :
"(null)");
Setup of a Basic DLNA Device service. The device registers itself to the network and answers to the D...
Definition: DLNADevice.h:46
Attributes needed for the DLNA Service Definition.
Definition: DLNAServiceInfo.h:18
Str service_id
Definition: DLNAServiceInfo.h:38
int instance_id
Definition: DLNAServiceInfo.h:56
const char * subscription_namespace_abbrev
Definition: DLNAServiceInfo.h:53
Simple API to process get, put, post, del http requests I tried to use Arduino HttpClient,...
Definition: HttpRequest.h:31
HttpRequestHeader & request() override
Returns the request header.
Definition: HttpRequest.h:170
void setHost(const char *host) override
Sets the host name for the requests.
Definition: HttpRequest.h:52
HttpReplyHeader & reply() override
Returns the reply header.
Definition: HttpRequest.h:167
int notify(Url &url, std::function< size_t(Print &, void *)> writer, const char *mime=nullptr, void *ref=nullptr) override
Sends a NOTIFY request with streaming body.
Definition: HttpRequest.h:96
void setTimeout(int ms) override
Sets the timeout.
Definition: HttpRequest.h:189
void setAgent(const char *agent) override
Sets the user agent.
Definition: HttpRequest.h:173
Definition: IHttpServer.h:19
virtual HttpRequestHeader & requestHeader()=0
virtual Client * client()=0
virtual HttpReplyHeader & replyHeader()=0
virtual void endClient()=0
Abstract interface for HTTP server functionality.
Definition: IHttpServer.h:50
Abstract interface for UPnP event subscription management.
Definition: ISubscriptionMgrDevice.h:27
Lock-free double linked list using atomic operations.
Definition: ListLockFree.h:28
Class with does not do any output: it can be used to determine the length of the output.
Definition: NullPrint.h:12
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 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 equals(const char *str)
checks if the string equals indicated parameter string
Definition: StrView.h:177
Heap-backed string utility used throughout tiny_dlna.
Definition: Str.h:27
bool isEmpty() const
True if empty.
Definition: Str.h:54
void trim()
Trim spaces on both ends.
Definition: Str.h:235
const char * c_str() const
C-string pointer to internal buffer.
Definition: Str.h:88
bool replace(const char *toReplace, const char *replaced, int startPos=0)
Replace first occurrence of toReplace with replaced starting at startPos.
Definition: Str.h:269
Manages UPnP event subscriptions and queued notifications for a DLNA device.
Definition: SubscriptionMgrDevice.h:91
Str subscribe(DLNAServiceInfo &service, const char *callbackUrl, const char *sid=nullptr, uint32_t timeoutSec=1800) override
Add or renew a subscription for a service.
Definition: SubscriptionMgrDevice.h:130
void addChange(DLNAServiceInfo &service, std::function< size_t(Print &, void *)> changeWriter, void *ref) override
Enqueue a state-variable change for delivery.
Definition: SubscriptionMgrDevice.h:250
int publish() override
Deliver queued notifications.
Definition: SubscriptionMgrDevice.h:288
Str renewSubscription(DLNAServiceInfo &service, const char *sid, const char *callbackUrl, uint32_t timeoutSec)
Try to renew an existing subscription identified by SID for the given service. If successful the subs...
Definition: SubscriptionMgrDevice.h:425
bool unsubscribe(DLNAServiceInfo &service, const char *sid) override
Remove a subscription identified by SID.
Definition: SubscriptionMgrDevice.h:211
size_t pendingCount() override
Number of queued pending notifications.
Definition: SubscriptionMgrDevice.h:365
void end() override
Convenience method to disable subscriptions at the end of the lifecycle.
Definition: SubscriptionMgrDevice.h:378
void setSubscriptionsActive(bool flag) override
Enable or disable subscription delivery.
Definition: SubscriptionMgrDevice.h:375
ListLockFree< Subscription * > subscriptions
Definition: SubscriptionMgrDevice.h:392
SubscriptionMgrDevice()=default
Construct a new Subscription Manager.
void clear()
Clear all subscriptions and pending notifications.
Definition: SubscriptionMgrDevice.h:447
bool processUnsubscribeRequest(IHttpServer &server, DLNAServiceInfo &service, IClientHandler *client)
Handle UNSUBSCRIBE request including HTTP response.
Definition: SubscriptionMgrDevice.h:597
static size_t createXML(Print &out, void *ref)
Generate the propertyset XML for a single variable and write it to the provided Print instance....
Definition: SubscriptionMgrDevice.h:467
~SubscriptionMgrDevice()
Destroy the Subscription Manager.
Definition: SubscriptionMgrDevice.h:111
bool isSubscriptionsActive() override
Query whether subscription delivery is active.
Definition: SubscriptionMgrDevice.h:384
bool processSubscribeRequest(IHttpServer &server, DLNAServiceInfo &service, IClientHandler *client)
Handle SUBSCRIBE request including HTTP response.
Definition: SubscriptionMgrDevice.h:513
bool is_active
Definition: SubscriptionMgrDevice.h:394
size_t subscriptionsCount() override
Number of active subscriptions.
Definition: SubscriptionMgrDevice.h:359
void removeExpired()
Remove expired subscriptions.
Definition: SubscriptionMgrDevice.h:403
ListLockFree< PendingNotification > pending_list
Definition: SubscriptionMgrDevice.h:393
URL parser which breaks a full url string up into its individual parts.
Definition: Url.h:18
const char * host()
Definition: Url.h:41
const char * url()
Definition: Url.h:39
#define DLNA_HTTP_REQUEST_TIMEOUT_MS
Define the default http request timeout.
Definition: dlna_config.h:25
#define MAX_NOTIFY_RETIES
Define maximum number of notify retries.
Definition: dlna_config.h:173
Definition: Allocator.h:13
Print wrapper that escapes & < > " ' while forwarding to an underlying Print. Returns the expanded ou...
Definition: EscapingPrint.h:9
Representation of a queued notification to be delivered later.
Definition: SubscriptionMgrDevice.h:52
int error_count
Definition: SubscriptionMgrDevice.h:58
int seq
Definition: SubscriptionMgrDevice.h:59
void * ref
Definition: SubscriptionMgrDevice.h:57
Subscription * p_subscription
Definition: SubscriptionMgrDevice.h:53
std::function< size_t(Print &, void *)> writer
Definition: SubscriptionMgrDevice.h:55
Represents a single event subscription for a service.
Definition: SubscriptionMgrDevice.h:34
uint32_t timeout_sec
Definition: SubscriptionMgrDevice.h:37
Str sid
Definition: SubscriptionMgrDevice.h:35
uint32_t seq
Definition: SubscriptionMgrDevice.h:38
DLNAServiceInfo * service
Definition: SubscriptionMgrDevice.h:40
Str callback_url
Definition: SubscriptionMgrDevice.h:36
uint64_t expires_at
Definition: SubscriptionMgrDevice.h:39