diff --git a/lib/biju/pdu.rb b/lib/biju/pdu.rb index afbf491..e0c1faf 100644 --- a/lib/biju/pdu.rb +++ b/lib/biju/pdu.rb @@ -4,6 +4,7 @@ require 'biju/pdu/encoding/ucs2' require 'biju/pdu/user_data' require 'biju/pdu/data_coding_scheme' +require 'biju/pdu/first_octet' require 'biju/pdu/timestamp' require 'biju/pdu/phone_number' require 'biju/pdu/type_of_address' @@ -13,15 +14,21 @@ module Biju def self.encode(phone_number, message, type_of_address: :international) phone_number = PhoneNumber.encode(phone_number) user_data = UserData.encode(message) + first_octet = FirstOctet.new.message_type_indicator!(:sms_submit) [ + # Length of SMSC information + # 0 means the SMSC stored in the phone should be used + '00', + # First octet + '%02x' % first_octet.binary, + # TP-Message-Reference '00', - '01', - '00', # TP-Message-Reference "%02x" % phone_number.length, "%02x" % phone_number.type_of_address.hex, phone_number.number, - '00', # TP-PID: Protocol identifier + # TP-PID: Protocol identifier + '00', "%02x" % user_data.encoding.hex, "%02x" % user_data.length, user_data.message diff --git a/lib/biju/pdu/first_octet.rb b/lib/biju/pdu/first_octet.rb new file mode 100644 index 0000000..3296afd --- /dev/null +++ b/lib/biju/pdu/first_octet.rb @@ -0,0 +1,68 @@ +module Biju + module PDU + class FirstOctet + FIRST_OCTET = { + reply_path: 0b10000000, + user_data_header: 0b01000000, + status_report_request: 0b00100000, + validity_period_format: 0b00011000, + reject_duplicates: 0b00000100, + message_type_indicator: 0b00000011, + } + + MESSAGE_TYPE_INDICATOR = { + sms_deliver: 0b00000000, + sms_submit: 0b00000001, + sms_status: 0b00000010, + reserved: 0b00000011, + } + + VALIDITY_PERIOD_FORMAT = { + not_present: 0b00000000, + reserved: 0b00001000, + relative: 0b00010000, + absolute: 0b00011000, + } + + attr_accessor :binary + + def initialize(first_octet = 0) + self.binary = first_octet + end + + def get(field) + binary & FIRST_OCTET[field] + end + + [:reply_path, :user_data_header, :status_report_request, + :reject_duplicates].each do |sym| + define_method :"#{sym}?" do + get(sym) > 0 + end + + define_method :"#{sym}!" do |value = true| + if value + self.binary |= FIRST_OCTET[sym] + else + self.binary &= (FIRST_OCTET[sym] ^ 0b11111111) + end + self + end + end + + [:message_type_indicator, :validity_period_format].each do |sym| + define_method sym do + self.class.const_get(sym.upcase).key(get(sym)) + end + + define_method :"#{sym}!" do |value| + hash = self.class.const_get(sym.upcase) + + self.binary = ((binary & (FIRST_OCTET[sym] ^ 0b11111111)) | + hash[value]) unless hash[value].nil? + self + end + end + end + end +end diff --git a/spec/biju/pdu/first_octet_spec.rb b/spec/biju/pdu/first_octet_spec.rb new file mode 100644 index 0000000..c24ca52 --- /dev/null +++ b/spec/biju/pdu/first_octet_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' +require 'biju/pdu' + +describe Biju::PDU::FirstOctet do + its(:reply_path?) { should be_false } + its(:user_data_header?) { should be_false } + its(:status_report_request?) { should be_false } + its(:reject_duplicates?) { should be_false } + + its(:message_type_indicator) { should eq(:sms_deliver) } + its(:validity_period_format) { should eq(:not_present) } +end