Arduino DLNA Server
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
tiny_dlna::SubscriptionMgrControlPoint Class Reference

Standalone manager for UPnP/DLNA event subscriptions used by control points and devices. More...

#include <SubscriptionMgrControlPoint.h>

Public Member Functions

void setup (IHttpRequest &http, IUDPService &udp, Url &localCallbackUrl, DLNADeviceInfo &device)
 Inject required dependencies and initialize the manager.
 
void setHttpServer (IHttpServer &server)
 Attach an HttpServer instance and register the internal NOTIFY handler.
 
bool hasEventSubscriptionCallback ()
 Return true when an application notification callback is set.
 
void setEventSubscriptionCallback (std::function< void(const char *sid, const char *varName, const char *newValue, void *reference)> callback, void *ref=nullptr)
 Register a callback invoked when event properties change.
 
void end ()
 Tear down the manager. This clears the internal setup state but does not perform network unsubscribe calls.
 
void setEventSubscriptionDurationSec (int seconds=3600)
 Configure desired subscription duration in seconds.
 
void setEventSubscriptionRetryMs (int ms)
 Set the retry threshold in milliseconds.
 
void setEventSubscriptionActive (bool active)
 Turn automatic event subscription on or off.
 
uint64_t getLastEventNotifyMs ()
 Get the timestamp of the last received NOTIFY message.
 
bool loop ()
 Periodic work to manage subscription renewals and retries.
 
bool isActive ()
 Query whether the manager is currently active.
 

Protected Member Functions

void updateSubscriptions ()
 Evaluate and apply subscription state transitions.
 
void updateReceived (const char *sid)
 Update internal and service metadata when a NOTIFY is received.
 
DLNAServiceInfogetServiceInfoBySID (const char *sid)
 
void attachHttpServer (IHttpServer &server)
 Locate a DLNAServiceInfo by its stored SID.
 
bool subscribeNotifications (bool subscribe=true)
 Convenience to subscribe or unsubscribe all services of the currently selected device.
 
bool subscribeToDevice (DLNADeviceInfo &device)
 Subscribe to all services exposed by device.
 
bool unsubscribeFromDevice (DLNADeviceInfo &device)
 Unsubscribe from all services of device.
 
bool subscribeToService (DLNAServiceInfo &service)
 Subscribe to a single eventing service described by service.
 
bool unsubscribeFromService (DLNAServiceInfo &service)
 Unsubscribe from a single service.
 

Static Protected Member Functions

static void notifyHandler (IHttpServer *server, const char *requestPath, HttpRequestHandlerLine *handlerLine)
 HTTP NOTIFY handler registered with HttpServer.
 

Protected Attributes

void * event_callback_ref = nullptr
 
bool is_active = false
 
SubscriptionState subscription_state = SubscriptionState::Unsubscribed
 
bool is_setup = false
 
uint64_t subscribe_timeout = 0
 
uint32_t event_subscription_duration_sec = 3600
 
uint32_t event_subscription_retry_ms = 0
 
bool event_subscription_active = false
 
uint64_t last_event_notify_ms = 0
 
IHttpRequestp_http = nullptr
 
IUDPServicep_udp = nullptr
 
IHttpServerp_http_server = nullptr
 
Urlp_local_url = nullptr
 
DLNADeviceInfop_device = nullptr
 
DLNAServiceInfo NO_SERVICE
 
uint64_t processing_timeout = 0
 
std::function< void(const char *sid, const char *varName, const char *newValue, void *reference)> event_callback
 

Detailed Description

Standalone manager for UPnP/DLNA event subscriptions used by control points and devices.

This class centralizes SUBSCRIBE / UNSUBSCRIBE lifecycle management and NOTIFY handling for UPnP event subscriptions. It is intentionally independent from DLNAControlPoint: the owner injects dependencies via setup() and may store this manager as a value member (no dynamic allocation required).

Responsibilities:

Thread / lifetime notes:

Member Function Documentation

◆ attachHttpServer()

void tiny_dlna::SubscriptionMgrControlPoint::attachHttpServer ( IHttpServer server)
inlineprotected

Locate a DLNAServiceInfo by its stored SID.

The method searches the currently selected device first (if set) and then across the injected device list. If no matching SID is found a reference to the internal sentinel NO_SERVICE is returned.

Parameters
sidNull-terminated subscription identifier to lookup.
Returns
Reference to the matching DLNAServiceInfo or NO_SERVICE when not found. Do NOT take ownership of the returned reference.

◆ end()

void tiny_dlna::SubscriptionMgrControlPoint::end ( )
inline

Tear down the manager. This clears the internal setup state but does not perform network unsubscribe calls.

◆ getLastEventNotifyMs()

uint64_t tiny_dlna::SubscriptionMgrControlPoint::getLastEventNotifyMs ( )
inline

Get the timestamp of the last received NOTIFY message.

◆ getServiceInfoBySID()

DLNAServiceInfo & tiny_dlna::SubscriptionMgrControlPoint::getServiceInfoBySID ( const char *  sid)
inlineprotected

◆ hasEventSubscriptionCallback()

bool tiny_dlna::SubscriptionMgrControlPoint::hasEventSubscriptionCallback ( )
inline

Return true when an application notification callback is set.

◆ isActive()

bool tiny_dlna::SubscriptionMgrControlPoint::isActive ( )
inline

Query whether the manager is currently active.

Active means the manager is allowed to maintain subscriptions (it does not imply that subscriptions currently exist).

◆ loop()

bool tiny_dlna::SubscriptionMgrControlPoint::loop ( )
inline

Periodic work to manage subscription renewals and retries.

Call this from the main Arduino loop() if you want automatic renewal and retry behavior. Returns true when the manager is active.

Returns
true when the manager is active and loop processing occurred.

◆ notifyHandler()

static void tiny_dlna::SubscriptionMgrControlPoint::notifyHandler ( IHttpServer server,
const char *  requestPath,
HttpRequestHandlerLine handlerLine 
)
inlinestaticprotected

HTTP NOTIFY handler registered with HttpServer.

This static method is registered as the endpoint that receives event NOTIFY messages from remote UPnP services. It:

The handler accepts the server, request path and the handler context line which embeds the pointer to the manager instance.

Parameters
serverPointer to the HttpServer handling the request.
requestPathPath of the incoming request (unused by implementation).
handlerLinePointer to the server-provided handler context which contains the manager instance in its context array.

◆ setEventSubscriptionActive()

void tiny_dlna::SubscriptionMgrControlPoint::setEventSubscriptionActive ( bool  active)
inline

Turn automatic event subscription on or off.

When enabled and the manager is setup and active the manager will attempt to subscribe to services and renew existing subscriptions as needed. When disabled the manager will attempt to unsubscribe from services if currently subscribed.

Parameters
activetrue to maintain subscriptions automatically; false to stop and attempt unsubscription.

◆ setEventSubscriptionCallback()

void tiny_dlna::SubscriptionMgrControlPoint::setEventSubscriptionCallback ( std::function< void(const char *sid, const char *varName, const char *newValue, void *reference)>  callback,
void *  ref = nullptr 
)
inline

Register a callback invoked when event properties change.

Parameters
callbackFunction with signature void callback(const char* sid, const char* varName, const char* newValue, void* reference)
  • sid: Subscription ID string reported by the remote service (may be empty).
  • varName: Name of the changed state variable.
  • newValue: New textual value for the state variable.
  • reference: Opaque pointer provided by the caller via ref.
refOpaque caller-provided pointer forwarded to the callback.

◆ setEventSubscriptionDurationSec()

void tiny_dlna::SubscriptionMgrControlPoint::setEventSubscriptionDurationSec ( int  seconds = 3600)
inline

Configure desired subscription duration in seconds.

This value will be used in the TIMEOUT header when issuing SUBSCRIBE requests. The remote service may honor a shorter duration; the manager tracks expiry via timestamps stored on the service info.

Parameters
secondsDesired subscription lifetime in seconds (default 3600).

◆ setEventSubscriptionRetryMs()

void tiny_dlna::SubscriptionMgrControlPoint::setEventSubscriptionRetryMs ( int  ms)
inline

Set the retry threshold in milliseconds.

If no NOTIFY messages are received for a subscribed service within this interval, the manager may attempt re-subscription. A value of 0 disables this behavior.

Parameters
msMilliseconds to wait without NOTIFY before retry (0 = disabled).

◆ setHttpServer()

void tiny_dlna::SubscriptionMgrControlPoint::setHttpServer ( IHttpServer server)
inline

Attach an HttpServer instance and register the internal NOTIFY handler.

Parameters
serverHttpServer used to receive NOTIFY callbacks.
portOptional port the server listens on (default 80). This is informational; the server instance controls actual binding.

The method registers an HTTP handler at the local callback path (derived from the injected Url via setup()).

◆ setup()

void tiny_dlna::SubscriptionMgrControlPoint::setup ( IHttpRequest http,
IUDPService udp,
Url localCallbackUrl,
DLNADeviceInfo device 
)
inline

Inject required dependencies and initialize the manager.

The manager keeps non-owning pointers to the provided objects; the caller must ensure the lifetime of these objects exceeds the manager's lifetime.

Parameters
httpReference to the HTTP helper used to perform SUBSCRIBE/ UNSUBSCRIBE requests.
udpReference to the UDP discovery/service helper (not owned).
localCallbackUrlURL that remote services should use when delivering NOTIFY messages (manager registers an endpoint based on this path).
devicesVector of DLNADeviceInfo instances managed by the control point; used to find matching services.

◆ subscribeNotifications()

bool tiny_dlna::SubscriptionMgrControlPoint::subscribeNotifications ( bool  subscribe = true)
inlineprotected

Convenience to subscribe or unsubscribe all services of the currently selected device.

This is a convenience wrapper: it iterates the services of the currently selected p_device and calls the per-service subscribeToService()/unsubscribeFromService() methods.

Parameters
subscribetrue to subscribe, false to unsubscribe.
Returns
true when all attempted operations returned success; false if at least one service operation failed or no device is selected.

◆ subscribeToDevice()

bool tiny_dlna::SubscriptionMgrControlPoint::subscribeToDevice ( DLNADeviceInfo device)
inlineprotected

Subscribe to all services exposed by device.

Iterates over device.getServices() and calls subscribeToService() for each service. Subscription metadata is stored on the corresponding DLNAServiceInfo entry.

Parameters
deviceReference to the device whose services will be subscribed.
Returns
true if all subscriptions succeeded; false otherwise (partial failures result in continued attempts for remaining services).

◆ subscribeToService()

bool tiny_dlna::SubscriptionMgrControlPoint::subscribeToService ( DLNAServiceInfo service)
inlineprotected

Subscribe to a single eventing service described by service.

Performs the SUBSCRIBE HTTP request using the injected IHttpRequest instance. On success the returned SID is stored in DLNAServiceInfo::subscription_id and timing metadata is updated.

Use event_subscription_duration_sec to control the TIMEOUT header.

Parameters
serviceReference to the DLNAServiceInfo describing the eventing service to subscribe to. The method updates the service object in-place.
Returns
true when subscription succeeded and the SID was recorded.

◆ unsubscribeFromDevice()

bool tiny_dlna::SubscriptionMgrControlPoint::unsubscribeFromDevice ( DLNADeviceInfo device)
inlineprotected

Unsubscribe from all services of device.

Iterates through the device's services and calls unsubscribeFromService() for each. Errors are logged and the method returns false if one or more unsubscriptions failed.

Parameters
deviceDevice whose services should be unsubscribed.
Returns
true if all unsubscriptions succeeded; false otherwise.

◆ unsubscribeFromService()

bool tiny_dlna::SubscriptionMgrControlPoint::unsubscribeFromService ( DLNAServiceInfo service)
inlineprotected

Unsubscribe from a single service.

Issues an UNSUBSCRIBE request. On success the manager clears local SID and timing metadata stored in service. If the remote call fails the subscription_state is set to Unsubscribing and the error is returned.

Parameters
serviceService information for the target eventing service.
Returns
true when the remote UNSUBSCRIBE returned HTTP 200 and local metadata was cleared; false otherwise.

◆ updateReceived()

void tiny_dlna::SubscriptionMgrControlPoint::updateReceived ( const char *  sid)
inlineprotected

Update internal and service metadata when a NOTIFY is received.

This method should be called early when a NOTIFY is processed to reset the last-received timestamp and mark the service as confirmed.

Parameters
sidSubscription ID (SID) extracted from the incoming NOTIFY request. If sid is nullptr or not found the call is a no-op.

◆ updateSubscriptions()

void tiny_dlna::SubscriptionMgrControlPoint::updateSubscriptions ( )
inlineprotected

Evaluate and apply subscription state transitions.

This helper inspects the manager-level flags and current SubscriptionState and triggers subscribe/unsubscribe actions by delegating to subscribeNotifications(). It implements the high-level policy:

  • If the manager should be maintaining subscriptions and there is no active subscription, trigger subscribing.
  • If the manager should not maintain subscriptions but a subscription exists, trigger unsubscribing.

The method does not parse NOTIFY payloads or manipulate per-service metadata directly; those responsibilities remain in the per-service subscribe/unsubscribe helpers and the notify handler.

This method is invoked by setEventSubcriptionActive() and loop() to drive periodic subscription maintenance.

Member Data Documentation

◆ event_callback

std::function<void(const char* sid, const char* varName, const char* newValue, void* reference)> tiny_dlna::SubscriptionMgrControlPoint::event_callback
protected
Initial value:
= [](const char* sid, const char* varName,
const char* newValue, void* reference) {
DlnaLogger.log(DlnaLogLevel::Debug,
"- Event notification: SID='%s' var='%s' value='%s'",
sid ? sid : "", varName ? varName : "",
newValue ? newValue : "");
}

◆ event_callback_ref

void* tiny_dlna::SubscriptionMgrControlPoint::event_callback_ref = nullptr
protected

◆ event_subscription_active

bool tiny_dlna::SubscriptionMgrControlPoint::event_subscription_active = false
protected

◆ event_subscription_duration_sec

uint32_t tiny_dlna::SubscriptionMgrControlPoint::event_subscription_duration_sec = 3600
protected

◆ event_subscription_retry_ms

uint32_t tiny_dlna::SubscriptionMgrControlPoint::event_subscription_retry_ms = 0
protected

◆ is_active

bool tiny_dlna::SubscriptionMgrControlPoint::is_active = false
protected

◆ is_setup

bool tiny_dlna::SubscriptionMgrControlPoint::is_setup = false
protected

◆ last_event_notify_ms

uint64_t tiny_dlna::SubscriptionMgrControlPoint::last_event_notify_ms = 0
protected

◆ NO_SERVICE

DLNAServiceInfo tiny_dlna::SubscriptionMgrControlPoint::NO_SERVICE
protected

◆ p_device

DLNADeviceInfo* tiny_dlna::SubscriptionMgrControlPoint::p_device = nullptr
protected

◆ p_http

IHttpRequest* tiny_dlna::SubscriptionMgrControlPoint::p_http = nullptr
protected

◆ p_http_server

IHttpServer* tiny_dlna::SubscriptionMgrControlPoint::p_http_server = nullptr
protected

◆ p_local_url

Url* tiny_dlna::SubscriptionMgrControlPoint::p_local_url = nullptr
protected

◆ p_udp

IUDPService* tiny_dlna::SubscriptionMgrControlPoint::p_udp = nullptr
protected

◆ processing_timeout

uint64_t tiny_dlna::SubscriptionMgrControlPoint::processing_timeout = 0
protected

◆ subscribe_timeout

uint64_t tiny_dlna::SubscriptionMgrControlPoint::subscribe_timeout = 0
protected

◆ subscription_state

SubscriptionState tiny_dlna::SubscriptionMgrControlPoint::subscription_state = SubscriptionState::Unsubscribed
protected

The documentation for this class was generated from the following file: