Arduino DLNA Server
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DLNADevice.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include <functional> // std::bind
5 
6 #include "DLNAServiceInfo.h"
7 #include "StringRegistry.h"
8 #include "basic/Icon.h"
9 #include "basic/Vector.h"
10 #include "service/Action.h"
11 #include "vector"
12 #include "xml/XMLPrinter.h"
13 
14 namespace tiny_dlna {
15 
27 class DLNADevice {
28  friend class XMLDeviceParser;
29  friend class DLNAControlPointMgr;
30 
31  public:
32  DLNADevice(bool ok = true) { is_active = true; }
33  ~DLNADevice() { DlnaLogger.log(DlnaDebug, "~DLNADevice()"); }
34 
36  void print(Print& out) {
37  xml.setOutput(out);
39  auto printRootCb = std::bind(&DLNADevice::printRoot, this);
40  xml.printNode("root", printRootCb, ns);
41  }
42 
43  // sets the device type (ST or NT)
44  void setDeviceType(const char* st) { device_type = st; }
45 
46  const char* getDeviceType() { return device_type; }
47 
49  void setUDN(const char* id) { udn = id; }
50 
52  const char* getUDN() { return udn; }
53 
55  void setBaseURL(const char* url) { base_url = url; }
56 
58  const char* getBaseURL() {
59  // replace localhost url
60  // if (base_url.contains("localhost")) {
61  // base_url.replace("localhost", getIPStr());
62  // }
63  return base_url;
64  }
65 
68  if (!device_url) {
69  Str str = getBaseURL();
70  if (!str.endsWith("/")) str += "/";
71  str += "device.xml";
72  Url new_url(str.c_str());
73  device_url = new_url;
74  }
75  return device_url;
76  }
77 
78  void setIPAddress(IPAddress address) { localhost = address; }
79 
80  IPAddress getIPAddress() { return localhost; }
81 
83  const char* getIPStr() {
84  static char result[80] = {0};
85  snprintf(result, 80, "%d.%d.%d.%d", localhost[0], localhost[1],
86  localhost[2], localhost[3]);
87  return result;
88  }
89 
90  void setNS(const char* ns) { this->ns = ns; }
91  const char* getNS() { return ns; }
92  void setFriendlyName(const char* name) { friendly_name = name; }
93  const char* getFriendlyName() { return friendly_name; }
94  void setManufacturer(const char* man) { manufacturer = man; }
95  const char* getManufacturer() { return manufacturer; }
96  void setManufacturerURL(const char* url) { manufacturer_url = url; }
97  const char* getManufacturerURL() { return manufacturer_url; }
98  void setModelDescription(const char* descr) { model_description = descr; }
99  const char* getModelDescription() { return model_description; }
100  void setModelName(const char* name) { model_name = name; }
101  const char* getModelName() { return model_name; }
102  void setModelNumber(const char* number) { model_number = number; }
103  const char* getModelNumber() { return model_number; }
104  void setSerialNumber(const char* sn) { serial_number = sn; }
105  const char* getSerialNumber() { return serial_number; }
106  void setUniveralProductCode(const char* upc) { universal_product_code = upc; }
108 
110  void addService(DLNAServiceInfo s) { services.push_back(s); }
111 
113  DLNAServiceInfo& getService(const char* id) {
114  static DLNAServiceInfo result{false};
115  for (auto& service : services) {
116  if (StrView(service.service_id).contains(id)) {
117  return service;
118  }
119  }
120  return result;
121  }
122 
124 
125  void clear() {
126  services.clear();
127  udn = nullptr;
128  ns = nullptr;
129  device_type = nullptr;
130  friendly_name = nullptr;
131  manufacturer = nullptr;
132  manufacturer_url = nullptr;
133  model_description = nullptr;
134  model_name = nullptr;
135  model_number = nullptr;
136  serial_number = nullptr;
137  universal_product_code = nullptr;
138  }
139 
141  void clearIcons() { icons.clear(); }
142  void addIcon(Icon icon) { icons.push_back(icon); }
143  Icon getIcon(int idx = 0) {
144  if (icons.size()==0){
145  Icon empty;
146  return empty;
147  }
148  return icons[idx]; }
149 
150  operator bool() { return is_active; }
151 
153  void updateTimestamp() { timestamp = millis(); }
154 
156  uint32_t getTimestamp() { return timestamp; }
157 
158  void setActive(bool flag) { is_active = flag; }
159 
160  virtual void loop(){
161  delay(1);
162  }
163 
164  virtual void setupServices(HttpServer& server, IUDPService& udp){}
165 
166  protected:
167  uint64_t timestamp = 0;
168  bool is_active = true;
171  IPAddress localhost;
172  int version_major = 1;
173  int version_minor = 0;
174  const char* base_url = "http://localhost:9876/dlna";
175  const char* udn = "uuid:09349455-2941-4cf7-9847-0dd5ab210e97";
176  const char* ns = "xmlns=\"urn:schemas-upnp-org:device-1-0\"";
177  const char* device_type = nullptr;
178  const char* friendly_name = nullptr;
179  const char* manufacturer = nullptr;
180  const char* manufacturer_url = nullptr;
181  const char* model_description = nullptr;
182  const char* model_name = nullptr;
183  const char* model_url = nullptr;
184  const char* model_number = nullptr;
185  const char* serial_number = nullptr;
186  const char* universal_product_code = nullptr;
190 
191  size_t printRoot() {
192  size_t result = 0;
193  auto printSpecVersionB = std::bind(&DLNADevice::printSpecVersion, this);
194  result += xml.printNode("specVersion", printSpecVersionB);
195  result += xml.printNode("URLBase", base_url);
196  auto printDeviceB = std::bind(&DLNADevice::printDevice, this);
197  result += xml.printNode("device", printDeviceB);
198  return result;
199  }
200 
201  size_t printDevice() {
202  size_t result = 0;
203  result += xml.printNode("deviceType", getDeviceType());
204  result += xml.printNode("friendlyName", friendly_name);
205  result += xml.printNode("manufacturer", manufacturer);
206  result += xml.printNode("manufacturerURL", manufacturer_url);
207  result += xml.printNode("modelDescription", model_description);
208  result += xml.printNode("modelName", model_name);
209  result += xml.printNode("modelNumber", model_number);
210  result += xml.printNode("modelURL", model_url);
211  result += xml.printNode("serialNumber", serial_number);
212  result += xml.printNode("UDN", getUDN());
213  result += xml.printNode("UPC", universal_product_code);
214  auto printIconListCb = std::bind(&DLNADevice::printIconList, this);
215  result += xml.printNode("iconList", printIconListCb);
216  auto printServiceListCb = std::bind(&DLNADevice::printServiceList, this);
217  result += xml.printNode("serviceList", printServiceListCb);
218  return result;
219  }
220 
221  size_t printSpecVersion() {
222  char major[5], minor[5];
223  sprintf(major, "%d", this->version_major);
224  sprintf(minor, "%d", this->version_minor);
225  return xml.printNode("major", major) + xml.printNode("minor", minor);
226  }
227 
228  size_t printServiceList() {
229  size_t result = 0;
230  for (auto& service : services) {
231  auto printServiceCb =
232  std::bind(&DLNADevice::printService, this, &service);
233  result += xml.printNode("service", printServiceCb);
234  }
235  return result;
236  }
237 
238  size_t printService(void* srv) {
239  size_t result = 0;
240  char buffer[DLNA_MAX_URL_LEN] = {0};
241  StrView url(buffer, DLNA_MAX_URL_LEN);
242  DLNAServiceInfo* service = (DLNAServiceInfo*)srv;
243  result += xml.printNode("serviceType", service->service_type);
244  result += xml.printNode("serviceId", service->service_id);
245  result += xml.printNode("SCPDURL",
246  url.buildPath(base_url, service->scpd_url));
247  result += xml.printNode(
248  "controlURL", url.buildPath(base_url, service->control_url));
249  result += xml.printNode(
250  "eventSubURL", url.buildPath(base_url, service->event_sub_url));
251  return result;
252  }
253 
254  size_t printIconList() {
255  // make sure we have at least the default icon
256  Icon icon;
257  if (icons.empty()) {
258  icons.push_back(icon);
259  }
260  int result = 0;
261 
262  // print all icons
263  for (auto icon : icons) {
264  auto printIconDlnaInfoCb =
265  std::bind(&DLNADevice::printIconDlnaInfo, this, icon);
266  result += xml.printNode("icon", printIconDlnaInfoCb);
267  }
268  return result;
269  }
270 
272  size_t result = 0;
273  if (!StrView(icon.icon_url).isEmpty()) {
274  char buffer[DLNA_MAX_URL_LEN] = {0};
275  StrView url(buffer, DLNA_MAX_URL_LEN);
276  result += xml.printNode("mimetype", "image/png");
277  result += xml.printNode("width", icon.width);
278  result += xml.printNode("height", icon.height);
279  result += xml.printNode("depth", icon.depth);
280  result +=
282  }
283  return result;
284  }
285 };
286 
287 } // namespace tiny_dlna
#define DLNA_MAX_URL_LEN
Definition: DLNAServiceInfo.h:5
Setup of a Basic DLNA Control Point. The control point.
Definition: DLNAControlPointMgr.h:32
Device Attributes and generation of XML using urn:schemas-upnp-org:device-1-0. We could just return a...
Definition: DLNADevice.h:27
Vector< DLNAServiceInfo > services
Definition: DLNADevice.h:188
const char * getSerialNumber()
Definition: DLNADevice.h:105
const char * model_number
Definition: DLNADevice.h:184
void setManufacturerURL(const char *url)
Definition: DLNADevice.h:96
size_t printService(void *srv)
Definition: DLNADevice.h:238
void setDeviceType(const char *st)
Definition: DLNADevice.h:44
void setSerialNumber(const char *sn)
Definition: DLNADevice.h:104
void setActive(bool flag)
Definition: DLNADevice.h:158
const char * getModelDescription()
Definition: DLNADevice.h:99
const char * model_description
Definition: DLNADevice.h:181
void setBaseURL(const char *url)
Defines the base url.
Definition: DLNADevice.h:55
const char * friendly_name
Definition: DLNADevice.h:178
uint32_t getTimestamp()
Returns the time when this object has been updated.
Definition: DLNADevice.h:156
const char * getModelNumber()
Definition: DLNADevice.h:103
void setModelDescription(const char *descr)
Definition: DLNADevice.h:98
const char * device_type
Definition: DLNADevice.h:177
Vector< DLNAServiceInfo > & getServices()
Definition: DLNADevice.h:123
const char * getModelName()
Definition: DLNADevice.h:101
Icon icon
Definition: DLNADevice.h:187
const char * manufacturer_url
Definition: DLNADevice.h:180
void setFriendlyName(const char *name)
Definition: DLNADevice.h:92
const char * universal_product_code
Definition: DLNADevice.h:186
size_t printRoot()
Definition: DLNADevice.h:191
void clear()
Definition: DLNADevice.h:125
bool is_active
Definition: DLNADevice.h:168
const char * model_url
Definition: DLNADevice.h:183
IPAddress localhost
Definition: DLNADevice.h:171
const char * model_name
Definition: DLNADevice.h:182
const char * getManufacturer()
Definition: DLNADevice.h:95
const char * manufacturer
Definition: DLNADevice.h:179
DLNAServiceInfo & getService(const char *id)
Finds a service definition by name.
Definition: DLNADevice.h:113
virtual void setupServices(HttpServer &server, IUDPService &udp)
Definition: DLNADevice.h:164
size_t printIconList()
Definition: DLNADevice.h:254
~DLNADevice()
Definition: DLNADevice.h:33
IPAddress getIPAddress()
Definition: DLNADevice.h:80
size_t printDevice()
Definition: DLNADevice.h:201
Url & getDeviceURL()
This method returns base url/device.xml.
Definition: DLNADevice.h:67
const char * base_url
Definition: DLNADevice.h:174
size_t printSpecVersion()
Definition: DLNADevice.h:221
void setManufacturer(const char *man)
Definition: DLNADevice.h:94
void print(Print &out)
renderes the device xml
Definition: DLNADevice.h:36
const char * getManufacturerURL()
Definition: DLNADevice.h:97
const char * getFriendlyName()
Definition: DLNADevice.h:93
void setModelNumber(const char *number)
Definition: DLNADevice.h:102
size_t printServiceList()
Definition: DLNADevice.h:228
void addService(DLNAServiceInfo s)
Adds a service defintion.
Definition: DLNADevice.h:110
Url device_url
Definition: DLNADevice.h:170
const char * serial_number
Definition: DLNADevice.h:185
void setUniveralProductCode(const char *upc)
Definition: DLNADevice.h:106
const char * getBaseURL()
Provides the base url.
Definition: DLNADevice.h:58
void setIPAddress(IPAddress address)
Definition: DLNADevice.h:78
size_t printIconDlnaInfo(Icon &icon)
Definition: DLNADevice.h:271
void setNS(const char *ns)
Definition: DLNADevice.h:90
int version_minor
Definition: DLNADevice.h:173
void setUDN(const char *id)
Define the udn uuid.
Definition: DLNADevice.h:49
const char * ns
Definition: DLNADevice.h:176
const char * getDeviceType()
Definition: DLNADevice.h:46
void clearIcons()
Overwrite the default icon.
Definition: DLNADevice.h:141
Icon getIcon(int idx=0)
Definition: DLNADevice.h:143
const char * getUDN()
Provide the udn uuid.
Definition: DLNADevice.h:52
uint64_t timestamp
Definition: DLNADevice.h:167
const char * getIPStr()
Provides the local address as string.
Definition: DLNADevice.h:83
void setModelName(const char *name)
Definition: DLNADevice.h:100
const char * getNS()
Definition: DLNADevice.h:91
int version_major
Definition: DLNADevice.h:172
const char * udn
Definition: DLNADevice.h:175
void addIcon(Icon icon)
Definition: DLNADevice.h:142
void updateTimestamp()
Update the timestamp.
Definition: DLNADevice.h:153
virtual void loop()
Definition: DLNADevice.h:160
XMLPrinter xml
Definition: DLNADevice.h:169
const char * getUniveralProductCode()
Definition: DLNADevice.h:107
Vector< Icon > icons
Definition: DLNADevice.h:189
DLNADevice(bool ok=true)
Definition: DLNADevice.h:32
Attributes needed for the DLNA Service Definition.
Definition: DLNAServiceInfo.h:16
const char * scpd_url
Definition: DLNAServiceInfo.h:35
const char * service_type
Definition: DLNAServiceInfo.h:33
const char * service_id
Definition: DLNAServiceInfo.h:34
const char * control_url
Definition: DLNAServiceInfo.h:36
const char * event_sub_url
Definition: DLNAServiceInfo.h:37
A Simple Header only implementation of Http Server that allows the registration of callback functions...
Definition: HttpServer.h:24
Abstract Interface for UDP API.
Definition: IUDPService.h:34
Information about the icon.
Definition: Icon.h:10
const char * icon_url
Definition: Icon.h:16
int width
Definition: Icon.h:13
int height
Definition: Icon.h:14
int depth
Definition: Icon.h:15
void log(DlnaLogLevel current_level, const char *fmt...)
Print log message.
Definition: Logger.h:40
A simple wrapper to provide string functions on char*. If the underlying char* is a const we do not a...
Definition: StrView.h:19
virtual bool isEmpty()
checks if the string is empty
Definition: StrView.h:376
const char * buildPath(const char *start, const char *p1=nullptr, const char *p2=nullptr)
Definition: StrView.h:739
virtual bool endsWith(const char *str)
checks if the string ends with the indicated substring
Definition: StrView.h:187
virtual bool contains(const char *str)
checks if the string contains a substring
Definition: StrView.h:279
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:188
URL parser which breaks a full url string up into its individual parts.
Definition: Url.h:18
Vector implementation which provides the most important methods as defined by std::vector....
Definition: Vector.h:21
Parses an DLNA device xml string to fill the DLNADevice data structure.
Definition: XMLDeviceParser.h:17
Definition: Allocator.h:6
@ DlnaDebug
Definition: Logger.h:16
LoggerClass DlnaLogger
Definition: Logger.cpp:5
Functions to efficiently output XML. XML data contains a lot of redundancy so it is more memory effic...
Definition: XMLPrinter.h:31
size_t printNode(XMLNode node)
Definition: XMLPrinter.h:43
void setOutput(Print &output)
Defines the output.
Definition: XMLPrinter.h:36
size_t printXMLHeader()
Definition: XMLPrinter.h:38