Standalone manager for UPnP/DLNA event subscriptions used by control points and devices.
More...
#include <SubscriptionMgrControlPoint.h>
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:
- Perform SUBSCRIBE requests and store subscription metadata on DLNAServiceInfo (SID, subscription_state, timestamps).
- Perform UNSUBSCRIBE requests and clear local metadata.
- Register an HTTP notify handler and parse incoming NOTIFY messages incrementally using XMLParserPrint to keep RAM usage low.
- Invoke a user-provided callback for property change events.
Thread / lifetime notes:
- The manager does not own injected pointers (HttpServer, IHttpRequest, IUDPService, Url, devices vector). The caller must ensure these outlive the manager.
- All public methods are safe to call from the single-threaded Arduino loop context. They are not thread-safe for concurrent access.
◆ 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
-
| sid | Null-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()
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
-
| server | Pointer to the HttpServer handling the request. |
| requestPath | Path of the incoming request (unused by implementation). |
| handlerLine | Pointer 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
-
| active | true 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
-
| callback | Function 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.
|
| ref | Opaque 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
-
| seconds | Desired 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
-
| ms | Milliseconds 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
-
| server | HttpServer used to receive NOTIFY callbacks. |
| port | Optional 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()
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
-
| http | Reference to the HTTP helper used to perform SUBSCRIBE/ UNSUBSCRIBE requests. |
| udp | Reference to the UDP discovery/service helper (not owned). |
| localCallbackUrl | URL that remote services should use when delivering NOTIFY messages (manager registers an endpoint based on this path). |
| devices | Vector 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
-
| subscribe | true 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
-
| device | Reference 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
-
| service | Reference 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
-
| device | Device 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
-
| service | Service 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
-
| sid | Subscription 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.
◆ 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) {
"- 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
◆ 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
The documentation for this class was generated from the following file: