• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

RealmProtocol.h

Go to the documentation of this file.
00001 #ifndef __REALM_PROTOCOL__
00002 #define __REALM_PROTOCOL__
00003 
00004 #include <string>
00005 #include <vector>
00006 #ifdef _MSC_VER
00007 #include "msc_stdint.h"
00008 #else
00009 #include <stdint.h>
00010 #endif
00011 #include <boost/shared_ptr.hpp>
00012 #if defined(HAVE_BOOST_ASIO_HPP)
00013 # include <boost/asio.hpp>
00014 #else
00015 # include <asio.hpp>
00016 #endif
00017 
00018 namespace realm {
00019 
00020 namespace protocol {
00021 
00022 enum handshake_response {
00023     HANDSHAKE_RESERVED = 0,             /* 0x00: reserved */
00024     HANDSHAKE_OK,                       /* 0x01: Login OK */
00025     HANDSHAKE_BAD_IDENTIFIER,           /* 0x02: Unrecognized protocol magic */
00026     HANDSHAKE_UNSUPPORTED_PROTOCOL,     /* 0x03: Unsupported protocol version */
00027     HANDSHAKE_INVALID_COOKIE            /* 0x04: Invalid cookie */
00028 };
00029 
00030 }
00031 
00032 namespace protocolv1 {
00033 
00034 class Packet;
00035 typedef boost::shared_ptr<Packet> PacketPtr;
00036 typedef boost::shared_ptr<asio::streambuf> StreamPtr;
00037 
00038 // the packet type values must match up the corresponding body_size in
00039 // RealmProtocol.cpp (ugly, but it's fast)!
00040 enum packet_type {
00041     PACKET_RESERVED = 0x00,
00042     PACKET_ROUTE, // 0x01
00043     PACKET_DELIVER, // 0x02
00044     PACKET_USERJOINED, // 0x03
00045     PACKET_USERLEFT, // 0x04
00046     PACKET_SESSIONTAKEOVER, // 0x05
00047     __LAST_PACKET__
00048 };
00049 
00050 class Packet {
00051 public:
00052     virtual ~Packet() {}
00053 
00054     static PacketPtr construct(uint8_t type);
00055 
00056     static bool s_valid(unsigned char type);
00057     static uint32_t s_body_size(unsigned char type);
00058 
00059     // Should be overwritten when the packet size is variable
00060     // Returns: the minimal number of bytes additionally needed before we can
00061     // re-assess if the packet is complete or not; -1 on error.
00062     // Note that this several complete() calls on the same buffer may return
00063     // several times with a value > 0. Only when complete() returns 0 the
00064     // buffer contains enough information to call parse().
00065     virtual int complete(const char* buf, size_t size);
00066 
00067     // should be overwritten when the packet 'has a body'
00068     // returns: the number of bytes read, -1 on error
00069     virtual int parse(const char* /*buf*/, size_t /*size*/) {
00070         return 0;
00071     }
00072 
00073     const uint8_t & type() const {
00074         return m_type;
00075     }
00076 
00077 protected:
00078     Packet(uint8_t type);
00079 
00080 private:
00081     uint8_t m_type;
00082 };
00083 
00084 class PayloadPacket : public Packet {
00085 public:
00086     virtual int complete(const char* buf, size_t size);
00087     virtual int parse(const char* buf, size_t size);
00088 
00089     const uint32_t& getPayloadSize() const {
00090         return m_payload_size;
00091     }
00092 protected:
00093     PayloadPacket(uint8_t t, uint32_t min_payload_size, uint32_t payload_size)
00094         : Packet(t),
00095         m_min_payload_size(min_payload_size),
00096         m_payload_size(payload_size)
00097     {}
00098     PayloadPacket(uint8_t t, uint32_t min_payload_size)
00099         : Packet(t),
00100         m_min_payload_size(min_payload_size),
00101         m_payload_size(0)
00102     {}
00103 private:
00104     uint32_t m_min_payload_size;
00105     uint32_t m_payload_size;
00106 };
00107 
00108 class RoutingPacket : public PayloadPacket {
00109 public:
00110     RoutingPacket();
00111     RoutingPacket(std::vector<uint8_t>& connection_ids, boost::shared_ptr<std::string> msg);
00112     virtual int parse(const char* buf, size_t size);
00113 
00114     const uint8_t& getAddressCount() const {
00115         return m_address_count;
00116     }
00117 
00118     const std::vector<uint8_t>& getConnectionIds() const {
00119         return m_connection_ids;
00120     }
00121 
00122     boost::shared_ptr<std::string> getMessage() const {
00123         return m_msg;
00124     }
00125 
00126 private:
00127     uint8_t                 m_address_count;    // a bit redundant (as it can be derived from m_connection_ids.size()),
00128                                                 // but it's convenient to be able to get a reference to this value
00129                                                 // when sending this packet
00130     std::vector<uint8_t>    m_connection_ids;
00131     boost::shared_ptr<std::string> m_msg;
00132 };
00133 
00134 class DeliverPacket : public PayloadPacket {
00135 public:
00136     DeliverPacket();
00137     DeliverPacket(uint8_t connection_id, boost::shared_ptr<std::string> msg);
00138     virtual int parse(const char* buf, size_t size);
00139 
00140     const uint8_t& getConnectionId() const {
00141         return m_connection_id;
00142     }
00143 
00144     boost::shared_ptr<std::string> getMessage() const {
00145         return m_msg;
00146     }
00147 
00148 private:
00149     uint8_t         m_connection_id;
00150     boost::shared_ptr<std::string>  m_msg;
00151 };
00152 
00153 class UserJoinedPacket : public PayloadPacket {
00154 public:
00155     UserJoinedPacket();
00156     UserJoinedPacket(uint8_t connection_id, bool master, boost::shared_ptr<std::string> userinfo);
00157     virtual int parse(const char* buf, size_t size);
00158 
00159     const uint8_t& getConnectionId() const {
00160         return m_connection_id;
00161     }
00162 
00163     const uint8_t& isMaster() const {
00164         return m_master;
00165     }
00166 
00167     boost::shared_ptr<std::string> getUserInfo() const {
00168         return m_userinfo;
00169     }
00170 
00171 private:
00172     uint8_t         m_connection_id;
00173     uint8_t         m_master;
00174     boost::shared_ptr<std::string>      m_userinfo;
00175 };
00176 
00177 class UserLeftPacket : public Packet {
00178 public:
00179     UserLeftPacket();
00180     UserLeftPacket(uint8_t connection_id);
00181     virtual int parse(const char* buf, size_t size);
00182 
00183     const uint8_t& getConnectionId() const {
00184         return m_connection_id;
00185     }
00186 
00187 private:
00188     uint8_t m_connection_id;
00189 };
00190 
00191 class SessionTakeOverPacket : public Packet {
00192 public:
00193     SessionTakeOverPacket();
00194 };
00195 
00196 }
00197 }
00198 
00199 #endif /* __REALM_PROTOCOL__ */

Generated on Sun Feb 14 2021 for AbiWord by  doxygen 1.7.1