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 00039 00040 00041 #include "jaus/core/header.h" 00042 00043 using namespace JAUS; 00044 00045 00051 Header::Header() : mMessageType(MessageType::Normal), 00052 mSequenceNumber(0), 00053 mSize(0), 00054 mPriorityFlag(Priority::Standard), 00055 mBroadcastFlag(Broadcast::None), 00056 mAckNackFlag(AckNack::None), 00057 mControlFlag(DataControl::Single), 00058 mCompressionFlag(Compression::None) 00059 { 00060 } 00061 00062 00068 Header::Header(const Header& header) 00069 { 00070 *this = header; 00071 } 00072 00073 00079 Header::~Header() 00080 { 00081 } 00082 00083 00095 int Header::Write(Packet& packet) const 00096 { 00097 int result = 0; 00098 unsigned int startPos = packet.GetWritePos(); 00099 // Make sure packet is big enought. 00100 packet.SetLength(startPos + mSize); 00101 packet.SetWritePos(startPos); 00102 00103 result += packet.Write((Byte)(mMessageType | (mCompressionFlag << 6))); 00104 result += packet.Write(mSize); 00105 Byte flags = 0; 00106 flags = mControlFlag << 6 | 00107 mAckNackFlag << 4 | 00108 mBroadcastFlag << 2 | 00109 mPriorityFlag; 00110 result += packet.Write(flags); 00111 result += packet.Write(mDestinationID.ToUInt()); 00112 result += packet.Write(mSourceID.ToUInt()); 00113 // Sequence number goes at the end of the packet (this is retarded). 00114 packet.SetWritePos(startPos + mSize - USHORT_SIZE); 00115 result += packet.Write(mSequenceNumber); 00116 packet.SetWritePos(startPos + PayloadOffset); 00117 return result >= MinSize ? result : 0; 00118 } 00119 00120 00130 int Header::Read(const Packet& packet) 00131 { 00132 int result = 0; 00133 00134 Byte type = 0; 00135 Byte flags = 0; 00136 UInt id = 0; 00137 unsigned int startPos = packet.GetReadPos(); 00138 00139 result += packet.Read(type); 00140 mMessageType = type & 0x3F; 00141 mCompressionFlag = type >> 6; 00142 00143 result += packet.Read(mSize); 00144 result += packet.Read(flags); 00145 mControlFlag = (flags >> 6); 00146 mAckNackFlag = (flags >> 4) & 0x03; 00147 mBroadcastFlag = (flags >> 2) & 0x03; 00148 mPriorityFlag = (flags & 0x03); 00149 00150 result += packet.Read(id); 00151 mDestinationID = id; 00152 result += packet.Read(id); 00153 mSourceID = id; 00154 packet.SetReadPos(startPos + mSize - USHORT_SIZE); 00155 result += packet.Read(mSequenceNumber); 00156 // Reset to where the payload is. 00157 packet.SetReadPos(startPos + PayloadOffset); 00158 return result >= MinSize ? result : 0; 00159 } 00160 00161 00172 bool Header::IsValid(std::string* errorMessage) const 00173 { 00174 if(mSourceID.IsValid() == false || 00175 mSourceID.IsBroadcast() || 00176 mDestinationID.IsValid() == false) 00177 { 00178 if(errorMessage) 00179 { 00180 *errorMessage = "Invalid Source or Destination ID"; 00181 } 00182 return false; 00183 } 00184 00185 if(mMessageType > MessageType::Normal) 00186 { 00187 if(errorMessage) 00188 { 00189 *errorMessage = "Invalid Message Type"; 00190 } 00191 return false; 00192 } 00193 00194 if(mSize < MinSize) 00195 { 00196 if(errorMessage) 00197 { 00198 *errorMessage = "Invalid Packet Size"; 00199 } 00200 return false; 00201 } 00202 00203 if(mSize > MinSize && (mAckNackFlag == AckNack::Nack || mAckNackFlag == AckNack::Ack)) 00204 { 00205 if(errorMessage) 00206 { 00207 *errorMessage = "Invalid ACK/NACK Header"; 00208 } 00209 return false; 00210 } 00211 00212 if(mSequenceNumber == 0 && (mControlFlag != DataControl::Single && mControlFlag != DataControl::First)) 00213 { 00214 if(errorMessage) 00215 { 00216 *errorMessage = "Invalid Sequence Number with Data Control Flag"; 00217 } 00218 return false; 00219 } 00220 00221 return true; 00222 } 00223 00224 00230 Header& Header::operator=(const Header& header) 00231 { 00232 if(this != &header) 00233 { 00234 mMessageType = header.mMessageType; 00235 mDestinationID = header.mDestinationID; 00236 mSourceID = header.mSourceID; 00237 mSequenceNumber = header.mSequenceNumber; 00238 mSize = header.mSize; 00239 mPriorityFlag = header.mPriorityFlag; 00240 mBroadcastFlag = header.mBroadcastFlag; 00241 mAckNackFlag = header.mAckNackFlag; 00242 mControlFlag = header.mControlFlag; 00243 mCompressionFlag = header.mCompressionFlag; 00244 } 00245 return *this; 00246 } 00247 00248 /* End of File */