UniSet  2.2.1
UDPPacket.h
00001 #ifndef UDPPacket_H_
00002 #define UDPPacket_H_
00003 // -----------------------------------------------------------------------------
00004 #include <list>
00005 #include <limits>
00006 #include <ostream>
00007 #include "UniSetTypes.h"
00008 // -----------------------------------------------------------------------------
00009 namespace UniSetUDP
00010 {
00022     const unsigned int UNETUDP_MAGICNUM = 0x1337A1D; // идентификатор протокола
00023 
00024     struct UDPHeader
00025     {
00026         UDPHeader(): magic(UNETUDP_MAGICNUM), num(0), nodeID(0), procID(0), dcount(0), acount(0) {}
00027         unsigned int magic;
00028         unsigned long num;
00029         long nodeID;
00030         long procID;
00031 
00033         size_t dcount; 
00034         size_t acount; 
00036         friend std::ostream& operator<<( std::ostream& os, UDPHeader& p );
00037         friend std::ostream& operator<<( std::ostream& os, UDPHeader* p );
00038     } __attribute__((packed));
00039 
00040     const size_t MaxPacketNum = std::numeric_limits<size_t>::max();
00041 
00042     struct UDPAData
00043     {
00044         UDPAData(): id(UniSetTypes::DefaultObjectId), val(0) {}
00045         UDPAData(long id, long val): id(id), val(val) {}
00046 
00047         long id;
00048         long val;
00049 
00050         friend std::ostream& operator<<( std::ostream& os, UDPAData& p );
00051     } __attribute__((packed));
00052 
00053     // Хотелось бы не вылезать за общий размер посылаемых пакетов 8192. (550,900 --> 8133)
00054     // ------
00055     // временное резрешение на A=800,D=5000! DI/DO
00056     // 1500*8 + 5000*4 + 5000/8 = 32625 байт максимальный размер данных + служебные заголовки
00057 
00058     static const size_t MaxACount = 1500;
00059     static const size_t MaxDCount = 5000;
00060     static const size_t MaxDDataCount = 1 + MaxDCount / 8 * sizeof(unsigned char);
00061 
00062     struct UDPPacket
00063     {
00064         UDPPacket(): len(0) {}
00065 
00066         size_t len;
00067         unsigned char data[ sizeof(UDPHeader) + MaxDCount * sizeof(long) + MaxDDataCount + MaxACount * sizeof(UDPAData) ];
00068     } __attribute__((packed));
00069 
00070     static const int MaxDataLen = sizeof(UDPPacket);
00071 
00072     struct UDPMessage:
00073         public UDPHeader
00074     {
00075         UDPMessage();
00076 
00077         explicit UDPMessage( UDPPacket& p );
00078         size_t transport_msg( UDPPacket& p );
00079         static size_t getMessage( UDPMessage& m, UDPPacket& p );
00080 
00081         size_t addDData( long id, bool val );
00082         bool setDData( size_t index, bool val );
00083         long dID( size_t index ) const;
00084         bool dValue( size_t index ) const;
00085 
00086         // функции addAData возвращают индекс, по которому потом можно напрямую писать при помощи setAData(index)
00087         size_t addAData( const UDPAData& dat );
00088         size_t addAData( long id, long val );
00089         bool setAData( size_t index, long val );
00090 
00091         long getDataID( ) const; 
00092         inline bool isAFull() const
00093         {
00094             return (acount >= MaxACount);
00095         }
00096         inline bool isDFull() const
00097         {
00098             return (dcount >= MaxDCount);
00099         }
00100 
00101         inline bool isFull() const
00102         {
00103             return !((dcount < MaxDCount) && (acount < MaxACount));
00104         }
00105         inline size_t dsize() const
00106         {
00107             return dcount;
00108         }
00109         inline size_t asize() const
00110         {
00111             return acount;
00112         }
00113         unsigned short getDataCRC();
00114 
00115         // количество байт в пакете с булевыми переменными...
00116         size_t d_byte() const
00117         {
00118             return dcount * sizeof(long) + dcount;
00119         }
00120 
00121         UDPAData a_dat[MaxACount]; 
00122         long d_id[MaxDCount];      
00123         unsigned char d_dat[MaxDDataCount];  
00125         friend std::ostream& operator<<( std::ostream& os, UDPMessage& p );
00126     };
00127 
00128     unsigned short makeCRC( unsigned char* buf, size_t len );
00129 }
00130 // -----------------------------------------------------------------------------
00131 #endif // UDPPacket_H_
00132 // -----------------------------------------------------------------------------