diff --git a/pdu/submit.go b/pdu/submit.go index 1cc2825..3c1957f 100644 --- a/pdu/submit.go +++ b/pdu/submit.go @@ -2,12 +2,10 @@ package pdu import ( "bytes" - "encoding/ascii85" "encoding/binary" "fmt" - "log" - "github.com/warthog618/sms/encoding/gsm7" + "smpptester/encoding" ) type ( @@ -67,55 +65,43 @@ type ( SUBMIT_MULTI struct{} SUBMIT_MULTI_RESP struct{} ) +// See https://www.codeproject.com/Tips/470755/Encoding-Decoding-7-bit-User-Data-for-SMS-PDU-PDU +// Another great site: https://doubleblak.com/blogPost.php?k=7bitpdu func (p *SUBMIT_SM) Encode(buf *bytes.Buffer) error { if buf == nil { return fmt.Errorf("cannot encode into nil buffer") } - // This won't do... - // TODO: Implement your own encoders and shit - // ASCII is easy - // UCS2 should also be fairly easy, use uint16 or something - // GSM7 will not be easy - // See https://www.codeproject.com/Tips/470755/Encoding-Decoding-7-bit-User-Data-for-SMS-PDU-PDU - // Another great site: https://doubleblak.com/blogPost.php?k=7bitpdu - asciiEncoder := ascii85.NewEncoder(buf) - // TODO: Implement encodings bsed on p.data_coding - messageEncoder := gsm7.NewEncoder() + messageEncoder := p.GetEncoder() p.header.Encode(buf) - n, err := asciiEncoder.Write([]byte("OOO")) - if err != nil { - return err - } - log.Println(n) - // asciiEncoder.Write([]byte(p.service_type)) + // These should be ASCII but UTF8 is a superset of ASCII so hopefully this'll be fine + buf.WriteString(p.service_type) buf.Write(NULL_ARR) binary.Write(buf, binary.BigEndian, p.source_addr_ton) binary.Write(buf, binary.BigEndian, p.source_addr_npi) - asciiEncoder.Write([]byte(p.source_addr)) + buf.WriteString(p.source_addr) buf.Write(NULL_ARR) binary.Write(buf, binary.BigEndian, p.dest_addr_ton) binary.Write(buf, binary.BigEndian, p.dest_addr_npi) - asciiEncoder.Write([]byte(p.destination_addr)) + buf.WriteString(p.destination_addr) buf.Write(NULL_ARR) binary.Write(buf, binary.BigEndian, p.esm_class) binary.Write(buf, binary.BigEndian, p.protocol_id) binary.Write(buf, binary.BigEndian, p.priority_flag) - asciiEncoder.Write([]byte(p.schedule_delivery_time)) + buf.WriteString(p.schedule_delivery_time) buf.Write(NULL_ARR) - asciiEncoder.Write([]byte(p.validity_period)) + buf.WriteString(p.validity_period) buf.Write(NULL_ARR) binary.Write(buf, binary.BigEndian, p.registered_delivery) binary.Write(buf, binary.BigEndian, p.replace_if_present) binary.Write(buf, binary.BigEndian, p.data_coding) binary.Write(buf, binary.BigEndian, p.sm_default_msg_id) binary.Write(buf, binary.BigEndian, p.sm_length) - encodedMsg, err := messageEncoder.Encode([]byte(p.short_message)) + err := messageEncoder.Encode(&p.short_message, buf) if err != nil { return err } - buf.Write(encodedMsg) return nil } func (p *SUBMIT_SM) Decode(buf *bytes.Buffer) error { @@ -144,20 +130,24 @@ func (p *SUBMIT_SM) Size() int { size += 1 // data_coding size += 1 // sm_default_msg_id size += 1 // sm_length - // TODO: Handle encoding based on p.data_coding - switch p.data_coding { - case 0b00000000: // GSM7 - size += (len(p.short_message)*7 + 8 - 1) / 8 - case 0b00000001: // ASCII - size += len(p.short_message) - case 0b00000011: // LATIN1 - size += len(p.short_message) - case 0b00001000: // UCS2 - size += len(p.short_message) * 2 - } + size += p.GetEncoder().EncodesInto(&p.short_message) return size } func (p *SUBMIT_SM) UpdateSize() { p.header.command_length = uint32(p.Size()) p.sm_length = byte(len(p.short_message)) } +func (p *SUBMIT_SM) GetEncoder() encoding.Coder { + switch p.data_coding { + case 0b00000000: // GSM7 + return &encoding.GSM7Coder{} + case 0b00000001: // ASCII + return &encoding.ASCIICoder{} + // case 0b00000011: // LATIN1 + // return &encoding.LATIN1Coder{} + case 0b00001000: // UCS2 + return &encoding.UCS2Coder{} + default: + return &encoding.ASCIICoder{} + } +} diff --git a/pdu/submit_test.go b/pdu/submit_test.go index 797b9e9..1ae1cd6 100644 --- a/pdu/submit_test.go +++ b/pdu/submit_test.go @@ -39,7 +39,7 @@ func TestEncodeFunctionCorrectlyEncodesAllFields(t *testing.T) { t.Fatalf("expected no error, got %v", err) } - expected := []byte{0,0,0,107,0,0,0,4,0,0,0,0,0,5,196,163,79,77,86,52,0,3,1,56,48,51,54,50,0,1,1,56,49,50,51,52,53,48,48,49,48,48,48,0,0,0,0,0,49,56,48,49,48,53,49,50,48,48,48,48,48,48,52,43,0,1,0,0,0,37,82,101,112,108,121,32,89,101,115,32,116,111,32,111,112,116,32,105,110,32,111,114,32,78,111,32,116,111,32,111,112,116,32,111,117,116,46} + expected := []byte{0, 0, 0, 107, 0, 0, 0, 4, 0, 0, 0, 0, 0, 5, 196, 163, 79, 77, 86, 52, 0, 3, 1, 56, 48, 51, 54, 50, 0, 1, 1, 56, 49, 50, 51, 52, 53, 48, 48, 49, 48, 48, 48, 0, 0, 0, 0, 0, 49, 56, 48, 49, 48, 53, 49, 50, 48, 48, 48, 48, 48, 48, 52, 43, 0, 1, 0, 1, 0, 37, 82, 101, 112, 108, 121, 32, 89, 101, 115, 32, 116, 111, 32, 111, 112, 116, 32, 105, 110, 32, 111, 114, 32, 78, 111, 32, 116, 111, 32, 111, 112, 116, 32, 111, 117, 116, 46} if !bytes.Equal(buf.Bytes(), expected) { t.Fatalf("expected %v, got %v", expected, buf.Bytes()) }