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.