package pdu import ( "bytes" "encoding/binary" "fmt" "smpptester/encoding" ) type ( SUBMIT_SM struct { Header *PDU_HEADER Service_type string Source_addr_ton byte Source_addr_npi byte Source_addr string Dest_addr_ton byte Dest_addr_npi byte Destination_addr string Esm_class byte Protocol_id byte Priority_flag byte Schedule_delivery_time string Validity_period string Registered_delivery byte Replace_if_present byte Data_coding byte Sm_default_msg_id byte Sm_length byte Short_message string // user_message_reference uint16 // source_port uint16 // source_addr_subunit byte // destination_port uint16 // dest_addr_subunit byte // sar_msg_ref_num uint16 // sar_total_segments byte // sar_segment_seqnum byte // more_messages_to_send byte // payload_type byte // message_payload string // privacy_indicator byte // callback_num string // callback_num_pres byte // callback_num_atag string // source_subaddress string // dest_subaddress string // user_response_code byte // display_time byte // sms_signal byte // ms_validity byte // ms_msg_wait_facilities byte // number_of_messages byte // alert_on_message_delivery byte // language_indicator byte // its_reply_type byte // its_session_info byte // ussd_service_op byte } SUBMIT_SM_RESP struct { Header *PDU_HEADER Message_id string } 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") } messageEncoder := p.GetEncoder() p.Header.Encode(buf) // 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) 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) 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) buf.WriteString(p.Schedule_delivery_time) buf.Write(NULL_ARR) 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) err := messageEncoder.Encode(&p.Short_message, buf) if err != nil { return err } return nil } func (p *SUBMIT_SM) Decode(buf *bytes.Buffer) error { if buf == nil { return fmt.Errorf("cannot decode nil buffer") } return nil } func (p *SUBMIT_SM) Size() int { var size int size += p.Header.Size() size += 1 + len(p.Service_type) size += 1 // source_addr_ton size += 1 // source_addr_npi size += 1 + len(p.Source_addr) size += 1 // dest_addr_ton size += 1 // dest_addr_npi size += 1 + len(p.Destination_addr) size += 1 // esm_class size += 1 // protocol_id size += 1 // priority_flag size += 1 + len(p.Schedule_delivery_time) size += 1 + len(p.Validity_period) size += 1 // registered_delivery size += 1 // replace_if_present size += 1 // data_coding size += 1 // sm_default_msg_id size += 1 // sm_length 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(p.GetEncoder().EncodesInto(&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{} } }