Arduino DLNA Server
Loading...
Searching...
No Matches
Schedule.h
Go to the documentation of this file.
1#pragma once
2
3#include "DLNADeviceInfo.h"
4#include "IUDPService.h"
5
6#define MAX_TMP_SIZE 300
7#define ALIVE_MS 0
8#define MAX_AGE (60 * 60 * 24)
9
10namespace tiny_dlna {
11
12
17struct Schedule {
18 //int id = 0;
19 // scheduled next execution time
20 uint64_t time = 0;
21 // repeat every n ms
22 uint32_t repeat_ms = 0;
23 // repeat until;
24 uint64_t end_time = 0;
25 // schedle is active
26 bool active = false;
27
28 virtual bool process(IUDPService &udp) { return false; }
29
30 virtual const char *name() { return "n/a"; };
31
32 operator bool() { return active; }
33};
34
39class MSearchSchedule : public Schedule {
40 public:
41 MSearchSchedule(IPAddressAndPort addr, const char *searchTarget, int mx = 3) {
42 address = addr;
43 search_target = searchTarget;
44 max_age = mx;
45 }
46 const char *name() override { return "MSearch"; }
47
48 bool process(IUDPService &udp) override {
49 // we keep the data on the stack
50 DlnaLogger.log(DlnaLogLevel::Debug, "Sending %s for %s to %s", name(), search_target,
52
53 char buffer[MAX_TMP_SIZE] = {0};
54 const char *tmp =
55 "M-SEARCH * HTTP/1.1\r\n"
56 "HOST: %s\r\n"
57 "MAN: \"ssdp:discover\"\r\n"
58 "MX: %d\r\n"
59 "ST: %s\r\n\r\n";
60 int n = snprintf(buffer, MAX_TMP_SIZE, tmp, address.toString(), max_age,
62 assert(n < MAX_TMP_SIZE);
63 DlnaLogger.log(DlnaLogLevel::Info, "sending: %s", buffer);
64 udp.send(address, (uint8_t *)buffer, n);
65 return true;
66 }
67
68 protected:
69 int max_age = 3;
71 const char *search_target = nullptr;
72};
73
79 public:
81 address = addr;
82 p_device = &device;
83 }
84 const char *name() override { return "MSearchReply"; }
85
86 bool process(IUDPService &udp) override {
87 // we keep the data on the stack
88 DlnaLogger.log(DlnaLogLevel::Debug, "Sending %s for %s to %s", name(),
90
91 DLNADeviceInfo &device = *p_device;
92 char buffer[MAX_TMP_SIZE] = {0};
93 const char *tmp =
94 "HTTP/1.1 200 OK\r\n"
95 "CACHE-CONTROL: max-age = %d\r\n"
96 "LOCATION: %s\r\n"
97 "ST: %s\r\n"
98 "USN: %s\r\n\r\n";
99 int n = snprintf(buffer, MAX_TMP_SIZE, tmp, max_age,
100 device.getDeviceURL().url(), search_target.c_str(),
101 device.getUDN());
102 assert(n < MAX_TMP_SIZE);
103 DlnaLogger.log(DlnaLogLevel::Debug, "sending: %s", buffer);
104 udp.send(address, (uint8_t *)buffer, n);
105 return true;
106 }
107
111 int mx = 0;
112
113 protected:
115};
116
122class MSearchReplyCP : public Schedule {
123 public:
124 const char *name() override { return "MSearchReplyCP"; }
128
129 bool process(IUDPService &udp) override {
130 DlnaLogger.log(DlnaLogLevel::Info, "-> %s not processed", search_target.c_str());
131 return true;
132 }
133
134};
135
164 public:
165 const char *name() override { return "NotifyReplyCP"; }
166 Str nts{80};
172
173 // callback invoked by the scheduler when processing this notification.
174 // Return true if the notification was handled; false otherwise.
175 std::function<bool(NotifyReplyCP &ref)> callback;
176
177 bool process(IUDPService &udp) override {
178 if (callback(*this)){
179 DlnaLogger.log(DlnaLogLevel::Info, "%s -> %s", name(), nts.c_str());
180 return true;
181 }
182
183 DlnaLogger.log(DlnaLogLevel::Info, "-> %s not processed", nts.c_str());
184 return true;
185 }
186};
187
193 public:
194 PostAliveSchedule(DLNADeviceInfo &device, uint32_t repeatMs) {
195 p_device = &device;
196 this->repeat_ms = repeatMs;
197 }
198 const char *name() override { return "PostAlive"; }
199
200 void setRepeatMs(uint32_t ms) { this->repeat_ms = ms; }
201
202 bool process(IUDPService &udp) override {
203 DlnaLogger.log(DlnaLogLevel::Info, "Sending %s to %s", name(),
204 DLNABroadcastAddress.toString());
205 DLNADeviceInfo &device = *p_device;
206 char nt[100];
207 char usn[200];
208
209 const char *device_url = device.getDeviceURL().url();
210 int max_age = 100;
211 // announce with udn
212 process(device.getUDN(), device.getUDN(), device_url, max_age, udp);
213 // NT: upnp:rootdevice\r\n
214 setupData("upnp:rootdevice", device.getUDN(), nt, usn);
215 process(nt, usn, device_url, max_age, udp);
216 // NT: urn:schemas-upnp-org:device:MediaRenderer:1\r\n
217 setupData(device.getDeviceType(), device.getUDN(), nt, usn);
218 process(nt, usn, device_url, max_age, udp);
219
220 // announce with service udn
221 for (auto &service : device.getServices()) {
222 setupData(service.service_type, device.getUDN(), nt, usn);
223 process(nt, usn, device_url, max_age, udp);
224 }
225 return true;
226 }
227
228 protected:
230 void setupData(const char *nt, const char *udn, char *result_nt,
231 char *result_usn) {
232 strcpy(result_nt, nt);
233 strcpy(result_usn, udn);
234 strcat(result_usn, "::");
235 strcat(result_usn, nt);
236 }
237
238 bool process(const char *nt, const char *usn, const char *device_url,
239 int max_age, IUDPService &udp) {
240 // we keep the data on the stack
241 char buffer[MAX_TMP_SIZE] = {0};
242 const char *tmp =
243 "NOTIFY * HTTP/1.1\r\n"
244 "HOST:%s\r\n"
245 "CACHE-CONTROL: max-age = %d\r\n"
246 "LOCATION: %s\r\n"
247 "NT: %s\r\n"
248 "NTS: ssdp:alive\r\n"
249 "USN: %s\r\n\r\n";
250 int n = snprintf(buffer, MAX_TMP_SIZE, tmp, DLNABroadcastAddress.toString(),
251 max_age, device_url, nt, usn);
252
253 assert(n < MAX_TMP_SIZE);
254 DlnaLogger.log(DlnaLogLevel::Debug, "sending: %s", buffer);
255 udp.send(DLNABroadcastAddress, (uint8_t *)buffer, n);
256 return true;
257 }
258};
259
264class PostByeSchedule : public Schedule {
265 public:
267 const char *name() override { return "ByeBye"; }
268 bool process(IUDPService &udp) override {
269 DlnaLogger.log(DlnaLogLevel::Info, "Sending %s to %s", name(),
270 DLNABroadcastAddress.toString());
271 // we keep the data on the stack
272 char buffer[MAX_TMP_SIZE] = {0};
273 const char *tmp =
274 "NOTIFY * HTTP/1.1\r\n"
275 "HOST: %s\r\n"
276 "CACHE-CONTROL: max-age = %d\r\n"
277 "LOCATION: *\r\n"
278 "NT: %s\r\n"
279 "NTS: ssdp:byebye\r\n"
280 "USN: %s\r\n\r\n";
281 int n = snprintf(buffer, MAX_TMP_SIZE, tmp, DLNABroadcastAddress.toString(),
283
284 DlnaLogger.log(DlnaLogLevel::Debug, "sending: %s", buffer);
285 udp.send(DLNABroadcastAddress, (uint8_t *)buffer, n);
286 return true;
287 }
288
289 protected:
290 int max_age = 120;
292};
293
298class PostSubscribe : public Schedule {
299 public:
300 PostSubscribe(IPAddressAndPort address, const char *path, uint32_t sec) {
302 setDuration(sec);
303 }
304 const char *name() override { return "Subscribe"; }
305
306 bool process(IUDPService &udp) override {
308 DlnaLogger.log(DlnaLogLevel::Info, "Sending Subscribe to %s", address);
309
310 char buffer[MAX_TMP_SIZE] = {0};
311 const char *tmp =
312 "SUBSCRIBE %s HTTP/1.1\r\n"
313 "HOST: %s\r\n"
314 "CALLBACK: %s"
315 "NT: upnp-event\r\n"
316 "TIMEOUT: Second-%d\r\n\r\n";
317 int n = snprintf(buffer, MAX_TMP_SIZE, tmp, path, address.toString(),
319 assert(n < MAX_TMP_SIZE);
320 DlnaLogger.log(DlnaLogLevel::Debug, "sending: %s", buffer);
321 udp.send(address, (uint8_t *)buffer, n);
322 return true;
323 }
324
325 protected:
327 const char *path;
329
331 this->address = address;
332 this->path = path;
333 }
334
335 void setDuration(uint32_t sec) { durationSec = sec; }
336};
337
338} // namespace tiny_dlna
#define MAX_TMP_SIZE
Definition: Schedule.h:6
#define MAX_AGE
Definition: Schedule.h:8
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:151
const char * getUDN()
Provide the udn uuid.
Definition: DLNADeviceInfo.h:56
Url & getDeviceURL()
This method returns base url/device.xml.
Definition: DLNADeviceInfo.h:92
const char * getDeviceType()
Definition: DLNADeviceInfo.h:50
Abstract Interface for UDP API.
Definition: IUDPService.h:34
virtual bool send(uint8_t *data, int len)=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
const char * name() override
Definition: Schedule.h:124
Str location
Definition: Schedule.h:125
Str search_target
Definition: Schedule.h:127
bool process(IUDPService &udp) override
Definition: Schedule.h:129
Answer from device to MSearch request by sending a reply.
Definition: Schedule.h:78
Str search_target
Definition: Schedule.h:108
int mx
Definition: Schedule.h:111
bool process(IUDPService &udp) override
Definition: Schedule.h:86
MSearchReplySchedule(DLNADeviceInfo &device, IPAddressAndPort addr)
Definition: Schedule.h:80
IPAddressAndPort address
Definition: Schedule.h:109
DLNADeviceInfo * p_device
Definition: Schedule.h:110
const char * name() override
Definition: Schedule.h:84
int max_age
Definition: Schedule.h:114
Send MSearch request.
Definition: Schedule.h:39
IPAddressAndPort address
Definition: Schedule.h:70
const char * search_target
Definition: Schedule.h:71
bool process(IUDPService &udp) override
Definition: Schedule.h:48
const char * name() override
Definition: Schedule.h:46
MSearchSchedule(IPAddressAndPort addr, const char *searchTarget, int mx=3)
Definition: Schedule.h:41
int max_age
Definition: Schedule.h:69
Represents a notification/notify reply scheduled for control-point processing.
Definition: Schedule.h:163
Str delivery_host_and_port
Definition: Schedule.h:167
std::function< bool(NotifyReplyCP &ref)> callback
Definition: Schedule.h:175
Str xml
Definition: Schedule.h:171
Str event_key
Definition: Schedule.h:170
Str subscription_id
Definition: Schedule.h:169
Str delivery_path
Definition: Schedule.h:168
const char * name() override
Definition: Schedule.h:165
bool process(IUDPService &udp) override
Definition: Schedule.h:177
Str nts
Definition: Schedule.h:166
Send out PostAlive messages: Repeated every 5 seconds.
Definition: Schedule.h:192
DLNADeviceInfo * p_device
Definition: Schedule.h:229
PostAliveSchedule(DLNADeviceInfo &device, uint32_t repeatMs)
Definition: Schedule.h:194
const char * name() override
Definition: Schedule.h:198
bool process(IUDPService &udp) override
Definition: Schedule.h:202
void setRepeatMs(uint32_t ms)
Definition: Schedule.h:200
bool process(const char *nt, const char *usn, const char *device_url, int max_age, IUDPService &udp)
Definition: Schedule.h:238
void setupData(const char *nt, const char *udn, char *result_nt, char *result_usn)
Definition: Schedule.h:230
Send out ByeBye message.
Definition: Schedule.h:264
DLNADeviceInfo * p_device
Definition: Schedule.h:291
PostByeSchedule(DLNADeviceInfo &device)
Definition: Schedule.h:266
bool process(IUDPService &udp) override
Definition: Schedule.h:268
int max_age
Definition: Schedule.h:290
const char * name() override
Definition: Schedule.h:267
Send SUBSCRIBE message via UDP unicast.
Definition: Schedule.h:298
void setDestination(IPAddressAndPort address, const char *path)
Definition: Schedule.h:330
const char * name() override
Definition: Schedule.h:304
void setDuration(uint32_t sec)
Definition: Schedule.h:335
IPAddressAndPort address
Definition: Schedule.h:326
const char * path
Definition: Schedule.h:327
int durationSec
Definition: Schedule.h:328
PostSubscribe(IPAddressAndPort address, const char *path, uint32_t sec)
Definition: Schedule.h:300
bool process(IUDPService &udp) override
Definition: Schedule.h:306
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
const char * url()
Definition: Url.h:43
Definition: Allocator.h:6
LoggerClass DlnaLogger
Definition: Logger.cpp:5
IP Adress including Port information.
Definition: IPAddressAndPort.h:20
const char * toString()
Definition: IPAddressAndPort.h:26
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
virtual bool process(IUDPService &udp)
Definition: Schedule.h:28
uint64_t time
Definition: Schedule.h:20
uint32_t repeat_ms
Definition: Schedule.h:22