Method: Smpp::Pdu::DeliverSm.from_wire_data

Defined in:
lib/smpp/pdu/deliver_sm.rb

.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
# 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
    msg_ref_match = short_message.match(/id:([^ ]*)/)
    if msg_ref_match
      options[:msg_reference] = msg_ref_match[1]
    end
    
    stat_match = short_message.match(/stat:([^ ]*)/)
    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