%%% Copyright (C) 2004 Enrique Marcote Peņa %%% %%% This library is free software; you can redistribute it and/or %%% modify it under the terms of the GNU Lesser General Public %%% License as published by the Free Software Foundation; either %%% version 2.1 of the License, or (at your option) any later version. %%% %%% This library is distributed in the hope that it will be useful, %%% but WITHOUT ANY WARRANTY; without even the implied warranty of %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %%% Lesser General Public License for more details. %%% %%% You should have received a copy of the GNU Lesser General Public %%% License along with this library; if not, write to the Free Software %%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA %%% @doc SMSC Skeleton. %%% %%%

You may use this skeleton as the starting point to implement your %%% own SMSCs.

%%% %%% @copyright 2004 Enrique Marcote Peņa %%% @author Enrique Marcote Peņa %%% [http://oserl.sourceforge.net/] %%% @version 1.1, { 6 Jul 2004} {@time}. %%% @end -module(smsc_skel). -behaviour(gen_smsc). %%%------------------------------------------------------------------- %%% Include files %%%------------------------------------------------------------------- -include("oserl.hrl"). %%%------------------------------------------------------------------- %%% External exports %%%------------------------------------------------------------------- -export([start_link/0, stop/0]). %%%------------------------------------------------------------------- %%% Internal SMSC exports %%%------------------------------------------------------------------- -export([init/1, handle_bind/3, handle_operation/3, handle_unbind/3, handle_listen_error/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %%%------------------------------------------------------------------- %%% Macros %%%------------------------------------------------------------------- -define(SERVER, ?MODULE). -define(SMPP_PORT, ?DEFAULT_SMPP_PORT). -define(SYSTEM_ID, atom_to_list(?MODULE)). %%%------------------------------------------------------------------- %%% Records %%%------------------------------------------------------------------- %% %@spec {state} %% %% %@doc Representation of the SMSC server state. %% %%
%%
:
%%
%%
%% %@end -record(state, {}). %%%=================================================================== %%% External functions %%%=================================================================== %% @spec start_link() -> Result %% Result = {ok, Pid} | ignore | {error, Error} %% Pid = pid() %% Error = {already_started, Pid} | term() %% %% @doc Starts the SMSC server. %% %% @see gen_smsc %% @see start/0 %% @end start_link() -> gen_smsc:start_link({local, ?SERVER}, ?MODULE, [], []). %% @spec stop() -> ok %% %% @doc Stops the SMSC server. %% %% @see handle_call/3 %% %% @equiv gen_smsc:call(SERVER, die, 10000) %% @end stop() -> gen_smsc:call(?SERVER, die, 10000). %%%=================================================================== %%% Server functions %%%=================================================================== %% @spec init(Args) -> Result %% Args = term() %% Result = {ok, State} | {ok, State, Timeout} | ignore | {stop, Reason} %% State = term() %% Timeout = int() | infinity %% Reason = term() %% %% @doc %% gen_smsc - init/1 callback implementation. %% %%

Initiates the server.

%% @end init([]) -> % You may start sessions and issue bind requests here. {ok, #state{}}. %% @spec handle_bind(Bind, From, State) -> Result %% Bind = {CmdName, Session, Pdu} %% CmdName = bind_receiver | bind_transmitter | bind_transceiver %% Session = pid() %% Pdu = pdu() %% From = term() %% State = term() %% Result = {reply, Reply, NewState} | %% {reply, Reply, NewState, Timeout} | %% {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, Reply, NewState} | %% {stop, Reason, NewState} %% Reply = {ok, ParamList} | {error, Error, ParamList} %% ParamList = [{ParamName, ParamValue}] %% ParamName = atom() %% ParamValue = term() %% NewState = term() %% Timeout = int() %% Reason = term() %% %% @doc gen_smsc - handle_bind/3 callback implementation. %% %%

Handle bind requests from the peer ESME.

%% %%

The ParamList included in the response is used to construct %% the bind response PDU. If a command_status other than ESME_ROK is to %% be returned by the SMSC in the response PDU, the callback should return the %% term {error, Error, ParamList}, where Error is the %% desired command_status error code.

%% @end handle_bind({CmdName, Session, Pdu}, From, State) -> ParamList = [{system_id, ?SYSTEM_ID}], {reply, {ok, ParamList}, State}. %% @spec handle_operation(Operation, From, State) -> Result %% Operation = {CmdName, Session, Pdu} %% CmdName = broadcast_sm | %% cancel_broadcast_sm | %% cancel_sm | %% query_broadcast_sm | %% query_sm | %% replace_sm | %% submit_multi | %% submit_sm | %% data_sm %% Session = pid() %% Pdu = pdu() %% From = term() %% State = term() %% Result = {reply, Reply, NewState} | %% {reply, Reply, NewState, Timeout} | %% {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, Reply, NewState} | %% {stop, Reason, NewState} %% Reply = {ok, ParamList} | {error, Error, ParamList} %% ParamList = [{ParamName, ParamValue}] %% ParamName = atom() %% ParamValue = term() %% NewState = term() %% Timeout = int() %% Reason = term() %% %% @doc gen_smsc - handle_operation/3 callback implementation. %% %%

Handle broadcast_sm, cancel_broadcast_sm, %% cancel_sm, query_broadcast_sm, query_sm, %% replace_sm, submit_multi, submit_sm and %% data_sm operations from peer ESMEs.

%% %%

The ParamList included in the response is used to construct %% the response PDU. If a command_status other than ESME_ROK is to %% be returned by the SMSC in the response PDU, the callback should return the %% term {error, Error, ParamList}, where Error is the %% desired command_status error code.

%% @end handle_operation({CmdName, Session, Pdu}, From, S) -> % Don't know how to handle CmdName {reply, {error, ?ESME_RINVCMDID, []}, S}. %% @spec handle_unbind(Unbind, From, State) -> Result %% Unbind = {unbind, Session, Pdu} %% Session = pid() %% Pdu = pdu() %% Result = {reply, Reply, NewState} | %% {reply, Reply, NewState, Timeout} | %% {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, Reply, NewState} | %% {stop, Reason, NewState} %% Reply = ok | {error, Error} %% Error = int() %% NewState = term() %% Timeout = int() %% Reason = term() %% %% @doc gen_smsc - handle_unbind/3 callback implementation. %% %%

Handle unbind requests from the peer ESMEs.

%% %%

If ok returned an unbind_resp with a ESME_ROK %% command_status is sent to the MC and the session moves into the unbound %% state. When {error, Error} is returned by the ESME, the %% response PDU sent by the session to the MC will have an Error %% command_status and the session will remain on it's current bound state %% (bound_rx, bound_tx or bound_trx).

%% @end handle_unbind({unbind, Session, Pdu}, From, State) -> {reply, ok, State}. %% @spec handle_listen_error(State) -> Result %% State = term() %% Result = {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, NewState} %% NewState = term() %% Timeout = int() %% Reason = term() %% %% @doc gen_smsc - handle_listen_error/1 callback implementation. %% %%

Handle listen failures.

%% @end handle_listen_error(State) -> {noreply, State}. %% @spec handle_call(Request, From, State) -> Result %% Request = term() %% From = {pid(), Tag} %% State = term() %% Result = {reply, Reply, NewState} | %% {reply, Reply, NewState, Timeout} | %% {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, Reply, NewState} | %% {stop, Reason, NewState} %% Reply = term() %% NewState = term() %% Timeout = int() | infinity %% Reason = term() %% %% @doc gen_smsc - handle_call/3 callback implementation. %% %%

Handling call messages.

%% %% %% %% @see terminate/2 %% @end handle_call(Request, From, State) -> Reply = ok, {reply, Reply, State}; handle_call(die, _From, State) -> {stop, normal, ok, State}. %% @spec handle_cast(Request, State) -> Result %% Request = term() %% Result = {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, NewState} %% NewState = term() %% Timeout = int() | infinity %% Reason = normal | term() %% %% @doc gen_smsc - handle_cast/2 callback implementation. %% %%

Handling cast messages.

%% %% %% %% @see terminate/2 %% @end handle_cast(Request, State) -> {noreply, State}. %% @spec handle_info(Info, State) -> Result %% Info = timeout | term() %% State = term() %% Result = {noreply, NewState} | %% {noreply, NewState, Timeout} | %% {stop, Reason, NewState} %% NewState = term() %% Timeout = int() | infinity %% Reason = normal | term() %% %% @doc gen_smsc - handle_info/2 callback implementation. %% %%

Handling all non call/cast messages.

%% %% %% %% @see terminate/2 %% @end handle_info(Info, State) -> {noreply, State}. %% @spec terminate(Reason, State) -> ok %% Reason = normal | shutdown | term() %% State = term() %% %% @doc %% gen_smsc - terminate/2 callback implementation. %% %%

Shutdown the SMSC server.

%% %%

Return value is ignored by gen_smsc.

%% @end terminate(Reason, State) -> % You may stop sessions and issue unbind requests here. ok. %% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} %% OldVsn = undefined | term() %% State = term() %% Extra = term %% NewState = term() %% %% @doc gen_smsc - code_change/2 callback implementation. %% %%

Convert process state when code is changed.

%% @end code_change(OldVsn, State, Extra) -> {ok, State}. %%%=================================================================== %%% Internal functions %%%===================================================================