Merge lp:~tes/goby/time_fix into lp:goby/trunk

Proposed by toby schneider
Status: Merged
Approved by: Chris Murphy
Approved revision: 44
Merged at revision: 43
Proposed branch: lp:~tes/goby/time_fix
Merge into: lp:goby/trunk
Diff against target: 13742 lines (+5010/-4748)
107 files modified
CMakeLists.txt (+2/-2)
COPYING (+1/-2)
src/acomms.h (+31/-0)
src/acomms/acomms_constants.h (+49/-52)
src/acomms/amac.h (+1/-1)
src/acomms/bind.h (+43/-44)
src/acomms/dccl.h (+1/-1)
src/acomms/examples/chat/CMakeLists.txt (+1/-1)
src/acomms/examples/chat/chat.cpp (+21/-19)
src/acomms/libamac/CMakeLists.txt (+2/-2)
src/acomms/libamac/examples/amac_simple/CMakeLists.txt (+1/-1)
src/acomms/libamac/examples/amac_simple/amac_simple.cpp (+10/-10)
src/acomms/libamac/mac_manager.cpp (+42/-40)
src/acomms/libamac/mac_manager.h (+247/-249)
src/acomms/libdccl/CMakeLists.txt (+2/-2)
src/acomms/libdccl/dccl.cpp (+106/-95)
src/acomms/libdccl/dccl.h (+480/-480)
src/acomms/libdccl/dccl_constants.h (+7/-4)
src/acomms/libdccl/examples/dccl_simple/CMakeLists.txt (+1/-1)
src/acomms/libdccl/examples/dccl_simple/dccl_simple.cpp (+4/-4)
src/acomms/libdccl/examples/delta/CMakeLists.txt (+1/-1)
src/acomms/libdccl/examples/delta/delta.cpp (+6/-6)
src/acomms/libdccl/examples/plusnet/CMakeLists.txt (+1/-1)
src/acomms/libdccl/examples/plusnet/plusnet.cpp (+9/-8)
src/acomms/libdccl/examples/test/CMakeLists.txt (+1/-1)
src/acomms/libdccl/examples/test/test.cpp (+21/-20)
src/acomms/libdccl/examples/test/test.xml (+2/-2)
src/acomms/libdccl/examples/two_message/CMakeLists.txt (+1/-1)
src/acomms/libdccl/examples/two_message/two_message.cpp (+5/-4)
src/acomms/libdccl/message.cpp (+71/-68)
src/acomms/libdccl/message.h (+195/-193)
src/acomms/libdccl/message_algorithms.cpp (+9/-8)
src/acomms/libdccl/message_algorithms.h (+38/-37)
src/acomms/libdccl/message_publish.cpp (+25/-25)
src/acomms/libdccl/message_publish.h (+58/-56)
src/acomms/libdccl/message_val.cpp (+71/-67)
src/acomms/libdccl/message_val.h (+143/-142)
src/acomms/libdccl/message_var.cpp (+24/-24)
src/acomms/libdccl/message_var.h (+125/-124)
src/acomms/libdccl/message_var_bool.h (+9/-6)
src/acomms/libdccl/message_var_enum.h (+68/-66)
src/acomms/libdccl/message_var_float.cpp (+13/-16)
src/acomms/libdccl/message_var_float.h (+66/-65)
src/acomms/libdccl/message_var_head.h (+189/-171)
src/acomms/libdccl/message_var_hex.h (+55/-52)
src/acomms/libdccl/message_var_int.h (+16/-15)
src/acomms/libdccl/message_var_static.h (+40/-39)
src/acomms/libdccl/message_var_string.h (+70/-69)
src/acomms/libdccl/message_xml_callbacks.cpp (+16/-14)
src/acomms/libdccl/message_xml_callbacks.h (+62/-61)
src/acomms/libdccl/tools/analyze_dccl_xml/CMakeLists.txt (+1/-1)
src/acomms/libdccl/tools/analyze_dccl_xml/analyze_dccl_xml.cpp (+3/-3)
src/acomms/libmodemdriver/CMakeLists.txt (+2/-2)
src/acomms/libmodemdriver/driver_base.cpp (+6/-6)
src/acomms/libmodemdriver/driver_base.h (+177/-160)
src/acomms/libmodemdriver/examples/driver_simple/CMakeLists.txt (+1/-1)
src/acomms/libmodemdriver/examples/driver_simple/driver_simple.cpp (+8/-8)
src/acomms/libmodemdriver/mm_driver.cpp (+58/-71)
src/acomms/libmodemdriver/mm_driver.h (+155/-153)
src/acomms/libqueue/CMakeLists.txt (+2/-2)
src/acomms/libqueue/examples/multimessage/CMakeLists.txt (+1/-1)
src/acomms/libqueue/examples/multimessage/multimessage.cpp (+13/-13)
src/acomms/libqueue/examples/queue_simple/CMakeLists.txt (+1/-1)
src/acomms/libqueue/examples/queue_simple/queue_simple.cpp (+11/-10)
src/acomms/libqueue/queue.cpp (+27/-29)
src/acomms/libqueue/queue.h (+82/-79)
src/acomms/libqueue/queue_config.cpp (+1/-1)
src/acomms/libqueue/queue_config.h (+134/-133)
src/acomms/libqueue/queue_constants.h (+13/-9)
src/acomms/libqueue/queue_key.h (+35/-34)
src/acomms/libqueue/queue_manager.cpp (+74/-76)
src/acomms/libqueue/queue_manager.h (+309/-308)
src/acomms/libqueue/queue_xml_callbacks.cpp (+3/-3)
src/acomms/libqueue/queue_xml_callbacks.h (+56/-53)
src/acomms/modem_driver.h (+2/-2)
src/acomms/modem_message.h (+299/-279)
src/acomms/queue.h (+1/-1)
src/acomms/xml/tags.h (+139/-133)
src/util.h (+31/-0)
src/util/CMakeLists.txt (+2/-3)
src/util/asioclient.h (+4/-3)
src/util/binary.h (+170/-0)
src/util/flexostream.h (+0/-26)
src/util/libasioclient/CMakeLists.txt (+2/-2)
src/util/libasioclient/client_base.h (+4/-3)
src/util/libasioclient/nmea_sentence.cpp (+6/-17)
src/util/libasioclient/nmea_sentence.h (+6/-9)
src/util/libasioclient/serial_client.cpp (+7/-7)
src/util/libasioclient/serial_client.h (+5/-3)
src/util/libasioclient/tcp_client.cpp (+7/-7)
src/util/libasioclient/tcp_client.h (+5/-2)
src/util/libflexostream/CMakeLists.txt (+0/-5)
src/util/liblogger/CMakeLists.txt (+2/-2)
src/util/liblogger/flex_ncurses.cpp (+69/-69)
src/util/liblogger/flex_ncurses.h (+218/-215)
src/util/liblogger/flex_ostream.cpp (+6/-6)
src/util/liblogger/flex_ostream.h (+6/-1)
src/util/liblogger/flex_ostreambuf.cpp (+21/-15)
src/util/liblogger/flex_ostreambuf.h (+17/-11)
src/util/liblogger/logger_manipulators.cpp (+2/-2)
src/util/liblogger/logger_manipulators.h (+0/-1)
src/util/liblogger/term_color.h (+10/-8)
src/util/logger.h (+2/-1)
src/util/sci.h (+64/-0)
src/util/string.h (+165/-0)
src/util/tes_utils.h (+0/-386)
src/util/time.h (+103/-0)
To merge this branch: bzr merge lp:~tes/goby/time_fix
Reviewer Review Type Date Requested Status
Chris Murphy Approve
Review via email: mp+29948@code.launchpad.net

Description of the change

1. Consistent source of time based on boost::posix_time. Should be minimal / no use of <ctime> and UNIX double time. Any such use should be flagged as a bug from now on.

2. Renamed and consolidated namespaces:
dccl -> goby::acomms
queue -> goby::acomms
modem -> goby::acomms
micromodem -> goby::acomms
amac -> goby::acomms

tes_util -> goby::util
serial-> goby::util

Renamed a few classes to resolve resulting ambiguity and increase consistency:

dccl::Message* -> DCCLMessage*
modem::Message -> ModemMessage

3. Reworked util libraries:
libstreamlogger + libflexcout -> liblogger
libserial -> libasioclient
tes_utils.h -> time.h / sci.h / string.h

4. Changed header file structure slightly. For example, must #include "goby/acomms/dccl.h" instead of #include "acomms/dccl.h". This reflects the structure for > make install (which puts headers in /usr/local/include/goby/...)

Added courtesy headers for all of goby::acomms and goby::util.

5. Documentation will need to be update to reflect these changes. I still need to do that, but I think we shouldn't have that delay the merge.

To post a comment you must log in.
Revision history for this message
Chris Murphy (chrismurf) wrote :

1) util/time.h still #includes <ctime>, but compiles fine without it. Probably okay to remove it, or is there a dependency I didn't see?

2) seems reasonable to me. I'll probably just do a 'using namespace goby' 99% of the time, but I can live with that. Consistent naming is a good thing.

3) looks good from a quick review.

4) did not review.

5) agreed.

 - c

review: Approve
Revision history for this message
Chris Murphy (chrismurf) wrote :

(In summary, looks good, I agree with the philosophy, but obviously didn't do a 100% code review).

lp:~tes/goby/time_fix updated
45. By toby <toby@eis>

fixed some Doxygen comments to reflect new namespaces

Revision history for this message
toby schneider (tes) wrote :

<ctime> is needed because there are (currently unused) conversions between ptime and time_t in util/time.h. Merged into lp:goby as 43

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2009-12-18 02:50:00 +0000
3+++ CMakeLists.txt 2010-07-15 12:38:39 +0000
4@@ -23,7 +23,7 @@
5
6 # set instructions for `make install`
7 install(DIRECTORY ${goby_BIN_DIR}/ DESTINATION /usr/local/bin FILE_PERMISSIONS WORLD_EXECUTE)
8-install(DIRECTORY ${goby_LIB_DIR}/ DESTINATION /usr/local/lib/goby)
9+install(DIRECTORY ${goby_LIB_DIR}/ DESTINATION /usr/local/lib)
10 install(DIRECTORY ${goby_INC_DIR}/ DESTINATION /usr/local/include/goby)
11
12 # find packages, libraries, and headers
13@@ -51,7 +51,7 @@
14 # copy to goby/include
15 file(GLOB_RECURSE INCLUDE_FILES RELATIVE ${goby_SRC_DIR} src/*.h)
16 foreach(I ${INCLUDE_FILES})
17- configure_file(${goby_SRC_DIR}/${I} ${goby_INC_DIR}/${I})
18+ configure_file(${goby_SRC_DIR}/${I} ${goby_INC_DIR}/goby/${I})
19 endforeach()
20
21 # let cmake know where the headers are
22
23=== modified file 'COPYING'
24--- COPYING 2010-07-14 22:03:13 +0000
25+++ COPYING 2010-07-15 12:38:39 +0000
26@@ -2,8 +2,7 @@
27 copying goby
28 ~~~~~~~~~~~~
29
30-goby is copyright 2008, 2009 by
31-- t. schneider tes@mit.edu
32+goby is copyright 2008, 2009, 2010 as listed in the individual header files.
33
34 see header files of individual components for copyright details.
35
36
37=== added file 'src/acomms.h'
38--- src/acomms.h 1970-01-01 00:00:00 +0000
39+++ src/acomms.h 2010-07-15 12:38:39 +0000
40@@ -0,0 +1,31 @@
41+// copyright 2010 t. schneider tes@mit.edu
42+//
43+// this file is part of goby-
44+//
45+// This program is free software: you can redistribute it and/or modify
46+// it under the terms of the GNU General Public License as published by
47+// the Free Software Foundation, either version 3 of the License, or
48+// (at your option) any later version.
49+//
50+// This software is distributed in the hope that it will be useful,
51+// but WITHOUT ANY WARRANTY; without even the implied warranty of
52+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53+// GNU General Public License for more details.
54+//
55+// You should have received a copy of the GNU General Public License
56+// along with this software. If not, see <http://www.gnu.org/licenses/>.
57+
58+
59+// courtesy header for all the goby acomms libraries
60+
61+#ifndef ACOMMSCOURTESY20100713H
62+#define ACOMMSCOURTESY20100713H
63+
64+#include "goby/acomms/dccl.h"
65+#include "goby/acomms/queue.h"
66+#include "goby/acomms/bind.h"
67+#include "goby/acomms/modem_driver.h"
68+#include "goby/acomms/modem_message.h"
69+#include "goby/acomms/amac.h"
70+
71+#endif
72
73=== modified file 'src/acomms/acomms_constants.h'
74--- src/acomms/acomms_constants.h 2010-03-20 06:09:16 +0000
75+++ src/acomms/acomms_constants.h 2010-07-15 12:38:39 +0000
76@@ -22,61 +22,58 @@
77 #include <limits>
78 #include <bitset>
79
80-#include "util/tes_utils.h"
81-
82-namespace acomms
83+namespace goby
84 {
85- const unsigned BITS_IN_BYTE = 8;
86- // one hex char is a nibble (4 bits), two nibbles per byte
87- const unsigned NIBS_IN_BYTE = 2;
88-
89- const unsigned BROADCAST_ID = 0;
90- const unsigned char DCCL_CCL_HEADER = 32;
91-
92- const double NaN = std::numeric_limits<double>::quiet_NaN();
93-
94- const unsigned NUM_HEADER_BYTES = 6;
95- const unsigned NUM_HEADER_NIBS = 6*NIBS_IN_BYTE;
96-
97- const unsigned NUM_HEADER_PARTS = 8;
98- enum DCCLHeaderPart { head_ccl_id = 0,
99- head_dccl_id = 1,
100- head_time = 2,
101- head_src_id = 3,
102- head_dest_id = 4,
103- head_multimessage_flag = 5,
104- head_broadcast_flag = 6,
105- head_unused = 7
106- };
107-
108- const std::string DCCL_HEADER_NAMES [] = { "_ccl_id",
109- "_id",
110- "_time",
111- "_src_id",
112- "_dest_id",
113- "_multimessage_flag",
114- "_broadcast_flag",
115- "_unused",
116- };
117- inline std::string to_str(DCCLHeaderPart p)
118+
119+ namespace acomms
120 {
121- return DCCL_HEADER_NAMES[p];
122+ const unsigned BITS_IN_BYTE = 8;
123+ // one hex char is a nibble (4 bits), two nibbles per byte
124+ const unsigned NIBS_IN_BYTE = 2;
125+
126+ const unsigned BROADCAST_ID = 0;
127+ const unsigned char DCCL_CCL_HEADER = 32;
128+
129+ const double NaN = std::numeric_limits<double>::quiet_NaN();
130+
131+ const unsigned DCCL_NUM_HEADER_BYTES = 6;
132+
133+ const unsigned DCCL_NUM_HEADER_PARTS = 8;
134+
135+ enum DCCLHeaderPart { head_ccl_id = 0,
136+ head_dccl_id = 1,
137+ head_time = 2,
138+ head_src_id = 3,
139+ head_dest_id = 4,
140+ head_multimessage_flag = 5,
141+ head_broadcast_flag = 6,
142+ head_unused = 7
143+ };
144+
145+ const std::string DCCL_HEADER_NAMES [] = { "_ccl_id",
146+ "_id",
147+ "_time",
148+ "_src_id",
149+ "_dest_id",
150+ "_multimessage_flag",
151+ "_broadcast_flag",
152+ "_unused",
153+ };
154+ inline std::string to_str(DCCLHeaderPart p)
155+ {
156+ return DCCL_HEADER_NAMES[p];
157+ }
158+
159+ enum DCCLHeaderBits { head_ccl_id_size = 8,
160+ head_dccl_id_size = 9,
161+ head_time_size = 17,
162+ head_src_id_size = 5,
163+ head_dest_id_size = 5,
164+ head_flag_size = 1,
165+ head_unused_size = 2
166+ };
167+
168 }
169-
170- enum DCCLHeaderBits { head_ccl_id_size = 8,
171- head_dccl_id_size = 9,
172- head_time_size = 17,
173- head_src_id_size = 5,
174- head_dest_id_size = 5,
175- head_flag_size = 1,
176- head_unused_size = 2
177- };
178-
179- const double NOT_A_TIME = -1;
180
181- // this is Micro-Modem specific and is used by libmac, therefore
182- // we must get rid of it at some point soon...
183- const unsigned PACKET_SIZE [] = { 32, 32, 64, 256, 256, 256 };
184 }
185-
186 #endif
187
188=== modified file 'src/acomms/amac.h'
189--- src/acomms/amac.h 2010-01-16 05:42:56 +0000
190+++ src/acomms/amac.h 2010-07-15 12:38:39 +0000
191@@ -20,7 +20,7 @@
192 #ifndef AMACCOURTESY20091211H
193 #define AMACCOURTESY20091211H
194
195-#include "acomms/libamac/mac_manager.h"
196+#include "goby/acomms/libamac/mac_manager.h"
197
198 #endif
199
200
201=== modified file 'src/acomms/bind.h'
202--- src/acomms/bind.h 2010-06-15 04:51:47 +0000
203+++ src/acomms/bind.h 2010-07-15 12:38:39 +0000
204@@ -23,58 +23,57 @@
205
206 #include <boost/bind.hpp>
207
208-#include "acomms/dccl.h"
209-#include "acomms/queue.h"
210-#include "acomms/modem_driver.h"
211-#include "acomms/amac.h"
212+#include "goby/acomms/dccl.h"
213+#include "goby/acomms/queue.h"
214+#include "goby/acomms/modem_driver.h"
215+#include "goby/acomms/amac.h"
216
217-/// utilites for dealing with goby-acomms
218-namespace acomms_util
219+namespace goby
220 {
221+ namespace acomms
222+ {
223
224 /// binds the driver link-layer callbacks to the QueueManager
225- void bind(modem::DriverBase& driver, queue::QueueManager& queue_manager)
226- {
227- using boost::bind;
228- driver.set_receive_cb
229- (bind(&queue::QueueManager::receive_incoming_modem_data, &queue_manager, _1));
230- driver.set_ack_cb
231- (bind(&queue::QueueManager::handle_modem_ack, &queue_manager, _1));
232- driver.set_datarequest_cb
233- (bind(&queue::QueueManager::provide_outgoing_modem_data, &queue_manager, _1, _2));
234- }
235+ void bind(ModemDriverBase& driver, QueueManager& queue_manager)
236+ {
237+ using boost::bind;
238+ driver.set_receive_cb
239+ (bind(&QueueManager::receive_incoming_modem_data, &queue_manager, _1));
240+ driver.set_ack_cb
241+ (bind(&QueueManager::handle_modem_ack, &queue_manager, _1));
242+ driver.set_datarequest_cb
243+ (bind(&QueueManager::provide_outgoing_modem_data, &queue_manager, _1, _2));
244+
245+ driver.set_destination_cb(boost::bind(&QueueManager::request_next_destination, &queue_manager, _1));
246+
247+ }
248
249 /// binds the MAC initiate transmission callback to the driver and the driver parsed message callback to the MAC
250- void bind(amac::MACManager& mac, modem::DriverBase& driver)
251- {
252- mac.set_initiate_transmission_cb(boost::bind(&modem::DriverBase::initiate_transmission, &driver, _1));
253- mac.set_initiate_ranging_cb(boost::bind(&modem::DriverBase::initiate_ranging, &driver, _1));
254- driver.set_in_parsed_cb(boost::bind(&amac::MACManager::process_message, &mac, _1));
255- }
256+ void bind(MACManager& mac, ModemDriverBase& driver)
257+ {
258+ mac.set_initiate_transmission_cb(boost::bind(&ModemDriverBase::initiate_transmission, &driver, _1));
259+ mac.set_initiate_ranging_cb(boost::bind(&ModemDriverBase::initiate_ranging, &driver, _1));
260+ mac.set_destination_cb(boost::bind(&ModemDriverBase::request_next_destination, &driver, _1));
261+ driver.set_in_parsed_cb(boost::bind(&MACManager::process_message, &mac, _1));
262+ }
263
264-/// binds the MAC destination request to the queue_manager
265- void bind(amac::MACManager& mac, queue::QueueManager& queue_manager)
266- {
267- mac.set_destination_cb(boost::bind(&queue::QueueManager::request_next_destination, &queue_manager, _1));
268- }
269-
270- /// bind all three (shortcut to calling the other three bind functions)
271- void bind(modem::DriverBase& driver, queue::QueueManager& queue_manager, amac::MACManager& mac)
272- {
273- bind(driver, queue_manager);
274- bind(mac, driver);
275- bind(mac, queue_manager);
276- }
277-
278- // examples
279- /// \example acomms/examples/chat/chat.cpp
280- /// chat.xml
281- /// \verbinclude chat.xml
282- /// chat.cpp
283-
284+
285+ /// bind all three (shortcut to calling the other three bind functions)
286+ void bind(ModemDriverBase& driver, QueueManager& queue_manager, MACManager& mac)
287+ {
288+ bind(driver, queue_manager);
289+ bind(mac, driver);
290+ }
291+
292+ // examples
293+ /// \example acomms/examples/chat/chat.cpp
294+ /// chat.xml
295+ /// \verbinclude chat.xml
296+ /// chat.cpp
297+
298+
299+ }
300
301 }
302
303-
304-
305 #endif
306
307=== modified file 'src/acomms/dccl.h'
308--- src/acomms/dccl.h 2009-12-16 20:12:41 +0000
309+++ src/acomms/dccl.h 2010-07-15 12:38:39 +0000
310@@ -22,6 +22,6 @@
311 #ifndef DCCLCOURTESY20091211H
312 #define DCCLCOURTESY20091211H
313
314-#include "acomms/libdccl/dccl.h"
315+#include "goby/acomms/libdccl/dccl.h"
316
317 #endif
318
319=== modified file 'src/acomms/examples/chat/CMakeLists.txt'
320--- src/acomms/examples/chat/CMakeLists.txt 2010-01-22 02:52:25 +0000
321+++ src/acomms/examples/chat/CMakeLists.txt 2010-07-15 12:38:39 +0000
322@@ -1,2 +1,2 @@
323 add_executable(chat chat.cpp chat_curses.cpp)
324-target_link_libraries(chat ${Boost_LIBRARIES} queue amac dccl modemdriver)
325+target_link_libraries(chat ${Boost_LIBRARIES} goby_queue goby_amac goby_dccl goby_modemdriver)
326
327=== modified file 'src/acomms/examples/chat/chat.cpp'
328--- src/acomms/examples/chat/chat.cpp 2010-03-10 01:14:38 +0000
329+++ src/acomms/examples/chat/chat.cpp 2010-07-15 12:38:39 +0000
330@@ -22,27 +22,29 @@
331
332 #include <iostream>
333
334-#include "acomms/dccl.h"
335-#include "acomms/queue.h"
336-#include "acomms/modem_driver.h"
337-#include "acomms/amac.h"
338-#include "acomms/modem_message.h"
339-#include "acomms/bind.h"
340+#include "goby/acomms/dccl.h"
341+#include "goby/acomms/queue.h"
342+#include "goby/acomms/modem_driver.h"
343+#include "goby/acomms/amac.h"
344+#include "goby/acomms/modem_message.h"
345+#include "goby/acomms/bind.h"
346
347 #include <boost/lexical_cast.hpp>
348
349 #include "chat_curses.h"
350
351+using namespace goby::acomms;
352+
353 int startup_failure();
354-void received_data(queue::QueueKey, const modem::Message&);
355-void received_ack(queue::QueueKey, const modem::Message&);
356+void received_data(QueueKey, const ModemMessage&);
357+void received_ack(QueueKey, const ModemMessage&);
358 std::string decode_received(unsigned id, const std::string& data);
359
360 std::ofstream fout_;
361-dccl::DCCLCodec dccl_;
362-queue::QueueManager q_manager_(&fout_);
363-micromodem::MMDriver mm_driver_(&fout_);
364-amac::MACManager mac_(&fout_);
365+DCCLCodec dccl_;
366+QueueManager q_manager_(&fout_);
367+MMDriver mm_driver_(&fout_);
368+MACManager mac_(&fout_);
369 ChatCurses curses_;
370
371
372@@ -77,7 +79,7 @@
373 }
374
375 // bind the callbacks of these libraries
376- acomms_util::bind(mm_driver_, q_manager_, mac_);
377+ bind(mm_driver_, q_manager_, mac_);
378
379 //
380 // Initiate DCCL (libdccl)
381@@ -100,7 +102,7 @@
382 //
383 // Initiate medium access control (libamac)
384 //
385- mac_.set_type(amac::mac_slotted_tdma);
386+ mac_.set_type(mac_slotted_tdma);
387 mac_.set_rate(0);
388 mac_.set_slot_time(15);
389 mac_.set_expire_cycles(5);
390@@ -133,7 +135,7 @@
391
392 if(!line.empty())
393 {
394- std::map<std::string, dccl::MessageVal> vals;
395+ std::map<std::string, DCCLMessageVal> vals;
396 vals["message"] = line;
397
398 std::string hex_out;
399@@ -141,7 +143,7 @@
400 unsigned message_id = 1;
401 dccl_.encode(message_id, hex_out, vals);
402
403- modem::Message message_out;
404+ ModemMessage message_out;
405 message_out.set_data(hex_out);
406 // send this message to my buddy!
407 message_out.set_dest(buddy_id);
408@@ -171,12 +173,12 @@
409 return 1;
410 }
411
412-void received_data(queue::QueueKey key, const modem::Message& message_in)
413+void received_data(QueueKey key, const ModemMessage& message_in)
414 {
415 curses_.post_message(message_in.src(), decode_received(key.id(), message_in.data()));
416 }
417
418-void received_ack(queue::QueueKey key, const modem::Message& ack_message)
419+void received_ack(QueueKey key, const ModemMessage& ack_message)
420 {
421
422 curses_.post_message
423@@ -187,7 +189,7 @@
424
425 std::string decode_received(unsigned id, const std::string& data)
426 {
427- std::map<std::string, dccl::MessageVal> vals;
428+ std::map<std::string, DCCLMessageVal> vals;
429 dccl_.decode(id, data, vals);
430 return vals["message"];
431 }
432
433=== modified file 'src/acomms/libamac/CMakeLists.txt'
434--- src/acomms/libamac/CMakeLists.txt 2010-01-21 04:25:08 +0000
435+++ src/acomms/libamac/CMakeLists.txt 2010-07-15 12:38:39 +0000
436@@ -4,8 +4,8 @@
437 include_directories(${Boost_INCLUDE_DIR})
438
439 file(GLOB SRC *.cpp *.c)
440- add_library(amac SHARED ${SRC})
441- target_link_libraries(amac streamlogger ${Boost_LIBRARIES})
442+ add_library(goby_amac SHARED ${SRC})
443+ target_link_libraries(goby_amac goby_logger ${Boost_LIBRARIES})
444 endif()
445
446 add_subdirectory(examples)
447\ No newline at end of file
448
449=== modified file 'src/acomms/libamac/examples/amac_simple/CMakeLists.txt'
450--- src/acomms/libamac/examples/amac_simple/CMakeLists.txt 2010-01-22 02:52:25 +0000
451+++ src/acomms/libamac/examples/amac_simple/CMakeLists.txt 2010-07-15 12:38:39 +0000
452@@ -1,2 +1,2 @@
453 add_executable(amac_simple amac_simple.cpp)
454-target_link_libraries(amac_simple amac)
455\ No newline at end of file
456+target_link_libraries(amac_simple goby_amac)
457\ No newline at end of file
458
459=== modified file 'src/acomms/libamac/examples/amac_simple/amac_simple.cpp'
460--- src/acomms/libamac/examples/amac_simple/amac_simple.cpp 2010-01-22 02:52:25 +0000
461+++ src/acomms/libamac/examples/amac_simple/amac_simple.cpp 2010-07-15 12:38:39 +0000
462@@ -13,12 +13,12 @@
463 // You should have received a copy of the GNU General Public License
464 // along with this software. If not, see <http://www.gnu.org/licenses/>.
465
466-#include "acomms/amac.h"
467-#include "acomms/modem_message.h"
468+#include "goby/acomms/amac.h"
469+#include "goby/acomms/modem_message.h"
470 #include <iostream>
471
472 int next_dest(unsigned);
473-void init_transmission(const modem::Message&);
474+void init_transmission(const goby::acomms::ModemMessage&);
475
476 int main(int argc, char* argv[])
477 {
478@@ -26,12 +26,12 @@
479 //
480 // 1. Create a MACManager and feed it a std::ostream to log to
481 //
482- amac::MACManager mac(&std::cout);
483+ goby::acomms::MACManager mac(&std::cout);
484
485 //
486 // 2. Configure it for TDMA with basic peer discovery, rate 0, 10 second slots, and expire vehicles after 2 cycles of no communications. also, we are modem id 1.
487 //
488- mac.set_type(amac::mac_slotted_tdma);
489+ mac.set_type(goby::acomms::mac_slotted_tdma);
490 mac.set_rate(0);
491 mac.set_slot_time(10);
492 mac.set_expire_cycles(2);
493@@ -43,7 +43,7 @@
494
495 // give callback for the next destination. this is called before a cycle is initiated, and would be bound to queue::QueueManager::request_next_destination if using libqueue.
496 mac.set_destination_cb(&next_dest);
497- // give a callback to use for actually initiating the transmission. this would be bound to modem::DriverBase::initiate_transmission if using libmodemdriver.
498+ // give a callback to use for actually initiating the transmission. this would be bound to goby::acomms::ModemDriverBase::initiate_transmission if using libmodemdriver.
499 mac.set_initiate_transmission_cb(&init_transmission);
500
501 //
502@@ -60,8 +60,8 @@
503 // 5. Discover some friends (modem ids 2 & 3)
504 //
505
506- mac.process_message(modem::Message("src=2"));
507- mac.process_message(modem::Message("src=3"));
508+ mac.process_message(goby::acomms::ModemMessage("src=2"));
509+ mac.process_message(goby::acomms::ModemMessage("src=3"));
510
511 //
512 // 6. Run it, hearing consistently from #3, but #2 has gone silent and will be expired after 2 cycles
513@@ -71,7 +71,7 @@
514 {
515 mac.do_work();
516 sleep(1);
517- mac.process_message(modem::Message("src=3"));
518+ mac.process_message(goby::acomms::ModemMessage("src=3"));
519 }
520
521 return 0;
522@@ -83,7 +83,7 @@
523 return 10;
524 }
525
526-void init_transmission(const modem::Message& init_message)
527+void init_transmission(const goby::acomms::ModemMessage& init_message)
528 {
529 std::cout << "starting transmission with these values: " << init_message << std::endl;
530 }
531
532=== modified file 'src/acomms/libamac/mac_manager.cpp'
533--- src/acomms/libamac/mac_manager.cpp 2010-07-11 16:20:55 +0000
534+++ src/acomms/libamac/mac_manager.cpp 2010-07-15 12:38:39 +0000
535@@ -1,4 +1,4 @@
536-// copyright 2009 t. schneider tes@mit.edu
537+// copyright 2009, 2010 t. schneider tes@mit.edu
538 //
539 // this file is part of libamac, a medium access control for
540 // acoustic networks.
541@@ -27,13 +27,15 @@
542 #include <boost/bind.hpp>
543 #include <boost/foreach.hpp>
544
545-#include "acomms/modem_message.h"
546-#include "acomms/libdccl/dccl_constants.h"
547-#include "util/streamlogger.h"
548+#include "goby/acomms/modem_message.h"
549+#include "goby/acomms/libdccl/dccl_constants.h"
550+#include "goby/util/logger.h"
551
552 #include "mac_manager.h"
553
554-amac::MACManager::MACManager(std::ostream* os /* =0 */)
555+using goby::util::goby_time;
556+
557+goby::acomms::MACManager::MACManager(std::ostream* os /* =0 */)
558 : rate_(0),
559 slot_time_(15),
560 expire_cycles_(5),
561@@ -45,34 +47,34 @@
562 type_(mac_notype)
563 { }
564
565-amac::MACManager::~MACManager()
566+goby::acomms::MACManager::~MACManager()
567 { }
568
569-void amac::MACManager::do_work()
570+void goby::acomms::MACManager::do_work()
571 {
572-// if(os_) *os_ << group("mac") << "timer is running: " << std::boolalpha << timer_is_running_ << std::endl;
573+ // if(os_) *os_ << group("mac") << "timer is running: " << std::boolalpha << timer_is_running_ << std::endl;
574
575 // let the io service execute ready handlers (in this case, is the timer up?)
576 if(timer_is_running_) io_.poll();
577 }
578
579-void amac::MACManager::restart_timer()
580+void goby::acomms::MACManager::restart_timer()
581 {
582 // cancel any old timer jobs waiting
583 timer_.cancel();
584 timer_.expires_at(next_slot_t_);
585- timer_.async_wait(boost::bind(&amac::MACManager::send_poll, this, _1));
586+ timer_.async_wait(boost::bind(&MACManager::send_poll, this, _1));
587 timer_is_running_ = true;
588 }
589
590-void amac::MACManager::stop_timer()
591+void goby::acomms::MACManager::stop_timer()
592 {
593 timer_is_running_ = false;
594 timer_.cancel();
595 }
596
597
598-void amac::MACManager::startup()
599+void goby::acomms::MACManager::startup()
600 {
601 switch(type_)
602 {
603@@ -80,17 +82,17 @@
604 if(os_) *os_ << group("mac")
605 << "Using the Slotted TDMA MAC scheme with autodiscovery"
606 << std::endl;
607- blank_it_ = add_slot(amac::Slot(acomms::BROADCAST_ID,
608- amac::Slot::query_destination,
609- rate_,
610- amac::Slot::slot_data,
611- slot_time_,
612- boost::posix_time::ptime(boost::posix_time::pos_infin)));
613+ blank_it_ = add_slot(Slot(acomms::BROADCAST_ID,
614+ Slot::query_destination,
615+ rate_,
616+ Slot::slot_data,
617+ slot_time_,
618+ boost::posix_time::ptime(boost::posix_time::pos_infin)));
619
620- add_slot(amac::Slot(modem_id_,
621- amac::Slot::query_destination,
622+ add_slot(Slot(modem_id_,
623+ Slot::query_destination,
624 rate_,
625- amac::Slot::slot_data,
626+ Slot::slot_data,
627 slot_time_,
628 boost::posix_time::ptime(boost::posix_time::pos_infin)));
629
630@@ -107,7 +109,7 @@
631 case mac_polled:
632 if(os_) *os_ << group("mac")
633 << "Using the Centralized Polling MAC scheme" << std::endl;
634- next_slot_t_ = now();
635+ next_slot_t_ = goby_time();
636 break;
637
638 default:
639@@ -118,7 +120,7 @@
640 restart_timer();
641 }
642
643-void amac::MACManager::send_poll(const asio::error_code& e)
644+void goby::acomms::MACManager::send_poll(const asio::error_code& e)
645 {
646 // canceled the last timer
647 if(e == asio::error::operation_aborted) return;
648@@ -129,7 +131,7 @@
649 bool send_poll = true;
650
651 int destination = (s.dest() == Slot::query_destination)
652- ? callback_dest(acomms::PACKET_SIZE[s.rate()]) : s.dest();
653+ ? callback_dest(s.rate()) : s.dest();
654
655 switch(type_)
656 {
657@@ -157,13 +159,13 @@
658 *os_ << " ]" << std::endl;
659
660 *os_ << group("mac") << s.type_as_string() << " slot is starting: {" << s.src() << " to "
661- << destination << " @ " << s.rate() << "}" << std::endl;
662+ << destination << " @ " << s.rate() << "}" << std::endl;
663 }
664
665
666 if(send_poll)
667 {
668- modem::Message m;
669+ ModemMessage m;
670 switch(s.type())
671 {
672 case Slot::slot_data:
673@@ -214,12 +216,12 @@
674 restart_timer();
675 }
676
677- boost::posix_time::ptime amac::MACManager::next_cycle_time()
678+boost::posix_time::ptime goby::acomms::MACManager::next_cycle_time()
679 {
680 using namespace boost::gregorian;
681 using namespace boost::posix_time;
682
683- int since_day_start = now().time_of_day().total_seconds();
684+ int since_day_start = goby_time().time_of_day().total_seconds();
685 cycles_since_day_start_ = (floor(since_day_start/cycle_length()) + 1);
686
687 if(os_) *os_ << group("mac") << "cycles since day start: "
688@@ -232,7 +234,7 @@
689 return ptime(day_clock::universal_day(), seconds(secs_to_next));
690 }
691
692-void amac::MACManager::process_message(const modem::Message& m)
693+void goby::acomms::MACManager::process_message(const ModemMessage& m)
694 {
695 unsigned id = m.src();
696
697@@ -249,7 +251,7 @@
698
699 slot_order_.push_back
700 (id2slot_.insert
701- (std::pair<unsigned, Slot> (id, Slot(id, Slot::query_destination, rate_, Slot::slot_data, slot_time_, now()))));
702+ (std::pair<unsigned, Slot> (id, Slot(id, Slot::query_destination, rate_, Slot::slot_data, slot_time_, goby_time()))));
703
704 slot_order_.sort();
705
706@@ -259,17 +261,17 @@
707 {
708 std::pair<id2slot_it, id2slot_it> p = id2slot_.equal_range(id);
709 for(id2slot_it it = p.first; it != p.second; ++it)
710- it->second.set_last_heard_time(now());
711+ it->second.set_last_heard_time(goby_time());
712 }
713 }
714
715-void amac::MACManager::expire_ids()
716+void goby::acomms::MACManager::expire_ids()
717 {
718 bool reset = false;
719
720 for(id2slot_it it = id2slot_.begin(), n = id2slot_.end(); it != n; ++it)
721 {
722- if(it->second.last_heard_time() < now()-boost::posix_time::seconds(cycle_length()*expire_cycles_) && it->first != modem_id_)
723+ if(it->second.last_heard_time() < goby_time()-boost::posix_time::seconds(cycle_length()*expire_cycles_) && it->first != modem_id_)
724 {
725 if(os_) *os_ << group("mac") << "removed id " << it->first
726 << " after not hearing for " << expire_cycles_
727@@ -284,7 +286,7 @@
728 if(reset) process_cycle_size_change();
729 }
730
731-void amac::MACManager::process_cycle_size_change()
732+void goby::acomms::MACManager::process_cycle_size_change()
733 {
734 next_slot_t_ = next_cycle_time();
735 if(os_) *os_ << group("mac") << "the MAC TDMA next cycle begins at time: "
736@@ -296,7 +298,7 @@
737 }
738
739
740-unsigned amac::MACManager::cycle_sum()
741+unsigned goby::acomms::MACManager::cycle_sum()
742 {
743 unsigned s = 0;
744 BOOST_FOREACH(id2slot_it it, slot_order_)
745@@ -304,7 +306,7 @@
746 return s;
747 }
748
749-void amac::MACManager::position_blank()
750+void goby::acomms::MACManager::position_blank()
751 {
752 unsigned blank_pos = cycle_length() - ((cycles_since_day_start_ % ENTROPY) == (cycle_sum() % ENTROPY)) - 1;
753
754@@ -319,11 +321,11 @@
755 current_slot_ = slot_order_.begin();
756 }
757
758-std::map<unsigned, amac::Slot>::iterator amac::MACManager::add_slot(const amac::Slot& s)
759+std::map<unsigned, goby::acomms::Slot>::iterator goby::acomms::MACManager::add_slot(const Slot& s)
760 {
761 bool do_timer_start = slot_order_.empty();
762
763- std::map<unsigned, amac::Slot>::iterator it =
764+ std::map<unsigned, Slot>::iterator it =
765 id2slot_.insert(std::pair<unsigned, Slot>(s.src(), s));
766
767 slot_order_.push_back(it);
768@@ -333,14 +335,14 @@
769
770 if(do_timer_start)
771 {
772- next_slot_t_ = now();
773+ next_slot_t_ = goby_time();
774 restart_timer();
775 }
776
777 return it;
778 }
779
780-bool amac::MACManager::remove_slot(const amac::Slot& s)
781+bool goby::acomms::MACManager::remove_slot(const Slot& s)
782 {
783 bool removed_a_slot = false;
784
785
786=== modified file 'src/acomms/libamac/mac_manager.h'
787--- src/acomms/libamac/mac_manager.h 2010-07-11 16:20:55 +0000
788+++ src/acomms/libamac/mac_manager.h 2010-07-15 12:38:39 +0000
789@@ -1,4 +1,4 @@
790-// copyright 2009 t. schneider tes@mit.edu
791+// copyright 2009, 2010 t. schneider tes@mit.edu
792 //
793 // this file is part of libamac, a medium access control for
794 // acoustic networks.
795@@ -23,268 +23,266 @@
796 #define MAC20091019H
797
798 #include <boost/lexical_cast.hpp>
799-#include <boost/date_time/posix_time/posix_time.hpp>
800 #include <boost/function.hpp>
801 #include "asio.hpp"
802
803-namespace modem { class Message; }
804+#include "goby/util/time.h"
805
806-/// \brief contains the medium access control objects
807-///
808-/// Use \code #include <goby/acomms/amac.h> \endcode to gain access to all these objects.
809-namespace amac
810+namespace goby
811 {
812- /// \name Acoustic MAC Library callback function type definitions
813- //@{
814-
815- /// \brief boost::function for a function taking a unsigned and returning an integer.
816- ///
817- /// Think of this as a generalized version of a function pointer (int (*) (unsigned)). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
818- typedef boost::function<int (unsigned)> IdFunc;
819-
820- /// \brief boost::function for a function taking a single modem::Message reference.
821- ///
822- /// Think of this as a generalized version of a function pointer (void (*)(modem::Message&)). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
823- typedef boost::function<void (const modem::Message & message)> MsgFunc1;
824-
825- //@}
826+ namespace acomms
827+ {
828+ class ModemMessage;
829+ /// \name Acoustic MAC Library callback function type definitions
830+ //@{
831+
832+ /// \brief boost::function for a function taking a unsigned and returning an integer.
833+ ///
834+ /// Think of this as a generalized version of a function pointer (int (*) (unsigned)). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
835+ typedef boost::function<int (unsigned)> MACIdFunc;
836+
837+ /// \brief boost::function for a function taking a single acomms::ModemMessage reference.
838+ ///
839+ /// Think of this as a generalized version of a function pointer (void (*)(acomms::ModemMessage&)). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
840+ typedef boost::function<void (const acomms::ModemMessage & message)> MACMsgFunc1;
841+
842+ //@}
843
844 /// Enumeration of MAC types
845- enum MACType {
846- mac_notype, /*!< no MAC */
847- mac_slotted_tdma, /*!< decentralized time division multiple access */
848- mac_polled /*!< centralized polling */
849- };
850+ enum MACType {
851+ mac_notype, /*!< no MAC */
852+ mac_slotted_tdma, /*!< decentralized time division multiple access */
853+ mac_polled /*!< centralized polling */
854+ };
855
856- /// Represents a slot of the TDMA cycle
857- class Slot
858- {
859- public:
860- /// Enumeration of slot types
861- enum SlotType
862+ /// Represents a slot of the TDMA cycle
863+ class Slot
864 {
865- slot_notype, /*!< useless slot */
866- slot_data, /*!< slot to send data packet */
867- slot_ping /*!< slot to send ping (ranging) */
868- };
869+ public:
870+ /// Enumeration of slot types
871+ enum SlotType
872+ {
873+ slot_notype, /*!< useless slot */
874+ slot_data, /*!< slot to send data packet */
875+ slot_ping /*!< slot to send ping (ranging) */
876+ };
877
878- /// \name Constructors/Destructor
879- //@{
880- /// \brief Default constructor.
881- ///
882- /// \param src id representing sender of the data packet or ping
883- /// \param dest id representing destination of the data packet or ping
884- /// \param rate value 0-5 representing modem transmission rate. 0 is slowest, 5 is fastest
885- /// \param type amac::Slot::SlotType of this slot
886- /// \param slot_time length of time this slot should last in seconds
887- /// \param last_heard_time last time (in seconds since 1/1/70) the src vehicle was heard from
888- Slot(unsigned src = 0,
889- unsigned dest = 0,
890- int rate = 0,
891- SlotType type = slot_notype,
892- unsigned slot_time = 15,
893- boost::posix_time::ptime last_heard_time = boost::posix_time::not_a_date_time)
894- : src_(src),
895- dest_(dest),
896- rate_(rate),
897- type_(type),
898- slot_time_(slot_time),
899- last_heard_time_(last_heard_time)
900- { }
901-
902- //@}
903-
904- /// \name Set
905- //@{
906- void set_src(unsigned src) { src_ = src; }
907- void set_dest(int dest) { dest_ = dest; }
908- void set_rate(int rate) { rate_ = rate; }
909- void set_type(SlotType type) { type_ = type; }
910- void set_last_heard_time(boost::posix_time::ptime t) { last_heard_time_ = t; }
911- void set_slot_time(unsigned t) { slot_time_ = t; }
912- //@}
913-
914- /// \name Get
915- //@{
916- unsigned src() const { return src_; }
917- int dest() const { return dest_; }
918- int rate() const { return rate_; }
919- SlotType type() const { return type_; }
920- std::string type_as_string() const
921- {
922- switch(type_)
923+ /// \name Constructors/Destructor
924+ //@{
925+ /// \brief Default constructor.
926+ ///
927+ /// \param src id representing sender of the data packet or ping
928+ /// \param dest id representing destination of the data packet or ping
929+ /// \param rate value 0-5 representing modem transmission rate. 0 is slowest, 5 is fastest
930+ /// \param type amac::Slot::SlotType of this slot
931+ /// \param slot_time length of time this slot should last in seconds
932+ /// \param last_heard_time last time (in seconds since 1/1/70) the src vehicle was heard from
933+ Slot(unsigned src = 0,
934+ unsigned dest = 0,
935+ int rate = 0,
936+ SlotType type = slot_notype,
937+ unsigned slot_time = 15,
938+ boost::posix_time::ptime last_heard_time = boost::posix_time::not_a_date_time)
939+ : src_(src),
940+ dest_(dest),
941+ rate_(rate),
942+ type_(type),
943+ slot_time_(slot_time),
944+ last_heard_time_(last_heard_time)
945+ { }
946+
947+ //@}
948+
949+ /// \name Set
950+ //@{
951+ void set_src(unsigned src) { src_ = src; }
952+ void set_dest(int dest) { dest_ = dest; }
953+ void set_rate(int rate) { rate_ = rate; }
954+ void set_type(SlotType type) { type_ = type; }
955+ void set_last_heard_time(boost::posix_time::ptime t) { last_heard_time_ = t; }
956+ void set_slot_time(unsigned t) { slot_time_ = t; }
957+ //@}
958+
959+ /// \name Get
960+ //@{
961+ unsigned src() const { return src_; }
962+ int dest() const { return dest_; }
963+ int rate() const { return rate_; }
964+ SlotType type() const { return type_; }
965+ std::string type_as_string() const
966 {
967- case slot_data: return "data";
968- case slot_ping: return "ping";
969- default: return "unknown";
970+ switch(type_)
971+ {
972+ case slot_data: return "data";
973+ case slot_ping: return "ping";
974+ default: return "unknown";
975+ }
976 }
977+
978+ boost::posix_time::ptime last_heard_time() const { return last_heard_time_; }
979+ unsigned slot_time() const { return slot_time_; }
980+ //@}
981+
982+ enum { query_destination = -1 };
983+
984+
985+ private:
986+ unsigned src_;
987+ int dest_;
988+ int rate_;
989+ SlotType type_;
990+ unsigned slot_time_;
991+ boost::posix_time::ptime last_heard_time_;
992+ };
993+
994+ inline std::ostream& operator<<(std::ostream& os, const Slot& s)
995+ { return os << "src: " << s.src() << " | dest: " << s.dest() << " | rate: " << s.rate() << " | slot_time: " << s.slot_time(); }
996+
997+
998+ /// provides an API to the goby-acomms MAC library.
999+ class MACManager
1000+ {
1001+
1002+ public:
1003+
1004+ /// \name Constructors/Destructor
1005+ //@{
1006+ /// \brief Default constructor.
1007+ ///
1008+ /// \param os std::ostream object or FlexOstream to capture all humanly readable runtime and debug information (optional).
1009+ MACManager(std::ostream* os = 0);
1010+ ~MACManager();
1011+ //@}
1012+
1013+ /// \brief Starts the MAC
1014+ void startup();
1015+ /// \brief Must be called regularly for the MAC to perform its work
1016+ void do_work();
1017+
1018+ /// \brief Manually initiate a transmission out of the normal cycle. This is not normally called by the user of MACManager
1019+ void send_poll(const asio::error_code&);
1020+
1021+ /// \brief Call every time a message is received from vehicle to "discover" this vehicle or reset the expire timer. Only needed when the type is amac::mac_slotted_tdma.
1022+ ///
1023+ /// \param message the new message (used to detect vehicles)
1024+ void process_message(const acomms::ModemMessage& m);
1025+
1026+ /// \name Manipulate slots
1027+ //@{
1028+ /// \return iterator to newly added slot
1029+ std::map<unsigned, Slot>::iterator add_slot(const Slot& s);
1030+ /// \brief removes any slots in the cycle where amac::operator==(const Slot&, const Slot&) is true.
1031+ ///
1032+ /// \return true if one or more slots are removed
1033+ bool remove_slot(const Slot& s);
1034+ void clear_all_slots() { id2slot_.clear(); slot_order_.clear(); }
1035+ //@}
1036+
1037+
1038+ /// \name Set
1039+ //@{
1040+ void set_type(MACType type) { type_ = type; }
1041+ void set_modem_id(unsigned modem_id) { modem_id_ = modem_id; }
1042+ void set_modem_id(const std::string& s) { set_modem_id(boost::lexical_cast<unsigned>(s)); }
1043+ void set_rate(int rate) { rate_ = rate; }
1044+ void set_rate(const std::string& s) { set_rate(boost::lexical_cast<int>(s)); }
1045+ void set_slot_time(unsigned slot_time) { slot_time_ = slot_time; }
1046+ void set_slot_time(const std::string& s) { set_slot_time(boost::lexical_cast<unsigned>(s)); }
1047+ void set_expire_cycles(unsigned expire_cycles) { expire_cycles_ = expire_cycles; }
1048+ void set_expire_cycles(const std::string& s) { set_expire_cycles(boost::lexical_cast<unsigned>(s)); }
1049+ /// \brief Callback to call to request which vehicle id should be the next destination. Typically bound to queue::QueueManager::request_next_destination.
1050+ //
1051+ // \param func has the form int next_dest(unsigned size). the return value of func should be the next destination id, or -1 for no message to send.
1052+ void set_destination_cb(MACIdFunc func) { callback_dest = func; }
1053+ /// \brief Callback for initiate a tranmission. Typically bound to acomms::ModemDriverBase::initiate_transmission.
1054+ void set_initiate_transmission_cb(MACMsgFunc1 func) { callback_initiate_transmission = func; }
1055+
1056+ /// \brief Callback for initiate ranging ("ping"). Typically bound to acomms::ModemDriverBase::initiate_ranging.
1057+ void set_initiate_ranging_cb(MACMsgFunc1 func) { callback_initiate_ranging = func; }
1058+
1059+//@}
1060+
1061+ /// \name Get
1062+ //@{
1063+ int rate() { return rate_; }
1064+ unsigned slot_time() { return slot_time_; }
1065+ MACType type() { return type_; }
1066+ //@}
1067+
1068+
1069+ /// \example libamac/examples/amac_simple/amac_simple.cpp
1070+ /// amac_simple.cpp
1071+
1072+ /// \example acomms/examples/chat/chat.cpp
1073+
1074+ private:
1075+ enum { NO_AVAILABLE_DESTINATION = -1 };
1076+ MACIdFunc callback_dest;
1077+ MACMsgFunc1 callback_initiate_transmission;
1078+ MACMsgFunc1 callback_initiate_ranging;
1079+
1080+ boost::posix_time::ptime next_cycle_time();
1081+
1082+ void restart_timer();
1083+ void stop_timer();
1084+
1085+ void expire_ids();
1086+ void process_cycle_size_change();
1087+
1088+ unsigned cycle_count() { return slot_order_.size(); }
1089+ unsigned cycle_length() { return cycle_count() * slot_time_; }
1090+
1091+ unsigned cycle_sum();
1092+ void position_blank();
1093+
1094+ private:
1095+ // (bit)-rate id number
1096+ int rate_;
1097+ // size of each slot (seconds)
1098+ unsigned slot_time_;
1099+ // how many cycles before we remove someone?
1100+ unsigned expire_cycles_;
1101+
1102+ std::ostream* os_;
1103+
1104+ unsigned modem_id_;
1105+
1106+ // asynchronous timer
1107+ asio::io_service io_;
1108+ asio::deadline_timer timer_;
1109+ bool timer_is_running_;
1110+
1111+ boost::posix_time::ptime next_cycle_t_;
1112+ boost::posix_time::ptime next_slot_t_;
1113+
1114+ // <id, last time heard from>
1115+ typedef std::multimap<unsigned, Slot>::iterator id2slot_it;
1116+
1117+ id2slot_it blank_it_;
1118+ std::list<id2slot_it> slot_order_;
1119+ std::multimap<unsigned, Slot> id2slot_;
1120+
1121+ std::list<id2slot_it>::iterator current_slot_;
1122+
1123+ unsigned cycles_since_day_start_;
1124+
1125+ // entropy value used to determine how the "blank" slot moves around relative to the values of the modem ids. determining the proper value for this is a bit of work and i will detail when i have time.
1126+ enum { ENTROPY = 5 };
1127+ MACType type_;
1128+ };
1129+
1130+ ///
1131+ inline bool operator<(const std::map<unsigned, Slot>::iterator& a, const std::map<unsigned, Slot>::iterator& b)
1132+ { return a->second.src() < b->second.src(); }
1133+
1134+ /// Are two amac::Slot equal?
1135+ inline bool operator==(const Slot& a, const Slot& b)
1136+ {
1137+ return a.src() == b.src() && a.dest() == b.dest() && a.rate() == b.rate() && a.type() == b.type() && a.slot_time() == b.slot_time();
1138 }
1139-
1140- boost::posix_time::ptime last_heard_time() const { return last_heard_time_; }
1141- unsigned slot_time() const { return slot_time_; }
1142- //@}
1143-
1144- enum { query_destination = -1 };
1145-
1146-
1147- private:
1148- unsigned src_;
1149- int dest_;
1150- int rate_;
1151- SlotType type_;
1152- unsigned slot_time_;
1153- boost::posix_time::ptime last_heard_time_;
1154- };
1155-
1156- inline std::ostream& operator<<(std::ostream& os, const Slot& s)
1157- { return os << "src: " << s.src() << " | dest: " << s.dest() << " | rate: " << s.rate() << " | slot_time: " << s.slot_time(); }
1158-
1159-
1160- /// provides an API to the goby-acomms MAC library.
1161- class MACManager
1162- {
1163-
1164- public:
1165-
1166- /// \name Constructors/Destructor
1167- //@{
1168- /// \brief Default constructor.
1169- ///
1170- /// \param os std::ostream object or FlexOstream to capture all humanly readable runtime and debug information (optional).
1171- MACManager(std::ostream* os = 0);
1172- ~MACManager();
1173- //@}
1174-
1175- /// \brief Starts the MAC
1176- void startup();
1177- /// \brief Must be called regularly for the MAC to perform its work
1178- void do_work();
1179-
1180- /// \brief Manually initiate a transmission out of the normal cycle. This is not normally called by the user of MACManager
1181- void send_poll(const asio::error_code&);
1182-
1183- /// \brief Call every time a message is received from vehicle to "discover" this vehicle or reset the expire timer. Only needed when the type is amac::mac_slotted_tdma.
1184- ///
1185- /// \param message the new message (used to detect vehicles)
1186- void process_message(const modem::Message& m);
1187-
1188- /// \name Manipulate slots
1189- //@{
1190- /// \return iterator to newly added slot
1191- std::map<unsigned, amac::Slot>::iterator add_slot(const amac::Slot& s);
1192- /// \brief removes any slots in the cycle where amac::operator==(const Slot&, const Slot&) is true.
1193- ///
1194- /// \return true if one or more slots are removed
1195- bool remove_slot(const amac::Slot& s);
1196- void clear_all_slots() { id2slot_.clear(); slot_order_.clear(); }
1197- //@}
1198-
1199-
1200- /// \name Set
1201- //@{
1202- void set_type(MACType type) { type_ = type; }
1203- void set_modem_id(unsigned modem_id) { modem_id_ = modem_id; }
1204- void set_modem_id(const std::string& s) { set_modem_id(boost::lexical_cast<unsigned>(s)); }
1205- void set_rate(int rate) { rate_ = rate; }
1206- void set_rate(const std::string& s) { set_rate(boost::lexical_cast<int>(s)); }
1207- void set_slot_time(unsigned slot_time) { slot_time_ = slot_time; }
1208- void set_slot_time(const std::string& s) { set_slot_time(boost::lexical_cast<unsigned>(s)); }
1209- void set_expire_cycles(unsigned expire_cycles) { expire_cycles_ = expire_cycles; }
1210- void set_expire_cycles(const std::string& s) { set_expire_cycles(boost::lexical_cast<unsigned>(s)); }
1211- /// \brief Callback to call to request which vehicle id should be the next destination. Typically bound to queue::QueueManager::request_next_destination.
1212- //
1213- // \param func has the form int next_dest(unsigned size). the return value of func should be the next destination id, or -1 for no message to send.
1214- void set_destination_cb(IdFunc func) { callback_dest = func; }
1215- /// \brief Callback for initiate a tranmission. Typically bound to modem::DriverBase::initiate_transmission.
1216- void set_initiate_transmission_cb(MsgFunc1 func) { callback_initiate_transmission = func; }
1217-
1218- /// \brief Callback for initiate ranging ("ping"). Typically bound to modem::DriverBase::initiate_ranging.
1219- void set_initiate_ranging_cb(MsgFunc1 func) { callback_initiate_ranging = func; }
1220-
1221-//@}
1222-
1223- /// \name Get
1224- //@{
1225- int rate() { return rate_; }
1226- unsigned slot_time() { return slot_time_; }
1227- MACType type() { return type_; }
1228- //@}
1229-
1230-
1231- /// \example libamac/examples/amac_simple/amac_simple.cpp
1232- /// amac_simple.cpp
1233-
1234- /// \example acomms/examples/chat/chat.cpp
1235-
1236- private:
1237- enum { NO_AVAILABLE_DESTINATION = -1 };
1238- IdFunc callback_dest;
1239- MsgFunc1 callback_initiate_transmission;
1240- MsgFunc1 callback_initiate_ranging;
1241-
1242- boost::posix_time::ptime next_cycle_time();
1243-
1244- void restart_timer();
1245- void stop_timer();
1246-
1247- void expire_ids();
1248- void process_cycle_size_change();
1249-
1250- unsigned cycle_count() { return slot_order_.size(); }
1251- unsigned cycle_length() { return cycle_count() * slot_time_; }
1252-
1253- boost::posix_time::ptime now() { return boost::posix_time::second_clock::universal_time(); }
1254- unsigned cycle_sum();
1255- void position_blank();
1256-
1257- private:
1258- // (bit)-rate id number
1259- int rate_;
1260- // size of each slot (seconds)
1261- unsigned slot_time_;
1262- // how many cycles before we remove someone?
1263- unsigned expire_cycles_;
1264-
1265- std::ostream* os_;
1266-
1267- unsigned modem_id_;
1268-
1269- // asynchronous timer
1270- asio::io_service io_;
1271- asio::deadline_timer timer_;
1272- bool timer_is_running_;
1273-
1274- boost::posix_time::ptime next_cycle_t_;
1275- boost::posix_time::ptime next_slot_t_;
1276-
1277- // <id, last time heard from>
1278- typedef std::multimap<unsigned, Slot>::iterator id2slot_it;
1279-
1280- id2slot_it blank_it_;
1281- std::list<id2slot_it> slot_order_;
1282- std::multimap<unsigned, Slot> id2slot_;
1283-
1284- std::list<id2slot_it>::iterator current_slot_;
1285-
1286- unsigned cycles_since_day_start_;
1287-
1288- // entropy value used to determine how the "blank" slot moves around relative to the values of the modem ids. determining the proper value for this is a bit of work and i will detail when i have time.
1289- enum { ENTROPY = 5 };
1290- MACType type_;
1291- };
1292-
1293- ///
1294- inline bool operator<(const std::map<unsigned, Slot>::iterator& a, const std::map<unsigned, Slot>::iterator& b)
1295- { return a->second.src() < b->second.src(); }
1296-
1297- /// Are two amac::Slot equal?
1298- inline bool operator==(const Slot& a, const Slot& b)
1299- {
1300- return a.src() == b.src() && a.dest() == b.dest() && a.rate() == b.rate() && a.type() == b.type() && a.slot_time() == b.slot_time();
1301+
1302+
1303 }
1304-
1305-
1306 }
1307
1308-
1309 #endif
1310
1311=== modified file 'src/acomms/libdccl/CMakeLists.txt'
1312--- src/acomms/libdccl/CMakeLists.txt 2010-03-15 16:21:43 +0000
1313+++ src/acomms/libdccl/CMakeLists.txt 2010-07-15 12:38:39 +0000
1314@@ -4,8 +4,8 @@
1315 include_directories(${Boost_INCLUDE_DIR})
1316
1317 file(GLOB SRC *.cpp *.c)
1318- add_library(dccl SHARED ${SRC})
1319- target_link_libraries(dccl xerces-c crypto++)
1320+ add_library(goby_dccl SHARED ${SRC})
1321+ target_link_libraries(goby_dccl xerces-c crypto++ ${Boost_LIBRARIES})
1322 endif()
1323
1324 add_subdirectory(examples)
1325
1326=== modified file 'src/acomms/libdccl/dccl.cpp'
1327--- src/acomms/libdccl/dccl.cpp 2010-06-15 04:51:47 +0000
1328+++ src/acomms/libdccl/dccl.cpp 2010-07-15 12:38:39 +0000
1329@@ -26,31 +26,39 @@
1330 #include "dccl.h"
1331 #include "message_xml_callbacks.h"
1332
1333+using goby::util::goby_time;
1334+
1335 /////////////////////
1336 // public methods (general use)
1337 /////////////////////
1338-dccl::DCCLCodec::DCCLCodec() : start_time_(time(NULL)), modem_id_(0)
1339+goby::acomms::DCCLCodec::DCCLCodec()
1340+ : start_time_(goby_time()),
1341+ modem_id_(0)
1342 { }
1343
1344-dccl::DCCLCodec::DCCLCodec(const std::string& file, const std::string schema) : start_time_(time(NULL)), modem_id_(0)
1345+goby::acomms::DCCLCodec::DCCLCodec(const std::string& file, const std::string schema)
1346+ : start_time_(goby_time()),
1347+ modem_id_(0)
1348 { add_xml_message_file(file, schema); }
1349
1350-dccl::DCCLCodec::DCCLCodec(const std::set<std::string>& files,
1351- const std::string schema) : start_time_(time(NULL)), modem_id_(0)
1352+goby::acomms::DCCLCodec::DCCLCodec(const std::set<std::string>& files,
1353+ const std::string schema)
1354+ : start_time_(goby_time()),
1355+ modem_id_(0)
1356 {
1357 BOOST_FOREACH(const std::string& s, files)
1358 add_xml_message_file(s, schema);
1359 }
1360
1361-std::set<unsigned> dccl::DCCLCodec::add_xml_message_file(const std::string& xml_file,
1362+std::set<unsigned> goby::acomms::DCCLCodec::add_xml_message_file(const std::string& xml_file,
1363 const std::string xml_schema)
1364 {
1365 size_t begin_size = messages_.size();
1366
1367
1368 // Register handlers for XML parsing
1369- MessageContentHandler content(messages_);
1370- MessageErrorHandler error;
1371+ DCCLMessageContentHandler content(messages_);
1372+ DCCLMessageErrorHandler error;
1373 // instantiate a parser for the xml message files
1374 XMLParser parser(content, error);
1375 // parse(file, [schema])
1376@@ -77,59 +85,59 @@
1377 return added_ids;
1378 }
1379
1380-std::set<unsigned> dccl::DCCLCodec::all_message_ids()
1381+std::set<unsigned> goby::acomms::DCCLCodec::all_message_ids()
1382 {
1383 std::set<unsigned> s;
1384- BOOST_FOREACH(const Message &msg, messages_)
1385+ BOOST_FOREACH(const DCCLMessage &msg, messages_)
1386 s.insert(msg.id());
1387 return s;
1388 }
1389-std::set<std::string> dccl::DCCLCodec::all_message_names()
1390+std::set<std::string> goby::acomms::DCCLCodec::all_message_names()
1391 {
1392 std::set<std::string> s;
1393- BOOST_FOREACH(const Message &msg, messages_)
1394+ BOOST_FOREACH(const DCCLMessage &msg, messages_)
1395 s.insert(msg.name());
1396 return s;
1397 }
1398
1399
1400-std::string dccl::DCCLCodec::summary() const
1401+std::string goby::acomms::DCCLCodec::summary() const
1402 {
1403 std::string out;
1404- for(std::vector<Message>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1405+ for(std::vector<DCCLMessage>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1406 out += it->get_display();
1407 return out;
1408 }
1409
1410-std::string dccl::DCCLCodec::brief_summary() const
1411+std::string goby::acomms::DCCLCodec::brief_summary() const
1412 {
1413 std::string out;
1414- for(std::vector<Message>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1415+ for(std::vector<DCCLMessage>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1416 out += it->get_short_display();
1417 return out;
1418 }
1419
1420-void dccl::DCCLCodec::add_algorithm(const std::string& name, AlgFunction1 func)
1421-{
1422- AlgorithmPerformer* ap = AlgorithmPerformer::getInstance();
1423- ap -> add_algorithm(name, func);
1424-}
1425-
1426-void dccl::DCCLCodec::add_adv_algorithm(const std::string& name, AlgFunction2 func)
1427-{
1428- AlgorithmPerformer* ap = AlgorithmPerformer::getInstance();
1429- ap -> add_algorithm(name, func);
1430-}
1431-
1432-
1433-std::ostream& dccl::operator<< (std::ostream& out, const DCCLCodec& d)
1434+void goby::acomms::DCCLCodec::add_algorithm(const std::string& name, AlgFunction1 func)
1435+{
1436+ DCCLAlgorithmPerformer* ap = DCCLAlgorithmPerformer::getInstance();
1437+ ap -> add_algorithm(name, func);
1438+}
1439+
1440+void goby::acomms::DCCLCodec::add_adv_algorithm(const std::string& name, AlgFunction2 func)
1441+{
1442+ DCCLAlgorithmPerformer* ap = DCCLAlgorithmPerformer::getInstance();
1443+ ap -> add_algorithm(name, func);
1444+}
1445+
1446+
1447+std::ostream& goby::acomms::operator<< (std::ostream& out, const DCCLCodec& d)
1448 {
1449 out << d.summary();
1450 return out;
1451 }
1452
1453
1454-std::ostream& dccl::operator<< (std::ostream& out, const std::set<std::string>& s)
1455+std::ostream& goby::acomms::operator<< (std::ostream& out, const std::set<std::string>& s)
1456 {
1457 out << "std::set<std::string>:" << std::endl;
1458 for (std::set<std::string>::const_iterator it = s.begin(), n = s.end(); it != n; ++it)
1459@@ -137,7 +145,7 @@
1460 return out;
1461 }
1462
1463-std::ostream& dccl::operator<< (std::ostream& out, const std::set<unsigned>& s)
1464+std::ostream& goby::acomms::operator<< (std::ostream& out, const std::set<unsigned>& s)
1465 {
1466 out << "std::set<unsigned>:" << std::endl;
1467 for (std::set<unsigned>::const_iterator it = s.begin(), n = s.end(); it != n; ++it)
1468@@ -155,9 +163,9 @@
1469 // to be processed. this allows the SAME moos trigger variable
1470 // to be used to trigger creation of different messages based on the
1471 // contents of the trigger message itself.
1472-bool dccl::DCCLCodec::is_publish_trigger(std::set<unsigned>& id, const std::string& key, const std::string& value)
1473+bool goby::acomms::DCCLCodec::is_publish_trigger(std::set<unsigned>& id, const std::string& key, const std::string& value)
1474 {
1475- for (std::vector<dccl::Message>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1476+ for (std::vector<DCCLMessage>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1477 {
1478 if(key == it->trigger_var() && (it->trigger_mandatory() == "" || value.find(it->trigger_mandatory()) != std::string::npos))
1479 id.insert(it->id());
1480@@ -165,11 +173,14 @@
1481 return (id.empty()) ? false : true;
1482 }
1483
1484-bool dccl::DCCLCodec::is_time_trigger(std::set<unsigned>& id)
1485+bool goby::acomms::DCCLCodec::is_time_trigger(std::set<unsigned>& id)
1486 {
1487- for (std::vector<dccl::Message>::iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1488+ using boost::posix_time::seconds;
1489+
1490+ for (std::vector<DCCLMessage>::iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1491 {
1492- if(it->trigger_type() == "time" && time(NULL) > (start_time_ + it->trigger_number() * it->trigger_time()))
1493+ if(it->trigger_type() == "time" &&
1494+ goby_time() > (start_time_ + seconds(it->trigger_number() * it->trigger_time())))
1495 {
1496 id.insert(it->id());
1497 // increment message counter
1498@@ -181,9 +192,9 @@
1499 }
1500
1501
1502-bool dccl::DCCLCodec::is_incoming(unsigned& id, const std::string& key)
1503+bool goby::acomms::DCCLCodec::is_incoming(unsigned& id, const std::string& key)
1504 {
1505- for (std::vector<dccl::Message>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1506+ for (std::vector<DCCLMessage>::const_iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1507 {
1508 if (key == it->in_var())
1509 {
1510@@ -199,55 +210,55 @@
1511 /////////////////////
1512
1513
1514-void dccl::DCCLCodec::check_duplicates()
1515+void goby::acomms::DCCLCodec::check_duplicates()
1516 {
1517- std::map<unsigned, std::vector<Message>::iterator> all_ids;
1518- for(std::vector<Message>::iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1519+ std::map<unsigned, std::vector<DCCLMessage>::iterator> all_ids;
1520+ for(std::vector<DCCLMessage>::iterator it = messages_.begin(), n = messages_.end(); it != n; ++it)
1521 {
1522 unsigned id = it->id();
1523
1524- std::map<unsigned, std::vector<Message>::iterator>::const_iterator id_it = all_ids.find(id);
1525+ std::map<unsigned, std::vector<DCCLMessage>::iterator>::const_iterator id_it = all_ids.find(id);
1526 if(id_it != all_ids.end())
1527 throw std::runtime_error(std::string("DCCL: duplicate variable id " + boost::lexical_cast<std::string>(id) + " specified for " + it->name() + " and " + id_it->second->name()));
1528
1529- all_ids.insert(std::pair<unsigned, std::vector<Message>::iterator>(id, it));
1530+ all_ids.insert(std::pair<unsigned, std::vector<DCCLMessage>::iterator>(id, it));
1531 }
1532 }
1533
1534-std::vector<dccl::Message>::const_iterator dccl::DCCLCodec::to_iterator(const std::string& message_name) const
1535-{
1536- if(name2messages_.count(message_name))
1537- return messages_.begin() + name2messages_.find(message_name)->second;
1538- else
1539- throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + message_name + "] which is not loaded"));
1540-}
1541-std::vector<dccl::Message>::iterator dccl::DCCLCodec::to_iterator(const std::string& message_name)
1542-{
1543- if(name2messages_.count(message_name))
1544- return messages_.begin() + name2messages_.find(message_name)->second;
1545- else
1546- throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + message_name + "] which is not loaded"));
1547-}
1548-std::vector<dccl::Message>::const_iterator dccl::DCCLCodec::to_iterator(const unsigned& id) const
1549-{
1550- if(id2messages_.count(id))
1551- return messages_.begin() + id2messages_.find(id)->second;
1552- else
1553- throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + boost::lexical_cast<std::string>(id) + "] which is not loaded"));
1554-}
1555-
1556-std::vector<dccl::Message>::iterator dccl::DCCLCodec::to_iterator(const unsigned& id)
1557-{
1558- if(id2messages_.count(id))
1559- return messages_.begin() + id2messages_.find(id)->second;
1560- else
1561- throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + boost::lexical_cast<std::string>(id) + "] which is not loaded"));
1562-}
1563-
1564-
1565-void dccl::DCCLCodec::encode_private(std::vector<Message>::iterator it,
1566+std::vector<goby::acomms::DCCLMessage>::const_iterator goby::acomms::DCCLCodec::to_iterator(const std::string& message_name) const
1567+{
1568+ if(name2messages_.count(message_name))
1569+ return messages_.begin() + name2messages_.find(message_name)->second;
1570+ else
1571+ throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + message_name + "] which is not loaded"));
1572+}
1573+std::vector<goby::acomms::DCCLMessage>::iterator goby::acomms::DCCLCodec::to_iterator(const std::string& message_name)
1574+{
1575+ if(name2messages_.count(message_name))
1576+ return messages_.begin() + name2messages_.find(message_name)->second;
1577+ else
1578+ throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + message_name + "] which is not loaded"));
1579+}
1580+std::vector<goby::acomms::DCCLMessage>::const_iterator goby::acomms::DCCLCodec::to_iterator(const unsigned& id) const
1581+{
1582+ if(id2messages_.count(id))
1583+ return messages_.begin() + id2messages_.find(id)->second;
1584+ else
1585+ throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + boost::lexical_cast<std::string>(id) + "] which is not loaded"));
1586+}
1587+
1588+std::vector<goby::acomms::DCCLMessage>::iterator goby::acomms::DCCLCodec::to_iterator(const unsigned& id)
1589+{
1590+ if(id2messages_.count(id))
1591+ return messages_.begin() + id2messages_.find(id)->second;
1592+ else
1593+ throw std::runtime_error(std::string("DCCL: attempted an operation on message [" + boost::lexical_cast<std::string>(id) + "] which is not loaded"));
1594+}
1595+
1596+
1597+void goby::acomms::DCCLCodec::encode_private(std::vector<DCCLMessage>::iterator it,
1598 std::string& out,
1599- std::map<std::string, std::vector<MessageVal> > in /* copy */)
1600+ std::map<std::string, std::vector<DCCLMessageVal> > in /* copy */)
1601 {
1602 // 1. encode parts
1603 std::string body, head;
1604@@ -267,9 +278,9 @@
1605 hex_encode(out);
1606 }
1607
1608-void dccl::DCCLCodec::decode_private(std::vector<Message>::iterator it,
1609+void goby::acomms::DCCLCodec::decode_private(std::vector<DCCLMessage>::iterator it,
1610 std::string in,
1611- std::map<std::string, std::vector<MessageVal> >& out)
1612+ std::map<std::string, std::vector<DCCLMessageVal> >& out)
1613 {
1614 // 4. hex decode
1615 hex_decode(in);
1616@@ -278,9 +289,9 @@
1617 in.resize(in.find_last_not_of(char(0))+1);
1618
1619 // 3. split body and header (avoid substr::out_of_range)
1620- std::string body = (acomms::NUM_HEADER_BYTES < in.size()) ?
1621- in.substr(acomms::NUM_HEADER_BYTES) : "";
1622- std::string head = in.substr(0, acomms::NUM_HEADER_BYTES);
1623+ std::string body = (DCCL_NUM_HEADER_BYTES < in.size()) ?
1624+ in.substr(DCCL_NUM_HEADER_BYTES) : "";
1625+ std::string head = in.substr(0, DCCL_NUM_HEADER_BYTES);
1626
1627 // 2. decrypt
1628 if(!crypto_key_.empty()) decrypt(body, head);
1629@@ -293,33 +304,33 @@
1630
1631 }
1632
1633-void dccl::DCCLCodec::encode_private(std::vector<Message>::iterator it,
1634- modem::Message& out_msg,
1635- const std::map<std::string, std::vector<MessageVal> >& in)
1636+void goby::acomms::DCCLCodec::encode_private(std::vector<DCCLMessage>::iterator it,
1637+ ModemMessage& out_msg,
1638+ const std::map<std::string, std::vector<DCCLMessageVal> >& in)
1639 {
1640 std::string out;
1641 encode_private(it, out, in);
1642
1643- dccl::DCCLHeaderDecoder head_dec(out);
1644+ DCCLHeaderDecoder head_dec(out);
1645
1646 out_msg.set_data(out);
1647
1648- MessageVal& t = head_dec[acomms::head_time];
1649- MessageVal& src = head_dec[acomms::head_src_id];
1650- MessageVal& dest = head_dec[acomms::head_dest_id];
1651+ DCCLMessageVal& t = head_dec[head_time];
1652+ DCCLMessageVal& src = head_dec[head_src_id];
1653+ DCCLMessageVal& dest = head_dec[head_dest_id];
1654
1655- out_msg.set_t(long(t));
1656+ out_msg.set_time(double(t));
1657 out_msg.set_src(long(src));
1658 out_msg.set_dest(long(dest));
1659 }
1660
1661-void dccl::DCCLCodec::decode_private(std::vector<Message>::iterator it,
1662- const modem::Message& in_msg,
1663- std::map<std::string,std::vector<MessageVal> >& out)
1664+void goby::acomms::DCCLCodec::decode_private(std::vector<DCCLMessage>::iterator it,
1665+ const ModemMessage& in_msg,
1666+ std::map<std::string,std::vector<DCCLMessageVal> >& out)
1667 { decode_private(it, in_msg.data(), out); }
1668
1669
1670-void dccl::DCCLCodec::set_crypto_passphrase(const std::string& s)
1671+void goby::acomms::DCCLCodec::set_crypto_passphrase(const std::string& s)
1672 {
1673 using namespace CryptoPP;
1674
1675@@ -328,7 +339,7 @@
1676 }
1677
1678
1679-void dccl::DCCLCodec::encrypt(std::string& s, const std::string& nonce)
1680+void goby::acomms::DCCLCodec::encrypt(std::string& s, const std::string& nonce)
1681 {
1682 using namespace CryptoPP;
1683
1684@@ -346,7 +357,7 @@
1685 s = cipher;
1686 }
1687
1688-void dccl::DCCLCodec::decrypt(std::string& s, const std::string& nonce)
1689+void goby::acomms::DCCLCodec::decrypt(std::string& s, const std::string& nonce)
1690 {
1691 using namespace CryptoPP;
1692
1693
1694=== modified file 'src/acomms/libdccl/dccl.h'
1695--- src/acomms/libdccl/dccl.h 2010-06-15 04:51:47 +0000
1696+++ src/acomms/libdccl/dccl.h 2010-07-15 12:38:39 +0000
1697@@ -1,5 +1,5 @@
1698 // copyright 2009 t. schneider tes@mit.edu
1699-//
1700+ //
1701 // this file is part of the Dynamic Compact Control Language (DCCL),
1702 // the goby-acomms codec. goby-acomms is a collection of libraries
1703 // for acoustic underwater networking
1704@@ -20,7 +20,6 @@
1705 #ifndef DCCL20091211H
1706 #define DCCL20091211H
1707
1708-#include <ctime>
1709 #include <string>
1710 #include <set>
1711 #include <map>
1712@@ -28,494 +27,495 @@
1713 #include <stdexcept>
1714 #include <vector>
1715
1716-#include "acomms/xml/xml_parser.h"
1717+#include "goby/acomms/xml/xml_parser.h"
1718+#include "goby/util/time.h"
1719
1720 #include "message.h"
1721 #include "message_val.h"
1722
1723-/// \brief contains Dynamic Compact Control Language objects.
1724-///
1725-/// Use \code #include <goby/acomms/dccl.h> \endcode to gain access to all these objects.
1726-namespace dccl
1727+namespace goby
1728 {
1729
1730- /// use this for displaying a human readable version
1731- template<typename Value>
1732- std::ostream& operator<< (std::ostream& out, const std::map<std::string, Value>& m)
1733- {
1734- typedef std::pair<std::string, Value> P;
1735- BOOST_FOREACH(const P& p, m)
1736- {
1737- out << "\t" << "key: " << p.first << std::endl
1738- << "\t" << "value: " << p.second << std::endl;
1739- }
1740- return out;
1741- }
1742-
1743- template<typename Value>
1744- std::ostream& operator<< (std::ostream& out, const std::multimap<std::string, Value>& m)
1745- {
1746- typedef std::pair<std::string, Value> P;
1747- BOOST_FOREACH(const P& p, m)
1748- {
1749- out << "\t" << "key: " << p.first << std::endl
1750- << "\t" << "value: " << p.second << std::endl;
1751- }
1752- return out;
1753- }
1754-
1755-
1756- /// use this for displaying a human readable version of this STL object
1757- std::ostream& operator<< (std::ostream& out, const std::set<unsigned>& s);
1758- /// use this for displaying a human readable version of this STL object
1759- std::ostream& operator<< (std::ostream& out, const std::set<std::string>& s);
1760-
1761-
1762-
1763- /// provides an API to the Dynamic CCL Codec.
1764- class DCCLCodec
1765- {
1766- public:
1767- /// \name Constructors/Destructor
1768- //@{
1769- /// \brief Instantiate with no XML files.
1770- DCCLCodec();
1771- /// \brief Instantiate with a single XML file.
1772- ///
1773- /// \param file path to an XML message file (i.e. contains \ref tag_layout and (optionally) \ref tag_publish sections) to parse for use by the codec.
1774- /// \param schema path (absolute or relative to the XML file path) for the validating schema (message_schema.xsd) (optional).
1775- DCCLCodec(const std::string& file, const std::string schema = "");
1776-
1777- /// \brief Instantiate with a set of XML files.
1778- ///
1779- /// \param files set of paths to XML message files to parse for use by the codec.
1780- /// \param schema path (absolute or relative to the XML file path) for the validating schema (message_schema.xsd) (optional).
1781- DCCLCodec(const std::set<std::string>& files, const std::string schema = "");
1782-
1783- /// destructor
1784- ~DCCLCodec() {}
1785- //@}
1786-
1787- /// \name Initialization Methods.
1788- ///
1789- /// These methods are intended to be called before doing any work with the class. However,
1790- /// they may be called at any time as desired.
1791- //@{
1792-
1793- /// \brief Add more messages to this instance of the codec.
1794- ///
1795- /// \param xml_file path to the xml file to parse and add to this codec.
1796- /// \param xml_schema path to the message_schema.xsd file to validate XML with. if using a relative path this
1797- /// must be relative to the directory of the xml_file, not the present working directory. if not provided
1798- /// no validation is done.
1799- /// \return returns id of the last message file parsed. note that there can be more than one message in a file
1800- std::set<unsigned> add_xml_message_file(const std::string& xml_file, const std::string xml_schema = "");
1801-
1802- /// \brief Set the schema used for xml syntax checking.
1803- ///
1804- /// location is relative to the XML file location!
1805- /// if you have XML files in different places you must pass the
1806- /// proper relative path (or just use absolute paths)
1807- /// \param schema location of the message_schema.xsd file
1808- void set_schema(const std::string& schema) { xml_schema_ = schema; }
1809-
1810- /// \brief Set a passphrase for encrypting all messages with
1811- ///
1812- /// \param passphrase text passphrase
1813- void set_crypto_passphrase(const std::string& passphrase);
1814-
1815- /// \brief Set the %modem id for this vehicle.
1816- ///
1817- /// \param modem_id unique (within a network) number representing the %modem on this vehicle.
1818- void set_modem_id(unsigned modem_id) { modem_id_ = modem_id; }
1819-
1820-
1821-
1822- /// \brief Add an algorithm callback for a dccl::MessageVal. The return value is stored back into the input parameter (dccl::MessageVal). See test.cpp for an example.
1823- ///
1824- /// \param name name of the algorithm (\xmltag{... algorithm="name"})
1825- /// \param func has the form void name(dccl::MessageVal& val_to_edit) (see dccl::AdvAlgFunction1). can be a function pointer (&name) or
1826- /// any function object supported by boost::function (http://www.boost.org/doc/libs/1_34_0/doc/html/function.html)
1827- void add_algorithm(const std::string& name, AlgFunction1 func);
1828-
1829- /// \brief Add an advanced algorithm callback for any DCCL C++ type that may also require knowledge of all the other message variables
1830- /// and can optionally have additional parameters
1831- ///
1832- /// \param name name of the algorithm (\xmltag{... algorithm="name:param1:param2"})
1833- /// \param func has the form
1834- /// void name(MessageVal& val_to_edit,
1835- /// const std::vector<std::string> params,
1836- /// const std::map<std::string,MessageVal>& vals) (see dccl::AdvAlgFunction3). func can be a function pointer (&name) or
1837- /// any function object supported by boost::function (http://www.boost.org/doc/libs/1_34_0/doc/html/function.html).
1838- /// \param params (passed to func) a list of colon separated parameters passed by the user in the XML file. param[0] is the name.
1839- /// \param vals (passed to func) a map of \ref tag_name to current values for all message variables.
1840- void add_adv_algorithm(const std::string& name, AlgFunction2 func);
1841- //@}
1842-
1843- /// \name Codec functions.
1844- ///
1845- /// This is where the real work happens.
1846- //@{
1847- /// \brief Encode a message.
1848- ///
1849- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
1850- /// \param hex location for the encoded hexadecimal to be stored. this is suitable for sending to the Micro-Modem
1851- /// \param m map of std::string (\ref tag_name) to a vector of dccl::MessageVal representing the values to encode. No fields can be arrays using this call. If fields are arrays, all values but the first in the array will be set to NaN or blank.
1852- template<typename Key>
1853- void encode(const Key& k, std::string& hex,
1854- const std::map<std::string, MessageVal>& m)
1855- {
1856- std::map<std::string, std::vector<MessageVal> > vm;
1857-
1858- typedef std::pair<std::string,MessageVal> P;
1859- BOOST_FOREACH(const P& p, m)
1860- vm.insert(std::pair<std::string,std::vector<MessageVal> >(p.first, p.second));
1861-
1862- encode_private(to_iterator(k), hex, vm);
1863- }
1864-
1865- /// \brief Encode a message.
1866- ///
1867- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
1868- /// \param hex location for the encoded hexadecimal to be stored. this is suitable for sending to the Micro-Modem
1869- /// \param m map of std::string (\ref tag_name) to a vector of dccl::MessageVal representing the values to encode. Fields can be arrays.
1870- template<typename Key>
1871- void encode(const Key& k, std::string& hex,
1872- const std::map<std::string, std::vector<MessageVal> >& m)
1873- { encode_private(to_iterator(k), hex, m); }
1874-
1875-
1876- /// \brief Decode a message.
1877- ///
1878- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message
1879- /// \param hex the hexadecimal to be decoded.
1880- /// \param m map of std::string (\ref tag_name) to dccl::MessageVal to store the values to be decoded. No fields can be arrays using this call. If fields are arrays, only the first value is returned.
1881- template<typename Key>
1882- void decode(const Key& k, const std::string& hex,
1883- std::map<std::string, MessageVal>& m)
1884- {
1885- std::map<std::string, std::vector<MessageVal> > vm;
1886-
1887- decode_private(to_iterator(k), hex, vm);
1888-
1889- typedef std::pair<std::string,std::vector<MessageVal> > P;
1890- BOOST_FOREACH(const P& p, vm)
1891- m.insert(std::pair<std::string,MessageVal>(p.first, MessageVal(p.second)));
1892- }
1893-
1894- /// \brief Decode a message.
1895- ///
1896- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message
1897- /// \param hex the hexadecimal to be decoded.
1898- /// \param m map of std::string (\ref tag_name) to dccl::MessageVal to store the values to be decoded
1899- template<typename Key>
1900- void decode(const Key& k, const std::string& hex,
1901- std::map<std::string, std::vector<MessageVal> >& m)
1902- { decode_private(to_iterator(k), hex, m); }
1903-
1904-
1905- //@}
1906-
1907- /// \name Informational Methods
1908- ///
1909- //@{
1910- /// long summary of a message for a given Key (std::string name or unsigned id)
1911- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
1912- template<typename Key>
1913- std::string summary(const Key& k) const
1914- { return to_iterator(k)->get_display(); }
1915- /// long summary of a message for all loaded messages
1916- std::string summary() const;
1917-
1918- /// brief summary of a message for a given Key (std::string name or unsigned id)
1919- template<typename Key>
1920- std::string brief_summary(const Key& k) const
1921- { return to_iterator(k)->get_short_display(); }
1922- /// brief summary of a message for all loaded messages
1923- std::string brief_summary() const;
1924-
1925- /// how many message are loaded?
1926- /// \return number of messages loaded
1927- unsigned message_count() { return messages_.size(); }
1928-
1929- /// \return repeat value (number of copies of the message per encode)
1930- template<typename Key>
1931- unsigned get_repeat(const Key& k)
1932- { return to_iterator(k)->repeat(); }
1933-
1934- /// \return set of all message ids loaded
1935- std::set<unsigned> all_message_ids();
1936- /// \return set of all message names loaded
1937- std::set<std::string> all_message_names();
1938- /// \return map of names to DCCL types needed to encode a given message
1939- template<typename Key>
1940- std::map<std::string, std::string> message_var_names(const Key& k) const
1941- { return to_iterator(k)->message_var_names(); }
1942-
1943- /// \param id message id
1944- /// \return name of message
1945- std::string id2name(unsigned id) {return to_iterator(id)->name();}
1946- /// \param name message name
1947- /// \return id of message
1948- unsigned name2id(const std::string& name) {return to_iterator(name)->id();}
1949- //@}
1950-
1951-
1952- /// \name Publish/subscribe architecture related methods
1953- /// \brief Methods written largely to support DCCL in the context of a publish/subscribe architecture (e.g., see MOOS (http://www.robots.ox.ac.uk/~mobile/MOOS/wiki/pmwiki.php)). The other methods provide a complete interface for encoding and decoding DCCL messages. However, the methods listed here extend the functionality to allow for
1954- /// <ul>
1955- /// <li> message creation triggering (a message is encoded on a certain event, either time based or publish based) </li>
1956- /// <li> encoding that will parse strings of the form: "key1=value,key2=value,key3=value" </li>
1957- /// <li> decoding to an arbitrarily formatted string (similar concept to printf) </li>
1958- /// </ul>
1959- /// These methods will be useful if you are interested in any of the features mentioned above.
1960-
1961- //@{
1962- /// \brief Encode a message using \ref tag_src_var tags instead of \ref tag_name tags
1963- ///
1964- /// Values can be passed in on one or more maps of names to values, similar to DCCLCodec::encode.
1965- /// Casts are made and string parsing of key=value comma delimited fields is performed.
1966- /// This differs substantially from the behavior of encode above.
1967- /// For example, take this message variable:
1968- /*! \verbatim
1969- <int>
1970- <name>myint</name>
1971- <src_var>somevar</src_var>
1972- </int> \endverbatim
1973- */
1974- ///
1975- /// Using this method you can pass vals["somevar"] = "mystring=foo,blah=dog,myint=32"
1976- /// or vals["somevar"] = 32.0
1977- /// and both cases will properly parse out 32 as the value for this field.
1978- /// In comparison, using the normal encode you would pass vals["myint"] = 32
1979- ///
1980- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
1981- /// \param msg modem::Message or std::string for encoded message to be stored.
1982- /// \param vals map of source variable name to dccl::MessageVal values.
1983- template<typename Key>
1984- void pubsub_encode(const Key& k,
1985- modem::Message& msg,
1986- const std::map<std::string, std::vector<dccl::MessageVal> >& pubsub_vals)
1987- {
1988- std::vector<dccl::Message>::iterator it = to_iterator(k);
1989-
1990- std::map<std::string, std::vector<dccl::MessageVal> > vals;
1991- // clean the pubsub vals into dccl vals
1992- // using <src_var/> tag, do casts from double, pull strings from key=value,key=value, etc.
1993- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, it->layout())
1994- mv->read_pubsub_vars(vals, pubsub_vals);
1995- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, it->header())
1996- mv->read_pubsub_vars(vals, pubsub_vals);
1997-
1998- encode_private(it, msg, vals);
1999- }
2000-
2001- /// \brief Encode a message using \ref tag_src_var tags instead of \ref tag_name tags
2002- ///
2003- /// Use this version if you do not have vectors of src_var values
2004- template<typename Key>
2005- void pubsub_encode(const Key& k,
2006- modem::Message& msg,
2007- const std::map<std::string, MessageVal>& pubsub_vals)
2008- {
2009- std::map<std::string, std::vector<MessageVal> > vm;
2010-
2011- typedef std::pair<std::string,MessageVal> P;
2012- BOOST_FOREACH(const P& p, pubsub_vals)
2013- vm.insert(std::pair<std::string,std::vector<MessageVal> >(p.first, p.second));
2014-
2015- pubsub_encode(k, msg, vm);
2016- }
2017-
2018-
2019- /// \brief Decode a message using formatting specified in \ref tag_publish tags.
2020- ///
2021- /// Values will be received in two maps, one of strings and the other of doubles. The \ref tag_publish value will be placed
2022- /// either based on the "type" parameter of the \ref tag_publish_var tag (e.g. \<publish_var type="long"\>SOMEVAR\</publish_var\> will be placed as a long). If no type parameter is given and the variable is numeric (e.g. "23242.23") it will be considered a double. If not numeric, it will be considered a string.
2023- ///
2024- /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
2025- /// \param msg modem::Message or std::string to be decode.
2026- /// \param vals pointer to std::multimap of publish variable name to std::string values.
2027- template<typename Key>
2028- void pubsub_decode(const Key& k,
2029- const modem::Message& msg,
2030- std::multimap<std::string, dccl::MessageVal>& pubsub_vals)
2031+ namespace acomms
2032+ {
2033+
2034+ /// use this for displaying a human readable version
2035+ template<typename Value>
2036+ std::ostream& operator<< (std::ostream& out, const std::map<std::string, Value>& m)
2037+ {
2038+ typedef std::pair<std::string, Value> P;
2039+ BOOST_FOREACH(const P& p, m)
2040+ {
2041+ out << "\t" << "key: " << p.first << std::endl
2042+ << "\t" << "value: " << p.second << std::endl;
2043+ }
2044+ return out;
2045+ }
2046+
2047+ template<typename Value>
2048+ std::ostream& operator<< (std::ostream& out, const std::multimap<std::string, Value>& m)
2049+ {
2050+ typedef std::pair<std::string, Value> P;
2051+ BOOST_FOREACH(const P& p, m)
2052+ {
2053+ out << "\t" << "key: " << p.first << std::endl
2054+ << "\t" << "value: " << p.second << std::endl;
2055+ }
2056+ return out;
2057+ }
2058+
2059+
2060+ /// use this for displaying a human readable version of this STL object
2061+ std::ostream& operator<< (std::ostream& out, const std::set<unsigned>& s);
2062+ /// use this for displaying a human readable version of this STL object
2063+ std::ostream& operator<< (std::ostream& out, const std::set<std::string>& s);
2064+
2065+
2066+
2067+ /// provides an API to the Dynamic CCL Codec.
2068+ class DCCLCodec
2069+ {
2070+ public:
2071+ /// \name Constructors/Destructor
2072+ //@{
2073+ /// \brief Instantiate with no XML files.
2074+ DCCLCodec();
2075+ /// \brief Instantiate with a single XML file.
2076+ ///
2077+ /// \param file path to an XML message file (i.e. contains \ref tag_layout and (optionally) \ref tag_publish sections) to parse for use by the codec.
2078+ /// \param schema path (absolute or relative to the XML file path) for the validating schema (message_schema.xsd) (optional).
2079+ DCCLCodec(const std::string& file, const std::string schema = "");
2080+
2081+ /// \brief Instantiate with a set of XML files.
2082+ ///
2083+ /// \param files set of paths to XML message files to parse for use by the codec.
2084+ /// \param schema path (absolute or relative to the XML file path) for the validating schema (message_schema.xsd) (optional).
2085+ DCCLCodec(const std::set<std::string>& files, const std::string schema = "");
2086+
2087+ /// destructor
2088+ ~DCCLCodec() {}
2089+ //@}
2090+
2091+ /// \name Initialization Methods.
2092+ ///
2093+ /// These methods are intended to be called before doing any work with the class. However,
2094+ /// they may be called at any time as desired.
2095+ //@{
2096+
2097+ /// \brief Add more messages to this instance of the codec.
2098+ ///
2099+ /// \param xml_file path to the xml file to parse and add to this codec.
2100+ /// \param xml_schema path to the message_schema.xsd file to validate XML with. if using a relative path this
2101+ /// must be relative to the directory of the xml_file, not the present working directory. if not provided
2102+ /// no validation is done.
2103+ /// \return returns id of the last message file parsed. note that there can be more than one message in a file
2104+ std::set<unsigned> add_xml_message_file(const std::string& xml_file, const std::string xml_schema = "");
2105+
2106+ /// \brief Set the schema used for xml syntax checking.
2107+ ///
2108+ /// location is relative to the XML file location!
2109+ /// if you have XML files in different places you must pass the
2110+ /// proper relative path (or just use absolute paths)
2111+ /// \param schema location of the message_schema.xsd file
2112+ void set_schema(const std::string& schema) { xml_schema_ = schema; }
2113+
2114+ /// \brief Set a passphrase for encrypting all messages with
2115+ ///
2116+ /// \param passphrase text passphrase
2117+ void set_crypto_passphrase(const std::string& passphrase);
2118+
2119+ /// \brief Set the %modem id for this vehicle.
2120+ ///
2121+ /// \param modem_id unique (within a network) number representing the %modem on this vehicle.
2122+ void set_modem_id(unsigned modem_id) { modem_id_ = modem_id; }
2123+
2124+
2125+
2126+ /// \brief Add an algorithm callback for a MessageVal. The return value is stored back into the input parameter (MessageVal). See test.cpp for an example.
2127+ ///
2128+ /// \param name name of the algorithm (\xmltag{... algorithm="name"})
2129+ /// \param func has the form void name(MessageVal& val_to_edit) (see AdvAlgFunction1). can be a function pointer (&name) or
2130+ /// any function object supported by boost::function (http://www.boost.org/doc/libs/1_34_0/doc/html/function.html)
2131+ void add_algorithm(const std::string& name, AlgFunction1 func);
2132+
2133+ /// \brief Add an advanced algorithm callback for any DCCL C++ type that may also require knowledge of all the other message variables
2134+ /// and can optionally have additional parameters
2135+ ///
2136+ /// \param name name of the algorithm (\xmltag{... algorithm="name:param1:param2"})
2137+ /// \param func has the form
2138+ /// void name(MessageVal& val_to_edit,
2139+ /// const std::vector<std::string> params,
2140+ /// const std::map<std::string,MessageVal>& vals) (see AdvAlgFunction3). func can be a function pointer (&name) or
2141+ /// any function object supported by boost::function (http://www.boost.org/doc/libs/1_34_0/doc/html/function.html).
2142+ /// \param params (passed to func) a list of colon separated parameters passed by the user in the XML file. param[0] is the name.
2143+ /// \param vals (passed to func) a map of \ref tag_name to current values for all message variables.
2144+ void add_adv_algorithm(const std::string& name, AlgFunction2 func);
2145+ //@}
2146+
2147+ /// \name Codec functions.
2148+ ///
2149+ /// This is where the real work happens.
2150+ //@{
2151+ /// \brief Encode a message.
2152+ ///
2153+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
2154+ /// \param hex location for the encoded hexadecimal to be stored. this is suitable for sending to the Micro-Modem
2155+ /// \param m map of std::string (\ref tag_name) to a vector of MessageVal representing the values to encode. No fields can be arrays using this call. If fields are arrays, all values but the first in the array will be set to NaN or blank.
2156+ template<typename Key>
2157+ void encode(const Key& k, std::string& hex,
2158+ const std::map<std::string, DCCLMessageVal>& m)
2159+ {
2160+ std::map<std::string, std::vector<DCCLMessageVal> > vm;
2161+
2162+ typedef std::pair<std::string,DCCLMessageVal> P;
2163+ BOOST_FOREACH(const P& p, m)
2164+ vm.insert(std::pair<std::string,std::vector<DCCLMessageVal> >(p.first, p.second));
2165+
2166+ encode_private(to_iterator(k), hex, vm);
2167+ }
2168+
2169+ /// \brief Encode a message.
2170+ ///
2171+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
2172+ /// \param hex location for the encoded hexadecimal to be stored. this is suitable for sending to the Micro-Modem
2173+ /// \param m map of std::string (\ref tag_name) to a vector of MessageVal representing the values to encode. Fields can be arrays.
2174+ template<typename Key>
2175+ void encode(const Key& k, std::string& hex,
2176+ const std::map<std::string, std::vector<DCCLMessageVal> >& m)
2177+ { encode_private(to_iterator(k), hex, m); }
2178+
2179+
2180+ /// \brief Decode a message.
2181+ ///
2182+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message
2183+ /// \param hex the hexadecimal to be decoded.
2184+ /// \param m map of std::string (\ref tag_name) to MessageVal to store the values to be decoded. No fields can be arrays using this call. If fields are arrays, only the first value is returned.
2185+ template<typename Key>
2186+ void decode(const Key& k, const std::string& hex,
2187+ std::map<std::string, DCCLMessageVal>& m)
2188+ {
2189+ std::map<std::string, std::vector<DCCLMessageVal> > vm;
2190+
2191+ decode_private(to_iterator(k), hex, vm);
2192+
2193+ typedef std::pair<std::string,std::vector<DCCLMessageVal> > P;
2194+ BOOST_FOREACH(const P& p, vm)
2195+ m.insert(std::pair<std::string,DCCLMessageVal>(p.first, DCCLMessageVal(p.second)));
2196+ }
2197+
2198+ /// \brief Decode a message.
2199+ ///
2200+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message
2201+ /// \param hex the hexadecimal to be decoded.
2202+ /// \param m map of std::string (\ref tag_name) to MessageVal to store the values to be decoded
2203+ template<typename Key>
2204+ void decode(const Key& k, const std::string& hex,
2205+ std::map<std::string, std::vector<DCCLMessageVal> >& m)
2206+ { decode_private(to_iterator(k), hex, m); }
2207+
2208+
2209+ //@}
2210+
2211+ /// \name Informational Methods
2212+ ///
2213+ //@{
2214+ /// long summary of a message for a given Key (std::string name or unsigned id)
2215+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
2216+ template<typename Key>
2217+ std::string summary(const Key& k) const
2218+ { return to_iterator(k)->get_display(); }
2219+ /// long summary of a message for all loaded messages
2220+ std::string summary() const;
2221+
2222+ /// brief summary of a message for a given Key (std::string name or unsigned id)
2223+ template<typename Key>
2224+ std::string brief_summary(const Key& k) const
2225+ { return to_iterator(k)->get_short_display(); }
2226+ /// brief summary of a message for all loaded messages
2227+ std::string brief_summary() const;
2228+
2229+ /// how many message are loaded?
2230+ /// \return number of messages loaded
2231+ unsigned message_count() { return messages_.size(); }
2232+
2233+ /// \return repeat value (number of copies of the message per encode)
2234+ template<typename Key>
2235+ unsigned get_repeat(const Key& k)
2236+ { return to_iterator(k)->repeat(); }
2237+
2238+ /// \return set of all message ids loaded
2239+ std::set<unsigned> all_message_ids();
2240+ /// \return set of all message names loaded
2241+ std::set<std::string> all_message_names();
2242+ /// \return map of names to DCCL types needed to encode a given message
2243+ template<typename Key>
2244+ std::map<std::string, std::string> message_var_names(const Key& k) const
2245+ { return to_iterator(k)->message_var_names(); }
2246+
2247+ /// \param id message id
2248+ /// \return name of message
2249+ std::string id2name(unsigned id) {return to_iterator(id)->name();}
2250+ /// \param name message name
2251+ /// \return id of message
2252+ unsigned name2id(const std::string& name) {return to_iterator(name)->id();}
2253+ //@}
2254+
2255+
2256+ /// \name Publish/subscribe architecture related methods
2257+ /// \brief Methods written largely to support DCCL in the context of a publish/subscribe architecture (e.g., see MOOS (http://www.robots.ox.ac.uk/~mobile/MOOS/wiki/pmwiki.php)). The other methods provide a complete interface for encoding and decoding DCCL messages. However, the methods listed here extend the functionality to allow for
2258+ /// <ul>
2259+ /// <li> message creation triggering (a message is encoded on a certain event, either time based or publish based) </li>
2260+ /// <li> encoding that will parse strings of the form: "key1=value,key2=value,key3=value" </li>
2261+ /// <li> decoding to an arbitrarily formatted string (similar concept to printf) </li>
2262+ /// </ul>
2263+ /// These methods will be useful if you are interested in any of the features mentioned above.
2264+
2265+ //@{
2266+ /// \brief Encode a message using \ref tag_src_var tags instead of \ref tag_name tags
2267+ ///
2268+ /// Values can be passed in on one or more maps of names to values, similar to DCCLCodec::encode.
2269+ /// Casts are made and string parsing of key=value comma delimited fields is performed.
2270+ /// This differs substantially from the behavior of encode above.
2271+ /// For example, take this message variable:
2272+ /*! \verbatim
2273+ <int>
2274+ <name>myint</name>
2275+ <src_var>somevar</src_var>
2276+ </int> \endverbatim
2277+ */
2278+ ///
2279+ /// Using this method you can pass vals["somevar"] = "mystring=foo,blah=dog,myint=32"
2280+ /// or vals["somevar"] = 32.0
2281+ /// and both cases will properly parse out 32 as the value for this field.
2282+ /// In comparison, using the normal encode you would pass vals["myint"] = 32
2283+ ///
2284+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
2285+ /// \param msg ModemMessage or std::string for encoded message to be stored.
2286+ /// \param vals map of source variable name to MessageVal values.
2287+ template<typename Key>
2288+ void pubsub_encode(const Key& k,
2289+ ModemMessage& msg,
2290+ const std::map<std::string, std::vector<DCCLMessageVal> >& pubsub_vals)
2291+ {
2292+ std::vector<DCCLMessage>::iterator it = to_iterator(k);
2293+
2294+ std::map<std::string, std::vector<DCCLMessageVal> > vals;
2295+ // clean the pubsub vals into dccl vals
2296+ // using <src_var/> tag, do casts from double, pull strings from key=value,key=value, etc.
2297+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, it->layout())
2298+ mv->read_pubsub_vars(vals, pubsub_vals);
2299+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, it->header())
2300+ mv->read_pubsub_vars(vals, pubsub_vals);
2301+
2302+ encode_private(it, msg, vals);
2303+ }
2304+
2305+ /// \brief Encode a message using \ref tag_src_var tags instead of \ref tag_name tags
2306+ ///
2307+ /// Use this version if you do not have vectors of src_var values
2308+ template<typename Key>
2309+ void pubsub_encode(const Key& k,
2310+ ModemMessage& msg,
2311+ const std::map<std::string, DCCLMessageVal>& pubsub_vals)
2312+ {
2313+ std::map<std::string, std::vector<DCCLMessageVal> > vm;
2314+
2315+ typedef std::pair<std::string,DCCLMessageVal> P;
2316+ BOOST_FOREACH(const P& p, pubsub_vals)
2317+ vm.insert(std::pair<std::string,std::vector<DCCLMessageVal> >(p.first, p.second));
2318+
2319+ pubsub_encode(k, msg, vm);
2320+ }
2321+
2322+
2323+ /// \brief Decode a message using formatting specified in \ref tag_publish tags.
2324+ ///
2325+ /// Values will be received in two maps, one of strings and the other of doubles. The \ref tag_publish value will be placed
2326+ /// either based on the "type" parameter of the \ref tag_publish_var tag (e.g. \<publish_var type="long"\>SOMEVAR\</publish_var\> will be placed as a long). If no type parameter is given and the variable is numeric (e.g. "23242.23") it will be considered a double. If not numeric, it will be considered a string.
2327+ ///
2328+ /// \param k can either be std::string (the name of the message) or unsigned (the id of the message)
2329+ /// \param msg ModemMessage or std::string to be decode.
2330+ /// \param vals pointer to std::multimap of publish variable name to std::string values.
2331+ template<typename Key>
2332+ void pubsub_decode(const Key& k,
2333+ const ModemMessage& msg,
2334+ std::multimap<std::string, DCCLMessageVal>& pubsub_vals)
2335
2336- {
2337- std::vector<dccl::Message>::iterator it = to_iterator(k);
2338-
2339- std::map<std::string, std::vector<dccl::MessageVal> > vals;
2340- decode_private(it, msg, vals);
2341-
2342- // go through all the publishes_ and fill in the format strings
2343- BOOST_FOREACH(Publish& p, it->publishes())
2344- p.write_publish(vals, pubsub_vals);
2345- }
2346-
2347-
2348- /// what moos variables do i need to provide to create a message with a call to encode_using_src_vars
2349- template<typename Key>
2350- std::set<std::string> get_pubsub_src_vars(const Key& k)
2351- { return to_iterator(k)->get_pubsub_src_vars(); }
2352-
2353- /// for a given message name, all architecture variables (sources, input, destination, trigger)
2354- template<typename Key>
2355- std::set<std::string> get_pubsub_all_vars(const Key& k)
2356- { return to_iterator(k)->get_pubsub_all_vars(); }
2357-
2358- /// all architecture variables needed for encoding (includes trigger)
2359- template<typename Key>
2360- std::set<std::string> get_pubsub_encode_vars(const Key& k)
2361- { return to_iterator(k)->get_pubsub_encode_vars(); }
2362-
2363- /// for a given message, all architecture variables for decoding (input)
2364- template<typename Key>
2365- std::set<std::string> get_pubsub_decode_vars(const Key& k)
2366- { return to_iterator(k)->get_pubsub_decode_vars(); }
2367-
2368- /// returns outgoing architecture hexadecimal variable
2369- template<typename Key>
2370- std::string get_outgoing_hex_var(const Key& k)
2371- { return to_iterator(k)->out_var(); }
2372-
2373- /// returns incoming architecture hexadecimal variable
2374- template<typename Key>
2375- std::string get_incoming_hex_var(const Key& k)
2376- { return to_iterator(k)->in_var(); }
2377-
2378-
2379- /// \brief look if key / value are trigger for any loaded messages
2380- /// if so, store to id and return true
2381- bool is_publish_trigger(std::set<unsigned>& id, const std::string& key, const std::string& value);
2382-
2383- /// \brief look if the time is right for trigger for any loaded messages
2384- /// if so, store to id and return true
2385- bool is_time_trigger(std::set<unsigned>& id);
2386-
2387- /// \brief see if this key is for an incoming message
2388- /// if so, return id for decoding
2389- bool is_incoming(unsigned& id, const std::string& key);
2390- //@}
2391-
2392-
2393- // returns a reference to all Message objects.
2394-
2395- // this is only used if one needs more control than DCCLCodec
2396- // provides
2397- std::vector<Message>& messages() {return messages_;}
2398-
2399-
2400- /// \example libdccl/examples/dccl_simple/dccl_simple.cpp
2401- /// simple.xml
2402- /// \verbinclude dccl_simple/simple.xml
2403- /// dccl_simple.cpp
2404-
2405- /// \example libdccl/examples/plusnet/plusnet.cpp
2406- /// nafcon_command.xml
2407- /// \verbinclude nafcon_command.xml
2408- /// nafcon_report.xml
2409- /// \verbinclude nafcon_report.xml
2410- /// plusnet.cpp
2411-
2412- /// \example libdccl/examples/test/test.cpp
2413- /// test.xml
2414- /// \verbinclude test.xml
2415- /// test.cpp
2416-
2417- /// \example libdccl/examples/two_message/two_message.cpp
2418- /// two_message.xml
2419- /// \verbinclude two_message.xml
2420- /// two_message.cpp
2421-
2422- /// \example acomms/examples/chat/chat.cpp
2423-
2424- private:
2425- std::vector<Message>::const_iterator to_iterator(const std::string& message_name) const;
2426- std::vector<Message>::iterator to_iterator(const std::string& message_name);
2427- std::vector<Message>::const_iterator to_iterator(const unsigned& id) const;
2428- std::vector<Message>::iterator to_iterator(const unsigned& id);
2429-
2430- // in map not passed by reference because we want to be able to modify it
2431- void encode_private(std::vector<Message>::iterator it,
2432- std::string& out,
2433- std::map<std::string, std::vector<MessageVal> > in);
2434-
2435- // in string not passed by reference because we want to be able to modify it
2436- void decode_private(std::vector<Message>::iterator it,
2437- std::string in,
2438- std::map<std::string, std::vector<MessageVal> >& out);
2439-
2440- void encode_private(std::vector<Message>::iterator it,
2441- modem::Message& out_msg,
2442- const std::map<std::string, std::vector<MessageVal> >& in);
2443-
2444- void decode_private(std::vector<Message>::iterator it,
2445- const modem::Message& in_msg,
2446- std::map<std::string, std::vector<MessageVal> >& out);
2447-
2448- void check_duplicates();
2449-
2450-
2451- void encrypt(std::string& s, const std::string& nonce);
2452- void decrypt(std::string& s, const std::string& nonce);
2453-
2454- private:
2455- std::vector<Message> messages_;
2456- std::map<std::string, size_t> name2messages_;
2457- std::map<unsigned, size_t> id2messages_;
2458-
2459- std::string xml_schema_;
2460- time_t start_time_;
2461-
2462- unsigned modem_id_;
2463-
2464- std::string crypto_key_;
2465- };
2466-
2467- /// outputs information about all available messages (same as std::string summary())
2468- std::ostream& operator<< (std::ostream& out, const DCCLCodec& d);
2469-
2470-
2471- class DCCLHeaderEncoder
2472- {
2473- public:
2474- DCCLHeaderEncoder(const std::map<std::string, std::vector<MessageVal> >& in)
2475- {
2476- std::map<std::string, std::vector<MessageVal> > in_copy = in;
2477- msg_.head_encode(encoded_, in_copy);
2478- hex_encode(encoded_);
2479- }
2480- std::string& get() { return encoded_; }
2481-
2482- private:
2483- Message msg_;
2484- std::string encoded_;
2485- };
2486-
2487- class DCCLHeaderDecoder
2488- {
2489- public:
2490- DCCLHeaderDecoder(const std::string& in_orig)
2491- {
2492- std::string in = in_orig.substr(0, acomms::NUM_HEADER_NIBS);
2493- hex_decode(in);
2494- msg_.head_decode(in, decoded_);
2495- }
2496- std::map<std::string, std::vector<MessageVal> >& get() { return decoded_; }
2497- MessageVal& operator[] (const std::string& s)
2498- { return decoded_[s][0]; }
2499- MessageVal& operator[] (acomms::DCCLHeaderPart p)
2500- { return decoded_[acomms::to_str(p)][0]; }
2501-
2502-
2503- private:
2504- Message msg_;
2505- std::map<std::string, std::vector<MessageVal> > decoded_;
2506- };
2507+ {
2508+ std::vector<DCCLMessage>::iterator it = to_iterator(k);
2509+
2510+ std::map<std::string, std::vector<DCCLMessageVal> > vals;
2511+ decode_private(it, msg, vals);
2512+
2513+ // go through all the publishes_ and fill in the format strings
2514+ BOOST_FOREACH(DCCLPublish& p, it->publishes())
2515+ p.write_publish(vals, pubsub_vals);
2516+ }
2517+
2518+
2519+ /// what moos variables do i need to provide to create a message with a call to encode_using_src_vars
2520+ template<typename Key>
2521+ std::set<std::string> get_pubsub_src_vars(const Key& k)
2522+ { return to_iterator(k)->get_pubsub_src_vars(); }
2523+
2524+ /// for a given message name, all architecture variables (sources, input, destination, trigger)
2525+ template<typename Key>
2526+ std::set<std::string> get_pubsub_all_vars(const Key& k)
2527+ { return to_iterator(k)->get_pubsub_all_vars(); }
2528+
2529+ /// all architecture variables needed for encoding (includes trigger)
2530+ template<typename Key>
2531+ std::set<std::string> get_pubsub_encode_vars(const Key& k)
2532+ { return to_iterator(k)->get_pubsub_encode_vars(); }
2533+
2534+ /// for a given message, all architecture variables for decoding (input)
2535+ template<typename Key>
2536+ std::set<std::string> get_pubsub_decode_vars(const Key& k)
2537+ { return to_iterator(k)->get_pubsub_decode_vars(); }
2538+
2539+ /// returns outgoing architecture hexadecimal variable
2540+ template<typename Key>
2541+ std::string get_outgoing_hex_var(const Key& k)
2542+ { return to_iterator(k)->out_var(); }
2543+
2544+ /// returns incoming architecture hexadecimal variable
2545+ template<typename Key>
2546+ std::string get_incoming_hex_var(const Key& k)
2547+ { return to_iterator(k)->in_var(); }
2548+
2549+
2550+ /// \brief look if key / value are trigger for any loaded messages
2551+ /// if so, store to id and return true
2552+ bool is_publish_trigger(std::set<unsigned>& id, const std::string& key, const std::string& value);
2553+
2554+ /// \brief look if the time is right for trigger for any loaded messages
2555+ /// if so, store to id and return true
2556+ bool is_time_trigger(std::set<unsigned>& id);
2557+
2558+ /// \brief see if this key is for an incoming message
2559+ /// if so, return id for decoding
2560+ bool is_incoming(unsigned& id, const std::string& key);
2561+ //@}
2562+
2563+
2564+ // returns a reference to all DCCLMessage objects.
2565+
2566+ // this is only used if one needs more control than DCCLCodec
2567+ // provides
2568+ std::vector<DCCLMessage>& messages() {return messages_;}
2569+
2570+
2571+ /// \example libdccl/examples/dccl_simple/dccl_simple.cpp
2572+ /// simple.xml
2573+ /// \verbinclude dccl_simple/simple.xml
2574+ /// dccl_simple.cpp
2575+
2576+ /// \example libdccl/examples/plusnet/plusnet.cpp
2577+ /// nafcon_command.xml
2578+ /// \verbinclude nafcon_command.xml
2579+ /// nafcon_report.xml
2580+ /// \verbinclude nafcon_report.xml
2581+ /// plusnet.cpp
2582+
2583+ /// \example libdccl/examples/test/test.cpp
2584+ /// test.xml
2585+ /// \verbinclude test.xml
2586+ /// test.cpp
2587+
2588+ /// \example libdccl/examples/two_message/two_message.cpp
2589+ /// two_message.xml
2590+ /// \verbinclude two_message.xml
2591+ /// two_message.cpp
2592+
2593+ /// \example acomms/examples/chat/chat.cpp
2594+
2595+ private:
2596+ std::vector<DCCLMessage>::const_iterator to_iterator(const std::string& message_name) const;
2597+ std::vector<DCCLMessage>::iterator to_iterator(const std::string& message_name);
2598+ std::vector<DCCLMessage>::const_iterator to_iterator(const unsigned& id) const;
2599+ std::vector<DCCLMessage>::iterator to_iterator(const unsigned& id);
2600+
2601+ // in map not passed by reference because we want to be able to modify it
2602+ void encode_private(std::vector<DCCLMessage>::iterator it,
2603+ std::string& out,
2604+ std::map<std::string, std::vector<DCCLMessageVal> > in);
2605+
2606+ // in string not passed by reference because we want to be able to modify it
2607+ void decode_private(std::vector<DCCLMessage>::iterator it,
2608+ std::string in,
2609+ std::map<std::string, std::vector<DCCLMessageVal> >& out);
2610+
2611+ void encode_private(std::vector<DCCLMessage>::iterator it,
2612+ ModemMessage& out_msg,
2613+ const std::map<std::string, std::vector<DCCLMessageVal> >& in);
2614+
2615+ void decode_private(std::vector<DCCLMessage>::iterator it,
2616+ const ModemMessage& in_msg,
2617+ std::map<std::string, std::vector<DCCLMessageVal> >& out);
2618+
2619+ void check_duplicates();
2620+
2621+
2622+ void encrypt(std::string& s, const std::string& nonce);
2623+ void decrypt(std::string& s, const std::string& nonce);
2624+
2625+ private:
2626+ std::vector<DCCLMessage> messages_;
2627+ std::map<std::string, size_t> name2messages_;
2628+ std::map<unsigned, size_t> id2messages_;
2629+
2630+ std::string xml_schema_;
2631+ boost::posix_time::ptime start_time_;
2632+
2633+ unsigned modem_id_;
2634+
2635+ std::string crypto_key_;
2636+ };
2637+
2638+ /// outputs information about all available messages (same as std::string summary())
2639+ std::ostream& operator<< (std::ostream& out, const DCCLCodec& d);
2640+
2641+
2642+ class DCCLHeaderEncoder
2643+ {
2644+ public:
2645+ DCCLHeaderEncoder(const std::map<std::string, std::vector<DCCLMessageVal> >& in)
2646+ {
2647+ std::map<std::string, std::vector<DCCLMessageVal> > in_copy = in;
2648+ msg_.head_encode(encoded_, in_copy);
2649+ hex_encode(encoded_);
2650+ }
2651+ std::string& get() { return encoded_; }
2652+
2653+ private:
2654+ DCCLMessage msg_;
2655+ std::string encoded_;
2656+ };
2657+
2658+ class DCCLHeaderDecoder
2659+ {
2660+ public:
2661+ DCCLHeaderDecoder(const std::string& in_orig)
2662+ {
2663+ std::string in = in_orig.substr(0, DCCL_NUM_HEADER_BYTES*NIBS_IN_BYTE);
2664+ hex_decode(in);
2665+ msg_.head_decode(in, decoded_);
2666+ }
2667+ std::map<std::string, std::vector<DCCLMessageVal> >& get() { return decoded_; }
2668+ DCCLMessageVal& operator[] (const std::string& s)
2669+ { return decoded_[s][0]; }
2670+ DCCLMessageVal& operator[] (DCCLHeaderPart p)
2671+ { return decoded_[to_str(p)][0]; }
2672+
2673+
2674+ private:
2675+ DCCLMessage msg_;
2676+ std::map<std::string, std::vector<DCCLMessageVal> > decoded_;
2677+ };
2678
2679
2680+ }
2681 }
2682
2683
2684-
2685 #endif
2686
2687=== modified file 'src/acomms/libdccl/dccl_constants.h'
2688--- src/acomms/libdccl/dccl_constants.h 2010-06-15 04:51:47 +0000
2689+++ src/acomms/libdccl/dccl_constants.h 2010-07-15 12:38:39 +0000
2690@@ -28,9 +28,12 @@
2691 #include <crypto++/filters.h>
2692 #include <crypto++/hex.h>
2693
2694-#include "acomms/acomms_constants.h"
2695-
2696-namespace dccl
2697+#include "goby/acomms/acomms_constants.h"
2698+
2699+namespace goby
2700+{
2701+
2702+namespace acomms
2703 {
2704
2705 /// Enumeration of DCCL types used for sending messages. dccl_enum and dccl_string primarily map to cpp_string, dccl_bool to cpp_bool, dccl_int to cpp_long, dccl_float to cpp_double
2706@@ -111,5 +114,5 @@
2707
2708
2709 }
2710-
2711+}
2712 #endif
2713
2714=== modified file 'src/acomms/libdccl/examples/dccl_simple/CMakeLists.txt'
2715--- src/acomms/libdccl/examples/dccl_simple/CMakeLists.txt 2010-01-22 02:52:25 +0000
2716+++ src/acomms/libdccl/examples/dccl_simple/CMakeLists.txt 2010-07-15 12:38:39 +0000
2717@@ -1,2 +1,2 @@
2718 add_executable(dccl_simple dccl_simple.cpp)
2719-target_link_libraries(dccl_simple dccl)
2720\ No newline at end of file
2721+target_link_libraries(dccl_simple goby_dccl)
2722\ No newline at end of file
2723
2724=== modified file 'src/acomms/libdccl/examples/dccl_simple/dccl_simple.cpp'
2725--- src/acomms/libdccl/examples/dccl_simple/dccl_simple.cpp 2010-03-15 16:21:43 +0000
2726+++ src/acomms/libdccl/examples/dccl_simple/dccl_simple.cpp 2010-07-15 12:38:39 +0000
2727@@ -17,17 +17,17 @@
2728 // encodes/decodes a string using the DCCL codec library
2729 // assumes prior knowledge of the message format (required fields)
2730
2731-#include "acomms/dccl.h"
2732+#include "goby/acomms/dccl.h"
2733 #include <iostream>
2734
2735-using dccl::operator<<;
2736+using goby::acomms::operator<<;
2737
2738 int main()
2739 {
2740 // initialize input contents to encoder. since
2741 // simple.xml only has a <string/> message var
2742 // we only need one map.
2743- std::map<std::string, dccl::MessageVal> val_map;
2744+ std::map<std::string, goby::acomms::DCCLMessageVal> val_map;
2745
2746 // initialize output hexadecimal
2747 std::string hex;
2748@@ -37,7 +37,7 @@
2749 // instantiate the parser with a single xml file (simple.xml).
2750 // also pass the schema, relative to simple.xml, for XML validity
2751 // checking (syntax).
2752- dccl::DCCLCodec dccl(DCCL_EXAMPLES_DIR "/dccl_simple/simple.xml",
2753+ goby::acomms::DCCLCodec dccl(DCCL_EXAMPLES_DIR "/dccl_simple/simple.xml",
2754 "../../message_schema.xsd");
2755
2756
2757
2758=== modified file 'src/acomms/libdccl/examples/delta/CMakeLists.txt'
2759--- src/acomms/libdccl/examples/delta/CMakeLists.txt 2010-03-05 03:32:48 +0000
2760+++ src/acomms/libdccl/examples/delta/CMakeLists.txt 2010-07-15 12:38:39 +0000
2761@@ -1,2 +1,2 @@
2762 add_executable(delta delta.cpp)
2763-target_link_libraries(delta dccl)
2764\ No newline at end of file
2765+target_link_libraries(delta goby_dccl)
2766\ No newline at end of file
2767
2768=== modified file 'src/acomms/libdccl/examples/delta/delta.cpp'
2769--- src/acomms/libdccl/examples/delta/delta.cpp 2010-03-10 01:14:38 +0000
2770+++ src/acomms/libdccl/examples/delta/delta.cpp 2010-07-15 12:38:39 +0000
2771@@ -17,22 +17,22 @@
2772 // encodes/decodes several fields using delta encoding
2773
2774
2775-#include "acomms/dccl.h"
2776+#include "goby/acomms/dccl.h"
2777 #include <iostream>
2778
2779-using dccl::operator<<;
2780+using goby::acomms::operator<<;
2781
2782 int main()
2783 {
2784- std::vector< std::map<std::string, dccl::MessageVal> > vals_vect;
2785- std::map<std::string, dccl::MessageVal> vals;
2786+ std::vector< std::map<std::string, acomms::DCCLMessageVal> > vals_vect;
2787+ std::map<std::string, acomms::DCCLMessageVal> vals;
2788
2789 // initialize output hexadecimal
2790 std::string hex;
2791
2792 std::cout << "loading xml file: delta.xml" << std::endl;
2793
2794- dccl::DCCLCodec dccl(DCCL_EXAMPLES_DIR "/delta/delta.xml",
2795+ goby::acomms::DCCLCodec dccl(DCCL_EXAMPLES_DIR "/delta/delta.xml",
2796 "../../message_schema.xsd");
2797
2798 std::cout << dccl << std::endl;
2799@@ -77,7 +77,7 @@
2800
2801 // dccl.delta_decode(1, hex, 0, &vals_vect, 0, 0);
2802
2803- for(std::vector< std::map<std::string, dccl::MessageVal> >::iterator
2804+ for(std::vector< std::map<std::string, acomms::DCCLMessageVal> >::iterator
2805 it = vals_vect.begin(),
2806 n = vals_vect.end();
2807 it != n;
2808
2809=== modified file 'src/acomms/libdccl/examples/plusnet/CMakeLists.txt'
2810--- src/acomms/libdccl/examples/plusnet/CMakeLists.txt 2009-12-18 02:50:00 +0000
2811+++ src/acomms/libdccl/examples/plusnet/CMakeLists.txt 2010-07-15 12:38:39 +0000
2812@@ -1,2 +1,2 @@
2813 add_executable(plusnet plusnet.cpp)
2814-target_link_libraries(plusnet dccl)
2815+target_link_libraries(plusnet goby_dccl)
2816
2817=== modified file 'src/acomms/libdccl/examples/plusnet/plusnet.cpp'
2818--- src/acomms/libdccl/examples/plusnet/plusnet.cpp 2010-03-20 06:09:16 +0000
2819+++ src/acomms/libdccl/examples/plusnet/plusnet.cpp 2010-07-15 12:38:39 +0000
2820@@ -20,18 +20,19 @@
2821
2822 // this is an example showing some of the "MOOS" related features of libdccl that can be used (if desired) in the absence of MOOS
2823
2824-#include "acomms/dccl.h"
2825+#include "goby/acomms/dccl.h"
2826
2827 #include <exception>
2828 #include <iostream>
2829
2830-using dccl::operator<<;
2831+using namespace goby;
2832+using goby::acomms::operator<<;
2833
2834 int main()
2835 {
2836 std::cout << "loading nafcon xml files" << std::endl;
2837
2838- dccl::DCCLCodec dccl;
2839+ acomms::DCCLCodec dccl;
2840 dccl.add_xml_message_file(DCCL_EXAMPLES_DIR "/plusnet/nafcon_command.xml", "../../message_schema.xsd");
2841 dccl.add_xml_message_file(DCCL_EXAMPLES_DIR "/plusnet/nafcon_report.xml", "../../message_schema.xsd");
2842
2843@@ -45,10 +46,10 @@
2844 << std::string(30, '#') << std::endl;
2845
2846 // initialize input contents to encoder
2847- std::map<std::string, dccl::MessageVal> in_vals;
2848+ std::map<std::string, acomms::DCCLMessageVal> in_vals;
2849
2850 // initialize output message
2851- modem::Message msg;
2852+ acomms::ModemMessage msg;
2853
2854 in_vals["PLUSNET_MESSAGES"] = "MessageType=SENSOR_STATUS,SensorReportType=0,SourcePlatformId=1,DestinationPlatformId=3,Timestamp=1191947446.91117,NodeLatitude=47.7448,NodeLongitude=-122.845,NodeDepth=0.26,NodeCEP=0,NodeHeading=169.06,NodeSpeed=0,MissionState=2,MissionType=2,LastGPSTimestamp=1191947440,PowerLife=6,SensorHealth=0,RecorderState=1,RecorderLife=0,NodeSpecificInfo0=0,NodeSpecificInfo1=0,NodeSpecificInfo2=23,NodeSpecificInfo3=0,NodeSpecificInfo4=3,NodeSpecificInfo5=0";
2855
2856@@ -57,15 +58,15 @@
2857
2858 dccl.pubsub_encode("SENSOR_STATUS", msg, in_vals);
2859
2860- std::cout << "received dccl::Message: "
2861+ std::cout << "received acomms::DCCLMessage: "
2862 << msg.serialize()
2863 << std::endl;
2864
2865
2866- std::multimap<std::string, dccl::MessageVal> out_vals;
2867+ std::multimap<std::string, acomms::DCCLMessageVal> out_vals;
2868
2869
2870- std::cout << "passed dccl::Message to decoder: "
2871+ std::cout << "passed acomms::DCCLMessage to decoder: "
2872 << msg.serialize()
2873 << std::endl;
2874
2875
2876=== modified file 'src/acomms/libdccl/examples/test/CMakeLists.txt'
2877--- src/acomms/libdccl/examples/test/CMakeLists.txt 2009-12-02 05:18:28 +0000
2878+++ src/acomms/libdccl/examples/test/CMakeLists.txt 2010-07-15 12:38:39 +0000
2879@@ -1,2 +1,2 @@
2880 add_executable(dccl_test test.cpp)
2881-target_link_libraries(dccl_test dccl)
2882\ No newline at end of file
2883+target_link_libraries(dccl_test goby_dccl)
2884\ No newline at end of file
2885
2886=== modified file 'src/acomms/libdccl/examples/test/test.cpp'
2887--- src/acomms/libdccl/examples/test/test.cpp 2010-06-15 04:51:47 +0000
2888+++ src/acomms/libdccl/examples/test/test.cpp 2010-07-15 12:38:39 +0000
2889@@ -14,41 +14,42 @@
2890 // along with this software. If not, see <http://www.gnu.org/licenses/>.
2891
2892
2893-#include "acomms/dccl.h"
2894+#include "goby/acomms/dccl.h"
2895 #include <iostream>
2896 #include <cassert>
2897
2898-using dccl::operator<<;
2899+using namespace goby;
2900+using goby::acomms::operator<<;
2901
2902-void plus1(dccl::MessageVal& mv)
2903+void plus1(acomms::DCCLMessageVal& mv)
2904 {
2905 long l = mv;
2906 ++l;
2907 mv = l;
2908 }
2909
2910-void times2(dccl::MessageVal& mv)
2911+void times2(acomms::DCCLMessageVal& mv)
2912 {
2913 double d = mv;
2914 d *= 2;
2915 mv = d;
2916 }
2917
2918-void prepend_fat(dccl::MessageVal& mv)
2919+void prepend_fat(acomms::DCCLMessageVal& mv)
2920 {
2921 std::string s = mv;
2922 s = "fat_" + s;
2923 mv = s;
2924 }
2925
2926-void invert(dccl::MessageVal& mv)
2927+void invert(acomms::DCCLMessageVal& mv)
2928 {
2929 bool b = mv;
2930 b ^= 1;
2931 mv = b;
2932 }
2933
2934-void algsum(dccl::MessageVal& mv, const std::vector<dccl::MessageVal>& ref_vals)
2935+void algsum(acomms::DCCLMessageVal& mv, const std::vector<acomms::DCCLMessageVal>& ref_vals)
2936 {
2937 double d = 0;
2938 // index 0 is the name ("sum"), so start at 1
2939@@ -65,7 +66,7 @@
2940 std::cout << "loading xml file: test.xml" << std::endl;
2941
2942 // instantiate the parser with a single xml file
2943- dccl::DCCLCodec dccl(DCCL_EXAMPLES_DIR "/test/test.xml", "../../message_schema.xsd");
2944+ acomms::DCCLCodec dccl(DCCL_EXAMPLES_DIR "/test/test.xml", "../../message_schema.xsd");
2945
2946 std::cout << dccl << std::endl;
2947
2948@@ -79,32 +80,32 @@
2949 // must be kept secret!
2950 dccl.set_crypto_passphrase("my_passphrase!");
2951
2952- std::map<std::string, std::vector<dccl::MessageVal> > in;
2953+ std::map<std::string, std::vector<acomms::DCCLMessageVal> > in;
2954
2955 bool b = true;
2956- std::vector<dccl::MessageVal> e;
2957+ std::vector<acomms::DCCLMessageVal> e;
2958 e.push_back("dog");
2959 e.push_back("cat");
2960 e.push_back("emu");
2961
2962 std::string s = "raccoon";
2963- std::vector<dccl::MessageVal> i;
2964+ std::vector<acomms::DCCLMessageVal> i;
2965 i.push_back(30);
2966 i.push_back(40);
2967- std::vector<dccl::MessageVal> f;
2968+ std::vector<acomms::DCCLMessageVal> f;
2969 f.push_back(-12.5);
2970 f.push_back(1);
2971
2972 std::string h = "abcd1234";
2973- std::vector<dccl::MessageVal> sum(2,0);
2974-
2975-
2976- in["B"] = std::vector<dccl::MessageVal>(1,b);
2977+ std::vector<acomms::DCCLMessageVal> sum(2,0);
2978+
2979+
2980+ in["B"] = std::vector<acomms::DCCLMessageVal>(1,b);
2981 in["E"] = e;
2982- in["S"] = std::vector<dccl::MessageVal>(1,s);
2983+ in["S"] = std::vector<acomms::DCCLMessageVal>(1,s);
2984 in["I"] = i;
2985 in["F"] = f;
2986- in["H"] = std::vector<dccl::MessageVal>(1,h);
2987+ in["H"] = std::vector<acomms::DCCLMessageVal>(1,h);
2988 in["SUM"] = sum;
2989
2990 std::string hex;
2991@@ -117,7 +118,7 @@
2992 hex.resize(hex.length() + 20,'0');
2993 std::cout << "hex in: " << hex << std::endl;
2994
2995- std::map<std::string, std::vector<dccl::MessageVal> > out;
2996+ std::map<std::string, std::vector<acomms::DCCLMessageVal> > out;
2997
2998 dccl.decode(4, hex, out);
2999
3000@@ -129,7 +130,7 @@
3001 i[0] = int(i[0]) + 1;
3002 i[1] = int(i[1]) + 1;
3003
3004- dccl::MessageVal tmp = b;
3005+ acomms::DCCLMessageVal tmp = b;
3006 invert(tmp);
3007 b = tmp;
3008
3009
3010=== modified file 'src/acomms/libdccl/examples/test/test.xml'
3011--- src/acomms/libdccl/examples/test/test.xml 2010-06-15 04:51:47 +0000
3012+++ src/acomms/libdccl/examples/test/test.xml 2010-07-15 12:38:39 +0000
3013@@ -2,9 +2,9 @@
3014 <message_set>
3015 <message>
3016 <name>TEST</name>
3017- <size>256</size>
3018+ <size>128</size>
3019 <id>4</id>
3020- <repeat>5</repeat>
3021+ <repeat/>
3022 <layout>
3023 <static>
3024 <name>Stat</name>
3025
3026=== modified file 'src/acomms/libdccl/examples/two_message/CMakeLists.txt'
3027--- src/acomms/libdccl/examples/two_message/CMakeLists.txt 2009-12-02 05:18:28 +0000
3028+++ src/acomms/libdccl/examples/two_message/CMakeLists.txt 2010-07-15 12:38:39 +0000
3029@@ -1,2 +1,2 @@
3030 add_executable(two_message two_message.cpp)
3031-target_link_libraries(two_message dccl)
3032\ No newline at end of file
3033+target_link_libraries(two_message goby_dccl)
3034\ No newline at end of file
3035
3036=== modified file 'src/acomms/libdccl/examples/two_message/two_message.cpp'
3037--- src/acomms/libdccl/examples/two_message/two_message.cpp 2010-03-22 02:52:39 +0000
3038+++ src/acomms/libdccl/examples/two_message/two_message.cpp 2010-07-15 12:38:39 +0000
3039@@ -17,11 +17,12 @@
3040 // encodes/decodes the message given in the pGeneralCodec documentation
3041 // also includes the simple.xml file to show example of DCCLCodec instantiation
3042 // with multiple files
3043-#include "acomms/dccl.h"
3044+#include "goby/acomms/dccl.h"
3045 #include <exception>
3046 #include <iostream>
3047
3048-using dccl::operator<<;
3049+using namespace goby;
3050+using goby::acomms::operator<<;
3051
3052
3053 int main()
3054@@ -33,7 +34,7 @@
3055 xml_files.insert(DCCL_EXAMPLES_DIR "/dccl_simple/simple.xml");
3056 xml_files.insert(DCCL_EXAMPLES_DIR "/two_message/two_message.xml");
3057
3058- dccl::DCCLCodec dccl(xml_files, "../../message_schema.xsd");
3059+ acomms::DCCLCodec dccl(xml_files, "../../message_schema.xsd");
3060
3061 // show some useful information about all the loaded messages
3062 std::cout << std::string(30, '#') << std::endl
3063@@ -75,7 +76,7 @@
3064 << std::string(30, '#') << std::endl;
3065
3066 // initialize input contents to encoder
3067- std::map<std::string, dccl::MessageVal> vals;
3068+ std::map<std::string, acomms::DCCLMessageVal> vals;
3069
3070 // initialize output hexadecimal
3071 std::string hex2, hex3;
3072
3073=== modified file 'src/acomms/libdccl/message.cpp'
3074--- src/acomms/libdccl/message.cpp 2010-07-11 16:20:55 +0000
3075+++ src/acomms/libdccl/message.cpp 2010-07-15 12:38:39 +0000
3076@@ -22,7 +22,7 @@
3077
3078 #include "message.h"
3079
3080-dccl::Message::Message():size_(0),
3081+goby::acomms::DCCLMessage::DCCLMessage():size_(0),
3082 trigger_number_(1),
3083 body_bits_(0),
3084 id_(0),
3085@@ -30,61 +30,64 @@
3086 repeat_enabled_(false),
3087 repeat_(1)
3088 {
3089- header_.resize(acomms::NUM_HEADER_PARTS);
3090- header_[acomms::head_ccl_id] =
3091- boost::shared_ptr<MessageVar>(new MessageVarCCLID());
3092- header_[acomms::head_dccl_id] =
3093- boost::shared_ptr<MessageVar>(new MessageVarDCCLID());
3094- header_[acomms::head_time] =
3095- boost::shared_ptr<MessageVar>(new MessageVarTime());
3096- header_[acomms::head_src_id] =
3097- boost::shared_ptr<MessageVar>(new MessageVarSrc());
3098- header_[acomms::head_dest_id] =
3099- boost::shared_ptr<MessageVar>(new MessageVarDest());
3100- header_[acomms::head_multimessage_flag] =
3101- boost::shared_ptr<MessageVar>(new MessageVarMultiMessageFlag());
3102- header_[acomms::head_broadcast_flag] =
3103- boost::shared_ptr<MessageVar>(new MessageVarBroadcastFlag());
3104- header_[acomms::head_unused] =
3105- boost::shared_ptr<MessageVar>(new MessageVarUnused());
3106+ header_.resize(DCCL_NUM_HEADER_PARTS);
3107+ header_[head_ccl_id] =
3108+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarCCLID());
3109+ header_[head_dccl_id] =
3110+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarDCCLID());
3111+ header_[head_time] =
3112+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarTime());
3113+ header_[head_src_id] =
3114+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarSrc());
3115+ header_[head_dest_id] =
3116+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarDest());
3117+ header_[head_multimessage_flag] =
3118+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarMultiMessageFlag());
3119+ header_[head_broadcast_flag] =
3120+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarBroadcastFlag());
3121+ header_[head_unused] =
3122+ boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarUnused());
3123 }
3124
3125
3126 // add a new message_var to the current messages vector
3127-void dccl::Message::add_message_var(const std::string& type)
3128+void goby::acomms::DCCLMessage::add_message_var(const std::string& type)
3129 {
3130 if(type == "static")
3131- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarStatic()));
3132+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarStatic()));
3133 else if(type == "int")
3134- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarInt()));
3135+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarInt()));
3136 else if(type == "string")
3137- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarString()));
3138+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarString()));
3139 else if(type == "float")
3140- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarFloat()));
3141+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarFloat()));
3142 else if(type == "enum")
3143- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarEnum()));
3144+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarEnum()));
3145 else if(type == "bool")
3146- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarBool()));
3147+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarBool()));
3148 else if(type == "hex")
3149- layout_.push_back(boost::shared_ptr<MessageVar>(new MessageVarHex()));
3150+ layout_.push_back(boost::shared_ptr<DCCLMessageVar>(new DCCLMessageVarHex()));
3151 }
3152
3153 // add a new publish, i.e. a set of parameters to publish
3154 // upon receipt of an incoming (hex) message
3155-void dccl::Message::add_publish()
3156+void goby::acomms::DCCLMessage::add_publish()
3157 {
3158- Publish p;
3159+ DCCLPublish p;
3160 publishes_.push_back(p);
3161 }
3162
3163 // a number of tasks to perform after reading in an entire <message> from
3164 // the xml file
3165-void dccl::Message::preprocess()
3166+void goby::acomms::DCCLMessage::preprocess()
3167 {
3168+ if(requested_bytes_total() <= bytes_head())
3169+ throw(std::runtime_error(std::string("<size> must be larger than the header size of " + boost::lexical_cast<std::string>(bytes_head()))));
3170+
3171 // calculate number of repeated messages that will fit and put this in `repeat_`.
3172 if(repeat_enabled_)
3173 {
3174- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, layout_)
3175+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, layout_)
3176 {
3177 if(mv->array_length() != 1)
3178 throw(std::runtime_error("<repeat> is not allowed on messages with arrays (<array_length> not 1)"));
3179@@ -105,7 +108,7 @@
3180 body_bits_ = calc_total_size();
3181
3182 // initialize header vars
3183- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, header_)
3184+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, header_)
3185 mv->initialize(trigger_var_);
3186
3187
3188@@ -115,7 +118,7 @@
3189 }
3190
3191 // iterate over publishes_
3192- BOOST_FOREACH(Publish& p, publishes_)
3193+ BOOST_FOREACH(DCCLPublish& p, publishes_)
3194 p.initialize(*this);
3195
3196 // set incoming_var / outgoing_var if not set
3197@@ -125,18 +128,18 @@
3198 out_var_ = "OUT_" + boost::to_upper_copy(name_) + "_HEX_" + boost::lexical_cast<std::string>(size_) + "B";
3199 }
3200
3201-void dccl::Message::set_repeat_array_length()
3202+void goby::acomms::DCCLMessage::set_repeat_array_length()
3203 {
3204- // set array_length_ for repeated messages for all MessageVars
3205- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, layout_)
3206+ // set array_length_ for repeated messages for all DCCLMessageVars
3207+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, layout_)
3208 mv->set_array_length(repeat_);
3209 }
3210
3211-unsigned dccl::Message::calc_total_size()
3212+unsigned goby::acomms::DCCLMessage::calc_total_size()
3213 {
3214 unsigned body_bits = 0;
3215 // iterate over layout_
3216- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, layout_)
3217+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, layout_)
3218 {
3219 mv->initialize(trigger_var_);
3220 // calculate total bits for the message from the bits for each message_var
3221@@ -147,15 +150,15 @@
3222
3223
3224
3225-std::map<std::string, std::string> dccl::Message::message_var_names() const
3226+std::map<std::string, std::string> goby::acomms::DCCLMessage::message_var_names() const
3227 {
3228 std::map<std::string, std::string> s;
3229- BOOST_FOREACH(const boost::shared_ptr<MessageVar> mv, layout_)
3230+ BOOST_FOREACH(const boost::shared_ptr<DCCLMessageVar> mv, layout_)
3231 s.insert(std::pair<std::string, std::string>(mv->name(), type_to_string(mv->type())));
3232 return s;
3233 }
3234
3235-std::set<std::string> dccl::Message::get_pubsub_encode_vars()
3236+std::set<std::string> goby::acomms::DCCLMessage::get_pubsub_encode_vars()
3237 {
3238 std::set<std::string> s = get_pubsub_src_vars();
3239 if(trigger_type_ == "publish")
3240@@ -163,14 +166,14 @@
3241 return s;
3242 }
3243
3244-std::set<std::string> dccl::Message::get_pubsub_decode_vars()
3245+std::set<std::string> goby::acomms::DCCLMessage::get_pubsub_decode_vars()
3246 {
3247 std::set<std::string> s;
3248 s.insert(in_var_);
3249 return s;
3250 }
3251
3252-std::set<std::string> dccl::Message::get_pubsub_all_vars()
3253+std::set<std::string> goby::acomms::DCCLMessage::get_pubsub_all_vars()
3254 {
3255 std::set<std::string> s_enc = get_pubsub_encode_vars();
3256 std::set<std::string> s_dec = get_pubsub_decode_vars();
3257@@ -181,25 +184,25 @@
3258 return s;
3259 }
3260
3261-std::set<std::string> dccl::Message::get_pubsub_src_vars()
3262+std::set<std::string> goby::acomms::DCCLMessage::get_pubsub_src_vars()
3263 {
3264 std::set<std::string> s;
3265
3266- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, layout_)
3267+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, layout_)
3268 s.insert(mv->source_var());
3269- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, header_)
3270+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, header_)
3271 s.insert(mv->source_var());
3272
3273 return s;
3274 }
3275
3276
3277-void dccl::Message::body_encode(std::string& body, std::map<std::string, std::vector<MessageVal> >& in)
3278+void goby::acomms::DCCLMessage::body_encode(std::string& body, std::map<std::string, std::vector<DCCLMessageVal> >& in)
3279 {
3280 boost::dynamic_bitset<unsigned char> body_bits(bytes2bits(used_bytes_body()));
3281
3282 // 1. encode each variable into the bitset
3283- for (std::vector< boost::shared_ptr<MessageVar> >::iterator it = layout_.begin(),
3284+ for (std::vector< boost::shared_ptr<DCCLMessageVar> >::iterator it = layout_.begin(),
3285 n = layout_.end();
3286 it != n;
3287 ++it)
3288@@ -214,7 +217,7 @@
3289 body.resize(body.find_last_not_of(char(0))+1);
3290 }
3291
3292-void dccl::Message::body_decode(std::string& body, std::map<std::string, std::vector<MessageVal> >& out)
3293+void goby::acomms::DCCLMessage::body_decode(std::string& body, std::map<std::string, std::vector<DCCLMessageVal> >& out)
3294 {
3295 boost::dynamic_bitset<unsigned char> body_bits(bytes2bits(used_bytes_body()));
3296
3297@@ -225,7 +228,7 @@
3298 string2bitset(body_bits, body);
3299
3300 // 1. pull the bits off the message in the reverse that they were put on
3301- for (std::vector< boost::shared_ptr<MessageVar> >::reverse_iterator it = layout_.rbegin(),
3302+ for (std::vector< boost::shared_ptr<DCCLMessageVar> >::reverse_iterator it = layout_.rbegin(),
3303 n = layout_.rend();
3304 it != n;
3305 ++it)
3306@@ -234,9 +237,9 @@
3307 }
3308 }
3309
3310-void dccl::Message::set_head_defaults(std::map<std::string, std::vector<MessageVal> >& in, unsigned modem_id)
3311+void goby::acomms::DCCLMessage::set_head_defaults(std::map<std::string, std::vector<DCCLMessageVal> >& in, unsigned modem_id)
3312 {
3313- for (std::vector< boost::shared_ptr<MessageVar> >::iterator it = header_.begin(),
3314+ for (std::vector< boost::shared_ptr<DCCLMessageVar> >::iterator it = header_.begin(),
3315 n = header_.end();
3316 it != n;
3317 ++it)
3318@@ -245,12 +248,12 @@
3319 }
3320 }
3321
3322-void dccl::Message::head_encode(std::string& head, std::map<std::string, std::vector<MessageVal> >& in)
3323+void goby::acomms::DCCLMessage::head_encode(std::string& head, std::map<std::string, std::vector<DCCLMessageVal> >& in)
3324 {
3325- boost::dynamic_bitset<unsigned char> head_bits(bytes2bits(acomms::NUM_HEADER_BYTES));
3326+ boost::dynamic_bitset<unsigned char> head_bits(bytes2bits(DCCL_NUM_HEADER_BYTES));
3327
3328
3329- for (std::vector< boost::shared_ptr<MessageVar> >::iterator it = header_.begin(),
3330+ for (std::vector< boost::shared_ptr<DCCLMessageVar> >::iterator it = header_.begin(),
3331 n = header_.end();
3332 it != n;
3333 ++it)
3334@@ -261,12 +264,12 @@
3335 bitset2string(head_bits, head);
3336 }
3337
3338-void dccl::Message::head_decode(const std::string& head, std::map<std::string, std::vector<MessageVal> >& out)
3339+void goby::acomms::DCCLMessage::head_decode(const std::string& head, std::map<std::string, std::vector<DCCLMessageVal> >& out)
3340 {
3341- boost::dynamic_bitset<unsigned char> head_bits(bytes2bits(acomms::NUM_HEADER_BYTES));
3342+ boost::dynamic_bitset<unsigned char> head_bits(bytes2bits(DCCL_NUM_HEADER_BYTES));
3343 string2bitset(head_bits, head);
3344
3345- for (std::vector< boost::shared_ptr<MessageVar> >::reverse_iterator it = header_.rbegin(), n = header_.rend();
3346+ for (std::vector< boost::shared_ptr<DCCLMessageVar> >::reverse_iterator it = header_.rbegin(), n = header_.rend();
3347 it != n;
3348 ++it)
3349 {
3350@@ -274,20 +277,20 @@
3351 }
3352 }
3353
3354-boost::shared_ptr<dccl::MessageVar> dccl::Message::name2message_var(const std::string& name)
3355+boost::shared_ptr<goby::acomms::DCCLMessageVar> goby::acomms::DCCLMessage::name2message_var(const std::string& name)
3356 {
3357- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, layout_)
3358+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, layout_)
3359 {
3360 if(mv->name() == name) return mv;
3361 }
3362- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, header_)
3363+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, header_)
3364 {
3365 if(mv->name() == name) return mv;
3366 }
3367
3368 throw std::runtime_error(std::string("DCCL: no such name \"" + name + "\" found in <layout> or <header>"));
3369
3370- return boost::shared_ptr<dccl::MessageVar>();
3371+ return boost::shared_ptr<DCCLMessageVar>();
3372 }
3373
3374 ////////////////////////////
3375@@ -295,8 +298,8 @@
3376 ////////////////////////////
3377
3378
3379-// a long visual display of all the parameters for a Message
3380-std::string dccl::Message::get_display() const
3381+// a long visual display of all the parameters for a DCCLMessage
3382+std::string goby::acomms::DCCLMessage::get_display() const
3383 {
3384 const unsigned int num_stars = 20;
3385
3386@@ -335,12 +338,12 @@
3387 ss << "actual size {bytes} [bits]: {" << used_bytes_total() << "} [" << used_bits_total() << "]" << std::endl;
3388
3389 ss << ">>>> HEADER <<<<" << std::endl;
3390- BOOST_FOREACH(const boost::shared_ptr<MessageVar> mv, header_)
3391+ BOOST_FOREACH(const boost::shared_ptr<DCCLMessageVar> mv, header_)
3392 ss << *mv;
3393
3394 ss << ">>>> LAYOUT (message_vars) <<<<" << std::endl;
3395
3396- BOOST_FOREACH(const boost::shared_ptr<MessageVar> mv, layout_)
3397+ BOOST_FOREACH(const boost::shared_ptr<DCCLMessageVar> mv, layout_)
3398 ss << *mv;
3399
3400 if(is_moos)
3401@@ -348,7 +351,7 @@
3402
3403 ss << ">>>> PUBLISHES <<<<" << std::endl;
3404
3405- BOOST_FOREACH(const Publish& p, publishes_)
3406+ BOOST_FOREACH(const DCCLPublish& p, publishes_)
3407 ss << p;
3408 }
3409
3410@@ -359,7 +362,7 @@
3411 }
3412
3413 // a much shorter rundown of the Message parameters
3414-std::string dccl::Message::get_short_display() const
3415+std::string goby::acomms::DCCLMessage::get_short_display() const
3416 {
3417 std::stringstream ss;
3418
3419@@ -384,7 +387,7 @@
3420 }
3421
3422 // overloaded <<
3423-std::ostream& dccl::operator<< (std::ostream& out, const Message& message)
3424+std::ostream& goby::acomms::operator<< (std::ostream& out, const DCCLMessage& message)
3425 {
3426 out << message.get_display();
3427 return out;
3428
3429=== modified file 'src/acomms/libdccl/message.h'
3430--- src/acomms/libdccl/message.h 2010-07-11 16:20:55 +0000
3431+++ src/acomms/libdccl/message.h 2010-07-15 12:38:39 +0000
3432@@ -31,8 +31,7 @@
3433 #include <boost/foreach.hpp>
3434 #include <boost/shared_ptr.hpp>
3435
3436-#include "util/tes_utils.h"
3437-#include "acomms/modem_message.h"
3438+#include "goby/acomms/modem_message.h"
3439
3440 #include "message_var.h"
3441 #include "message_var_int.h"
3442@@ -47,197 +46,200 @@
3443 #include "message_publish.h"
3444 #include "dccl_constants.h"
3445
3446-namespace dccl
3447+
3448+namespace goby
3449 {
3450-
3451-// the Message itself
3452- class Message
3453- {
3454- public:
3455- Message();
3456-
3457- // set
3458- void set_name(const std::string& name) {name_ = name;}
3459-
3460- void set_id(unsigned id)
3461- { id_ = id; }
3462- template<typename T> void set_id(const T& t)
3463- { set_id(boost::lexical_cast<unsigned>(t)); }
3464-
3465- void set_trigger(const std::string& trigger_type)
3466- { trigger_type_ = trigger_type; }
3467-
3468- void set_trigger_var(const std::string& trigger_var)
3469- { trigger_var_ = trigger_var; }
3470-
3471- void set_trigger_time(double trigger_time)
3472- { trigger_time_ = trigger_time; }
3473- template<typename T> void set_trigger_time(const T& t)
3474- { set_trigger_time(boost::lexical_cast<double>(t)); }
3475-
3476- void set_trigger_mandatory(const std::string& trigger_mandatory)
3477- { trigger_mandatory_ = trigger_mandatory; }
3478-
3479- void set_in_var(const std::string& in_var)
3480- { in_var_ = in_var; }
3481-
3482- void set_out_var(const std::string& out_var)
3483- { out_var_ = out_var; }
3484-
3485- void set_size(unsigned size)
3486- { size_ = size; }
3487-
3488- template<typename T> void set_size(const T& t)
3489- { set_size(boost::lexical_cast<unsigned>(t)); }
3490-
3491- void set_repeat_enabled(unsigned repeat_enabled)
3492- { repeat_enabled_ = repeat_enabled; }
3493- template<typename T> void set_repeat_enabled(const T& t)
3494- { set_repeat_enabled(boost::lexical_cast<unsigned>(t)); }
3495-
3496- void add_message_var(const std::string& type);
3497- void add_publish();
3498-
3499- //get
3500- std::string name() const { return name_; }
3501- unsigned id() const { return id_; }
3502- std::string trigger_var() const { return trigger_var_; }
3503- std::string trigger_mandatory() const { return trigger_mandatory_; }
3504- double trigger_time() const { return trigger_time_; }
3505- unsigned trigger_number() const { return trigger_number_; }
3506- std::string trigger_type() const { return trigger_type_; }
3507- std::string in_var() const { return in_var_; }
3508- std::string out_var() const { return out_var_; }
3509- bool repeat_enabled() const { return repeat_enabled_; }
3510- unsigned repeat() const { return repeat_; }
3511-
3512- MessageVar& last_message_var() { return *layout_.back(); }
3513- MessageVar& header_var(acomms::DCCLHeaderPart p) { return *header_[p]; }
3514- Publish& last_publish() { return publishes_.back(); }
3515-
3516- std::vector< boost::shared_ptr<MessageVar> >& layout() { return layout_; }
3517- std::vector< boost::shared_ptr<MessageVar> >& header() { return header_; }
3518- std::vector<Publish>& publishes() { return publishes_; }
3519-
3520- std::set<std::string> get_pubsub_encode_vars();
3521- std::set<std::string> get_pubsub_decode_vars();
3522- std::set<std::string> get_pubsub_src_vars();
3523- std::set<std::string> get_pubsub_all_vars();
3524-
3525- boost::shared_ptr<MessageVar> name2message_var(const std::string& name);
3526-
3527-
3528- //other
3529- std::string get_display() const;
3530- std::string get_short_display() const;
3531- std::map<std::string, std::string> message_var_names() const;
3532- void preprocess();
3533- void set_repeat_array_length();
3534- unsigned calc_total_size();
3535-
3536- void set_head_defaults(std::map<std::string, std::vector<MessageVal> >& in, unsigned modem_id);
3537-
3538-
3539- void head_encode(std::string& head, std::map<std::string, std::vector<MessageVal> >& in);
3540- void head_decode(const std::string& head, std::map<std::string, std::vector<MessageVal> >& out);
3541-
3542- void body_encode(std::string& body, std::map<std::string, std::vector<MessageVal> >& in);
3543- void body_decode(std::string& body, std::map<std::string, std::vector<MessageVal> >& out);
3544-
3545- // increment, means increase trigger number
3546- // prefix ++Message
3547- Message& operator++()
3548- { ++trigger_number_; return(*this); }
3549- // postfix Message++
3550- const Message operator++(int)
3551- { Message tmp(*this); ++(*this); return tmp;}
3552-
3553-
3554- private:
3555- unsigned bytes_head() const
3556- { return acomms::NUM_HEADER_BYTES; }
3557- unsigned bits_head() const
3558- { return bytes2bits(acomms::NUM_HEADER_BYTES); }
3559-
3560- // more efficient way to do ceil(total_bits / 8)
3561- // to get the number of bytes rounded up.
3562-
3563- enum { BYTE_MASK = 7 }; // 00000111
3564- unsigned used_bytes_body() const
3565- {
3566- return (body_bits_& BYTE_MASK) ?
3567- bits2bytes(body_bits_) + 1 :
3568- bits2bytes(body_bits_);
3569- }
3570-
3571- unsigned used_bytes_total() const
3572- { return bytes_head() + used_bytes_body(); }
3573-
3574- unsigned used_bits_body() const
3575- { return body_bits_; }
3576-
3577- unsigned used_bits_total() const
3578- { return bits_head() + used_bits_body(); }
3579-
3580- unsigned requested_bytes_body() const
3581- { return size_ - acomms::NUM_HEADER_BYTES; }
3582-
3583- unsigned requested_bytes_total() const
3584- { return size_; }
3585-
3586- unsigned requested_bits_body() const
3587- { return bytes2bits(size_ - acomms::NUM_HEADER_BYTES); }
3588-
3589- unsigned requested_bits_total() const
3590- { return bytes2bits(size_); }
3591-
3592-
3593- private:
3594- // total request size of message, e.g. 32 bytes
3595- unsigned size_;
3596-
3597- unsigned trigger_number_;
3598- // actual used bits in body part of message (not including header bits)
3599- unsigned body_bits_;
3600-
3601- unsigned id_;
3602- unsigned modem_id_;
3603- double trigger_time_;
3604-
3605- bool repeat_enabled_;
3606- unsigned repeat_;
3607-
3608- std::string name_;
3609- std::string trigger_type_;
3610- std::string trigger_var_;
3611- std::string trigger_mandatory_;
3612- std::string in_var_;
3613- std::string out_var_;
3614-
3615- std::vector< boost::shared_ptr<MessageVar> > layout_;
3616- std::vector< boost::shared_ptr<MessageVar> > header_;
3617-
3618-
3619- std::vector<Publish> publishes_;
3620-
3621- };
3622-
3623-
3624- inline void bitset2string(const boost::dynamic_bitset<unsigned char>& body_bits,
3625- std::string& body)
3626- {
3627- body.resize(body_bits.num_blocks()); // resize the string to fit the bitset
3628- to_block_range(body_bits, body.rbegin());
3629- }
3630-
3631- inline void string2bitset(boost::dynamic_bitset<unsigned char>& body_bits,
3632- const std::string& body)
3633- {
3634- from_block_range(body.rbegin(), body.rend(), body_bits);
3635- }
3636-
3637-
3638- std::ostream& operator<< (std::ostream& out, const Message& message);
3639+ namespace acomms
3640+ {
3641+
3642+// the DCCLMessage itself
3643+ class DCCLMessage
3644+ {
3645+ public:
3646+ DCCLMessage();
3647+
3648+ // set
3649+ void set_name(const std::string& name) {name_ = name;}
3650+
3651+ void set_id(unsigned id)
3652+ { id_ = id; }
3653+ template<typename T> void set_id(const T& t)
3654+ { set_id(boost::lexical_cast<unsigned>(t)); }
3655+
3656+ void set_trigger(const std::string& trigger_type)
3657+ { trigger_type_ = trigger_type; }
3658+
3659+ void set_trigger_var(const std::string& trigger_var)
3660+ { trigger_var_ = trigger_var; }
3661+
3662+ void set_trigger_time(double trigger_time)
3663+ { trigger_time_ = trigger_time; }
3664+ template<typename T> void set_trigger_time(const T& t)
3665+ { set_trigger_time(boost::lexical_cast<double>(t)); }
3666+
3667+ void set_trigger_mandatory(const std::string& trigger_mandatory)
3668+ { trigger_mandatory_ = trigger_mandatory; }
3669+
3670+ void set_in_var(const std::string& in_var)
3671+ { in_var_ = in_var; }
3672+
3673+ void set_out_var(const std::string& out_var)
3674+ { out_var_ = out_var; }
3675+
3676+ void set_size(unsigned size)
3677+ { size_ = size; }
3678+
3679+ template<typename T> void set_size(const T& t)
3680+ { set_size(boost::lexical_cast<unsigned>(t)); }
3681+
3682+ void set_repeat_enabled(unsigned repeat_enabled)
3683+ { repeat_enabled_ = repeat_enabled; }
3684+ template<typename T> void set_repeat_enabled(const T& t)
3685+ { set_repeat_enabled(boost::lexical_cast<unsigned>(t)); }
3686+
3687+ void add_message_var(const std::string& type);
3688+ void add_publish();
3689+
3690+ //get
3691+ std::string name() const { return name_; }
3692+ unsigned id() const { return id_; }
3693+ std::string trigger_var() const { return trigger_var_; }
3694+ std::string trigger_mandatory() const { return trigger_mandatory_; }
3695+ double trigger_time() const { return trigger_time_; }
3696+ unsigned trigger_number() const { return trigger_number_; }
3697+ std::string trigger_type() const { return trigger_type_; }
3698+ std::string in_var() const { return in_var_; }
3699+ std::string out_var() const { return out_var_; }
3700+ bool repeat_enabled() const { return repeat_enabled_; }
3701+ unsigned repeat() const { return repeat_; }
3702+
3703+ DCCLMessageVar& last_message_var() { return *layout_.back(); }
3704+ DCCLMessageVar& header_var(acomms::DCCLHeaderPart p) { return *header_[p]; }
3705+ DCCLPublish& last_publish() { return publishes_.back(); }
3706+
3707+ std::vector< boost::shared_ptr<DCCLMessageVar> >& layout() { return layout_; }
3708+ std::vector< boost::shared_ptr<DCCLMessageVar> >& header() { return header_; }
3709+ std::vector<DCCLPublish>& publishes() { return publishes_; }
3710+
3711+ std::set<std::string> get_pubsub_encode_vars();
3712+ std::set<std::string> get_pubsub_decode_vars();
3713+ std::set<std::string> get_pubsub_src_vars();
3714+ std::set<std::string> get_pubsub_all_vars();
3715+
3716+ boost::shared_ptr<DCCLMessageVar> name2message_var(const std::string& name);
3717+
3718+
3719+ //other
3720+ std::string get_display() const;
3721+ std::string get_short_display() const;
3722+ std::map<std::string, std::string> message_var_names() const;
3723+ void preprocess();
3724+ void set_repeat_array_length();
3725+ unsigned calc_total_size();
3726+
3727+ void set_head_defaults(std::map<std::string, std::vector<DCCLMessageVal> >& in, unsigned modem_id);
3728+
3729+
3730+ void head_encode(std::string& head, std::map<std::string, std::vector<DCCLMessageVal> >& in);
3731+ void head_decode(const std::string& head, std::map<std::string, std::vector<DCCLMessageVal> >& out);
3732+
3733+ void body_encode(std::string& body, std::map<std::string, std::vector<DCCLMessageVal> >& in);
3734+ void body_decode(std::string& body, std::map<std::string, std::vector<DCCLMessageVal> >& out);
3735+
3736+ // increment, means increase trigger number
3737+ // prefix ++DCCLMessage
3738+ DCCLMessage& operator++()
3739+ { ++trigger_number_; return(*this); }
3740+ // postfix DCCLMessage++
3741+ const DCCLMessage operator++(int)
3742+ { DCCLMessage tmp(*this); ++(*this); return tmp;}
3743+
3744+
3745+ private:
3746+ unsigned bytes_head() const
3747+ { return acomms::DCCL_NUM_HEADER_BYTES; }
3748+ unsigned bits_head() const
3749+ { return bytes2bits(acomms::DCCL_NUM_HEADER_BYTES); }
3750+
3751+ // more efficient way to do ceil(total_bits / 8)
3752+ // to get the number of bytes rounded up.
3753+
3754+ enum { BYTE_MASK = 7 }; // 00000111
3755+ unsigned used_bytes_body() const
3756+ {
3757+ return (body_bits_& BYTE_MASK) ?
3758+ bits2bytes(body_bits_) + 1 :
3759+ bits2bytes(body_bits_);
3760+ }
3761+
3762+ unsigned used_bytes_total() const
3763+ { return bytes_head() + used_bytes_body(); }
3764+
3765+ unsigned used_bits_body() const
3766+ { return body_bits_; }
3767+
3768+ unsigned used_bits_total() const
3769+ { return bits_head() + used_bits_body(); }
3770+
3771+ unsigned requested_bytes_body() const
3772+ { return size_ - acomms::DCCL_NUM_HEADER_BYTES; }
3773+
3774+ unsigned requested_bytes_total() const
3775+ { return size_; }
3776+
3777+ unsigned requested_bits_body() const
3778+ { return bytes2bits(size_ - acomms::DCCL_NUM_HEADER_BYTES); }
3779+
3780+ unsigned requested_bits_total() const
3781+ { return bytes2bits(size_); }
3782+
3783+
3784+ private:
3785+ // total request size of message, e.g. 32 bytes
3786+ unsigned size_;
3787+
3788+ unsigned trigger_number_;
3789+ // actual used bits in body part of message (not including header bits)
3790+ unsigned body_bits_;
3791+
3792+ unsigned id_;
3793+ unsigned modem_id_;
3794+ double trigger_time_;
3795+
3796+ bool repeat_enabled_;
3797+ unsigned repeat_;
3798+
3799+ std::string name_;
3800+ std::string trigger_type_;
3801+ std::string trigger_var_;
3802+ std::string trigger_mandatory_;
3803+ std::string in_var_;
3804+ std::string out_var_;
3805+
3806+ std::vector< boost::shared_ptr<DCCLMessageVar> > layout_;
3807+ std::vector< boost::shared_ptr<DCCLMessageVar> > header_;
3808+
3809+
3810+ std::vector<DCCLPublish> publishes_;
3811+
3812+ };
3813+
3814+
3815+ inline void bitset2string(const boost::dynamic_bitset<unsigned char>& body_bits,
3816+ std::string& body)
3817+ {
3818+ body.resize(body_bits.num_blocks()); // resize the string to fit the bitset
3819+ to_block_range(body_bits, body.rbegin());
3820+ }
3821+
3822+ inline void string2bitset(boost::dynamic_bitset<unsigned char>& body_bits,
3823+ const std::string& body)
3824+ {
3825+ from_block_range(body.rbegin(), body.rend(), body_bits);
3826+ }
3827+
3828+
3829+ std::ostream& operator<< (std::ostream& out, const DCCLMessage& message);
3830+ }
3831 }
3832-
3833 #endif
3834
3835=== modified file 'src/acomms/libdccl/message_algorithms.cpp'
3836--- src/acomms/libdccl/message_algorithms.cpp 2010-06-15 04:51:47 +0000
3837+++ src/acomms/libdccl/message_algorithms.cpp 2010-07-15 12:38:39 +0000
3838@@ -22,33 +22,34 @@
3839 #include "message_algorithms.h"
3840 #include "message_val.h"
3841
3842-dccl::AlgorithmPerformer* dccl::AlgorithmPerformer::inst_ = NULL;
3843+#include "goby/util/string.h"
3844+
3845+goby::acomms::DCCLAlgorithmPerformer* goby::acomms::DCCLAlgorithmPerformer::inst_ = 0;
3846
3847 // singleton class, use this to get pointer
3848-dccl::AlgorithmPerformer* dccl::AlgorithmPerformer::getInstance()
3849+goby::acomms::DCCLAlgorithmPerformer* goby::acomms::DCCLAlgorithmPerformer::getInstance()
3850 {
3851- if(inst_ == NULL)
3852- inst_ = new AlgorithmPerformer();
3853+ if(!inst_) inst_ = new DCCLAlgorithmPerformer();
3854
3855 return(inst_);
3856 }
3857
3858-void dccl::AlgorithmPerformer::algorithm(MessageVal& in, unsigned array_index, const std::string& algorithm, const std::map<std::string,std::vector<MessageVal> >& vals)
3859+void goby::acomms::DCCLAlgorithmPerformer::algorithm(DCCLMessageVal& in, unsigned array_index, const std::string& algorithm, const std::map<std::string,std::vector<DCCLMessageVal> >& vals)
3860 {
3861 if(in.empty()) return;
3862
3863 // algo_name:ref_variable_name1:ref_variable_name2...
3864
3865- std::vector<std::string>ref_vars = tes_util::explode(algorithm, ':', true);
3866+ std::vector<std::string>ref_vars = util::explode(algorithm, ':', true);
3867
3868 std::string alg;
3869- std::vector<MessageVal> tied_vals;
3870+ std::vector<DCCLMessageVal> tied_vals;
3871
3872 for(std::vector<std::string>::size_type i = 1, n = ref_vars.size();
3873 i < n;
3874 ++i)
3875 {
3876- std::map<std::string, std::vector<dccl::MessageVal> >::const_iterator it = vals.find(ref_vars[i]);
3877+ std::map<std::string, std::vector<DCCLMessageVal> >::const_iterator it = vals.find(ref_vars[i]);
3878 if(it != vals.end() && array_index < it->second.size())
3879 tied_vals.push_back(it->second[array_index]);
3880 else
3881
3882=== modified file 'src/acomms/libdccl/message_algorithms.h'
3883--- src/acomms/libdccl/message_algorithms.h 2010-06-15 04:51:47 +0000
3884+++ src/acomms/libdccl/message_algorithms.h 2010-07-15 12:38:39 +0000
3885@@ -28,45 +28,46 @@
3886
3887 #include <boost/algorithm/string.hpp>
3888 #include <boost/function.hpp>
3889-
3890-namespace dccl
3891+namespace goby
3892 {
3893- class MessageVal;
3894+ namespace acomms
3895+ {
3896+ class DCCLMessageVal;
3897
3898- /// \brief boost::function for a function taking a single dccl::MessageVal reference. Used for algorithm callbacks.
3899- ///
3900- /// Think of this as a generalized version of a function pointer (void (*)(dccl::MessageVal&)). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
3901- typedef boost::function<void (MessageVal&)> AlgFunction1;
3902- /// \brief boost::function for a function taking a dccl::MessageVal reference, and the MessageVal of a second part of the message. Used for algorithm callbacks.
3903- ///
3904- /// Think of this as a generalized version of a function pointer (void (*)(MessageVal&, const MessageVal&). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
3905- typedef boost::function<void (MessageVal&, const std::vector<MessageVal>&)> AlgFunction2;
3906-
3907- class AlgorithmPerformer
3908- {
3909- public:
3910- static AlgorithmPerformer* getInstance();
3911-
3912- void algorithm(MessageVal& in, unsigned array_index, const std::string& algorithm, const std::map<std::string,std::vector<MessageVal> >& vals);
3913-
3914- void add_algorithm(const std::string& name, AlgFunction1 func)
3915- { adv_map1_[name] = func; }
3916-
3917- void add_algorithm(const std::string& name, AlgFunction2 func)
3918- { adv_map2_[name] = func; }
3919-
3920- private:
3921- static AlgorithmPerformer* inst_;
3922- std::map<std::string, AlgFunction1> adv_map1_;
3923- std::map<std::string, AlgFunction2> adv_map2_;
3924-
3925- AlgorithmPerformer()
3926- {}
3927-
3928- AlgorithmPerformer(const AlgorithmPerformer&);
3929- AlgorithmPerformer& operator = (const AlgorithmPerformer&);
3930+ /// \brief boost::function for a function taking a single DCCLMessageVal reference. Used for algorithm callbacks.
3931+ ///
3932+ /// Think of this as a generalized version of a function pointer (void (*)(DCCLMessageVal&)). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
3933+ typedef boost::function<void (DCCLMessageVal&)> AlgFunction1;
3934+ /// \brief boost::function for a function taking a dccl::MessageVal reference, and the MessageVal of a second part of the message. Used for algorithm callbacks.
3935+ ///
3936+ /// Think of this as a generalized version of a function pointer (void (*)(DCCLMessageVal&, const DCCLMessageVal&). See http://www.boost.org/doc/libs/1_34_0/doc/html/function.html for more on boost:function.
3937+ typedef boost::function<void (DCCLMessageVal&, const std::vector<DCCLMessageVal>&)> AlgFunction2;
3938+
3939+ class DCCLAlgorithmPerformer
3940+ {
3941+ public:
3942+ static DCCLAlgorithmPerformer* getInstance();
3943+
3944+ void algorithm(DCCLMessageVal& in, unsigned array_index, const std::string& algorithm, const std::map<std::string,std::vector<DCCLMessageVal> >& vals);
3945+
3946+ void add_algorithm(const std::string& name, AlgFunction1 func)
3947+ { adv_map1_[name] = func; }
3948+
3949+ void add_algorithm(const std::string& name, AlgFunction2 func)
3950+ { adv_map2_[name] = func; }
3951+
3952+ private:
3953+ static DCCLAlgorithmPerformer* inst_;
3954+ std::map<std::string, AlgFunction1> adv_map1_;
3955+ std::map<std::string, AlgFunction2> adv_map2_;
3956+
3957+ DCCLAlgorithmPerformer()
3958+ {}
3959+
3960+ DCCLAlgorithmPerformer(const DCCLAlgorithmPerformer&);
3961+ DCCLAlgorithmPerformer& operator = (const DCCLAlgorithmPerformer&);
3962
3963- };
3964+ };
3965+ }
3966 }
3967-
3968 #endif
3969
3970=== modified file 'src/acomms/libdccl/message_publish.cpp'
3971--- src/acomms/libdccl/message_publish.cpp 2010-06-15 04:51:47 +0000
3972+++ src/acomms/libdccl/message_publish.cpp 2010-07-15 12:38:39 +0000
3973@@ -22,9 +22,9 @@
3974 #include "message_publish.h"
3975 #include "message.h"
3976
3977-using acomms::NaN;
3978+using goby::acomms::NaN;
3979
3980-void dccl::Publish::initialize(Message& msg)
3981+void goby::acomms::DCCLPublish::initialize(DCCLMessage& msg)
3982 {
3983 repeat_ = msg.repeat();
3984
3985@@ -36,7 +36,7 @@
3986 // add names for any <all/> publishes and empty std::vector for algorithms
3987 if(use_all_names_)
3988 {
3989- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, msg.header())
3990+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, msg.header())
3991 {
3992 // ignore header pieces not explicitly overloaded by the <name> tag
3993 if(!mv->name().empty() && !(mv->name()[0] == '_'))
3994@@ -47,7 +47,7 @@
3995 }
3996 }
3997
3998- BOOST_FOREACH(boost::shared_ptr<MessageVar> mv, msg.layout())
3999+ BOOST_FOREACH(boost::shared_ptr<DCCLMessageVar> mv, msg.layout())
4000 {
4001 add_message_var(mv);
4002 // add an empty std::vector for algorithms (no algorithms allowed for <all/> tag)
4003@@ -60,7 +60,7 @@
4004 if(!format_set_)
4005 {
4006 std::string format_str;
4007- for (std::vector<boost::shared_ptr<MessageVar> >::size_type j = 0, m = message_vars_.size(); j < m; ++j)
4008+ for (std::vector<boost::shared_ptr<DCCLMessageVar> >::size_type j = 0, m = message_vars_.size(); j < m; ++j)
4009 {
4010 if (m > 1)
4011 {
4012@@ -102,10 +102,10 @@
4013 }
4014
4015
4016-void dccl::Publish::fill_format(const std::map<std::string,std::vector<MessageVal> >& vals,
4017- std::string& key,
4018- std::string& value,
4019- unsigned repeat_index)
4020+void goby::acomms::DCCLPublish::fill_format(const std::map<std::string,std::vector<DCCLMessageVal> >& vals,
4021+ std::string& key,
4022+ std::string& value,
4023+ unsigned repeat_index)
4024 {
4025 std::string filled_value;
4026 // format is a boost library class for replacing printf and its ilk
4027@@ -120,10 +120,10 @@
4028 f.parse(input_format);
4029
4030 // iterate over the message_vars and fill in the format field
4031- for (std::vector<boost::shared_ptr<MessageVar> >::size_type k = 0, o = message_vars_.size(); k < o; ++k)
4032+ for (std::vector<boost::shared_ptr<DCCLMessageVar> >::size_type k = 0, o = message_vars_.size(); k < o; ++k)
4033 {
4034- std::vector<MessageVal> vm = vals.find(message_vars_[k]->name())->second;
4035- for(std::vector<MessageVal>::size_type i = (repeat_ > 1) ? repeat_index : 0,
4036+ std::vector<DCCLMessageVal> vm = vals.find(message_vars_[k]->name())->second;
4037+ for(std::vector<DCCLMessageVal>::size_type i = (repeat_ > 1) ? repeat_index : 0,
4038 n = (repeat_ > 1) ? repeat_index + 1 : vm.size();
4039 i < n;
4040 ++i)
4041@@ -159,8 +159,8 @@
4042
4043
4044
4045-void dccl::Publish::write_publish(const std::map<std::string,std::vector<MessageVal> >& vals,
4046- std::multimap<std::string,MessageVal>& pubsub_vals)
4047+void goby::acomms::DCCLPublish::write_publish(const std::map<std::string,std::vector<DCCLMessageVal> >& vals,
4048+ std::multimap<std::string,DCCLMessageVal>& pubsub_vals)
4049
4050 {
4051 for(unsigned i = 0, n = repeat_;
4052@@ -173,29 +173,29 @@
4053 // user sets to string
4054 if(type_ == cpp_string)
4055 {
4056- pubsub_vals.insert(std::pair<std::string, MessageVal>(out_var, out_val));
4057+ pubsub_vals.insert(std::pair<std::string, DCCLMessageVal>(out_var, out_val));
4058 continue;
4059 }
4060
4061- // pass through a MessageVal to do the type conversions
4062- MessageVal mv = out_val;
4063+ // pass through a DCCLMessageVal to do the type conversions
4064+ DCCLMessageVal mv = out_val;
4065 double out_dval = mv;
4066 if(type_ == cpp_double)
4067 {
4068- pubsub_vals.insert(std::pair<std::string, MessageVal>(out_var, out_dval));
4069+ pubsub_vals.insert(std::pair<std::string, DCCLMessageVal>(out_var, out_dval));
4070 continue;
4071 }
4072 long out_lval = mv;
4073 if(type_ == cpp_long)
4074 {
4075- pubsub_vals.insert(std::pair<std::string, MessageVal>(out_var, out_lval));
4076+ pubsub_vals.insert(std::pair<std::string, DCCLMessageVal>(out_var, out_lval));
4077 continue;
4078
4079 }
4080 bool out_bval = mv;
4081 if(type_ == cpp_bool)
4082 {
4083- pubsub_vals.insert(std::pair<std::string, MessageVal>(out_var, out_bval));
4084+ pubsub_vals.insert(std::pair<std::string, DCCLMessageVal>(out_var, out_bval));
4085 continue;
4086 }
4087
4088@@ -205,14 +205,14 @@
4089 catch (boost::bad_lexical_cast &) { is_numeric = false; }
4090
4091 if(!is_numeric)
4092- pubsub_vals.insert(std::pair<std::string, MessageVal>(out_var, out_val));
4093+ pubsub_vals.insert(std::pair<std::string, DCCLMessageVal>(out_var, out_val));
4094 else
4095- pubsub_vals.insert(std::pair<std::string, MessageVal>(out_var, out_dval));
4096+ pubsub_vals.insert(std::pair<std::string, DCCLMessageVal>(out_var, out_dval));
4097 }
4098 }
4099
4100
4101-std::string dccl::Publish::get_display() const
4102+std::string goby::acomms::DCCLPublish::get_display() const
4103 {
4104 std::stringstream ss;
4105
4106@@ -220,7 +220,7 @@
4107 ss << ")moos_var: {" << var_ << "}" << std::endl;
4108 ss << "\tvalue: \"" << format_ << "\"" << std::endl;
4109 ss << "\tmessage_vars:" << std::endl;
4110- for (std::vector<boost::shared_ptr<MessageVar> >::size_type j = 0, m = message_vars_.size(); j < m; ++j)
4111+ for (std::vector<boost::shared_ptr<DCCLMessageVar> >::size_type j = 0, m = message_vars_.size(); j < m; ++j)
4112 {
4113 ss << "\t\t" << (j+1) << ": " << message_vars_[j]->name();
4114
4115@@ -240,7 +240,7 @@
4116 }
4117
4118 // overloaded <<
4119-std::ostream& dccl::operator<< (std::ostream& out, const Publish& publish)
4120+std::ostream& goby::acomms::operator<< (std::ostream& out, const DCCLPublish& publish)
4121 {
4122 out << publish.get_display();
4123 return out;
4124
4125=== modified file 'src/acomms/libdccl/message_publish.h'
4126--- src/acomms/libdccl/message_publish.h 2010-06-15 04:51:47 +0000
4127+++ src/acomms/libdccl/message_publish.h 2010-07-15 12:38:39 +0000
4128@@ -31,77 +31,79 @@
4129 #include "message_algorithms.h"
4130 #include "dccl_constants.h"
4131
4132-namespace dccl
4133+namespace goby
4134 {
4135- class Message;
4136+ namespace acomms
4137+ {
4138+ class DCCLMessage;
4139
4140 // defines (a single) thing to do with the decoded message
4141 // that is, where do we publish it and what should we include in the
4142 // published message
4143- class Publish
4144- {
4145- public:
4146- Publish() : var_(""),
4147- format_(""),
4148- format_set_(false),
4149- use_all_names_(false),
4150- type_(cpp_notype),
4151- ap_(AlgorithmPerformer::getInstance()),
4152- repeat_(1)
4153- { }
4154-
4155- //set
4156-
4157- void set_var(std::string var) {var_=var;}
4158- void set_format(std::string format) {format_=format; format_set_ = true;}
4159- void set_use_all_names(bool use_all_names) {use_all_names_ = use_all_names;}
4160- void set_type(DCCLCppType type) {type_ = type;}
4161-
4162- void add_name(const std::string& name) {names_.push_back(name);}
4163- void add_message_var(boost::shared_ptr<MessageVar> mv) {message_vars_.push_back(mv);}
4164- void add_algorithms(const std::vector<std::string> algorithms) {algorithms_.push_back(algorithms);}
4165-
4166- //get
4167+ class DCCLPublish
4168+ {
4169+ public:
4170+ DCCLPublish() : var_(""),
4171+ format_(""),
4172+ format_set_(false),
4173+ use_all_names_(false),
4174+ type_(cpp_notype),
4175+ ap_(DCCLAlgorithmPerformer::getInstance()),
4176+ repeat_(1)
4177+ { }
4178+
4179+ //set
4180+
4181+ void set_var(std::string var) {var_=var;}
4182+ void set_format(std::string format) {format_=format; format_set_ = true;}
4183+ void set_use_all_names(bool use_all_names) {use_all_names_ = use_all_names;}
4184+ void set_type(DCCLCppType type) {type_ = type;}
4185+
4186+ void add_name(const std::string& name) {names_.push_back(name);}
4187+ void add_message_var(boost::shared_ptr<DCCLMessageVar> mv) {message_vars_.push_back(mv);}
4188+ void add_algorithms(const std::vector<std::string> algorithms) {algorithms_.push_back(algorithms);}
4189+
4190+ //get
4191 // std::string var() const {return var_;}
4192 // std::string format() const {return format_;}
4193 // bool format_set() const {return format_set_;}
4194 // bool use_all_names() const {return use_all_names_;}
4195
4196- DCCLCppType type() {return type_;}
4197+ DCCLCppType type() {return type_;}
4198 // std::vector<std::string> const& names() {return names_;}
4199 // std::vector<std::vector<std::string> > const& algorithms(){return algorithms_;}
4200
4201
4202- std::string get_display() const;
4203-
4204- void write_publish(const std::map<std::string,std::vector<MessageVal> >& vals,
4205- std::multimap<std::string,MessageVal>& pubsub_vals);
4206-
4207-
4208-
4209-
4210- void initialize(Message& msg);
4211-
4212- private:
4213- void fill_format(const std::map<std::string,std::vector<MessageVal> >& vals,
4214- std::string& key,
4215- std::string& value,
4216- unsigned repeat_index);
4217+ std::string get_display() const;
4218+
4219+ void write_publish(const std::map<std::string,std::vector<DCCLMessageVal> >& vals,
4220+ std::multimap<std::string,DCCLMessageVal>& pubsub_vals);
4221+
4222+
4223+
4224+
4225+ void initialize(DCCLMessage& msg);
4226+
4227+ private:
4228+ void fill_format(const std::map<std::string,std::vector<DCCLMessageVal> >& vals,
4229+ std::string& key,
4230+ std::string& value,
4231+ unsigned repeat_index);
4232
4233- private:
4234- std::string var_;
4235- std::string format_;
4236- bool format_set_;
4237- bool use_all_names_;
4238- DCCLCppType type_;
4239- std::vector<std::string> names_;
4240- std::vector<boost::shared_ptr<MessageVar> > message_vars_;
4241- std::vector< std::vector<std::string> > algorithms_;
4242- AlgorithmPerformer* ap_;
4243- unsigned repeat_;
4244- };
4245+ private:
4246+ std::string var_;
4247+ std::string format_;
4248+ bool format_set_;
4249+ bool use_all_names_;
4250+ DCCLCppType type_;
4251+ std::vector<std::string> names_;
4252+ std::vector<boost::shared_ptr<DCCLMessageVar> > message_vars_;
4253+ std::vector< std::vector<std::string> > algorithms_;
4254+ DCCLAlgorithmPerformer* ap_;
4255+ unsigned repeat_;
4256+ };
4257
4258- std::ostream& operator<< (std::ostream& out, const Publish& publish);
4259+ std::ostream& operator<< (std::ostream& out, const DCCLPublish& publish);
4260+ }
4261 }
4262-
4263 #endif
4264
4265=== modified file 'src/acomms/libdccl/message_val.cpp'
4266--- src/acomms/libdccl/message_val.cpp 2010-07-13 01:57:57 +0000
4267+++ src/acomms/libdccl/message_val.cpp 2010-07-15 12:38:39 +0000
4268@@ -17,13 +17,17 @@
4269 // You should have received a copy of the GNU General Public License
4270 // along with this software. If not, see <http://www.gnu.org/licenses/>.
4271
4272-#include <exception>
4273+#include <stdexcept>
4274+#include <iomanip>
4275
4276 #include <boost/foreach.hpp>
4277
4278+#include "goby/util/string.h"
4279+#include "goby/util/sci.h"
4280+
4281 #include "message_val.h"
4282
4283-void dccl::MessageVal::init()
4284+void goby::acomms::DCCLMessageVal::init()
4285 {
4286 sval_ = "";
4287 dval_ = 0;
4288@@ -34,27 +38,27 @@
4289 }
4290
4291
4292-dccl::MessageVal::MessageVal()
4293+goby::acomms::DCCLMessageVal::DCCLMessageVal()
4294 { init(); }
4295
4296
4297-dccl::MessageVal::MessageVal(const std::string& s)
4298-{
4299- init();
4300- sval_ = s;
4301- type_ = cpp_string;
4302-}
4303-
4304-
4305-dccl::MessageVal::MessageVal(const char* s)
4306-{
4307- init();
4308- sval_ = s;
4309- type_ = cpp_string;
4310-}
4311-
4312-
4313-dccl::MessageVal::MessageVal(double d, int p /* = MAX_DBL_PRECISION*/ )
4314+goby::acomms::DCCLMessageVal::DCCLMessageVal(const std::string& s)
4315+{
4316+ init();
4317+ sval_ = s;
4318+ type_ = cpp_string;
4319+}
4320+
4321+
4322+goby::acomms::DCCLMessageVal::DCCLMessageVal(const char* s)
4323+{
4324+ init();
4325+ sval_ = s;
4326+ type_ = cpp_string;
4327+}
4328+
4329+
4330+goby::acomms::DCCLMessageVal::DCCLMessageVal(double d, int p /* = MAX_DBL_PRECISION*/ )
4331 {
4332 init();
4333 dval_ = d;
4334@@ -62,28 +66,28 @@
4335 type_ = cpp_double;
4336 }
4337
4338-dccl::MessageVal::MessageVal(float f)
4339+goby::acomms::DCCLMessageVal::DCCLMessageVal(float f)
4340 {
4341 init();
4342 dval_ = f;
4343 type_ = cpp_double;
4344 }
4345
4346-dccl::MessageVal::MessageVal(long l)
4347+goby::acomms::DCCLMessageVal::DCCLMessageVal(long l)
4348 {
4349 init();
4350 lval_ = l;
4351 type_ = cpp_long;
4352 }
4353
4354-dccl::MessageVal::MessageVal(int i)
4355+goby::acomms::DCCLMessageVal::DCCLMessageVal(int i)
4356 {
4357 init();
4358 lval_ = i;
4359 type_ = cpp_long;
4360 }
4361
4362-dccl::MessageVal::MessageVal(bool b)
4363+goby::acomms::DCCLMessageVal::DCCLMessageVal(bool b)
4364 {
4365 init();
4366 bval_ = b;
4367@@ -91,26 +95,26 @@
4368 }
4369
4370
4371-dccl::MessageVal::MessageVal(const std::vector<MessageVal>& vm)
4372+goby::acomms::DCCLMessageVal::DCCLMessageVal(const std::vector<DCCLMessageVal>& vm)
4373 {
4374 if(vm.size() != 1)
4375- throw(std::runtime_error("vector cast to MessageVal failed: vector is not size 1"));
4376+ throw(std::runtime_error("vector cast to DCCLMessageVal failed: vector is not size 1"));
4377 else
4378 *this = vm[0];
4379 }
4380
4381
4382-void dccl::MessageVal::set(std::string sval)
4383+void goby::acomms::DCCLMessageVal::set(std::string sval)
4384 { sval_ = sval; type_ = cpp_string; }
4385-void dccl::MessageVal::set(double dval, int precision /* = MAX_DBL_PRECISION */)
4386+void goby::acomms::DCCLMessageVal::set(double dval, int precision /* = MAX_DBL_PRECISION */)
4387 { dval_ = dval; type_ = cpp_double; precision_ = precision; }
4388-void dccl::MessageVal::set(long lval)
4389+void goby::acomms::DCCLMessageVal::set(long lval)
4390 { lval_ = lval; type_ = cpp_long; }
4391-void dccl::MessageVal::set(bool bval)
4392+void goby::acomms::DCCLMessageVal::set(bool bval)
4393 { bval_ = bval; type_ = cpp_bool; }
4394
4395
4396-bool dccl::MessageVal::get(std::string& s) const
4397+bool goby::acomms::DCCLMessageVal::get(std::string& s) const
4398 {
4399 std::stringstream ss;
4400 switch(type_)
4401@@ -141,14 +145,14 @@
4402 }
4403 }
4404
4405-bool dccl::MessageVal::get(bool& b) const
4406+bool goby::acomms::DCCLMessageVal::get(bool& b) const
4407 {
4408 switch(type_)
4409 {
4410 case cpp_string:
4411- if(tes_util::stricmp(sval_, "true") || tes_util::stricmp(sval_, "1"))
4412+ if(util::stricmp(sval_, "true") || util::stricmp(sval_, "1"))
4413 b = true;
4414- else if(tes_util::stricmp(sval_, "false") || tes_util::stricmp(sval_, "0"))
4415+ else if(util::stricmp(sval_, "false") || util::stricmp(sval_, "0"))
4416 b = false;
4417 else
4418 return false;
4419@@ -173,7 +177,7 @@
4420 }
4421 }
4422
4423-bool dccl::MessageVal::get(long& t) const
4424+bool goby::acomms::DCCLMessageVal::get(long& t) const
4425 {
4426 switch(type_)
4427 {
4428@@ -181,13 +185,13 @@
4429 try
4430 {
4431 double d = boost::lexical_cast<double>(sval_);
4432- t = boost::numeric_cast<long>(tes_util::sci_round(d, 0));
4433+ t = boost::numeric_cast<long>(util::unbiased_round(d, 0));
4434 }
4435 catch (...)
4436 {
4437- if(tes_util::stricmp(sval_, "true"))
4438+ if(util::stricmp(sval_, "true"))
4439 t = 1;
4440- else if(tes_util::stricmp(sval_, "false"))
4441+ else if(util::stricmp(sval_, "false"))
4442 t = 0;
4443 else
4444 return false;
4445@@ -195,7 +199,7 @@
4446 return true;
4447
4448 case cpp_double:
4449- try { t = boost::numeric_cast<long>(tes_util::sci_round(dval_, 0)); }
4450+ try { t = boost::numeric_cast<long>(util::unbiased_round(dval_, 0)); }
4451 catch(...) { return false; }
4452 return true;
4453
4454@@ -212,7 +216,7 @@
4455 }
4456 }
4457
4458-bool dccl::MessageVal::get(double& d) const
4459+bool goby::acomms::DCCLMessageVal::get(double& d) const
4460 {
4461 switch(type_)
4462 {
4463@@ -220,9 +224,9 @@
4464 try { d = boost::lexical_cast<double>(sval_); }
4465 catch (boost::bad_lexical_cast &)
4466 {
4467- if(tes_util::stricmp(sval_, "true"))
4468+ if(util::stricmp(sval_, "true"))
4469 d = 1;
4470- else if(tes_util::stricmp(sval_, "false"))
4471+ else if(util::stricmp(sval_, "false"))
4472 d = 0;
4473 else
4474 return false;
4475@@ -251,7 +255,7 @@
4476
4477
4478
4479-dccl::MessageVal::operator double() const
4480+goby::acomms::DCCLMessageVal::operator double() const
4481 {
4482 double d;
4483 if(get(d)) return d;
4484@@ -259,48 +263,48 @@
4485 }
4486
4487
4488-dccl::MessageVal::operator bool() const
4489+goby::acomms::DCCLMessageVal::operator bool() const
4490 {
4491 bool b;
4492 if(get(b)) return b;
4493 else return false;
4494 }
4495
4496-dccl::MessageVal::operator std::string() const
4497+goby::acomms::DCCLMessageVal::operator std::string() const
4498 {
4499 std::string s;
4500 if(get(s)) return s;
4501 else return "";
4502 }
4503
4504-dccl::MessageVal::operator long() const
4505+goby::acomms::DCCLMessageVal::operator long() const
4506 {
4507 long l;
4508 if(get(l)) return l;
4509 else return 0;
4510 }
4511
4512-dccl::MessageVal::operator int() const
4513-{
4514- return long(*this);
4515-}
4516-
4517-dccl::MessageVal::operator unsigned() const
4518-{
4519- return long(*this);
4520-}
4521-
4522-dccl::MessageVal::operator float() const
4523+goby::acomms::DCCLMessageVal::operator int() const
4524+{
4525+ return long(*this);
4526+}
4527+
4528+goby::acomms::DCCLMessageVal::operator unsigned() const
4529+{
4530+ return long(*this);
4531+}
4532+
4533+goby::acomms::DCCLMessageVal::operator float() const
4534 {
4535 return double(*this);
4536 }
4537
4538-dccl::MessageVal::operator std::vector<MessageVal>() const
4539+goby::acomms::DCCLMessageVal::operator std::vector<DCCLMessageVal>() const
4540 {
4541- return std::vector<MessageVal>(1, *this);
4542+ return std::vector<DCCLMessageVal>(1, *this);
4543 }
4544
4545-bool dccl::MessageVal::operator==(const MessageVal& mv) const
4546+bool goby::acomms::DCCLMessageVal::operator==(const DCCLMessageVal& mv) const
4547 {
4548 switch(mv.type_)
4549 {
4550@@ -312,25 +316,25 @@
4551 }
4552 }
4553
4554-bool dccl::MessageVal::operator==(const std::string& s) const
4555+bool goby::acomms::DCCLMessageVal::operator==(const std::string& s) const
4556 {
4557 std::string us;
4558 return get(us) && us == s;
4559 }
4560
4561-bool dccl::MessageVal::operator==(double d) const
4562+bool goby::acomms::DCCLMessageVal::operator==(double d) const
4563 {
4564 double us;
4565 return get(us) && us == d;
4566 }
4567
4568-bool dccl::MessageVal::operator==(long l) const
4569+bool goby::acomms::DCCLMessageVal::operator==(long l) const
4570 {
4571 long us;
4572 return get(us) && us == l;
4573 }
4574
4575-bool dccl::MessageVal::operator==(bool b) const
4576+bool goby::acomms::DCCLMessageVal::operator==(bool b) const
4577 {
4578 bool us;
4579 return get(us) && us == b;
4580@@ -338,7 +342,7 @@
4581
4582
4583
4584-std::ostream& dccl::operator<<(std::ostream& os, const dccl::MessageVal& mv)
4585+std::ostream& goby::acomms::operator<<(std::ostream& os, const goby::acomms::DCCLMessageVal& mv)
4586 {
4587 switch(mv.type_)
4588 {
4589@@ -351,10 +355,10 @@
4590 }
4591
4592
4593-std::ostream& dccl::operator<<(std::ostream& os, const std::vector<dccl::MessageVal>& vm)
4594+std::ostream& goby::acomms::operator<<(std::ostream& os, const std::vector<goby::acomms::DCCLMessageVal>& vm)
4595 {
4596 int j=0;
4597- BOOST_FOREACH(const dccl::MessageVal& m, vm)
4598+ BOOST_FOREACH(const DCCLMessageVal& m, vm)
4599 {
4600 if(j) os << ",";
4601 os << m;
4602
4603=== modified file 'src/acomms/libdccl/message_val.h'
4604--- src/acomms/libdccl/message_val.h 2010-06-15 04:51:47 +0000
4605+++ src/acomms/libdccl/message_val.h 2010-07-15 12:38:39 +0000
4606@@ -25,157 +25,158 @@
4607 #include <boost/numeric/conversion/cast.hpp>
4608 #include <boost/lexical_cast.hpp>
4609
4610-#include "util/tes_utils.h"
4611 #include "dccl_constants.h"
4612
4613-namespace dccl
4614+namespace goby
4615 {
4616+ namespace acomms
4617+ {
4618
4619 /// defines a DCCL value
4620- class MessageVal
4621- {
4622- public:
4623- enum { MAX_DBL_PRECISION = 15 };
4624-
4625- /// \name Constructors/Destructor
4626- //@{
4627- /// empty
4628- MessageVal();
4629-
4630- /// construct with string value
4631- MessageVal(const std::string& s);
4632-
4633- /// construct with char* value
4634- MessageVal(const char* s);
4635-
4636- /// construct with double value, optionally giving the precision of the double (number of decimal places) which is used if a cast to std::string is required in the future.
4637- MessageVal(double d, int p = MAX_DBL_PRECISION);
4638-
4639- /// construct with long value
4640- MessageVal(long l);
4641-
4642- /// construct with int value
4643- MessageVal(int i);
4644-
4645- /// construct with float value
4646- MessageVal(float f);
4647-
4648- /// construct with bool value
4649- MessageVal(bool b);
4650-
4651- /// construct with vector
4652- MessageVal(const std::vector<MessageVal>& vm);
4653-
4654-
4655-
4656- //@}
4657-
4658- /// \name Setters
4659- //@{
4660- /// set the value with a string (overwrites previous value regardless of type)
4661- void set(std::string sval);
4662- /// \brief set the value with a double (overwrites previous value regardless of type)
4663- /// \param dval values to set
4664- /// \param precision decimal places of precision to preserve if this is cast to a string
4665- void set(double dval, int precision = MAX_DBL_PRECISION);
4666- /// set the value with a long (overwrites previous value regardless of type)
4667- void set(long lval);
4668- /// set the value with a bool (overwrites previous value regardless of type)
4669- void set(bool bval);
4670-
4671- //@}
4672-
4673- /// \name Getters
4674- //@{
4675- /// \brief extract as std::string (all reasonable casts are done)
4676- /// \param s std::string to store value in
4677- /// \return successfully extracted (and if necessary successfully cast to this type)
4678- bool get(std::string& s) const;
4679- /// \brief extract as bool (all reasonable casts are done)
4680- /// \param b bool to store value in
4681- /// \return successfully extracted (and if necessary successfully cast to this type)
4682- bool get(bool& b) const;
4683- /// \brief extract as long (all reasonable casts are done)
4684- /// \param t long to store value in
4685- /// \return successfully extracted (and if necessary successfully cast to this type)
4686- bool get(long& t) const;
4687- /// \brief extract as double (all reasonable casts are done)
4688- /// \param d double to store value in
4689- /// \return successfully extracted (and if necessary successfully cast to this type)
4690- bool get(double& d) const;
4691-
4692- ///
4693- /// allows statements of the form \code double d = MessageVal("3.23"); \endcode
4694- operator double() const;
4695-
4696- ///
4697- /// allows statements of the form \code bool b = MessageVal("1"); \endcode
4698- operator bool() const;
4699-
4700- ///
4701- /// allows statements of the form \code std::string s = MessageVal(3); \endcode
4702- operator std::string() const;
4703-
4704- ///
4705- /// allows statements of the form \code long l = MessageVal(5); \endcode
4706- operator long() const;
4707-
4708- ///
4709- /// allows statements of the form \code int i = MessageVal(2); \endcode
4710- operator int() const;
4711-
4712- ///
4713- /// allows statements of the form \code unsigned u = MessageVal(2); \endcode
4714- operator unsigned() const;
4715-
4716- ///
4717- /// allows statements of the form \code float f = MessageVal("3.5"); \endcode
4718- operator float() const;
4719-
4720- operator std::vector<MessageVal>() const;
4721-
4722-
4723- /// what type is the original type of this MessageVal?
4724- DCCLCppType type() const { return type_; }
4725-
4726- /// was this just constructed with MessageVal() ?
4727- bool empty() const { return type_ == cpp_notype; }
4728-
4729- unsigned precision() const { return precision_; }
4730+ class DCCLMessageVal
4731+ {
4732+ public:
4733+ enum { MAX_DBL_PRECISION = 15 };
4734+
4735+ /// \name Constructors/Destructor
4736+ //@{
4737+ /// empty
4738+ DCCLMessageVal();
4739+
4740+ /// construct with string value
4741+ DCCLMessageVal(const std::string& s);
4742+
4743+ /// construct with char* value
4744+ DCCLMessageVal(const char* s);
4745+
4746+ /// construct with double value, optionally giving the precision of the double (number of decimal places) which is used if a cast to std::string is required in the future.
4747+ DCCLMessageVal(double d, int p = MAX_DBL_PRECISION);
4748+
4749+ /// construct with long value
4750+ DCCLMessageVal(long l);
4751+
4752+ /// construct with int value
4753+ DCCLMessageVal(int i);
4754+
4755+ /// construct with float value
4756+ DCCLMessageVal(float f);
4757+
4758+ /// construct with bool value
4759+ DCCLMessageVal(bool b);
4760+
4761+ /// construct with vector
4762+ DCCLMessageVal(const std::vector<DCCLMessageVal>& vm);
4763+
4764+
4765+
4766+ //@}
4767+
4768+ /// \name Setters
4769+ //@{
4770+ /// set the value with a string (overwrites previous value regardless of type)
4771+ void set(std::string sval);
4772+ /// \brief set the value with a double (overwrites previous value regardless of type)
4773+ /// \param dval values to set
4774+ /// \param precision decimal places of precision to preserve if this is cast to a string
4775+ void set(double dval, int precision = MAX_DBL_PRECISION);
4776+ /// set the value with a long (overwrites previous value regardless of type)
4777+ void set(long lval);
4778+ /// set the value with a bool (overwrites previous value regardless of type)
4779+ void set(bool bval);
4780+
4781+ //@}
4782+
4783+ /// \name Getters
4784+ //@{
4785+ /// \brief extract as std::string (all reasonable casts are done)
4786+ /// \param s std::string to store value in
4787+ /// \return successfully extracted (and if necessary successfully cast to this type)
4788+ bool get(std::string& s) const;
4789+ /// \brief extract as bool (all reasonable casts are done)
4790+ /// \param b bool to store value in
4791+ /// \return successfully extracted (and if necessary successfully cast to this type)
4792+ bool get(bool& b) const;
4793+ /// \brief extract as long (all reasonable casts are done)
4794+ /// \param t long to store value in
4795+ /// \return successfully extracted (and if necessary successfully cast to this type)
4796+ bool get(long& t) const;
4797+ /// \brief extract as double (all reasonable casts are done)
4798+ /// \param d double to store value in
4799+ /// \return successfully extracted (and if necessary successfully cast to this type)
4800+ bool get(double& d) const;
4801+
4802+ ///
4803+ /// allows statements of the form \code double d = DCCLMessageVal("3.23"); \endcode
4804+ operator double() const;
4805+
4806+ ///
4807+ /// allows statements of the form \code bool b = DCCLMessageVal("1"); \endcode
4808+ operator bool() const;
4809+
4810+ ///
4811+ /// allows statements of the form \code std::string s = DCCLMessageVal(3); \endcode
4812+ operator std::string() const;
4813+
4814+ ///
4815+ /// allows statements of the form \code long l = DCCLMessageVal(5); \endcode
4816+ operator long() const;
4817+
4818+ ///
4819+ /// allows statements of the form \code int i = DCCLMessageVal(2); \endcode
4820+ operator int() const;
4821+
4822+ ///
4823+ /// allows statements of the form \code unsigned u = DCCLMessageVal(2); \endcode
4824+ operator unsigned() const;
4825+
4826+ ///
4827+ /// allows statements of the form \code float f = DCCLMessageVal("3.5"); \endcode
4828+ operator float() const;
4829+
4830+ operator std::vector<DCCLMessageVal>() const;
4831+
4832+
4833+ /// what type is the original type of this DCCLMessageVal?
4834+ DCCLCppType type() const { return type_; }
4835+
4836+ /// was this just constructed with DCCLMessageVal() ?
4837+ bool empty() const { return type_ == cpp_notype; }
4838+
4839+ unsigned precision() const { return precision_; }
4840
4841 //@}
4842
4843
4844- /// \name Comparison
4845- //@{
4846- bool operator==(const MessageVal& mv) const;
4847- bool operator==(const std::string& s) const;
4848- bool operator==(double d) const;
4849- bool operator==(long l) const;
4850- bool operator==(bool b) const;
4851-
4852- // @}
4853-
4854- private:
4855- void init();
4856-
4857- friend std::ostream& operator<<(std::ostream& os, const MessageVal& mv);
4858-
4859- private:
4860- std::string sval_;
4861- double dval_;
4862- long lval_;
4863- bool bval_;
4864-
4865- unsigned precision_;
4866-
4867- DCCLCppType type_;
4868- };
4869-
4870- std::ostream& operator<<(std::ostream& os, const dccl::MessageVal& mv);
4871- std::ostream& operator<<(std::ostream& os, const std::vector<dccl::MessageVal>& vm);
4872+ /// \name Comparison
4873+ //@{
4874+ bool operator==(const DCCLMessageVal& mv) const;
4875+ bool operator==(const std::string& s) const;
4876+ bool operator==(double d) const;
4877+ bool operator==(long l) const;
4878+ bool operator==(bool b) const;
4879+
4880+ // @}
4881+
4882+ private:
4883+ void init();
4884+
4885+ friend std::ostream& operator<<(std::ostream& os, const DCCLMessageVal& mv);
4886+
4887+ private:
4888+ std::string sval_;
4889+ double dval_;
4890+ long lval_;
4891+ bool bval_;
4892+
4893+ unsigned precision_;
4894+
4895+ DCCLCppType type_;
4896+ };
4897+
4898+ std::ostream& operator<<(std::ostream& os, const acomms::DCCLMessageVal& mv);
4899+ std::ostream& operator<<(std::ostream& os, const std::vector<acomms::DCCLMessageVal>& vm);
4900+ }
4901+
4902 }
4903
4904-
4905-
4906 #endif
4907
4908=== modified file 'src/acomms/libdccl/message_var.cpp'
4909--- src/acomms/libdccl/message_var.cpp 2010-06-15 04:51:47 +0000
4910+++ src/acomms/libdccl/message_var.cpp 2010-07-15 12:38:39 +0000
4911@@ -19,21 +19,21 @@
4912
4913 #include <boost/foreach.hpp>
4914
4915-#include "util/tes_utils.h"
4916+#include "goby/util/string.h"
4917
4918 #include "message_var.h"
4919 #include "message_val.h"
4920 #include "dccl_constants.h"
4921 #include "message_algorithms.h"
4922
4923-dccl::MessageVar::MessageVar()
4924+goby::acomms::DCCLMessageVar::DCCLMessageVar()
4925 : array_length_(1),
4926 is_key_frame_(true),
4927 source_set_(false),
4928- ap_(AlgorithmPerformer::getInstance())
4929+ ap_(DCCLAlgorithmPerformer::getInstance())
4930 { }
4931
4932-void dccl::MessageVar::initialize(const std::string& trigger_var)
4933+void goby::acomms::DCCLMessageVar::initialize(const std::string& trigger_var)
4934 {
4935 // add trigger_var_ as source_var for any message_vars without a source
4936 if(!source_set_)
4937@@ -43,30 +43,30 @@
4938
4939 }
4940
4941-void dccl::MessageVar::set_defaults(std::map<std::string,std::vector<MessageVal> >& vals, unsigned modem_id, unsigned id)
4942+void goby::acomms::DCCLMessageVar::set_defaults(std::map<std::string,std::vector<DCCLMessageVal> >& vals, unsigned modem_id, unsigned id)
4943 {
4944 vals[name_].resize(array_length_);
4945
4946- std::vector<MessageVal>& vm = vals[name_];
4947+ std::vector<DCCLMessageVal>& vm = vals[name_];
4948
4949- for(std::vector<MessageVal>::size_type i = 0, n = vm.size(); i < n; ++i)
4950+ for(std::vector<DCCLMessageVal>::size_type i = 0, n = vm.size(); i < n; ++i)
4951 set_defaults_specific(vm[i], modem_id, id);
4952
4953 }
4954
4955
4956-void dccl::MessageVar::var_encode(std::map<std::string,std::vector<MessageVal> >& vals, boost::dynamic_bitset<unsigned char>& bits)
4957+void goby::acomms::DCCLMessageVar::var_encode(std::map<std::string,std::vector<DCCLMessageVal> >& vals, boost::dynamic_bitset<unsigned char>& bits)
4958 {
4959- // ensure that every MessageVar has the full number of (maybe blank) MessageVals
4960+ // ensure that every DCCLMessageVar has the full number of (maybe blank) DCCLMessageVals
4961 vals[name_].resize(array_length_);
4962
4963 // copy so algorithms can modify directly and not affect other algorithms' use of original values
4964- std::vector<MessageVal> vm = vals[name_];
4965+ std::vector<DCCLMessageVal> vm = vals[name_];
4966
4967 // write all the delta values first
4968 is_key_frame_ = false;
4969
4970- for(std::vector<MessageVal>::size_type i = 0, n = vm.size(); i < n; ++i)
4971+ for(std::vector<DCCLMessageVal>::size_type i = 0, n = vm.size(); i < n; ++i)
4972 {
4973 for(std::vector<std::string>::size_type j = 0, m = algorithms_.size(); j < m; ++j)
4974 ap_->algorithm(vm[i], i, algorithms_[j], vals);
4975@@ -83,7 +83,7 @@
4976 encode_value(key_val_, bits);
4977 }
4978
4979-void dccl::MessageVar::encode_value(const MessageVal& val, boost::dynamic_bitset<unsigned char>& bits)
4980+void goby::acomms::DCCLMessageVar::encode_value(const DCCLMessageVal& val, boost::dynamic_bitset<unsigned char>& bits)
4981 {
4982 bits <<= calc_size();
4983
4984@@ -94,7 +94,7 @@
4985 }
4986
4987
4988-void dccl::MessageVar::var_decode(std::map<std::string,std::vector<MessageVal> >& vals, boost::dynamic_bitset<unsigned char>& bits)
4989+void goby::acomms::DCCLMessageVar::var_decode(std::map<std::string,std::vector<DCCLMessageVal> >& vals, boost::dynamic_bitset<unsigned char>& bits)
4990 {
4991 vals[name_].resize(array_length_);
4992
4993@@ -106,7 +106,7 @@
4994 boost::dynamic_bitset<unsigned char> remove_bits = bits;
4995 remove_bits.resize(calc_size());
4996
4997- MessageVal val = decode_specific(remove_bits);
4998+ DCCLMessageVal val = decode_specific(remove_bits);
4999
5000 bits >>= calc_size();
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: