package pdu import ( "bytes" "encoding/binary" "fmt" ) type ( PDU interface { Encode(*bytes.Buffer) error Decode(*bytes.Buffer) error // Size in bytes Size() int UpdateSize() } PDU_HEADER struct { Command_length uint32 Command_id uint32 Command_status uint32 Sequence_number uint32 } GENERIC_NACK struct { Header *PDU_HEADER } ) // Hmm the header can be partially encoded // As in command_status can just be null // So not 0s, null, non existent, not encoded // So we'll have to maybe set them to nil or something... // Wireshark dump of a submit_sm // See header: 00 00 00 3e (size, 62 bytes), 00 00 00 04 (command_id), status and sequence number are 0 // So they are not encoded // Here the header is 8 bytes, not 16 // 0000 02 00 00 00 45 00 00 66 6f ff 40 00 80 06 00 00 ....E..fo.@..... // 0010 7f 00 00 01 7f 00 00 01 31 4f 0a d7 e8 b0 b1 b5 ........1O...... // 0020 3e 91 d9 dc 50 18 20 fa 2a 1f 00 00 00 00 00 3e >...P. .*......> // 0030 00 00 00 04 00 00 00 00 00 00 00 02 00 00 00 73 ...............s // 0040 6d 70 70 5f 74 65 73 74 5f 31 00 00 00 31 32 33 mpp_test_1...123 // 0050 31 32 33 31 32 33 31 32 33 00 00 00 00 00 00 00 123123123....... // 0060 00 c0 00 06 48 65 6c 6c 6f 21 ....Hello! // I AM NOT RIGHT // Beyond the size and command_id, command_status and sequence_number here are: // 00 00 00 00 (0) 00 00 00 02 (2) // // Another example - bind_transciever: // 0000 02 00 00 00 45 00 00 47 6f fb 40 00 80 06 00 00 ....E..Go.@..... // 0010 7f 00 00 01 7f 00 00 01 31 4f 0a d7 e8 b0 b1 96 ........1O...... // 0020 3e 91 d9 cb 50 18 20 fa df ab 00 00 00 00 00 1f >...P. ......... // 0030 00 00 00 09 00 00 00 00 00 00 00 01 74 65 73 74 ............test // 0040 00 74 65 73 74 00 00 50 00 00 00 .test..P... // 00 00 00 1f - 00 00 00 09 - 00 00 00 00 - 00 00 00 01 (header) // 74 65 73 74 00 - 74 65 73 74 00 - 00 50 00 00 00 // ^system_id ^password ^interface_version // What are the other 0s? // Don't know func (p *PDU_HEADER) Encode(buf *bytes.Buffer) error { if buf == nil { return fmt.Errorf("cannot encode into nil buffer") } binary.Write(buf, binary.BigEndian, p.Command_length) binary.Write(buf, binary.BigEndian, p.Command_id) binary.Write(buf, binary.BigEndian, p.Command_status) binary.Write(buf, binary.BigEndian, p.Sequence_number) return nil } func (p *PDU_HEADER) Decode(buf *bytes.Buffer) error { if buf == nil { return fmt.Errorf("cannot decode nil buffer") } binary.Read(buf, binary.BigEndian, &p.Command_length) binary.Read(buf, binary.BigEndian, &p.Command_id) binary.Read(buf, binary.BigEndian, &p.Command_status) binary.Read(buf, binary.BigEndian, &p.Sequence_number) return nil } func (p *PDU_HEADER) Size() int { return 16 } func (p *PDU_HEADER) UpdateSize() { p.Command_length = uint32(p.Size()) }