From 5e1fcbd1bf588b295fa3bc79b101729b6d98261b Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 13 Mar 2009 17:33:17 +0000 Subject: [PATCH] Make handlecall return more correct errors; sync freeswitch.erl with git version git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12592 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../mod_erlang_event/freeswitch.erl | 85 ++++++++++++++++--- .../mod_erlang_event/handle_msg.c | 16 ++-- 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/src/mod/event_handlers/mod_erlang_event/freeswitch.erl b/src/mod/event_handlers/mod_erlang_event/freeswitch.erl index c61d0aa5a7..248eddd79c 100644 --- a/src/mod/event_handlers/mod_erlang_event/freeswitch.erl +++ b/src/mod/event_handlers/mod_erlang_event/freeswitch.erl @@ -14,13 +14,13 @@ -module(freeswitch). --export([send/2, api/3, bgapi/3, event/2, +-export([send/2, api/3, api/2, bgapi/3, bgapi/4, event/2, nixevent/2, noevents/1, close/1, get_event_header/2, get_event_body/1, get_event_name/1, getpid/1, sendmsg/3, - sendevent/3, handlecall/2, start_fetch_handler/4, + sendevent/3, handlecall/2, handlecall/3, start_fetch_handler/4, start_log_handler/3, start_event_handler/3]). --define(TIMEOUT, 10000). +-define(TIMEOUT, 5000). %% @doc Return the value for a specific header in an event or `{error,notfound}'. get_event_header([], _Needle) -> @@ -63,11 +63,18 @@ send(Node, Term) -> api(Node, Cmd, Args) -> {api, Node} ! {api, Cmd, Args}, receive - X -> X + {ok, X} -> + {ok, X}; + {error, X} -> + {error, X} after ?TIMEOUT -> timeout end. +%% @doc Same as @link{api/3} except there's no additional arguments. +api(Node, Cmd) -> + api(Node, Cmd, ""). + %% @doc Make a backgrounded API call to FreeSWITCH. The asynchronous reply is %% sent to calling process after it is received. This function %% returns the result of the initial bgapi call or `timeout' if FreeSWITCH fails @@ -104,11 +111,48 @@ bgapi(Node, Cmd, Args) -> {api, X} -> X end. +%% @doc Make a backgrounded API call to FreeSWITCH. The asynchronous reply is +%% passed as the argument to `Fun' after it is received. This function +%% returns the result of the initial bgapi call or `timeout' if FreeSWITCH fails +%% to respond. +bgapi(Node, Cmd, Args, Fun) -> + Self = self(), + % spawn a new process so that both responses go here instead of directly to + % the calling process. + spawn(fun() -> + {bgapi, Node} ! {bgapi, Cmd, Args}, + receive + {error, Reason} -> + % send the error condition to the calling process + Self ! {api, {error, Reason}}; + {ok, JobID} -> + % send the reply to the calling process + Self ! {api, ok}, + receive % wait for the job's reply + {bgok, JobID, Reply} -> + % Call the function with the reply + Fun(ok, Reply); + {bgerror, JobID, Reply} -> + Fun(error, Reply) + end + after ?TIMEOUT -> + % send a timeout to the calling process + Self ! {api, timeout} + end + end), + + % get the initial result of the command, NOT the asynchronous response, and + % return it + receive + {api, X} -> X + end. + %% @doc Request to receive any events in the list `List'. event(Node, Events) when is_list(Events) -> {event, Node} ! list_to_tuple(lists:append([event], Events)), receive - X -> X + ok -> ok; + {error, Reason} -> {error, Reason} after ?TIMEOUT -> timeout end; @@ -130,7 +174,8 @@ nixevent(Node, Event) when is_atom(Event) -> noevents(Node) -> {noevents, Node} ! noevents, receive - X -> X + ok -> ok; + {error, Reason} -> {error, Reason} after ?TIMEOUT -> timeout end. @@ -139,7 +184,7 @@ noevents(Node) -> close(Node) -> {close, Node} ! exit, receive - X -> X + ok -> ok after ?TIMEOUT -> timeout end. @@ -150,7 +195,8 @@ close(Node) -> sendevent(Node, EventName, Headers) -> {sendevent, Node} ! {sendevent, EventName, Headers}, receive - X -> X + ok -> ok; + {error, Reason} -> {error, Reason} after ?TIMEOUT -> timeout end. @@ -160,7 +206,8 @@ sendevent(Node, EventName, Headers) -> sendmsg(Node, UUID, Headers) -> {sendmsg, Node} ! {sendmsg, UUID, Headers}, receive - X -> X + ok -> ok; + {error, Reason} -> {error, Reason} after ?TIMEOUT -> timeout end. @@ -171,17 +218,29 @@ sendmsg(Node, UUID, Headers) -> getpid(Node) -> {getpid, Node} ! getpid, receive - X -> X + {ok, Pid} when is_pid(Pid) -> {ok, Pid} after ?TIMEOUT -> timeout end. %% @doc Request that FreeSWITCH send any events pertaining to call `UUID' to %% `Process' where process is a registered process name. -handlecall(Node, Process) -> - {handlecall, Node} ! {handlecall, Process}, +handlecall(Node, UUID, Process) -> + {handlecall, Node} ! {handlecall, UUID, Process}, receive - X -> X + ok -> ok; + {error, Reason} -> {error, Reason} + after ?TIMEOUT -> + timeout + end. + +%% @doc Request that FreeSWITCH send any events pertaining to call `UUID' to +%% the calling process. +handlecall(Node, UUID) -> + {handlecall, Node} ! {handlecall, UUID}, + receive + ok -> ok; + {error, Reason} -> {error, Reason} after ?TIMEOUT -> timeout end. diff --git a/src/mod/event_handlers/mod_erlang_event/handle_msg.c b/src/mod/event_handlers/mod_erlang_event/handle_msg.c index 28c704f7c1..23b34fad43 100644 --- a/src/mod/event_handlers/mod_erlang_event/handle_msg.c +++ b/src/mod/event_handlers/mod_erlang_event/handle_msg.c @@ -568,11 +568,17 @@ static switch_status_t handle_msg_handlecall(listener_t *listener, erlang_msg *m ei_x_encode_atom(rbuf, "badarg"); } else { switch_core_session_t *session; - if (!switch_strlen_zero_buf(uuid_str) && (session = switch_core_session_locate(uuid_str))) { - /* create a new session list element and attach it to this listener */ - if ((arity==2 && attach_call_to_pid(listener, &msg->from, session)) || - (arity==3 && attach_call_to_registered_process(listener, reg_name, session))) { - ei_x_encode_atom(rbuf, "ok"); + if (!switch_strlen_zero_buf(uuid_str) && SWITCH_UUID_FORMATTED_LENGTH == strlen(uuid_str)) { + if ((session = switch_core_session_locate(uuid_str))) { + /* create a new session list element and attach it to this listener */ + if ((arity==2 && attach_call_to_pid(listener, &msg->from, session)) || + (arity==3 && attach_call_to_registered_process(listener, reg_name, session))) { + ei_x_encode_atom(rbuf, "ok"); + } else { + ei_x_encode_tuple_header(rbuf, 2); + ei_x_encode_atom(rbuf, "error"); + ei_x_encode_atom(rbuf, "session_attach_failed"); + } } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error");