package pdu import ( "bytes" "encoding/ascii85" "encoding/binary" "fmt" "log" "github.com/warthog618/sms/encoding/gsm7" ) 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{} ) 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 asciiEncoder := ascii85.NewEncoder(buf) // TODO: Implement encodings bsed on p.data_coding messageEncoder := gsm7.NewEncoder() p.header.Encode(buf) n, err := asciiEncoder.Write([]byte("OOO")) if err != nil { return err } log.Println(n) // asciiEncoder.Write([]byte(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.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.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.Write(NULL_ARR) asciiEncoder.Write([]byte(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)) if err != nil { return err } buf.Write(encodedMsg) 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 // 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 } return size } func (p *SUBMIT_SM) UpdateSize() { p.header.command_length = uint32(p.Size()) p.sm_length = byte(len(p.short_message)) }