00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef TCPDEVICE_HPP_
00039 #define TCPDEVICE_HPP_
00040 #include <labust/tritech/tritechfwd.hpp>
00041 #include <labust/preprocessor/mem_serialized_struct.hpp>
00042
00043 #include <boost/asio.hpp>
00044 #include <boost/thread.hpp>
00045
00046
00047 #include <string>
00048 #include <map>
00049
00050 namespace labust
00051 {
00052 namespace tritech
00053 {
00054 struct TCPRequest
00055 {
00056 enum {default_size = 23};
00057 enum client_server_command {scAttachToNode = 1, scDetachFromNode = 7};
00058 enum app_classes {atNull=0, atGeneric = 15, atAMNAV = 26, atMiniAttSen = 33};
00059 enum con_type {rctHead = 1};
00060
00061 TCPRequest():
00062 size(default_size),
00063 node(labust::tritech::Nodes::USBL),
00064 command(scAttachToNode),
00065 priority(129),
00066 app_class(atAMNAV),
00067 type(rctHead){};
00068
00069 uint16_t size;
00070 uint8_t node, command, priority, app_class, type;
00071 uint8_t guid[16];
00072 };
00073
00074 struct TCONMsg
00075 {
00076 enum {default_size = 14};
00077 TCONMsg():
00078 size(default_size),
00079 time(0),
00080 txNode(255),
00081 rxNode(255),
00082 msgType(0),
00083 seq(128),
00084 node(255),
00085 data(new boost::asio::streambuf()){};
00086
00090 inline void setup()
00091 {
00092 this->size = data->size()+ default_size;
00093 }
00094
00095 uint16_t size;
00096 double time;
00097 uint8_t txNode, rxNode;
00098 uint8_t msgType;
00099 uint8_t seq;
00100 uint8_t node;
00101
00102 StreamPtr data;
00103 };
00104
00110 class TCPDevice
00111 {
00112 enum {Sync,Header,Data};
00113 enum {ringBufferSize = 7};
00114 public:
00118 typedef boost::function<void (TCONMsgPtr)> FunctorType;
00122 typedef std::map<int,FunctorType> HandlerMap;
00123
00127 TCPDevice(const std::string& address, uint32_t port,
00128 uint8_t device = Nodes::USBL,
00129 uint8_t app_class = TCPRequest::atAMNAV,
00130 uint8_t priority = 129);
00134 ~TCPDevice();
00135
00139 void send(TCONMsgPtr message);
00143 inline void registerHandlers(const HandlerMap& map)
00144 {
00145 this->handlers.insert(map.begin(),map.end());
00146 }
00147
00148 private:
00152 void _setup();
00156 void registerDevice(bool register=true);
00160 void onSync(const boost::system::error_code& error, std::size_t bytes_transferred);
00164 void onHeader(StreamPtr data, const boost::system::error_code& error, std::size_t bytes_transferred);
00168 void onData(const boost::system::error_code& error, std::size_t bytes_transferred);
00172 void start_receive(uint8_t state);
00173
00177 boost::asio::io_service io;
00181 boost::asio::ip::tcp::socket socket;
00185 std::string address;
00189 uint32_t port;
00193 boost::asio::streambuf input;
00197 std::vector<uint8_t> ringBuffer;
00201 boost::thread service;
00205 HandlerMap handlers;
00209 uint8_t device,app_class,priority;
00210 };
00211 }
00212 }
00213
00215 PP_LABUST_MAKE_BOOST_SERIALIZATOR(labust::tritech::TCPRequest,
00216 (uint16_t, size)
00217 (uint8_t, node)
00218 (uint8_t, command)
00219 (uint8_t, priority)
00220 (uint8_t, app_class)
00221 (uint8_t, type))
00222 BOOST_CLASS_IMPLEMENTATION(labust::tritech::TCPRequest, boost::serialization::primitive_type)
00223
00224 PP_LABUST_MAKE_BOOST_SERIALIZATOR_CLEAN(labust::tritech::TCONMsg,
00225 (uint16_t, size)
00226 (double, time)
00227 (uint8_t, txNode)
00228 (uint8_t, rxNode)
00229 (uint8_t, msgType)
00230 (uint8_t, seq)
00231 (uint8_t, node))
00232
00233
00234 #endif