Mark,
You might want to send this question to freeswitch-dev@lists.freeswitch.org as it's a bit intense for the users list. :)
-MC
I still need to stuff the Freeswitch PID into global storage somewhere so the process that's handling the configuration requests can send the reply without crashing (it's just getting a node id, not a Pid), but I seem to be on my way to configuring Freeswitch via ERLang.
freeswitch_bind.erl has the calls added to register the ERLang callbacks. The callback function itself is in the aptly named freeswitch_callback.erl.
-module(freeswitch_bind).
-behaviour(gen_server).
-record(st, {fsnode, pbxpid, configpid, dirpid, dialpid}).
-export([start/3, terminate/2, code_change/3, init/1,
handle_call/3, handle_cast/2, handle_info/2]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% gen_server methods
start(Node, Section, Pid) ->
gen_server:start(?MODULE, [Node, Section, Pid], []).
init([Node, Section, Pid]) ->
io:format( "freeswitch_bind:init( [Node=~w, Section=~w, Pid=~w])~n", [Node, Section, Pid] ),
{api, Node} ! {bind, Section},
receive
ok ->
{ok, ConfigurationPid } = freeswitch:start_fetch_handler( Node, configuration, freeswitch_callback, fetch_handler ),
{ok, DirectoryPid } = freeswitch:start_fetch_handler( Node, directory, freeswitch_callback, fetch_handler ),
{ok, DialplanPid } = freeswitch:start_fetch_handler( Node, dialplan, freeswitch_callback, fetch_handler ),
{ok, #st{fsnode=Node, pbxpid=Pid, configpid=ConfigurationPid, dirpid=DirectoryPid, dialpid=DialplanPid}};
{error, Reason} ->
{stop, {error, {freeswitch_error, Reason}}}
after 5000 ->
{stop, {error, freeswitch_timeout}}
end.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%
%% If the request isn't recognized, just log it and do nothing.
%%
handle_call(Request, _From, State) ->
io:format("freeswitch_bind:handle_call( ~w, _From, State) unrecognized request~n",
[Request]),
{reply, {error, unrecognized_request}, State}.
handle_cast(Message, State) ->
error_logger:error_msg("~p received unrecognized cast ~p~n",
[self(), Message]),
{noreply, State}.
handle_info({fetch, Section, Tag, Key, Value, FetchID, Params}, #st{fsnode=Node, pbxpid=Pid}=State) ->
{ok, XML} = gen_server:call(Pid, {fetch, Section, Tag, Key, Value, Params}),
{api, Node} ! {fetch_reply, FetchID, XML},
receive
ok ->
{noreply, State};
{error, Reason} ->
{stop, {error, Reason}, State}
end.
%% Author: mark
%% Created: Sep 15, 2009
%% Description: TODO: Add description to freeswitch_callback
-module(freeswitch_callback).
-behaviour(gen_server).
-record(st, {fsnode, pbxpid}).
-export([start/3, terminate/2, code_change/3, init/1,
handle_call/3, handle_cast/2, handle_info/2, fetch_handler/1]).
start(Node, Section, Pid) ->
gen_server:start(?MODULE, [Node, Section, Pid], []).
init([Node, Section, Pid]) ->
io:format( "freeswitch_callback:init( [Node=~w, Section=~w, Pid=~w])~n", [Node, Section, Pid] ),
{ok, #st{fsnode=Node, pbxpid=Pid}}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%
%% Callback for freeswitch:start_fetch_handler() called in freeswitch_bind:init()
%%
fetch_handler( FreeswitchNode ) ->
receive
{ nodedown, Node } ->
io:format( "freeswitch_callback:fetch_handler() Node ~w is down~n", [Node] ),
ok;
{ fetch, Section, Tag, Key, Value, FetchId, Params } ->
io:format( "freeswitch_callback:fetch_handler() Invoking xml_fetch()~n" ),
{ok, Xml} = xml_fetch( {fetch, Section, Tag, Key, Value, Params} ),
io:format( "freeswitch_callback:fetch_handler() Sending reply to FreeswitchNode ~w: ~s~n", [FreeswitchNode, Xml] ),
FreeswitchNode ! { fetch_reply, FetchId, Xml },
io:format( "freeswitch_callback:fetch_handler() Reply sent~n" ),
ok
end,
{ ok } = fetch_handler( FreeswitchNode ),
{ ok }.
%%
%% Configuration handler replies that the requested document section, tag, and key are not
%% found.
%%
xml_fetch({fetch, configuration, Tag, Key, Value, Params}) ->
io:format( "freeswitch_callback:handle_call( {fetch, configuration, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
[Tag, Key, Value, Params]),
Xml =
"<document type=\"freeswitch/xml\">
<section name=\"result\">
<result status=\"not found\" />
</section>
</document>",
{ok, Xml };
%%
%% Directory handler replies that the requested document section, tag, and key are not
%% found.
%%
xml_fetch({fetch, directory, Tag, Key, Value, Params}) ->
io:format( "freeswitch_callback:xml_fetch( {fetch, directory, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
[Tag, Key, Value, Params]),
Xml =
"<document type=\"freeswitch/xml\">
<section name=\"result\">
<result status=\"not found\" />
</section>
</document>",
{ok, Xml };
%%
%% Dialplan handler replies that the requested document section, tag, and key are not
%% found.
%%
xml_fetch({fetch, dialplan, Tag, Key, Value, Params}) ->
io:format( "freeswitch_callback:xml_fetch( {fetch, dialplan, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
[Tag, Key, Value, Params]),
Xml =
"<document type=\"freeswitch/xml\">
<section name=\"result\">
<result status=\"not found\" />
</section>
</document>",
{ok, Xml };
%%
%% Default handler replies that the requested document section, tag, and key are not
%% found.
%%
xml_fetch({fetch, Section, Tag, Key, Value, Params}) ->
io:format( "freeswitch_callback:xml_fetch( {fetch, Section=~w, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
[Section, Tag, Key, Value, Params]),
Xml =
"<document type=\"freeswitch/xml\">
<section name=\"result\">
<result status=\"not found\" />
</section>
</document>",
{ok, Xml };
%%
%% If the request isn't recognized, just log it.
%%
xml_fetch( Request ) ->
io:format( "freeswitch_callback:xml_fetch( Request=~w ) not recognized~n",
[Request]),
Xml =
"<document type=\"freeswitch/xml\">
<section name=\"result\">
<result status=\"not found\" />
</section>
</document>",
{ok, Xml }.
%%
%% If the request isn't recognized, just log it and do nothing.
%%
handle_call(Request, _From, State) ->
io:format("freeswitch_callback:handle_call( ~w, _From, State) unrecognized request~n",
[Request]),
{reply, {error, unrecognized_request}, State}.
handle_cast(Message, State) ->
error_logger:error_msg("~p received unrecognized cast ~p~n",
[self(), Message]),
{noreply, State}.
handle_info({fetch, Section, Tag, Key, Value, FetchID, Params}, #st{fsnode=Node, pbxpid=Pid}=State) ->
{ok, XML} = gen_server:call(Pid, {fetch, Section, Tag, Key, Value, Params}),
{api, Node} ! {fetch_reply, FetchID, XML},
receive
ok ->
{noreply, State};
{error, Reason} ->
{stop, {error, Reason}, State}
end.
_______________________________________________
FreeSWITCH-users mailing list
FreeSWITCH-users@lists.freeswitch.org
http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
http://www.freeswitch.org