Note: Goby version 1 (shown here) is now considered obsolete. Please use version 2 for new projects, and consider upgrading old projects.

Goby Underwater Autonomy Project  Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
acomms/libdccl/message.h
00001 // copyright 2008, 2009 t. schneider tes@mit.edu
00002 // 
00003 // this file is part of the Dynamic Compact Control Language (DCCL),
00004 // the goby-acomms codec. goby-acomms is a collection of libraries 
00005 // for acoustic underwater networking
00006 //
00007 // This program is free software: you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation, either version 3 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // This software is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this software.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 #ifndef MESSAGE20091211H
00021 #define MESSAGE20091211H
00022 
00023 #include <iostream>
00024 #include <vector>
00025 #include <sstream>
00026 #include <bitset>
00027 #include <algorithm>
00028 #include <set>
00029 #include <map>
00030 
00031 #include <boost/foreach.hpp>
00032 #include <boost/shared_ptr.hpp>
00033 
00034 #include "message_var.h"
00035 #include "message_var_int.h"
00036 #include "message_var_float.h"
00037 #include "message_var_static.h"
00038 #include "message_var_hex.h"
00039 #include "message_var_bool.h"
00040 #include "message_var_string.h"
00041 #include "message_var_enum.h"
00042 #include "message_var_head.h"
00043 
00044 #include "message_publish.h"
00045 #include "dccl_constants.h"
00046 
00047 
00048 namespace goby
00049 {
00050     namespace acomms
00051     {
00052     
00053 // the DCCLMessage itself
00054         class DCCLMessage 
00055         {
00056           public:
00057             DCCLMessage();
00058         
00059             // set
00060             void set_name(const std::string& name) {name_ = name;}
00061 
00062             void set_id(unsigned id)
00063             { id_ = id; }
00064             template<typename T> void set_id(const T& t)
00065             { set_id(util::as<unsigned>(t)); }
00066         
00067             void set_trigger(const std::string& trigger_type) 
00068             { trigger_type_ = trigger_type; }
00069         
00070             void set_trigger_var(const std::string& trigger_var)
00071             { trigger_var_ = trigger_var; }
00072 
00073             void set_trigger_time(double trigger_time)
00074             { trigger_time_ = trigger_time; }
00075             template<typename T> void set_trigger_time(const T& t)
00076             { set_trigger_time(util::as<double>(t)); }        
00077         
00078             void set_trigger_mandatory(const std::string& trigger_mandatory)
00079             { trigger_mandatory_ = trigger_mandatory; }
00080     
00081             void set_in_var(const std::string& in_var)
00082             { in_var_ = in_var; }
00083 
00084             void set_out_var(const std::string& out_var)
00085             { out_var_ = out_var; }
00086 
00087             void set_size(unsigned size)
00088             { size_ = size; }
00089 
00090             template<typename T> void set_size(const T& t)
00091             { set_size(util::as<unsigned>(t)); }
00092 
00093             void set_repeat_enabled(unsigned repeat_enabled)
00094             { repeat_enabled_ = repeat_enabled; }
00095             template<typename T> void set_repeat_enabled(const T& t)
00096             { set_repeat_enabled(util::as<unsigned>(t)); }
00097         
00098             void add_message_var(const std::string& type);        
00099             void add_publish();
00100 
00101             //get
00102             std::string name() const              { return name_; }
00103             unsigned id() const                   { return id_; }
00104             unsigned size() const                 { return size_; }
00105             std::string trigger_var() const       { return trigger_var_; }
00106             std::string trigger_mandatory() const { return trigger_mandatory_; }
00107             double trigger_time() const           { return trigger_time_; }
00108             unsigned trigger_number() const       { return trigger_number_; }
00109             std::string trigger_type() const      { return trigger_type_; }
00110             std::string in_var() const            { return in_var_; }
00111             std::string out_var() const           { return out_var_; }
00112             bool repeat_enabled() const       { return repeat_enabled_; }
00113             unsigned repeat() const               { return repeat_; }
00114 
00115             DCCLMessageVar& last_message_var()        { return *layout_.back(); }
00116             DCCLMessageVar& header_var(acomms::DCCLHeaderPart p) { return *header_[p]; }
00117             DCCLPublish& last_publish()               { return publishes_.back(); }        
00118         
00119             std::vector< boost::shared_ptr<DCCLMessageVar> >& layout()     { return layout_; }
00120             std::vector< boost::shared_ptr<DCCLMessageVar> >& header()     { return header_; }
00121 
00122             const std::vector< boost::shared_ptr<DCCLMessageVar> >& layout_const() const { return layout_; }
00123             const std::vector< boost::shared_ptr<DCCLMessageVar> >& header_const() const { return header_; }
00124 
00125             std::vector<DCCLPublish>& publishes()                      { return publishes_; }
00126 
00127             std::set<std::string> get_pubsub_encode_vars();
00128             std::set<std::string> get_pubsub_decode_vars();
00129             std::set<std::string> get_pubsub_src_vars();
00130             std::set<std::string> get_pubsub_all_vars();
00131 
00132             boost::shared_ptr<DCCLMessageVar> name2message_var(const std::string& name) const;
00133         
00134         
00135             //other
00136             std::string get_display() const;
00137             std::string get_short_display() const;
00138             std::map<std::string, std::string> message_var_names() const;
00139             void preprocess();
00140             void set_repeat_array_length();
00141             unsigned calc_total_size();
00142         
00143             void set_head_defaults(std::map<std::string, std::vector<DCCLMessageVal> >& in, unsigned modem_id);
00144         
00145     
00146             void head_encode(std::string& head, std::map<std::string, std::vector<DCCLMessageVal> >& in);
00147             void head_decode(const std::string& head, std::map<std::string, std::vector<DCCLMessageVal> >& out);
00148         
00149             void body_encode(std::string& body, std::map<std::string, std::vector<DCCLMessageVal> >& in);
00150             void body_decode(std::string& body, std::map<std::string, std::vector<DCCLMessageVal> >& out);
00151 
00152             // increment, means increase trigger number
00153             // prefix ++DCCLMessage
00154             DCCLMessage& operator++()
00155             { ++trigger_number_; return(*this); }
00156             // postfix DCCLMessage++
00157             const DCCLMessage operator++(int)
00158             { DCCLMessage tmp(*this); ++(*this); return tmp;}
00159         
00160         
00161           private:
00162             unsigned bytes_head() const
00163             { return acomms::DCCL_NUM_HEADER_BYTES; }
00164             unsigned bits_head() const
00165             { return bytes2bits(acomms::DCCL_NUM_HEADER_BYTES); }
00166 
00167             // more efficient way to do ceil(total_bits / 8)
00168             // to get the number of bytes rounded up.
00169         
00170             enum { BYTE_MASK = 7 }; // 00000111
00171             unsigned used_bytes_body() const
00172             {
00173                 return (body_bits_& BYTE_MASK) ?
00174                     bits2bytes(body_bits_) + 1 :
00175                     bits2bytes(body_bits_);
00176             }
00177 
00178             unsigned used_bytes_total() const
00179             { return bytes_head() + used_bytes_body(); }
00180 
00181             unsigned used_bits_body() const
00182             { return body_bits_; }
00183         
00184             unsigned used_bits_total() const
00185             { return bits_head() + used_bits_body(); }
00186         
00187             unsigned requested_bytes_body() const
00188             { return size_ - acomms::DCCL_NUM_HEADER_BYTES; }
00189 
00190             unsigned requested_bytes_total() const
00191             { return size_; }
00192 
00193             unsigned requested_bits_body() const
00194             { return bytes2bits(size_ - acomms::DCCL_NUM_HEADER_BYTES); } 
00195 
00196             unsigned requested_bits_total() const
00197             { return bytes2bits(size_); }
00198         
00199         
00200           private:
00201             // total request size of message, e.g. 32 bytes
00202             unsigned size_;
00203         
00204             unsigned trigger_number_;
00205             // actual used bits in body part of message (not including header bits)
00206             unsigned body_bits_;
00207 
00208             unsigned id_;
00209             unsigned modem_id_;
00210             double trigger_time_;        
00211 
00212             bool repeat_enabled_;
00213             unsigned repeat_;
00214         
00215             std::string name_;
00216             std::string trigger_type_;
00217             std::string trigger_var_;
00218             std::string trigger_mandatory_;
00219             std::string in_var_;
00220             std::string out_var_;
00221 
00222             std::vector< boost::shared_ptr<DCCLMessageVar> > layout_;
00223             std::vector< boost::shared_ptr<DCCLMessageVar> > header_;
00224         
00225         
00226             std::vector<DCCLPublish> publishes_;
00227 
00228         };
00229 
00230 
00231         inline void bitset2string(const boost::dynamic_bitset<unsigned char>& body_bits,
00232                                   std::string& body)
00233         {
00234             body.resize(body_bits.num_blocks()); // resize the string to fit the bitset
00235             to_block_range(body_bits, body.rbegin());
00236         }
00237     
00238         inline void string2bitset(boost::dynamic_bitset<unsigned char>& body_bits,
00239                                   const std::string& body)
00240         {
00241             from_block_range(body.rbegin(), body.rend(), body_bits);
00242         }
00243 
00244 
00245         std::ostream& operator<< (std::ostream& out, const DCCLMessage& message);
00246     }
00247 }
00248 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends