Class: Smpp::Base

Inherits:
EventMachine::Connection
  • Object
show all
Includes:
Smpp
Defined in:
lib/smpp/base.rb

Direct Known Subclasses

Server, Transceiver

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Base



37
38
39
40
41
# File 'lib/smpp/base.rb', line 37

def initialize(config)
  @state = :unbound
  @config = config
  @data = ""
end

Instance Attribute Details

#stateObject

:bound or :unbound



14
15
16
# File 'lib/smpp/base.rb', line 14

def state
  @state
end

Class Method Details

.loggerObject



25
26
27
# File 'lib/smpp/base.rb', line 25

def Base.logger
  @@logger
end

.logger=(logger) ⇒ Object



29
30
31
# File 'lib/smpp/base.rb', line 29

def Base.logger=(logger)
  @@logger = logger
end

Instance Method Details

#bound?Boolean



21
22
23
# File 'lib/smpp/base.rb', line 21

def bound?
  @state == :bound
end

#loggerObject



33
34
35
# File 'lib/smpp/base.rb', line 33

def logger
  @@logger
end

#post_initObject

invoked by EventMachine when connected



44
45
46
47
48
49
50
51
52
53
# File 'lib/smpp/base.rb', line 44

def post_init
  # send Bind PDU if we are a binder (eg
  # Receiver/Transmitter/Transceiver
  send_bind unless defined?(am_server?) && am_server?

  # start timer that will periodically send enquire link PDUs
  start_enquire_link_timer(@config[:enquire_link_delay_secs]) if @config[:enquire_link_delay_secs]
rescue Exception => ex
  logger.error "Error starting RX: #{ex.message} at #{ex.backtrace[0]}"
end

#process_pdu(pdu) ⇒ Object

process common PDUs returns true if no further processing necessary



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/smpp/base.rb', line 119

def process_pdu(pdu)      
  case pdu
  when Pdu::EnquireLinkResponse
    # nop
  when Pdu::EnquireLink
    write_pdu(Pdu::EnquireLinkResponse.new(pdu.sequence_number))
  when Pdu::Unbind
    @state = :unbound
    write_pdu(Pdu::UnbindResponse.new(pdu.sequence_number, Pdu::Base::ESME_ROK))
    close_connection
  when Pdu::UnbindResponse      
    logger.info "Unbound OK. Closing connection."
    close_connection
  when Pdu::GenericNack
    logger.warn "Received NACK! (error code #{pdu.error_code})."
    # we don't take this lightly: close the connection
    close_connection
  else
    logger.warn "(#{self.class.name}) Received unexpected PDU: #{pdu.to_human}."
    close_connection
  end
end

#receive_data(data) ⇒ Object

EventMachine::Connection#receive_data



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/smpp/base.rb', line 81

def receive_data(data)
  #append data to buffer
  @data << data

  while (@data.length >=4)
    cmd_length = @data[0..3].unpack('N').first
    if(@data.length < cmd_length)
      #not complete packet ... break
      break
    end
    
    pkt = @data.slice!(0,cmd_length)

    # parse incoming PDU
    pdu = read_pdu(pkt)

    # let subclass process it
    process_pdu(pdu) if pdu

  end
end

#send_unbindObject



112
113
114
115
# File 'lib/smpp/base.rb', line 112

def send_unbind
  write_pdu Pdu::Unbind.new
  @state = :unbound
end

sets up a periodic timer that will periodically enquire as to the state of the connection Note: to add in custom executable code (that only runs on an open connection), derive from the appropriate Smpp class and overload the method named: periodic_call_method



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/smpp/base.rb', line 60

def start_enquire_link_timer(delay_secs)
  logger.info "Starting enquire link timer (with #{delay_secs}s interval)"
  EventMachine::PeriodicTimer.new(delay_secs) do 
    if error?
      logger.warn "Link timer: Connection is in error state. Disconnecting."
      close_connection
    elsif unbound?
      logger.warn "Link is unbound, waiting until next #{delay_secs} interval before querying again"
    else

      # if the user has defined a method to be called periodically, do
      # it now - and continue if it indicates to do so
      rval = defined?(periodic_call_method) ? periodic_call_method : true

      # only send an OK if this worked
      write_pdu Pdu::EnquireLink.new if rval 
    end
  end
end

#unbindObject

EventMachine::Connection#unbind Invoked by EM when connection is closed. Delegates should consider breaking the event loop and reconnect when they receive this callback.



106
107
108
109
110
# File 'lib/smpp/base.rb', line 106

def unbind
  if @delegate.respond_to?(:unbound)
    @delegate.unbound(self)
  end
end

#unbound?Boolean

queries the state of the transmitter - is it bound?



17
18
19
# File 'lib/smpp/base.rb', line 17

def unbound?
  @state == :unbound
end