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

On Tue, Sep 15, 2009 at 7:38 AM, Mark Sobkow <m.sobkow@marketelsystems.com> wrote:
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