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{} } }