Class: Smpp::Server
- Defined in:
- lib/smpp/server.rb
Overview
the opposite of a client-based receiver, the server transmitter will send out MOs to the client when set up
Constant Summary collapse
- BIND_STATUSES =
set of valid bind statuses
{:transmitter => :bound_tx, :receiver => :bound_rx, :transceiver => :bound_trx}
Constants included from Smpp
Instance Attribute Summary collapse
-
#bind_status ⇒ Object
what is the bind_status?.
Attributes inherited from Base
Instance Method Summary collapse
-
#accept_deliver_sm_response(pdu) ⇒ Object
Acknowledge delivery of an outgoing MO message REVISIT = just a stub.
- #am_server? ⇒ Boolean
-
#bind_session(bind_pdu, bind_classname) ⇒ Object
actually perform the action of binding the session to the given session type.
-
#bound? ⇒ Boolean
convenience methods is this session currently bound?.
-
#deliver_sm(from, to, message, config = {}) ⇒ Object
Message delivery (receiver) functions (used by receiver and transceiver-bound system).
-
#fetch_bind_response_class(bind_classname) ⇒ Object
REVISIT - not sure if these are using the correct data.
-
#initialize(config, received_messages = [], sent_messages = []) ⇒ Server
constructor
Expects a config hash, a proc to invoke for incoming (MO) messages, a proc to invoke for delivery reports, and optionally a hash-like storage for pending delivery reports.
-
#process_pdu(pdu) ⇒ Object
a PDU is received these pdus are all responses to a message sent by the client and require their own special response.
-
#receive_sm(pdu) ⇒ Object
Message submission (transmitter) functions (used by transmitter and transceiver-bound system) Note - we only support submit_sm message type, not submit_multi or data_sm message types.
-
#receiving? ⇒ Boolean
convenience function - are we able to receive in this bind-Status?.
-
#send_bind_response(bind_pdu, bind_class) ⇒ Object
Send BindReceiverResponse PDU - used in response to a “bind_receiver” pdu.
-
#set_bind_status(bind_classname) ⇒ Object
set the bind status based on the common-name for the bind class.
-
#transmitting? ⇒ Boolean
convenience function - are we able to transmit in this bind-Status?.
-
#unbound? ⇒ Boolean
is this session currently unbound?.
-
#unset_bind_status ⇒ Object
and kill the bind status when done.
Methods inherited from Base
logger, #logger, logger=, #post_init, #receive_data, #run_callback, #send_unbind, #start_enquire_link_timer, #unbind
Constructor Details
#initialize(config, received_messages = [], sent_messages = []) ⇒ Server
Expects a config hash, a proc to invoke for incoming (MO) messages, a proc to invoke for delivery reports, and optionally a hash-like storage for pending delivery reports.
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/smpp/server.rb', line 15 def initialize(config, = [], = []) super(config, nil) @state = :unbound @received_messages = @sent_messages = ed = @config[:enquire_link_delay_secs] || 5 comm_inactivity_timeout = [ed - 5, 3].max rescue Exception => ex logger.error "Exception setting up server: #{ex}" raise end |
Instance Attribute Details
#bind_status ⇒ Object
what is the bind_status?
55 56 57 |
# File 'lib/smpp/server.rb', line 55 def bind_status @bind_status end |
Instance Method Details
#accept_deliver_sm_response(pdu) ⇒ Object
Acknowledge delivery of an outgoing MO message REVISIT = just a stub
185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/smpp/server.rb', line 185 def accept_deliver_sm_response(pdu) m_seq = pdu.sequence_number # add the id to the list of ids we're awaiting acknowledgement of # REVISIT - what id do we need to store? unless @sent_messages && @sent_messages.include?(m_seq) logger.error("Received deliver response for message for which we have no saved id: #{m_seq}") else @sent_messages.delete(m_seq) logger.info "Acknowledged receipt of SM delivery message id: #{m_seq}" end end |
#am_server? ⇒ Boolean
73 74 75 |
# File 'lib/smpp/server.rb', line 73 def am_server? true end |
#bind_session(bind_pdu, bind_classname) ⇒ Object
actually perform the action of binding the session to the given session type
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/smpp/server.rb', line 98 def bind_session(bind_pdu, bind_classname) # TODO: probably should not "raise" here - what's better? raise IOError, "Session already bound." if bound? response_class = fetch_bind_response_class(bind_classname) # TODO: look inside the pdu for the password and check it send_bind_response(bind_pdu, response_class) @state = :bound set_bind_status(bind_classname) end |
#bound? ⇒ Boolean
convenience methods is this session currently bound?
36 37 38 |
# File 'lib/smpp/server.rb', line 36 def bound? @state == :bound end |
#deliver_sm(from, to, message, config = {}) ⇒ Object
Message delivery (receiver) functions (used by receiver and transceiver-bound system)
When we get an incoming SMS to send on to the client, we need to initiate one of these PDUs. Note - data doesn’t have to be valid, as we’re not really doing much useful with it. Only the params that will be pulled out by the test system need to be valid.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/smpp/server.rb', line 167 def deliver_sm(from, to, , config = {}) # TODO: probably should not "raise" here - what's better? raise IOError, "Connection not bound." if unbound? raise IOError, "Connection not set to receive" unless receiving? # submit the given message new_pdu = Pdu::DeliverSm.new(from, to, , config) write_pdu(new_pdu) # add the id to the list of ids of which we're awaiting acknowledgement @sent_messages << m_seq logger.info "Delivered SM message id: #{m_seq}" new_pdu end |
#fetch_bind_response_class(bind_classname) ⇒ Object
REVISIT - not sure if these are using the correct data. Currently just pulls the data straight out of the given pdu and sends it right back.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/smpp/server.rb', line 80 def fetch_bind_response_class(bind_classname) # check we have a valid classname - probably overkill as only our code # will send the classnames through raise IOError, "bind class name missing" if bind_classname.nil? raise IOError, "bind class name: #{bind_classname} unknown" unless BIND_STATUSES.has_key?(bind_classname) case bind_classname when :transceiver return Smpp::Pdu::BindTransceiverResponse when :transmitter return Smpp::Pdu::BindTransmitterResponse when :receiver return Smpp::Pdu::BindReceiverResponse end end |
#process_pdu(pdu) ⇒ Object
a PDU is received these pdus are all responses to a message sent by the client and require their own special response
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/smpp/server.rb', line 201 def process_pdu(pdu) case pdu # client has asked to set up a connection when Pdu::BindTransmitter bind_session(pdu, :transmitter) when Pdu::BindReceiver bind_session(pdu, :receiver) when Pdu::BindTransceiver bind_session(pdu, :transceiver) # client has acknowledged receipt of a message we sent to them when Pdu::DeliverSmResponse accept_deliver_sm_response(pdu) # acknowledge its sending # client has asked for a message to be sent when Pdu::SubmitSm receive_sm(pdu) else # for generic functions or default fallback super(pdu) end end |
#receive_sm(pdu) ⇒ Object
Message submission (transmitter) functions (used by transmitter and transceiver-bound system) Note - we only support submit_sm message type, not submit_multi or data_sm message types
Receive an incoming message to send to the network and respond REVISIT = just a stub
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/smpp/server.rb', line 132 def receive_sm(pdu) # TODO: probably should not "raise" here - what's better? raise IOError, "Connection not bound." if unbound? # Doesn't matter if it's a TX/RX/TRX, have to send a SubmitSmResponse: # raise IOError, "Connection not set to receive" unless receiving? # Must respond to SubmitSm requests with the same sequence number m_seq = pdu.sequence_number # add the id to the list of ids of which we're awaiting acknowledgement @received_messages << m_seq # In theory this is where the MC would actually do something useful with # the PDU - eg send it on to the network. We'd check if it worked and # send a failure PDU if it failed. # # Given this is a dummy MC, that's not necessary, so all our responses # will be OK. # so respond with a successful response pdu = Pdu::SubmitSmResponse.new(m_seq, Pdu::Base::ESME_ROK, = '' ) write_pdu pdu @received_messages.delete m_seq logger.info "Received submit sm message: #{m_seq}" end |
#receiving? ⇒ Boolean
convenience function - are we able to receive in this bind-Status?
66 67 68 69 70 71 |
# File 'lib/smpp/server.rb', line 66 def receiving? # not receiving if not bound return false if unbound? || bind_status.nil? # transmitters can't receive bind_status != :bound_tx end |
#send_bind_response(bind_pdu, bind_class) ⇒ Object
Send BindReceiverResponse PDU - used in response to a “bind_receiver” pdu.
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/smpp/server.rb', line 113 def send_bind_response(bind_pdu, bind_class) resp_pdu = bind_class.new( bind_pdu.sequence_number, # currently assume that it binds ok Pdu::Base::ESME_ROK, # TODO: not sure where we get the system ID # is this the session id? bind_pdu.system_id) write_pdu(resp_pdu) end |
#set_bind_status(bind_classname) ⇒ Object
set the bind status based on the common-name for the bind class
47 48 49 |
# File 'lib/smpp/server.rb', line 47 def set_bind_status(bind_classname) @bind_status = BIND_STATUSES[bind_classname] end |
#transmitting? ⇒ Boolean
convenience function - are we able to transmit in this bind-Status?
59 60 61 62 63 64 |
# File 'lib/smpp/server.rb', line 59 def transmitting? # not transmitting if not bound return false if unbound? || bind_status.nil? # receivers can't transmit bind_status != :bound_rx end |
#unbound? ⇒ Boolean
is this session currently unbound?
40 41 42 |
# File 'lib/smpp/server.rb', line 40 def unbound? @state == :unbound end |
#unset_bind_status ⇒ Object
and kill the bind status when done
51 52 53 |
# File 'lib/smpp/server.rb', line 51 def unset_bind_status @bind_status = nil end |