package packet import "errors" // MessageBoundary flags for where this packet falls within a message type MessageBoundary uint8 const ( // MbFirst is the first packet in a multi-packet message MbFirst MessageBoundary = 2 // MbLast is the last packet in a multi-packet message MbLast MessageBoundary = 1 // MbOnly is the only packet in this message MbOnly MessageBoundary = 3 // MbMiddle is neither the first nor last packet in a multi-packet message MbMiddle MessageBoundary = 0 ) // DataPacket is a UDT packet containing message data type DataPacket struct { Seq PacketID // packet sequence number (top bit = 0) msg uint32 // message sequence number (top three bits = message control) ts uint32 // timestamp when message is sent DstSockID uint32 // destination socket Data []byte // payload } // PacketType returns the packetType associated with this packet func (dp *DataPacket) PacketType() PacketType { return ptData } // SetHeader sets the fields common to UDT data packets func (dp *DataPacket) SetHeader(destSockID uint32, ts uint32) { dp.DstSockID = destSockID dp.ts = ts } // SocketID sets the Socket ID for this data packet func (dp *DataPacket) SocketID() (sockID uint32) { return dp.DstSockID } // SendTime sets the timestamp field for this data packet func (dp *DataPacket) SendTime() (ts uint32) { return dp.ts } // SetMessageData sets the message field for this data packet func (dp *DataPacket) SetMessageData(boundary MessageBoundary, order bool, msg uint32) { var iOrder uint32 = 0 if order { iOrder = 0x20000000 } dp.msg = (uint32(boundary) << 30) | iOrder | (msg & 0x1FFFFFFF) } // GetMessageData returns the message field for this data packet func (dp *DataPacket) GetMessageData() (MessageBoundary, bool, uint32) { return MessageBoundary(dp.msg >> 30), (dp.msg & 0x20000000) != 0, dp.msg & 0x1FFFFFFF } // WriteTo writes this packet to the provided buffer, returning the length of the packet func (dp *DataPacket) WriteTo(buf []byte) (uint, error) { l := len(buf) ol := 16 + len(dp.Data) if l < ol { return 0, errors.New("write data packet too small") } endianness.PutUint32(buf[0:4], dp.Seq.Seq&0x7FFFFFFF) endianness.PutUint32(buf[4:8], dp.msg) endianness.PutUint32(buf[8:12], dp.ts) endianness.PutUint32(buf[12:16], dp.DstSockID) copy(buf[16:], dp.Data) return uint(ol), nil } func (dp *DataPacket) readFrom(data []byte) (err error) { l := len(data) if l < 16 { return errors.New("read data packet too small") } //dp.seq = endianness.Uint32(data[0:4]) dp.msg = endianness.Uint32(data[4:8]) dp.ts = endianness.Uint32(data[8:12]) dp.DstSockID = endianness.Uint32(data[12:16]) // The data is whatever is what comes after the 16 bytes of header dp.Data = make([]byte, l-16) copy(dp.Data, data[16:]) return }