Class: Smpp::Pdu::DeliverSm

Inherits:
Base
  • Object
show all
Defined in:
lib/smpp/pdu/deliver_sm.rb

Overview

Received for MO message or delivery notification

Constant Summary collapse

@@encoder =
nil

Constants inherited from Base

Base::BIND_RECEIVER, Base::BIND_RECEIVER_RESP, Base::BIND_TRANSCEIVER, Base::BIND_TRANSCEIVER_RESP, Base::BIND_TRANSMITTER, Base::BIND_TRANSMITTER_RESP, Base::CANCEL_SM, Base::CANCEL_SM_RESP, Base::DELIVER_SM, Base::DELIVER_SM_RESP, Base::ENQUIRE_LINK, Base::ENQUIRE_LINK_RESP, Base::ESME_RALYBND, Base::ESME_RBINDFAIL, Base::ESME_RCANCELFAIL, Base::ESME_RCNTSUBDL, Base::ESME_RINVBNDSTS, Base::ESME_RINVCMDID, Base::ESME_RINVCMDLEN, Base::ESME_RINVDESTFLAG, Base::ESME_RINVDLNAME, Base::ESME_RINVDSTADR, Base::ESME_RINVDSTNPI, Base::ESME_RINVDSTTON, Base::ESME_RINVESMCLASS, Base::ESME_RINVMSGID, Base::ESME_RINVMSGLEN, Base::ESME_RINVNUMDESTS, Base::ESME_RINVNUMMSGS, Base::ESME_RINVPASWD, Base::ESME_RINVPRTFLG, Base::ESME_RINVREGDLVFLG, Base::ESME_RINVREPFLAG, Base::ESME_RINVSERTYP, Base::ESME_RINVSRCADR, Base::ESME_RINVSRCNPI, Base::ESME_RINVSRCTON, Base::ESME_RINVSUBREP, Base::ESME_RINVSYSID, Base::ESME_RINVSYSTYP, Base::ESME_RMSGQFUL, Base::ESME_ROK, Base::ESME_RREPLACEFAIL, Base::ESME_RSUBMITFAIL, Base::ESME_RSYSERR, Base::ESME_RTHROTTLED, Base::ESME_RX_T_APPN, Base::GENERIC_NACK, Base::OPTIONAL_MESSAGE_STATE, Base::OPTIONAL_RECEIPTED_MESSAGE_ID, Base::PROTOCOL_VERSION, Base::QUERY_SM, Base::QUERY_SM_RESP, Base::REPLACE_SM, Base::REPLACE_SM_RESP, Base::SEQUENCE_MAX, Base::SUBMIT_MULTI, Base::SUBMIT_MULTI_RESP, Base::SUBMIT_SM, Base::SUBMIT_SM_RESP, Base::UNBIND, Base::UNBIND_RESP

Instance Attribute Summary collapse

Attributes inherited from Base

#body, #command_id, #command_status, #data, #sequence_number

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

create, fixed_int, #fixed_int, handles_cmd, #logger, next_sequence_number, #next_sequence_number, #optional_parameters_to_buffer, optional_parameters_to_buffer, parse_optional_parameters, #to_human

Constructor Details

#initialize(source_addr, destination_addr, short_message, options = {}, seq = nil) ⇒ DeliverSm

Returns a new instance of DeliverSm.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/smpp/pdu/deliver_sm.rb', line 14

def initialize(source_addr, destination_addr, short_message, options={}, seq=nil) 
  
  @udh = options[:udh]      
  @service_type            = options[:service_type]? options[:service_type] :''
  @source_addr_ton         = options[:source_addr_ton]?options[:source_addr_ton]:0 # network specific
  @source_addr_npi         = options[:source_addr_npi]?options[:source_addr_npi]:1 # unknown
  @source_addr             = source_addr
  @dest_addr_ton           = options[:dest_addr_ton]?options[:dest_addr_ton]:1 # international
  @dest_addr_npi           = options[:dest_addr_npi]?options[:dest_addr_npi]:1 # unknown 
  @destination_addr        = destination_addr
  @esm_class               = options[:esm_class]?options[:esm_class]:0 # default smsc mode
  @protocol_id             = options[:protocol_id]?options[:protocol_id]:0
  @priority_flag           = options[:priority_flag]?options[:priority_flag]:0
  @schedule_delivery_time  = options[:schedule_delivery_time]?options[:schedule_delivery_time]:''
  @validity_period         = options[:validity_period]?options[:validity_period]:''
  @registered_delivery     = options[:registered_delivery]?options[:registered_delivery]:1 # we want delivery notifications
  @replace_if_present_flag = options[:replace_if_present_flag]?options[:replace_if_present_flag]:0
  @data_coding             = options[:data_coding]?options[:data_coding]:3 # iso-8859-1
  @sm_default_msg_id       = options[:sm_default_msg_id]?options[:sm_default_msg_id]:0
  @short_message           = short_message
  payload                  = @udh ? @udh.to_s + @short_message : @short_message 
  @sm_length               = payload.length

  #fields set for delivery report
  @stat                    = options[:stat]
  @msg_reference           = options[:msg_reference]
  @receipted_message_id    = options[:receipted_message_id]
  @message_state           = options[:message_state]
  @optional_parameters     = options[:optional_parameters]

  pdu_body = sprintf("%s\0%c%c%s\0%c%c%s\0%c%c%c%s\0%s\0%c%c%c%c%c%s", @service_type, @source_addr_ton, @source_addr_npi, @source_addr,
  @dest_addr_ton, @dest_addr_npi, @destination_addr, @esm_class, @protocol_id, @priority_flag, @schedule_delivery_time, @validity_period,
  @registered_delivery, @replace_if_present_flag, @data_coding, @sm_default_msg_id, @sm_length, payload)

  seq ||= next_sequence_number

  super(DELIVER_SM, 0, seq, pdu_body)
end

Instance Attribute Details

#data_codingObject (readonly)

Returns the value of attribute data_coding.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def data_coding
  @data_coding
end

#dest_addr_npiObject (readonly)

Returns the value of attribute dest_addr_npi.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def dest_addr_npi
  @dest_addr_npi
end

#dest_addr_tonObject (readonly)

Returns the value of attribute dest_addr_ton.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def dest_addr_ton
  @dest_addr_ton
end

#destination_addrObject (readonly)

Returns the value of attribute destination_addr.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def destination_addr
  @destination_addr
end

#esm_classObject (readonly)

Returns the value of attribute esm_class.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def esm_class
  @esm_class
end

#message_stateObject (readonly)

Returns the value of attribute message_state.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def message_state
  @message_state
end

#msg_referenceObject (readonly)

Returns the value of attribute msg_reference.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def msg_reference
  @msg_reference
end

#optional_parametersObject (readonly)

Returns the value of attribute optional_parameters.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def optional_parameters
  @optional_parameters
end

#priority_flagObject (readonly)

Returns the value of attribute priority_flag.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def priority_flag
  @priority_flag
end

#protocol_idObject (readonly)

Returns the value of attribute protocol_id.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def protocol_id
  @protocol_id
end

#receipted_message_idObject (readonly)

Returns the value of attribute receipted_message_id.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def receipted_message_id
  @receipted_message_id
end

#registered_deliveryObject (readonly)

Returns the value of attribute registered_delivery.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def registered_delivery
  @registered_delivery
end

#replace_if_present_flagObject (readonly)

Returns the value of attribute replace_if_present_flag.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def replace_if_present_flag
  @replace_if_present_flag
end

#schedule_delivery_timeObject (readonly)

Returns the value of attribute schedule_delivery_time.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def schedule_delivery_time
  @schedule_delivery_time
end

#service_typeObject (readonly)

Returns the value of attribute service_type.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def service_type
  @service_type
end

#short_messageObject (readonly)

Returns the value of attribute short_message.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def short_message
  @short_message
end

#sm_default_msg_idObject (readonly)

Returns the value of attribute sm_default_msg_id.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def sm_default_msg_id
  @sm_default_msg_id
end

#sm_lengthObject (readonly)

Returns the value of attribute sm_length.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def sm_length
  @sm_length
end

#source_addrObject (readonly)

Returns the value of attribute source_addr.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def source_addr
  @source_addr
end

#source_addr_npiObject (readonly)

Returns the value of attribute source_addr_npi.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def source_addr_npi
  @source_addr_npi
end

#source_addr_tonObject (readonly)

Returns the value of attribute source_addr_ton.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def source_addr_ton
  @source_addr_ton
end

#statObject (readonly)

Returns the value of attribute stat.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def stat
  @stat
end

#udhObject (readonly)

Returns the value of attribute udh.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def udh
  @udh
end

#validity_periodObject (readonly)

Returns the value of attribute validity_period.



6
7
8
# File 'lib/smpp/pdu/deliver_sm.rb', line 6

def validity_period
  @validity_period
end

Class Method Details

.data_encoder=(encoder) ⇒ Object

set an encoder that can be called to yield the data_coding and short_message



147
148
149
# File 'lib/smpp/pdu/deliver_sm.rb', line 147

def self.data_encoder=(encoder)
  @@encoder = encoder
end

.from_wire_data(seq, status, body) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/smpp/pdu/deliver_sm.rb', line 65

def self.from_wire_data(seq, status, body)
  options = {}
  # brutally unpack it
  options[:service_type], 
  options[:source_addr_ton], 
  options[:source_addr_npi], 
  source_addr, 
  options[:dest_addr_ton], 
  options[:dest_addr_npi], 
  destination_addr, 
  options[:esm_class], 
  options[:protocol_id],
  options[:priority_flag], 
  options[:schedule_delivery_time], 
  options[:validity_period], 
  options[:registered_delivery], 
  options[:replace_if_present_flag], 
  options[:data_coding], 
  options[:sm_default_msg_id],
  options[:sm_length], 
  remaining_bytes = body.unpack('Z*CCZ*CCZ*CCCZ*Z*CCCCCa*')    

  short_message = remaining_bytes.slice!(0...options[:sm_length])

  #everything left in remaining_bytes is 3.4 optional parameters
  options[:optional_parameters] = parse_optional_parameters(remaining_bytes)

  #parse the 'standard' optional parameters for delivery receipts
  options[:optional_parameters].each do |tag, tlv|
    if OPTIONAL_MESSAGE_STATE == tag
      value = tlv[:value].unpack('C')
      options[:message_state] = value[0] if value

    elsif OPTIONAL_RECEIPTED_MESSAGE_ID == tag
      value = tlv[:value].unpack('A*')
      options[:receipted_message_id] = value[0] if value
    end
  end

  # Check to see if body has a 5 bit header
  if short_message.unpack("c")[0] == 5
    options[:udh] = short_message.slice!(0..5).unpack("CCCCCC")
  end

  #Note: if the SM is a delivery receipt (esm_class=4) then the short_message _may_ be in this format:  
  # "id:Smsc2013 sub:1 dlvrd:1 submit date:0610171515 done date:0610171515 stat:0 err:0 text:blah"
  # or this format:
  # "4790000000SMSAlert^id:1054BC63 sub:0 dlvrd:1 submit date:0610231217 done date:0610231217 stat:DELIVRD err: text:"
  # (according to the SMPP spec, the format is vendor specific)
  # For example, Tele2 (Norway):
  # "<msisdn><shortcode>?id:10ea34755d3d4f7a20900cdb3349e549 sub:001 dlvrd:001 submit date:0611011228 done date:0611011230 stat:DELIVRD err:000 Text:abc'!10ea34755d3d4f7a20900cdb3349e549"
  if options[:esm_class] == 4
    # id is in the mandatory part
    msg_ref_match = short_message.match(/id:([^ ]*)/)
    # id is not found, search it in the optional part
    msg_ref_match = remaining_bytes.match(/id:([^ ]*)/) if !msg_ref_match
    
    if msg_ref_match
      options[:msg_reference] = msg_ref_match[1]
    end
    
    # stat is the mandatory part
    stat_match = short_message.match(/stat:([^ ]*)/)
    # stat is not found, search it in the optional part
    stat_match = remaining_bytes.match(/stat:([^ ]*)/) if !stat_match
    
    if stat_match
      options[:stat] = stat_match[1]
    end
    
    Smpp::Base.logger.debug "DeliverSM with source_addr=#{source_addr}, destination_addr=#{destination_addr}, msg_reference=#{options[:msg_reference]}, stat=#{options[:stat]}"
  else
    Smpp::Base.logger.debug "DeliverSM with source_addr=#{source_addr}, destination_addr=#{destination_addr}"
  end

  #yield the data_coding and short_message to the encoder if one is set
  short_message = @@encoder.encode(options[:data_coding], short_message) if @@encoder.respond_to?(:encode)

  new(source_addr, destination_addr, short_message, options, seq) 
end

Instance Method Details

#message_idObject



61
62
63
# File 'lib/smpp/pdu/deliver_sm.rb', line 61

def message_id
  @udh ? @udh[3] : 0
end

#partObject



57
58
59
# File 'lib/smpp/pdu/deliver_sm.rb', line 57

def part
  @udh ? @udh[5] : 0
end

#total_partsObject



53
54
55
# File 'lib/smpp/pdu/deliver_sm.rb', line 53

def total_parts
  @udh ? @udh[4] : 0
end