MessageSpec.h
Go to the documentation of this file.
1 /****
2  * MessageSpec.h - Template specification for constructing SSDP message packets
3  *
4  * Rather than manually constructing a message from scratch, the framework uses a template
5  * to define the type of standard message to be sent with various parameters. Callbacks
6  * may be used to customise the message before sending.
7  *
8  * Copyright 2019 mikee47 <mike@sillyhouse.net>
9  *
10  * This file is part of the Sming SSDP Library
11  *
12  * This library is free software: you can redistribute it and/or modify it under the terms of the
13  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
14  *
15  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
16  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  * See the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along with this library.
20  * If not, see <https://www.gnu.org/licenses/>.
21  *
22  ****/
23 
24 #pragma once
25 
26 #include "Message.h"
27 #include <IpAddress.h>
28 
29 #define SSDP_NOTIFY_SUBTYPE_MAP(XX) \
30  XX(alive, "ssdp:alive") \
31  XX(byebye, "ssdp:byebye") \
32  XX(update, "ssdp:update") \
33  XX(event, "upnp:propchange")
34 
35 namespace SSDP
36 {
40 enum class NotifySubtype {
41 #define XX(type, str) type,
43 #undef XX
44  OTHER
45 };
46 
50 enum class SearchTarget {
51  root,
52  type,
54  uuid,
55  all,
56 };
57 
61 enum class SearchMatch {
62  root,
63  uuid,
64  type,
65 };
66 
67 NotifySubtype getNotifySubtype(const char* subtype);
68 
75 {
76 public:
78  {
79  data.messageType = uint8_t(type);
80  next = nullptr;
81  }
82 
83  MessageSpec(MessageType type, SearchTarget target, void* object = nullptr)
84  {
85  data.messageType = uint8_t(type);
86  data.target = uint8_t(target);
87  m_object = object;
88  next = nullptr;
89  }
90 
91  MessageSpec(NotifySubtype nts, SearchTarget target, void* object = nullptr)
93  {
94  data.notifySubtype = uint8_t(nts);
95  }
96 
103  MessageSpec(const MessageSpec& ms, SearchMatch match, void* object)
104  {
105  *this = ms;
106  next = nullptr;
107  data.match = uint8_t(match);
108  m_object = object;
109  }
110 
111  bool operator==(const MessageSpec& rhs) const
112  {
113  return m_object == rhs.m_object && remoteIp() == rhs.remoteIp() &&
114  (data.packed & packed_mask) == (rhs.data.packed & packed_mask);
115  }
116 
121  {
122  return m_remoteIp;
123  }
124 
128  uint16_t remotePort() const
129  {
130  return data.remotePort;
131  }
132 
140  template <class Object> Object* object() const
141  {
142  return static_cast<Object*>(m_object);
143  }
144 
149  {
150  return MessageType(data.messageType);
151  }
152 
157  {
158  return NotifySubtype(data.notifySubtype);
159  }
160 
165  {
166  return SearchMatch(data.match);
167  }
168 
173  {
174  return SearchTarget(data.target);
175  }
176 
181  {
182  data.target = uint8_t(target);
183  }
184 
188  void setRemote(IpAddress address, uint16_t port)
189  {
190  m_remoteIp = address;
191  data.remotePort = port;
192  }
193 
197  void setRepeat(uint8_t count)
198  {
199  data.repeat = count;
200  }
201 
205  uint8_t repeat() const
206  {
207  return data.repeat;
208  }
209 
214  {
215  if(data.repeat == 0) {
216  return false;
217  }
218  --data.repeat;
219  return true;
220  }
221 
222 private:
223  void* m_object{nullptr};
224  IpAddress m_remoteIp{};
225  union Data {
226  struct {
227  uint32_t remotePort : 16;
228  uint32_t messageType : 4;
229  uint32_t notifySubtype : 4;
230  uint32_t match : 2;
231  uint32_t target : 2;
232  uint32_t repeat : 4;
233  };
234  uint32_t packed{0};
235  };
236  Data data;
237  // Compare all but the repeat value
238  static constexpr uint32_t packed_mask{0x03FFFFFF};
239 
240  // These fields are used by the message queue
241  friend class MessageQueue;
242  uint32_t due;
243  MessageSpec* next;
244 };
245 
246 } // namespace SSDP
247 
#define SSDP_NOTIFY_SUBTYPE_MAP(XX)
Definition: MessageSpec.h:29
String toString(SSDP::NotifySubtype subtype)
A class to make it easier to handle and pass around IP addresses.
Definition: IpAddress.h:45
Queue of objects managed by a single timer.
Definition: MessageQueue.h:37
Defines the information used to create an outgoing message.
Definition: MessageSpec.h:75
IpAddress remoteIp() const
Get the remote IP address.
Definition: MessageSpec.h:120
void setRepeat(uint8_t count)
Set number of times to repeat message.
Definition: MessageSpec.h:197
MessageSpec(const MessageSpec &ms, SearchMatch match, void *object)
Construct a new message spec for a specific match type.
Definition: MessageSpec.h:103
uint16_t remotePort() const
Get the remote port number.
Definition: MessageSpec.h:128
MessageSpec(MessageType type)
Definition: MessageSpec.h:77
void setRemote(IpAddress address, uint16_t port)
Set the remote address and port.
Definition: MessageSpec.h:188
uint8_t repeat() const
Get current repeat value.
Definition: MessageSpec.h:205
void setTarget(SearchTarget target)
Set the search target.
Definition: MessageSpec.h:180
MessageSpec(MessageType type, SearchTarget target, void *object=nullptr)
Definition: MessageSpec.h:83
Object * object() const
Get the target object pointer.
Definition: MessageSpec.h:140
bool operator==(const MessageSpec &rhs) const
Definition: MessageSpec.h:111
NotifySubtype notifySubtype() const
Get the notification sub-type.
Definition: MessageSpec.h:156
SearchTarget target() const
Get the search target.
Definition: MessageSpec.h:172
bool shouldRepeat()
Check if message should be repeated and adjust counter.
Definition: MessageSpec.h:213
MessageType type() const
Get the message type.
Definition: MessageSpec.h:148
SearchMatch match() const
Get the search match type.
Definition: MessageSpec.h:164
MessageSpec(NotifySubtype nts, SearchTarget target, void *object=nullptr)
Definition: MessageSpec.h:91
The String class.
Definition: WString.h:137
Definition: SSDP/src/include/Network/SSDP/Message.h:32
MessageType
Definition: SSDP/src/include/Network/SSDP/Message.h:40
SearchTarget
SSDP Search target types.
Definition: MessageSpec.h:50
@ type
or urn:{domain}:service:{serviceType}:{v}
@ root
Root devices only: upnp:rootdevice
@ all
All devices and services: ssdp::all
@ uuid
Search for specific device: uuid:{device-UUID}
NotifySubtype getNotifySubtype(const char *subtype)
NotifySubtype
SSDP Notification subtype.
Definition: MessageSpec.h:40
SearchMatch
Determines the kind of match obtained when scanning incoming packets.
Definition: MessageSpec.h:61
@ type
Matched device or service type.
@ root
Matched root device.
@ uuid
Matched with device UUID.