Stefan Schuermans commited on 2014-01-03 16:19:05
Showing 15 changed files, with 390 additions and 3 deletions.
... | ... |
@@ -0,0 +1 @@ |
1 |
+0.0.0.0:5740 |
... | ... |
@@ -0,0 +1 @@ |
1 |
+test |
... | ... |
@@ -0,0 +1 @@ |
1 |
+[::]:5740 |
... | ... |
@@ -0,0 +1 @@ |
1 |
+test |
... | ... |
@@ -107,7 +107,7 @@ protected: |
107 | 107 |
AddrFile m_fileBind; ///< bind address file |
108 | 108 |
AddrFile m_fileSrc; ///< source address file |
109 | 109 |
ProtocolFile m_fileProtocol; ///< protocol file |
110 |
- SOCK *m_pSock; ///< socket to use for sending streams |
|
110 |
+ SOCK *m_pSock; ///< socket to use for receiving stream |
|
111 | 111 |
Time m_timeout; ///< timeout of network stream |
112 | 112 |
bool m_needTimeout; ///< if a timeout is needed |
113 | 113 |
Time m_nextReq; ///< when to send next request |
... | ... |
@@ -0,0 +1,92 @@ |
1 |
+/* Blinker |
|
2 |
+ Copyright 2011-2014 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 BLINKER_SYNCRECEIVER_H |
|
7 |
+#define BLINKER_SYNCRECEIVER_H |
|
8 |
+ |
|
9 |
+#include <string> |
|
10 |
+ |
|
11 |
+#include "Directory.h" |
|
12 |
+#include "File.h" |
|
13 |
+#include "IoCallee.h" |
|
14 |
+#include "Mgrs.h" |
|
15 |
+#include "Module.h" |
|
16 |
+#include "OutSyncFile.h" |
|
17 |
+#include "Protocol.h" |
|
18 |
+#include "ProtocolFile.h" |
|
19 |
+#include "SettingFile.h" |
|
20 |
+ |
|
21 |
+namespace Blinker { |
|
22 |
+ |
|
23 |
+/// stream receiver |
|
24 |
+template<typename ADDR, typename SOCK> |
|
25 |
+class SyncReceiver: public IoCallee, public Module |
|
26 |
+{ |
|
27 |
+protected: |
|
28 |
+ /// type for address setting file |
|
29 |
+ typedef SettingFile<ADDR> AddrFile; |
|
30 |
+ |
|
31 |
+public: |
|
32 |
+ /** |
|
33 |
+ * @brief constructor |
|
34 |
+ * @param[in] name module name |
|
35 |
+ * @param[in] mgrs managers |
|
36 |
+ * @param[in] dirBase base directory |
|
37 |
+ */ |
|
38 |
+ SyncReceiver(const std::string &name, Mgrs &mgrs, const Directory &dirBase); |
|
39 |
+ |
|
40 |
+ /// virtual destructor |
|
41 |
+ virtual ~SyncReceiver(); |
|
42 |
+ |
|
43 |
+private: |
|
44 |
+ /// copy constructor disabled |
|
45 |
+ SyncReceiver(const SyncReceiver &that); |
|
46 |
+ |
|
47 |
+ /// assignment operator disabled |
|
48 |
+ const SyncReceiver & operator=(const SyncReceiver &that); |
|
49 |
+ |
|
50 |
+public: |
|
51 |
+ /// check for update of configuration |
|
52 |
+ virtual void updateConfig(); |
|
53 |
+ |
|
54 |
+ /** |
|
55 |
+ * @brief callback when I/O object is readable |
|
56 |
+ * @param[in] io I/O object that is readable |
|
57 |
+ */ |
|
58 |
+ virtual void ioReadCall(Io *io); |
|
59 |
+ |
|
60 |
+ /** |
|
61 |
+ * @brief callback when I/O object is writable |
|
62 |
+ * @param[in] io I/O object that is writable |
|
63 |
+ */ |
|
64 |
+ virtual void ioWriteCall(Io *io); |
|
65 |
+ |
|
66 |
+protected: |
|
67 |
+ /// create socket and bind it |
|
68 |
+ void createSock(); |
|
69 |
+ |
|
70 |
+ /// destroy socket |
|
71 |
+ void destroySock(); |
|
72 |
+ |
|
73 |
+ /// receive data from socket |
|
74 |
+ void receiveFromSock(); |
|
75 |
+ |
|
76 |
+ /** |
|
77 |
+ * @brief process synchronization information |
|
78 |
+ * @param[in] data received synchronization data |
|
79 |
+ */ |
|
80 |
+ void procInfo(const std::string &data); |
|
81 |
+ |
|
82 |
+protected: |
|
83 |
+ OutSyncFile m_fileOutSync; ///< output sync stream name file |
|
84 |
+ AddrFile m_fileBind; ///< bind address file |
|
85 |
+ AddrFile m_fileSrc; ///< source address file |
|
86 |
+ SOCK *m_pSock; ///< socket to use for receiving sync stream |
|
87 |
+}; // class SyncReceiver |
|
88 |
+ |
|
89 |
+} // namespace Blinker |
|
90 |
+ |
|
91 |
+#endif // #ifndef BLINKER_SYNCRECEIVER_H |
|
92 |
+ |
... | ... |
@@ -0,0 +1,206 @@ |
1 |
+/* Blinker |
|
2 |
+ Copyright 2011-2014 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 BLINKER_SYNCRECEIVER_IMPL_H |
|
7 |
+#define BLINKER_SYNCRECEIVER_IMPL_H |
|
8 |
+ |
|
9 |
+#include <stdint.h> |
|
10 |
+#include <string> |
|
11 |
+#include <string.h> |
|
12 |
+ |
|
13 |
+#include "Directory.h" |
|
14 |
+#include "File.h" |
|
15 |
+#include "IoCallee.h" |
|
16 |
+#include "Mgrs.h" |
|
17 |
+#include "Module.h" |
|
18 |
+#include "NetHost.h" |
|
19 |
+#include "OutSyncFile.h" |
|
20 |
+#include "Protocol.h" |
|
21 |
+#include "ProtocolFile.h" |
|
22 |
+#include "SettingFile.h" |
|
23 |
+#include "SyncRecv.h" |
|
24 |
+#include "SyncReceiver.h" |
|
25 |
+ |
|
26 |
+namespace Blinker { |
|
27 |
+ |
|
28 |
+/** |
|
29 |
+ * @brief constructor |
|
30 |
+ * @param[in] name module name |
|
31 |
+ * @param[in] mgrs managers |
|
32 |
+ * @param[in] dirBase base directory |
|
33 |
+ */ |
|
34 |
+template<typename ADDR, typename SOCK> |
|
35 |
+SyncReceiver<ADDR, SOCK>::SyncReceiver(const std::string &name, Mgrs &mgrs, |
|
36 |
+ const Directory &dirBase): |
|
37 |
+ Module(name, mgrs, dirBase), |
|
38 |
+ m_fileOutSync(dirBase.getFile("outsync"), mgrs.m_syncMgr), |
|
39 |
+ m_fileBind(dirBase.getFile("bind")), |
|
40 |
+ m_fileSrc(dirBase.getFile("source")), |
|
41 |
+ m_pSock(NULL) |
|
42 |
+{ |
|
43 |
+ // read source address |
|
44 |
+ m_fileSrc.update(); |
|
45 |
+ |
|
46 |
+ // create and bind socket |
|
47 |
+ createSock(); |
|
48 |
+} |
|
49 |
+ |
|
50 |
+/// virtual destructor |
|
51 |
+template<typename ADDR, typename SOCK> |
|
52 |
+SyncReceiver<ADDR, SOCK>::~SyncReceiver() |
|
53 |
+{ |
|
54 |
+ // destroy socket |
|
55 |
+ destroySock(); |
|
56 |
+} |
|
57 |
+ |
|
58 |
+/// check for update of configuration |
|
59 |
+template<typename ADDR, typename SOCK> |
|
60 |
+void SyncReceiver<ADDR, SOCK>::updateConfig() |
|
61 |
+{ |
|
62 |
+ // output sync stream name file was modified -> re-get output sync stream |
|
63 |
+ if (m_fileOutSync.checkModified()) |
|
64 |
+ m_fileOutSync.update(); |
|
65 |
+ |
|
66 |
+ // bind address file was modified -> re-create socket |
|
67 |
+ if (m_fileBind.checkModified()) { |
|
68 |
+ destroySock(); |
|
69 |
+ createSock(); |
|
70 |
+ } |
|
71 |
+ |
|
72 |
+ // source address file was modified -> re-read source address |
|
73 |
+ if (m_fileSrc.checkModified()) |
|
74 |
+ m_fileSrc.update(); |
|
75 |
+} |
|
76 |
+ |
|
77 |
+/** |
|
78 |
+ * @brief callback when I/O object is readable |
|
79 |
+ * @param[in] io I/O object that is readable |
|
80 |
+ */ |
|
81 |
+template<typename ADDR, typename SOCK> |
|
82 |
+void SyncReceiver<ADDR, SOCK>::ioReadCall(Io *io) |
|
83 |
+{ |
|
84 |
+ // reception on socket |
|
85 |
+ if (io == m_pSock) |
|
86 |
+ receiveFromSock(); |
|
87 |
+} |
|
88 |
+ |
|
89 |
+/** |
|
90 |
+ * @brief callback when I/O object is writable |
|
91 |
+ * @param[in] io I/O object that is writable |
|
92 |
+ */ |
|
93 |
+template<typename ADDR, typename SOCK> |
|
94 |
+void SyncReceiver<ADDR, SOCK>::ioWriteCall(Io *io) |
|
95 |
+{ |
|
96 |
+ (void)io; // unused |
|
97 |
+} |
|
98 |
+ |
|
99 |
+/// create socket and bind it |
|
100 |
+template<typename ADDR, typename SOCK> |
|
101 |
+void SyncReceiver<ADDR, SOCK>::createSock() |
|
102 |
+{ |
|
103 |
+ // create socket |
|
104 |
+ if (!m_pSock) { |
|
105 |
+ m_pSock = new SOCK(); |
|
106 |
+ if (!m_pSock) |
|
107 |
+ return; |
|
108 |
+ } |
|
109 |
+ |
|
110 |
+ // get bind address from bind address setting file |
|
111 |
+ m_fileBind.update(); |
|
112 |
+ if (!m_fileBind.m_valid) { |
|
113 |
+ delete m_pSock; |
|
114 |
+ m_pSock = NULL; |
|
115 |
+ return; |
|
116 |
+ } |
|
117 |
+ |
|
118 |
+ // bind socket |
|
119 |
+ if (!m_pSock->bind(m_fileBind.m_obj)) { |
|
120 |
+ delete m_pSock; |
|
121 |
+ m_pSock = NULL; |
|
122 |
+ return; |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ // request callback on recepetion |
|
126 |
+ m_mgrs.m_callMgr.requestIoReadCall(this, m_pSock); |
|
127 |
+} |
|
128 |
+ |
|
129 |
+/// destroy socket |
|
130 |
+template<typename ADDR, typename SOCK> |
|
131 |
+void SyncReceiver<ADDR, SOCK>::destroySock() |
|
132 |
+{ |
|
133 |
+ // cancel callback request |
|
134 |
+ m_mgrs.m_callMgr.cancelIoReadCall(this, m_pSock); |
|
135 |
+ |
|
136 |
+ // destroy socket |
|
137 |
+ if (m_pSock) { |
|
138 |
+ delete m_pSock; |
|
139 |
+ m_pSock = NULL; |
|
140 |
+ } |
|
141 |
+} |
|
142 |
+ |
|
143 |
+/// receive data from socket |
|
144 |
+template<typename ADDR, typename SOCK> |
|
145 |
+void SyncReceiver<ADDR, SOCK>::receiveFromSock() |
|
146 |
+{ |
|
147 |
+ std::string data; |
|
148 |
+ ADDR addr; |
|
149 |
+ |
|
150 |
+ // make sure socket exists |
|
151 |
+ if (!m_pSock) |
|
152 |
+ return; |
|
153 |
+ |
|
154 |
+ // receive (leave if no reception) |
|
155 |
+ if (!m_pSock->recv(data, addr)) |
|
156 |
+ return; |
|
157 |
+ |
|
158 |
+ // check source address (if configured) |
|
159 |
+ if (m_fileSrc.m_valid && addr != m_fileSrc.m_obj) |
|
160 |
+ return; // mismatch |
|
161 |
+ |
|
162 |
+ // process received synchronization information |
|
163 |
+ procInfo(data); |
|
164 |
+} |
|
165 |
+ |
|
166 |
+/** |
|
167 |
+ * @brief process synchronization information |
|
168 |
+ * @param[in] data received synchronization data |
|
169 |
+ */ |
|
170 |
+template<typename ADDR, typename SOCK> |
|
171 |
+void SyncReceiver<ADDR, SOCK>::procInfo(const std::string &data) |
|
172 |
+{ |
|
173 |
+ /// Po.W.E.R. (stage play by BBM) synchronization protocol |
|
174 |
+ struct PoSyPacket { |
|
175 |
+ char magic[4]; ///< fixed magic, always "PoSy" |
|
176 |
+ uint32_t flags; ///< flags, see PosSyFlags below |
|
177 |
+ char name[64]; ///< name of current piece in playlist |
|
178 |
+ uint32_t pos_ms; ///< position within current piece in milliseconds |
|
179 |
+ }; |
|
180 |
+ |
|
181 |
+ /// flags for PoSyPacket |
|
182 |
+ enum PoSyFlags { |
|
183 |
+ PoSyPause = 0x00000001, ///< pause mode active |
|
184 |
+ }; |
|
185 |
+ |
|
186 |
+ PoSyPacket packet; |
|
187 |
+ SyncRecv::Info info; |
|
188 |
+ |
|
189 |
+ // parse frame, leave if invalid |
|
190 |
+ if (data.size() < sizeof(packet)) |
|
191 |
+ return; |
|
192 |
+ memcpy(&packet, data.c_str(), sizeof(packet)); |
|
193 |
+ if (memcmp(packet.magic, "PoSy", sizeof(packet.magic)) != 0) |
|
194 |
+ return; |
|
195 |
+ info.pause = (Net2Host32(packet.flags) & PoSyPause) != 0; |
|
196 |
+ info.name = packet.name; |
|
197 |
+ info.pos_ms = Net2Host32(packet.pos_ms); |
|
198 |
+ |
|
199 |
+ // pass on sync information |
|
200 |
+ m_fileOutSync.sendInfo(info); |
|
201 |
+} |
|
202 |
+ |
|
203 |
+} // namespace Blinker |
|
204 |
+ |
|
205 |
+#endif // #ifndef BLINKER_SYNCRECEIVER_IMPL_H |
|
206 |
+ |
... | ... |
@@ -0,0 +1,21 @@ |
1 |
+/* Blinker |
|
2 |
+ Copyright 2011-2014 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 UDP4SYNCRECEIVER_H |
|
7 |
+#define UDP4SYNCRECEIVER_H |
|
8 |
+ |
|
9 |
+#include "SyncReceiver_impl.h" |
|
10 |
+#include "Udp4Addr.h" |
|
11 |
+#include "Udp4Sock.h" |
|
12 |
+ |
|
13 |
+namespace Blinker { |
|
14 |
+ |
|
15 |
+/// UDP v4 synchronization stream receiver |
|
16 |
+typedef SyncReceiver<Udp4Addr, Udp4Sock> Udp4SyncReceiver; |
|
17 |
+ |
|
18 |
+} // namespace Blinker |
|
19 |
+ |
|
20 |
+#endif // #ifndef UDP4SYNCRECEIVER_H |
|
21 |
+ |
... | ... |
@@ -0,0 +1,21 @@ |
1 |
+/* Blinker |
|
2 |
+ Copyright 2011-2014 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 UDP6SYNCRECEIVER_H |
|
7 |
+#define UDP6SYNCRECEIVER_H |
|
8 |
+ |
|
9 |
+#include "SyncReceiver_impl.h" |
|
10 |
+#include "Udp6Addr.h" |
|
11 |
+#include "Udp6Sock.h" |
|
12 |
+ |
|
13 |
+namespace Blinker { |
|
14 |
+ |
|
15 |
+/// UDP v6 synchronization stream receiver |
|
16 |
+typedef SyncReceiver<Udp6Addr, Udp6Sock> Udp6SyncReceiver; |
|
17 |
+ |
|
18 |
+} // namespace Blinker |
|
19 |
+ |
|
20 |
+#endif // #ifndef UDP6SYNCRECEIVER_H |
|
21 |
+ |
... | ... |
@@ -27,9 +27,11 @@ |
27 | 27 |
#include "Udp4Phone.h" |
28 | 28 |
#include "Udp4Receiver.h" |
29 | 29 |
#include "Udp4Sender.h" |
30 |
+#include "Udp4SyncReceiver.h" |
|
30 | 31 |
#include "Udp6Phone.h" |
31 | 32 |
#include "Udp6Receiver.h" |
32 | 33 |
#include "Udp6Sender.h" |
34 |
+#include "Udp6SyncReceiver.h" |
|
33 | 35 |
|
34 | 36 |
using namespace Blinker; |
35 | 37 |
|
... | ... |
@@ -59,9 +61,11 @@ void run(const std::string &dirConfig) |
59 | 61 |
MODULEMGR(Udp4Phone, udp4phones); |
60 | 62 |
MODULEMGR(Udp4Receiver, udp4receivers); |
61 | 63 |
MODULEMGR(Udp4Sender, udp4senders); |
64 |
+ MODULEMGR(Udp4SyncReceiver, udp4syncreceivers); |
|
62 | 65 |
MODULEMGR(Udp6Phone, udp6phones); |
63 | 66 |
MODULEMGR(Udp6Receiver, udp6receivers); |
64 | 67 |
MODULEMGR(Udp6Sender, udp6senders); |
68 |
+ MODULEMGR(Udp6SyncReceiver, udp6syncreceivers); |
|
65 | 69 |
|
66 | 70 |
#undef MODULEMGR |
67 | 71 |
|
... | ... |
@@ -0,0 +1,20 @@ |
1 |
+/* Blinker |
|
2 |
+ Copyright 2011-2014 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 <arpa/inet.h> |
|
7 |
+#include <stdint.h> |
|
8 |
+ |
|
9 |
+#include "NetHost.h" |
|
10 |
+ |
|
11 |
+namespace Blinker { |
|
12 |
+ |
|
13 |
+/// convert 32 bit unsigned integer from network to host byte order |
|
14 |
+uint32_t Net2Host32(uint32_t val) |
|
15 |
+{ |
|
16 |
+ return ntohl(val); |
|
17 |
+} |
|
18 |
+ |
|
19 |
+} // namespace Blinker |
|
20 |
+ |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+/* Blinker |
|
2 |
+ Copyright 2011-2014 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 BLINKER_NETHOST_H |
|
7 |
+#define BLINKER_NETHOST_H |
|
8 |
+ |
|
9 |
+#include <stdint.h> |
|
10 |
+ |
|
11 |
+namespace Blinker { |
|
12 |
+ |
|
13 |
+/// convert 32 bit unsigned integer from network to host byte order |
|
14 |
+uint32_t Net2Host32(uint32_t val); |
|
15 |
+ |
|
16 |
+} // namespace Blinker |
|
17 |
+ |
|
18 |
+#endif // #ifndef BLINKER_NETHOST_H |
|
19 |
+ |
|
0 | 20 |