smppex v0.3.1 SMPPEX.ESME behaviour
Module for implementing custom SMPP ESME entities.
SMPPEX.ESME
represents a GenServer
process which spawns and interacts with SMPPEX.Session
ranch_protocol
. The session is spawned under control of ranch
supervision tree.
The session makes all requests to the ESME process syncronously (via GenServer.call
),
while the ESME process makes only asyncronous(via GenServer.cast
) requests to the session.
This is made intentionally since this allows:
- to avoid any kind of deadlocks while the session and the ESME process interact actively;
- to control incoming SMPP message rate to avoid overflooding;
- not to lose any control over connection because of the asyncronous nature of TCP implementation in OTP.
To implement an ESME entitiy, one should implement several callbacks (SMPPEX.ESME
behaviour).
The most proper way to do it is to use
SMPPEX.ESME
:
defmodule MyESME do
use SMPPEX.ESME
# ...Callback implementation
end
In this case all callbacks have reasonable defaults.
Summary
Functions
Makes a syncronous call to ESME
Makes an asyncronous call to ESME
Sends reply to previously received PDU from the ESME
Sends outcoming PDU from the ESME
Starts ESME entitiy
Stops ESME asyncronously
Asyncronously executes the passed lambda passing SMPP session(SMPPEX.Session
) to it directly
Callbacks
Invoked for handling call/3
calls
Invoked for handling cast/2
calls
Invoked for handling generic messages sent to the ESME process
Invoked when ESME was stopped abnormally and wasn’t able to
handle sent PDUs without resps in handle_stop
Invoked when the ESME receives an incoming PDU (which is not a response PDU)
Invoked when the ESME receives a response to a previously sent PDU
Invoked when the ESME does not receive a response to a previously sent PDU for the specified timeout
Invoked when the SMPP session successfully sent PDU to transport or failed to do this
Invoked when the SMPP session is about to stop
Invoked when the ESME is started after connection to SMSC successfully established
Types
Functions
Specs
call(esme :: pid, arg :: term, timeout) :: term
Makes a syncronous call to ESME.
The call is handled by handle_call/3
ESME callback.
Specs
cast(pid, term) :: :ok
Makes an asyncronous call to ESME.
The call is handled by handle_cast/2
ESME callback.
Specs
reply(esme :: pid, pdu :: SMPPEX.Pdu.t, reply_pdu :: SMPPEX.Pdu.t) :: :ok
Sends reply to previously received PDU from the ESME.
The whole command is sent to the ESME asyncronously. The further lifecycle of the response PDU can be traced through callbacks.
Specs
send_pdu(esme :: pid, pdu :: SMPPEX.Pdu.t) :: :ok
Sends outcoming PDU from the ESME.
The whole command is sent to the ESME asyncronously. The further lifecycle of the PDU can be traced through callbacks.
Specs
start_link(host :: term, port :: non_neg_integer, {module, args :: term}, opts :: Keyword.t) :: GenServer.on_start
Starts ESME entitiy.
The function does not return until ESME successfully connects to the specified
host
and port
and initializes or fails.
module
is the callback module which should implement SMPPEX.ESME
behaviour.
args
is the argument passed to the init
callback.
opts
is a keyword list of different options:
:transport
is Ranch transport used for TCP connection: eitherranch_tcp
(the default) orranch_ssl
;:gen_server_opts
is a list of options passed directly to the underlyingGenServer.start_link
call, the default is[]
;:timeout
is timeout for the whole connect and initialization process. The default is 5000 ms;:esme_opts
is a keyword list of ESME options::timer_resolution
is interval of internalticks
on which time related events happen, like checking timeouts for pdus, checking SMPP timers, etc. The default is 100 ms;:enquire_link_limit
is value for enquire_link SMPP timer, i.e. the interval of SMPP session inactivity after which enquire_link PDU is send to “ping” the connetion. The default value is 30000 ms;:enquire_link_resp_limit
is the maximum time for which ESME waits for enquire_link PDU response. If the response is not received within this interval of time and no activity from the peer occurs, the session is then considered dead and the ESME stops. The default value is 30000 ms;:inactivity_limit
is the maximum time for which the peer is allowed not to send PDUs (which are not response PDUs). If no such PDUs are received within this interval of time, ESME stops. The default is infinity ms;:response_limit
is the maximum time to wait for a response for a previously sent PDU. If the response is not received within this interval,handle_resp_timeout
callback is triggered for the original pdu. If the response is received later, it is discarded. The default value is 60000 ms. If:esme_opts
list of options is ommited, all options take their default values.
The whole opts
argument may also be ommited in order to start ESME with the defaults.
The returned value is either {:ok, pid}
or {:error, reason}
.
Specs
stop(esme :: pid) :: :ok
Stops ESME asyncronously.
The very moment of the SMPP session termination can be traced via handle_stop
callback.
Callbacks
Specs
handle_call(request, from :: GenServer.from, state) ::
{:reply, reply :: term, state} |
{:noreply, state}
Invoked for handling call/3
calls.
The callback is called syncronously for handling.
The returned values have the same meaning as in GenServer
handle_call
callback
(but note that only two kinds of responses are possible). In case of delaying a reply ({:noreply, state}
callback result)
it can be later send using GenServer.reply(from, reply)
Invoked for handling cast/2
calls.
The callback is called asyncronously.
The returned value is used as the new state.
Invoked for handling generic messages sent to the ESME process.
The returned value is used as the new state.
Specs
handle_lost_pdus(esme :: pid, reason :: term, pdus :: [SMPPEX.Pdu.t]) :: any
Invoked when ESME was stopped abnormally and wasn’t able to
handle sent PDUs without resps in handle_stop
.
Since the ESME is already stopped, the callback does not receive state, but the former pid of ESME, the reason of its termination and unconfirmed PDUs.
The returned value is ignored.
Specs
handle_pdu(pdu :: SMPPEX.Pdu.t, state) :: state
Invoked when the ESME receives an incoming PDU (which is not a response PDU).
The returned value is used as the new state.
Specs
handle_resp(pdu :: SMPPEX.Pdu.t, original_pdu :: SMPPEX.Pdu.t, state) :: state
Invoked when the ESME receives a response to a previously sent PDU.
pdu
argument contains the received response PDU, original_pdu
contains
the previously sent pdu for which the handled response is received.
The returned value is used as the new state.
Specs
handle_resp_timeout(pdu :: SMPPEX.Pdu.t, state) :: state
Invoked when the ESME does not receive a response to a previously sent PDU for the specified timeout.
pdu
argument contains the PDU for which no response was received. If the response
will be received later it will be dropped (with an info
log message).
The returned value is used as the new state.
Specs
handle_send_pdu_result(pdu :: SMPPEX.Pdu.t, send_pdu_result :: SMPPEX.SMPPHandler.send_pdu_result, state) :: state
Invoked when the SMPP session successfully sent PDU to transport or failed to do this.
pdu
argument contains the PDU for which send status is reported. send_pdu_result
can be
either :ok
or {:error, reason}
.
The returned value is used as the new state.
Specs
handle_stop(reason :: term, lost_pdus :: [SMPPEX.Pdu.t], state) :: {exit_reason :: term, state}
Invoked when the SMPP session is about to stop.
lost_pdus
contains sent PDUs which have not received resps (and will never
receive since the session terminates).
reason
contains one of the following:
:custom
— session manually stopped by call toESME.stop
;{:parse_error, error}
— error in parsing incoming SMPP packet occured;:socket_closed
— peer closed socket;{:socket_error, error}
— socket error occured;{:timers, reason}
— session closed by timers.
The return value is {stop_reason, new_state}
. The session GenServer will stop
with stop_reason
.
Specs
init(args :: term) ::
{:ok, state} |
{:stop, reason :: term}
Invoked when the ESME is started after connection to SMSC successfully established.
args
argument is taken directly from start_link
call, which does not return until init
finishes.
The return value should be either {:ok, state}
, then ESME will successfully start and returned state will
be later passed to the other callbacks, or {:stop, reason}
, then ESME GenServer
will stop
with the returned reason.