simplified sender module a lot, support only one protocol per instance
Stefan Schuermans

Stefan Schuermans commited on 2011-12-04 14:49:17
Showing 13 changed files, with 226 additions and 166 deletions.

... ...
@@ -21,6 +21,12 @@
21 21
       read.
22 22
       The frames received from this stream are sent over the network.
23 23
     </p>
24
+    <h3>Protocol</h3>
25
+    <p>
26
+      The protcol to use is configured in the file <code>protocol</code>.
27
+      It can contain the string <code>blp</code>, <code>eblp</code> or
28
+      <code>mcuf</code> to select the BLP, EBLP or MCUF protocol respectively.
29
+    </p>
24 30
     <h3>Bind Address</h3>
25 31
     <p>
26 32
       The file <code>bind</code> contains the local address to bind to.
... ...
@@ -31,14 +37,13 @@
31 37
     </p>
32 38
     <h3>Static Destinations</h3>
33 39
     <p>
34
-      Static destinations to supply with a network stream in BLP, EBLP
35
-      or MCUF protocol can be configured in the subdirectories
36
-      <code>blp</code>, <code>eblp</code> and <code>mcuf</code> respectively.
40
+      Static destinations to supply with a network stream in the configured
41
+      protocol can be configured in the subdirectory <code>destinations</code>.
37 42
 
38 43
       Each static destination is configured in an own subdirectory.
39
-      E.g. the configurations for static MCUF destinations with name
44
+      E.g. the configuration for a static destination with name
40 45
       <code>local</code> resides in the subdirectory
41
-      <code>mcuf/local</code>.
46
+      <code>destinations/local</code>.
42 47
     </p>
43 48
     <p>
44 49
       The configuration inside a static destination consists of the following
... ...
@@ -0,0 +1,57 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include <sstream>
7
+#include <string>
8
+
9
+#include "Protocol.h"
10
+
11
+namespace Blinker {
12
+
13
+/// constructor
14
+Protocol::Protocol():
15
+  m_proto(BlinkenProtoNone)
16
+{
17
+}
18
+
19
+/**
20
+ * @brief parse from string format
21
+ * @param[in] str string format
22
+ * @return if parsing was successful
23
+ */
24
+bool Protocol::fromStr(const std::string &str)
25
+{
26
+  if (str == "blp") {
27
+    m_proto = BlinkenProtoBlp;
28
+    return true;
29
+  }
30
+  else if (str =="eblp") {
31
+    m_proto = BlinkenProtoEblp;
32
+    return true;
33
+  }
34
+  else if (str =="mcuf") {
35
+    m_proto = BlinkenProtoMcuf;
36
+    return true;
37
+  }
38
+  else
39
+    return false;
40
+}
41
+
42
+/**
43
+ * @brief convert to string format
44
+ * @return string format
45
+ */
46
+std::string Protocol::toStr() const
47
+{
48
+  switch (m_proto) {
49
+    case BlinkenProtoBlp: return "blp";
50
+    case BlinkenProtoEblp: return "eblp";
51
+    case BlinkenProtoMcuf: return "mcuf";
52
+    default: return "";
53
+  }
54
+}
55
+
56
+} // namespace Blinker
57
+
... ...
@@ -0,0 +1,43 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef PROTOCOL_H
7
+#define PROTOCOL_H
8
+
9
+#include <string>
10
+
11
+#include <BlinkenLib/BlinkenProto.h>
12
+
13
+namespace Blinker {
14
+
15
+/// a Blinken protocol
16
+class Protocol
17
+{
18
+public:
19
+  /// constructor
20
+  Protocol();
21
+
22
+public:
23
+  /**
24
+   * @brief parse from string format
25
+   * @param[in] str string format
26
+   * @return if parsing was successful
27
+   */
28
+  bool fromStr(const std::string &str);
29
+
30
+  /**
31
+   * @brief convert to string format
32
+   * @return string format
33
+   */
34
+  std::string toStr() const;
35
+
36
+public:
37
+  etBlinkenProto m_proto; ///< protocol
38
+}; // class Protocol
39
+
40
+} // namespace Blinker
41
+
42
+#endif // #ifndef PROTOCOL_H
43
+
... ...
@@ -18,6 +18,7 @@
18 18
 #include "File.h"
19 19
 #include "IoCallee.h"
20 20
 #include "Module.h"
21
+#include "Protocol.h"
21 22
 #include "SettingFile.h"
22 23
 #include "StreamMgr.h"
23 24
 #include "StreamRecv.h"
... ...
@@ -94,11 +95,8 @@ public:
94 95
   virtual void ioWriteCall(Io *io);
95 96
 
96 97
 protected:
97
-  /**
98
-   * @brief free static destiation list
99
-   * @param[in] destList static destination list to free
100
-   */
101
-  void freeDestList(DestList &destList);
98
+  /// (re-)read protocol
99
+  void readProto();
102 100
 
103 101
   /// get input stream and attach to it
104 102
   void getInStream();
... ...
@@ -115,19 +113,14 @@ protected:
115 113
   /**
116 114
    * @brief light update of static destinations,
117 115
    *        i.e. stat all files in current static destination directory
118
-   * @param[in] destList static destinations for protocol
119 116
    */
120
-  void updateDestsLight(DestList &destList);
117
+  void updateDestsLight();
121 118
 
122 119
   /**
123 120
    * @brief full update of static destinations,
124 121
    *        i.e. scan files in playlist directory
125
-   * @param[in] dirDests static destinations directory for protocol
126
-   * @param[in] destList static destinations for protocol
127
-   * @param[in] pNoFrameData "no frame" protocol data
128 122
    */
129
-  void updateDestsFull(Directory &dirDests, DestList &destList,
130
-                       const std::string *pNoFrameData);
123
+  void updateDestsFull();
131 124
 
132 125
   /// remove timed-out dynamic destinations
133 126
   void removeTimedOutDynDests();
... ...
@@ -141,15 +134,12 @@ protected:
141 134
   /**
142 135
    * @brief send data to static/dynamic destinations
143 136
    * @param[in] data *pData protocol data to send
144
-   * @param[in] destList static destinations
145
-   * @param[in] dynDests dynamic destinations
146 137
    */
147
-  void sendDests(const std::string *pData, const DestList destList,
148
-                 const DynDests dynDests);
138
+  void sendDests(const std::string *pData);
149 139
 
150 140
   /**
151 141
    * @brief send protocol data to address
152
-   * @param[in] data protcol data of frame
142
+   * @param[in] data protcol data of frame (empty if unknown)
153 143
    * @param[in] addr address to send to
154 144
    */
155 145
   void sendProto(const std::string &data, const ADDR &addr) const;
... ...
@@ -157,11 +147,9 @@ protected:
157 147
   /**
158 148
    * @brief convert frame to protocol data
159 149
    * @param[in] pFrame frame (NULL for none)
160
-   * @param[in] proto Blinken protocol identifier
161 150
    * @param[out] data protcol data
162 151
    */
163
-  static void frame2data(stBlinkenFrame *pFrame, etBlinkenProto proto,
164
-                         std::string &data);
152
+  void frame2data(stBlinkenFrame *pFrame, std::string &data) const;
165 153
 
166 154
   /// receive data from socket
167 155
   void receiveFromSock();
... ...
@@ -169,24 +157,17 @@ protected:
169 157
 protected:
170 158
   SettingFile m_fileInStream; ///< input stream name file
171 159
   SettingFile m_fileBind;     ///< bind address file
172
-  Directory   m_dirDestsBlp;     ///< static BLP destinations directory
173
-  Directory   m_dirDestsEblp;    ///< static EBLP destinations directory
174
-  Directory   m_dirDestsMcuf;    ///< static MCUF destinations directory
160
+  SettingFile m_fileProtocol; ///< protocol file
161
+  Directory   m_dirDests;     ///< static destinations directory
175 162
   std::string m_nameInStream; ///< name of input stream
176 163
   Stream      *m_pInStream;   ///< input stream
177 164
   SOCK        *m_pSock;       ///< socket to use for sending streams
178
-  DestList    m_destListBlp;     ///< static BLP destinations
179
-  DestList    m_destListEblp;    ///< static EBLP destinations
180
-  DestList    m_destListMcuf;    ///< static MCUF destinations
181
-  DynDests    m_dynDestsBlp;     ///< dynamic BLP destinations
182
-  DynDests    m_dynDestsEblp;    ///< dynamic EBLP destinations
183
-  DynDests    m_dynDestsMcuf;    ///< dynamic MCUF destinations
184
-  std::string m_noFrameDataBlp;  ///< "no frame" BLP protocol data
185
-  std::string m_noFrameDataEblp; ///< "no frame" EBLP protocol data
186
-  std::string m_noFrameDataMcuf; ///< "no frame" MCUF protocol data
187
-  std::string m_dataBlp;         ///< current BLP protocol data
188
-  std::string m_dataEblp;        ///< current BLP protocol data
189
-  std::string m_dataMcuf;        ///< current BLP protocol data
165
+  Protocol    m_protocol;     ///< protocol
166
+  bool        m_haveProtocol; ///< if protocol is known
167
+  DestList    m_destList;     ///< static destinations
168
+  DynDests    m_dynDests;     ///< dynamic destinations
169
+  std::string m_noFrameData;  ///< "no frame" protocol data (empty if unknown)
170
+  std::string m_data;         ///< current protocol data (empty if unknown)
190 171
 }; // class Sender
191 172
 
192 173
 } // namespace Blinker
... ...
@@ -26,6 +26,7 @@ public:
26 26
    * @param[in] sender owning sender object
27 27
    * @param[in] dirBase base directory
28 28
    * @param[in] pNoFrameData protocol data for "no frame" packet
29
+   *                         (empty if unknown)
29 30
    */
30 31
   Dest(Sender &sender, const Directory &dirBase,
31 32
        const std::string *pNoFrameData);
... ...
@@ -46,7 +47,7 @@ public:
46 47
 
47 48
   /**
48 49
    * @brief set current protocol data
49
-   * @param[in] pData protocol data to send to address
50
+   * @param[in] pData protocol data to send to address (empty if unkown)
50 51
    */
51 52
   void setProtoData(const std::string *pData);
52 53
 
... ...
@@ -56,7 +57,7 @@ protected:
56 57
 
57 58
   /**
58 59
    * @brief send protocol data to address
59
-   * @param[in] pData protocol data to send to address
60
+   * @param[in] pData protocol data to send to address (empty if unknown)
60 61
    */
61 62
   void send(const std::string *pData);
62 63
 
... ...
@@ -22,6 +22,7 @@ namespace Blinker {
22 22
  * @param[in] sender owning sender object
23 23
  * @param[in] dirBase base directory
24 24
  * @param[in] pNoFrameData protocol data for "no frame" packet
25
+ *                         (empty if unknown)
25 26
  */
26 27
 template<typename ADDR, typename SOCK>
27 28
 Sender<ADDR, SOCK>::Dest::Dest(Sender &sender, const Directory &dirBase,
... ...
@@ -55,7 +56,7 @@ void Sender<ADDR, SOCK>::Dest::updateConfig()
55 56
 
56 57
 /**
57 58
  * @brief set current protocol data
58
- * @param[in] pData protocol data to send to address
59
+ * @param[in] pData protocol data to send to address (empty if unknown)
59 60
  */
60 61
 template<typename ADDR, typename SOCK>
61 62
 void Sender<ADDR, SOCK>::Dest::setProtoData(const std::string *pData)
... ...
@@ -85,12 +86,12 @@ void Sender<ADDR, SOCK>::Dest::getAddr()
85 86
 
86 87
 /**
87 88
  * @brief send protocol data to address
88
- * @param[in] pData protocol data to send to address
89
+ * @param[in] pData protocol data to send to address (empty if unknown)
89 90
  */
90 91
 template<typename ADDR, typename SOCK>
91 92
 void Sender<ADDR, SOCK>::Dest::send(const std::string *pData)
92 93
 {
93
-  if (m_sender.m_pSock && m_haveAddr && pData)
94
+  if (m_sender.m_pSock && m_haveAddr && !pData->empty())
94 95
     m_sender.m_pSock->send(*pData, m_addr);
95 96
 }
96 97
 
... ...
@@ -18,6 +18,7 @@
18 18
 #include "File.h"
19 19
 #include "IoCallee.h"
20 20
 #include "Module.h"
21
+#include "Protocol.h"
21 22
 #include "Sender.h"
22 23
 #include "SenderDest.h"
23 24
 #include "SenderDest_impl.h"
... ...
@@ -41,19 +42,14 @@ Sender<ADDR, SOCK>::Sender(CallMgr &callMgr, StreamMgr &streamMgr,
41 42
   Module(callMgr, streamMgr, dirBase),
42 43
   m_fileInStream(dirBase.getFile("instream")),
43 44
   m_fileBind(dirBase.getFile("bind")),
44
-  m_dirDestsBlp(dirBase.getSubdir("blp")),
45
-  m_dirDestsEblp(dirBase.getSubdir("eblp")),
46
-  m_dirDestsMcuf(dirBase.getSubdir("mcuf")),
45
+  m_fileProtocol(dirBase.getFile("protocol")),
46
+  m_dirDests(dirBase.getSubdir("destinations")),
47 47
   m_pInStream(NULL),
48
-  m_pSock(NULL)
48
+  m_pSock(NULL),
49
+  m_haveProtocol(false)
49 50
 {
50
-  // initialize protocol data buffers
51
-  frame2data(NULL, BlinkenProtoBlp, m_noFrameDataBlp);
52
-  frame2data(NULL, BlinkenProtoEblp, m_noFrameDataEblp);
53
-  frame2data(NULL, BlinkenProtoMcuf, m_noFrameDataMcuf);
54
-  m_dataBlp = m_noFrameDataBlp;
55
-  m_dataEblp = m_noFrameDataEblp;
56
-  m_dataMcuf = m_noFrameDataMcuf;
51
+  // read protocol
52
+  readProto();
57 53
 
58 54
   // get input stream and attach to it
59 55
   getInStream();
... ...
@@ -61,9 +57,7 @@ Sender<ADDR, SOCK>::Sender(CallMgr &callMgr, StreamMgr &streamMgr,
61 57
   createSock();
62 58
 
63 59
   // load static destinations
64
-  updateDestsFull(m_dirDestsBlp, m_destListBlp, &m_noFrameDataBlp);
65
-  updateDestsFull(m_dirDestsEblp, m_destListEblp, &m_noFrameDataEblp);
66
-  updateDestsFull(m_dirDestsMcuf, m_destListMcuf, &m_noFrameDataMcuf);
60
+  updateDestsFull();
67 61
 }
68 62
 
69 63
 /// virtual destructor
... ...
@@ -74,9 +68,10 @@ Sender<ADDR, SOCK>::~Sender()
74 68
   sendAllNoFrame();
75 69
 
76 70
   // free static destination lists
77
-  freeDestList(m_destListBlp);
78
-  freeDestList(m_destListEblp);
79
-  freeDestList(m_destListMcuf);
71
+  while (!m_destList.empty()) {
72
+    delete m_destList.back().m_pDest;
73
+    m_destList.pop_back();
74
+  }
80 75
 
81 76
   // destroy socket
82 77
   destroySock();
... ...
@@ -102,20 +97,16 @@ void Sender<ADDR, SOCK>::updateConfig()
102 97
     createSock();
103 98
   }
104 99
 
100
+  // protocol file was modified -> re-read protocol
101
+  if (m_fileProtocol.checkModified())
102
+    readProto();
103
+
105 104
   // static destinations update
106 105
   // (directory modified -> full, otherwise -> light)
107
-  if (m_dirDestsBlp.checkModified())
108
-    updateDestsFull(m_dirDestsBlp, m_destListBlp, &m_noFrameDataBlp);
109
-  else
110
-    updateDestsLight(m_destListBlp);
111
-  if (m_dirDestsEblp.checkModified())
112
-    updateDestsFull(m_dirDestsEblp, m_destListEblp, &m_noFrameDataEblp);
106
+  if (m_dirDests.checkModified())
107
+    updateDestsFull();
113 108
   else
114
-    updateDestsLight(m_destListEblp);
115
-  if (m_dirDestsMcuf.checkModified())
116
-    updateDestsFull(m_dirDestsMcuf, m_destListMcuf, &m_noFrameDataMcuf);
117
-  else
118
-    updateDestsLight(m_destListMcuf);
109
+    updateDestsLight();
119 110
 }
120 111
 
121 112
 /**
... ...
@@ -128,9 +119,7 @@ void Sender<ADDR, SOCK>::setFrame(const std::string &stream,
128 119
                                   stBlinkenFrame *pFrame)
129 120
 {
130 121
   // convert new frame to protocol data
131
-  frame2data(pFrame, BlinkenProtoBlp, m_dataBlp);
132
-  frame2data(pFrame, BlinkenProtoEblp, m_dataEblp);
133
-  frame2data(pFrame, BlinkenProtoMcuf, m_dataMcuf);
122
+  frame2data(pFrame, m_data);
134 123
 
135 124
   // send new protocol data to all destinations
136 125
   sendAllProto();
... ...
@@ -168,17 +157,40 @@ void Sender<ADDR, SOCK>::ioWriteCall(Io *io)
168 157
   (void)io; // unused
169 158
 }
170 159
 
171
-/**
172
- * @brief free static destiation list
173
- * @param[in] destList static destination list to free
174
- */
160
+/// (re-)read protocol
175 161
 template<typename ADDR, typename SOCK>
176
-void Sender<ADDR, SOCK>::freeDestList(DestList &destList)
162
+void Sender<ADDR, SOCK>::readProto()
177 163
 {
178
-  while (!destList.empty()) {
179
-    delete destList.back().m_pDest;
180
-    destList.pop_back();
164
+  std::string strProto;
165
+  stBlinkenFrame *pFrame;
166
+
167
+  // send "no frame" to all destinations
168
+  // (stream with old protocol will stop now)
169
+  sendAllNoFrame();
170
+
171
+  // clear dynamic destinations
172
+  // (they registered with old protocol, which is out of service now)
173
+  m_dynDests.clear();
174
+
175
+  // clear old frame data and old no frame data
176
+  m_noFrameData.clear();
177
+  m_data.clear();
178
+
179
+  // read new protocol from file
180
+  m_haveProtocol = m_fileProtocol.getStr(strProto) &&
181
+                   m_protocol.fromStr(strProto);
182
+
183
+  // create new no frame protocol data and new protocol data
184
+  if (m_haveProtocol) {
185
+    frame2data(NULL, m_noFrameData);
186
+    pFrame = NULL;
187
+    if (m_pInStream)
188
+      m_pInStream->getCurFrame(pFrame);
189
+    frame2data(pFrame, m_data);
181 190
   }
191
+
192
+  // send current protocol data to all destinations
193
+  sendAllProto();
182 194
 }
183 195
 
184 196
 /// get input stream and attach to it
... ...
@@ -235,8 +247,11 @@ void Sender<ADDR, SOCK>::createSock()
235 247
     return;
236 248
   }
237 249
 
238
-  // request callback on recpetion
250
+  // request callback on recepetion
239 251
   m_callMgr.requestIoReadCall(this, m_pSock);
252
+
253
+  // send current protocol data to all destinations
254
+  sendAllProto();
240 255
 }
241 256
 
242 257
 /// destroy socket
... ...
@@ -249,9 +264,7 @@ void Sender<ADDR, SOCK>::destroySock()
249 264
 
250 265
   // clear dynamic destinations
251 266
   // (they registered with this socket and this socket is gone)
252
-  m_dynDestsBlp.clear();
253
-  m_dynDestsEblp.clear();
254
-  m_dynDestsMcuf.clear();
267
+  m_dynDests.clear();
255 268
 
256 269
   // cancel callback request
257 270
   m_callMgr.cancelIoReadCall(this, m_pSock);
... ...
@@ -266,49 +279,43 @@ void Sender<ADDR, SOCK>::destroySock()
266 279
 /**
267 280
  * @brief light update of static destinations,
268 281
  *        i.e. stat all files in current static destination directory
269
- * @param[in] destList static destinations for one protocol
270 282
  */
271 283
 template<typename ADDR, typename SOCK>
272
-void Sender<ADDR, SOCK>::updateDestsLight(DestList &destList)
284
+void Sender<ADDR, SOCK>::updateDestsLight()
273 285
 {
274 286
   // walk through all files in static dest dir and check for modification
275 287
   typename DestList::iterator itDest;
276
-  for (itDest = destList.begin(); itDest != destList.end(); ++itDest)
288
+  for (itDest = m_destList.begin(); itDest != m_destList.end(); ++itDest)
277 289
     itDest->m_pDest->updateConfig();
278 290
 }
279 291
 
280 292
 /**
281 293
  * @brief full update of static destinations,
282 294
  *        i.e. scan files in playlist directory
283
- * @param[in] dirDests static destinations directory for protocol
284
- * @param[in] destList static destinations for protocol
285
- * @param[in] pNoFrameData "no frame" protocaol data
286 295
  */
287 296
 template<typename ADDR, typename SOCK>
288
-void Sender<ADDR, SOCK>::updateDestsFull(Directory &dirDests,
289
-                                         DestList &destList,
290
-                                         const std::string *pNoFrameData)
297
+void Sender<ADDR, SOCK>::updateDestsFull()
291 298
 {
292 299
   // get list of subdirs in input directory
293 300
   typedef std::list<std::string> Subdirlist;
294 301
   Subdirlist curSubdirs;
295
-  dirDests.getEntries(Directory::TypeSubdir, curSubdirs);
302
+  m_dirDests.getEntries(Directory::TypeSubdir, curSubdirs);
296 303
 
297 304
   // walk through current static destinations and subdir list simultaneously
298 305
   Subdirlist::const_iterator  itSubdir = curSubdirs.begin();
299
-  typename DestList::iterator itDest   = destList.begin();
300
-  while (itSubdir != curSubdirs.end() || itDest != destList.end()) {
306
+  typename DestList::iterator itDest   = m_destList.begin();
307
+  while (itSubdir != curSubdirs.end() || itDest != m_destList.end()) {
301 308
 
302 309
     // new static destination inserted
303
-    if (itDest == destList.end() ||
310
+    if (itDest == m_destList.end() ||
304 311
         (itSubdir != curSubdirs.end() && *itSubdir < itDest->m_name)) {
305 312
       // create static destination object
306 313
       DestEntry destEntry(*itSubdir);
307
-      destEntry.m_pDest = new Dest(*this, dirDests.getSubdir(*itSubdir),
308
-                                   pNoFrameData);
314
+      destEntry.m_pDest = new Dest(*this, m_dirDests.getSubdir(*itSubdir),
315
+                                   &m_noFrameData);
309 316
       if (destEntry.m_pDest)
310 317
         // insert static destination entry
311
-        destList.insert(itDest, destEntry);
318
+        m_destList.insert(itDest, destEntry);
312 319
       // advance to next subdir
313 320
       ++itSubdir;
314 321
     }
... ...
@@ -317,7 +324,7 @@ void Sender<ADDR, SOCK>::updateDestsFull(Directory &dirDests,
317 324
     else if (itSubdir == curSubdirs.end() || *itSubdir > itDest->m_name) {
318 325
       // remove static destination
319 326
       delete itDest->m_pDest;
320
-      itDest = destList.erase(itDest);
327
+      itDest = m_destList.erase(itDest);
321 328
       // do not advance to next subdir
322 329
     }
323 330
 
... ...
@@ -343,19 +350,9 @@ void Sender<ADDR, SOCK>::removeTimedOutDynDests()
343 350
   now = Time::now();
344 351
   timeout = Time(30);
345 352
 
346
-  for (itDyn = m_dynDestsBlp.begin(); itDyn != m_dynDestsBlp.end(); )
347
-    if (itDyn->second + timeout < now)
348
-      m_dynDestsBlp.erase(itDyn++);
349
-    else
350
-      ++itDyn;
351
-  for (itDyn = m_dynDestsEblp.begin(); itDyn != m_dynDestsEblp.end(); )
352
-    if (itDyn->second + timeout < now)
353
-      m_dynDestsEblp.erase(itDyn++);
354
-    else
355
-      ++itDyn;
356
-  for (itDyn = m_dynDestsMcuf.begin(); itDyn != m_dynDestsMcuf.end(); )
353
+  for (itDyn = m_dynDests.begin(); itDyn != m_dynDests.end(); )
357 354
     if (itDyn->second + timeout < now)
358
-      m_dynDestsMcuf.erase(itDyn++);
355
+      m_dynDests.erase(itDyn++);
359 356
     else
360 357
       ++itDyn;
361 358
 }
... ...
@@ -368,9 +365,7 @@ void Sender<ADDR, SOCK>::sendAllProto()
368 365
   removeTimedOutDynDests();
369 366
 
370 367
   // send current protocol data to all static/dynamic destinations
371
-  sendDests(&m_dataBlp, m_destListBlp, m_dynDestsBlp);
372
-  sendDests(&m_dataEblp, m_destListEblp, m_dynDestsEblp);
373
-  sendDests(&m_dataMcuf, m_destListMcuf, m_dynDestsMcuf);
368
+  sendDests(&m_data);
374 369
 
375 370
   // request time callback in one second
376 371
   m_callMgr.requestTimeCall(this, Time::now() + Time(1));
... ...
@@ -384,9 +379,7 @@ void Sender<ADDR, SOCK>::sendAllNoFrame()
384 379
   removeTimedOutDynDests();
385 380
 
386 381
   // get "no frame" protocol data and send to all static/dynamic destinations
387
-  sendDests(&m_noFrameDataBlp, m_destListBlp, m_dynDestsBlp);
388
-  sendDests(&m_noFrameDataEblp, m_destListEblp, m_dynDestsEblp);
389
-  sendDests(&m_noFrameDataMcuf, m_destListMcuf, m_dynDestsMcuf);
382
+  sendDests(&m_noFrameData);
390 383
 
391 384
   // request time callback in one second
392 385
   m_callMgr.requestTimeCall(this, Time::now() + Time(1));
... ...
@@ -395,57 +388,57 @@ void Sender<ADDR, SOCK>::sendAllNoFrame()
395 388
 /**
396 389
  * @brief send data to static/dynamic destinations
397 390
  * @param[in] data *pData protocol data to send
398
- * @param[in] destList static destinations
399
- * @param[in] dynDests dynamic destinations
400 391
  */
401 392
 template<typename ADDR, typename SOCK>
402
-void Sender<ADDR, SOCK>::sendDests(const std::string *pData,
403
-                                   const DestList destList,
404
-                                   const DynDests dynDests)
393
+void Sender<ADDR, SOCK>::sendDests(const std::string *pData)
405 394
 {
406 395
   // send data to static destinations
407 396
   typename DestList::const_iterator itDest;
408
-  for (itDest = destList.begin(); itDest != destList.end(); ++itDest)
397
+  for (itDest = m_destList.begin(); itDest != m_destList.end(); ++itDest)
409 398
     itDest->m_pDest->setProtoData(pData);
410 399
 
411 400
   // send data to all dynamic destinations
412 401
   typename DynDests::const_iterator itDyn;
413
-  for (itDyn = dynDests.begin(); itDyn != dynDests.end(); ++itDyn)
402
+  for (itDyn = m_dynDests.begin(); itDyn != m_dynDests.end(); ++itDyn)
414 403
     sendProto(*pData, itDyn->first);
415 404
 }
416 405
 
417 406
 /**
418 407
  * @brief send protocol data to address
419
- * @param[in] data protocol data of frame
408
+ * @param[in] data protocol data of frame (empty if unknown)
420 409
  * @param[in] addr address to send to
421 410
  */
422 411
 template<typename ADDR, typename SOCK>
423 412
 void Sender<ADDR, SOCK>::sendProto(const std::string &data,
424 413
                                    const ADDR &addr) const
425 414
 {
426
-  if (m_pSock) {
415
+  if (m_pSock && !data.empty())
427 416
     m_pSock->send(data, addr);
428 417
 }
429
-}
430 418
 
431 419
 /**
432 420
  * @brief convert frame to protocol data
433 421
  * @param[in] pFrame frame (NULL for none)
434
- * @param[in] proto Blinken protocol identifier
435 422
  * @param[out] data protocol data
436 423
  */
437 424
 template<typename ADDR, typename SOCK>
438 425
 void Sender<ADDR, SOCK>::frame2data(stBlinkenFrame *pFrame,
439
-                                    etBlinkenProto proto, std::string &data)
426
+                                    std::string &data) const
440 427
 {
441 428
   char buf[65536];
442 429
   int len;
443 430
 
431
+  // no protocol -> leave with empty data
432
+  if (!m_haveProtocol) {
433
+    data.clear();
434
+    return;
435
+  }
436
+
444 437
   // convert frame to protcol data
445 438
   if (pFrame)
446
-    len = BlinkenFrameToNetwork(pFrame, proto, buf, sizeof(buf));
439
+    len = BlinkenFrameToNetwork(pFrame, m_protocol.m_proto, buf, sizeof(buf));
447 440
   else
448
-    len = BlinkenProtoMakePacket(proto, BlinkenPacketStreamEnd,
441
+    len = BlinkenProtoMakePacket(m_protocol.m_proto, BlinkenPacketStreamEnd,
449 442
                                  buf, sizeof(buf));
450 443
   if (len < 0)
451 444
     len = 0;
... ...
@@ -472,49 +465,25 @@ void Sender<ADDR, SOCK>::receiveFromSock()
472 465
   // detect packet type and protocol
473 466
   BlinkenProtoDetectPacket(data.c_str(), data.size(), &proto, &packet);
474 467
 
468
+  if (m_haveProtocol && proto == m_protocol.m_proto) {
475 469
     switch (packet) {
476 470
 
477 471
       // request -> add to dynamic destinations and send current frame
478 472
       case BlinkenPacketRequest:
479
-      switch (proto) {
480
-        case BlinkenProtoBlp:
481
-          m_dynDestsBlp[addr] = Time::now();
482
-          sendProto(m_dataBlp, addr);
483
-          break;
484
-        case BlinkenProtoEblp:
485
-          m_dynDestsEblp[addr] = Time::now();
486
-          sendProto(m_dataEblp, addr);
487
-          break;
488
-        case BlinkenProtoMcuf:
489
-          m_dynDestsMcuf[addr] = Time::now();
490
-          sendProto(m_dataMcuf, addr);
491
-          break;
492
-        default:
493
-          break;
494
-      }
473
+        m_dynDests[addr] = Time::now();
474
+        sendProto(m_data, addr);
495 475
         break;
496 476
 
497 477
       // end request -> remove from dynamic destinations
498 478
       case BlinkenPacketEndRequest:
499
-      switch (proto) {
500
-        case BlinkenProtoBlp:
501
-          m_dynDestsBlp.erase(addr);
502
-          break;
503
-        case BlinkenProtoEblp:
504
-          m_dynDestsEblp.erase(addr);
505
-          break;
506
-        case BlinkenProtoMcuf:
507
-          m_dynDestsMcuf.erase(addr);
508
-          break;
509
-        default:
510
-          break;
511
-      }
479
+        m_dynDests.erase(addr);
512 480
         break;
513 481
 
514 482
       default:
515 483
         break;
516 484
 
517 485
     } // switch (packet)
486
+  } // if (m_haveProtocol ...
518 487
 
519 488
 }
520 489
 
521 490