Navigation Menu

Skip to content

Commit

Permalink
Merge branch 'master' into v2.07
Browse files Browse the repository at this point in the history
  • Loading branch information
James Aimonetti committed Dec 4, 2012
2 parents a7f8721 + c9252a7 commit 1dc0203
Show file tree
Hide file tree
Showing 19 changed files with 290 additions and 185 deletions.
3 changes: 2 additions & 1 deletion ecallmgr/src/ecallmgr_fs_nodes.erl
Expand Up @@ -734,7 +734,8 @@ close_node(#node{node=Node}) ->
close_node(Node);
close_node(Node) ->
catch erlang:monitor_node(Node, false), % will crash if Node is down already
_ = ecallmgr_fs_pinger_sup:remove_node(Node),
_P = ecallmgr_fs_pinger_sup:remove_node(Node),
lager:debug("stopped pinger: ~p", [_P]),
ecallmgr_fs_sup:remove_node(Node).

start_preconfigured_servers() ->
Expand Down
3 changes: 2 additions & 1 deletion ecallmgr/src/ecallmgr_fs_pinger_sup.erl
Expand Up @@ -46,7 +46,8 @@ add_node(Node, Options) ->

-spec remove_node/1 :: (atom()) -> 'ok' | {'error', 'running' | 'not_found' | 'simple_one_for_one'}.
remove_node(Node) ->
_ = supervisor:terminate_child(?SERVER, Node),
_T = supervisor:terminate_child(?SERVER, Node),
lager:debug("terminated pinger: ~p", [_T]),
supervisor:delete_child(?SERVER, Node).

%% ===================================================================
Expand Down
6 changes: 3 additions & 3 deletions ecallmgr/src/ecallmgr_fs_sup.erl
Expand Up @@ -38,9 +38,9 @@
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).

-spec add_node/2 :: (atom(), proplist()) -> {'error', term()} |
{'ok','undefined' | pid()} |
{'ok','undefined' | pid(), term()}.
-spec add_node/2 :: (atom(), wh_proplist()) -> {'error', term()} |
{'ok','undefined' | pid()} |
{'ok','undefined' | pid(), term()}.
add_node(Node, Options) ->
supervisor:start_child(?SERVER, ?NODE(Node, [Node, Options])).

Expand Down
37 changes: 30 additions & 7 deletions ecallmgr/src/ecallmgr_originate.erl
Expand Up @@ -195,16 +195,21 @@ handle_cast({maybe_update_node, Node}, #state{node=_OldNode}=State) ->
{noreply, State#state{node=Node}, hibernate};

handle_cast({create_uuid}, #state{node=Node, originate_req=JObj}=State) ->
lager:debug("creating a new uuid", []),
lager:debug("creating a new uuid"),
{noreply, State#state{uuid=create_uuid(JObj, Node)}, hibernate};

handle_cast({get_originate_action}, #state{originate_req=JObj}=State) ->
handle_cast({get_originate_action}, #state{originate_req=JObj, node=Node}=State) ->
gen_listener:cast(self(), {build_originate_args}),
ApplicationName = wh_json:get_value(<<"Application-Name">>, JObj),

Action = get_originate_action(ApplicationName, JObj),
UseNode = maybe_update_node(JObj, Node),
lager:debug("maybe updating node from ~s to ~s", [Node, UseNode]),

{noreply, State#state{action=Action, app=ApplicationName}};
{noreply, State#state{action=Action
,app=ApplicationName
,node=UseNode
}};

handle_cast({build_originate_args}, #state{uuid=undefined
,action = ?ORIGINATE_PARK
Expand Down Expand Up @@ -272,8 +277,13 @@ handle_cast({originate_execute}, #state{tref=TRef}=State) when is_reference(TRef
gen_listener:cast(self(), {originate_execute}),
_ = erlang:cancel_timer(TRef),
{noreply, State#state{tref=undefined}};
handle_cast({originate_execute}, #state{dialstrings=Dialstrings, node=Node, originate_req=JObj
,uuid=UUID, server_id=ServerId, control_pid=CtrlPid}=State) ->
handle_cast({originate_execute}, #state{dialstrings=Dialstrings
,node=Node
,originate_req=JObj
,uuid=UUID
,server_id=ServerId
,control_pid=CtrlPid
}=State) ->
case originate_execute(Node, Dialstrings) of
{ok, _} when is_pid(CtrlPid) ->
lager:debug("originate completed"),
Expand Down Expand Up @@ -424,6 +434,17 @@ get_originate_action(_, _) ->
lager:debug("got originate with action park"),
?ORIGINATE_PARK.

-spec maybe_update_node/2 :: (wh_json:object(), atom()) -> atom().
maybe_update_node(JObj, Node) ->
case wh_json:get_value(<<"Existing-Call-ID">>, JObj) of
undefined -> Node;
CallId ->
case ecallmgr_fs_nodes:channel_node(CallId) of
{error, _} -> Node;
{ok, N} -> N
end
end.

get_eavesdrop_action(JObj) ->
{CallId, Group} = case wh_json:get_value(<<"Eavesdrop-Group-ID">>, JObj) of
undefined -> {wh_json:get_value(<<"Eavesdrop-Call-ID">>, JObj), <<>>};
Expand All @@ -450,9 +471,11 @@ build_originate_args(Action, Endpoints, JObj) ->
], JObj),
list_to_binary([ecallmgr_fs_xml:get_channel_vars(J), DialStrings, " ", Action]).

-spec originate_execute/2 :: (atom(), ne_binary()) -> {'ok', ne_binary()} |
{'error', ne_binary()}.
-spec originate_execute/2 :: (atom(), ne_binary()) ->
{'ok', ne_binary()} |
{'error', ne_binary()}.
originate_execute(Node, Dialstrings) ->
lager:debug("executing on ~s: ~s", [Node, Dialstrings]),
{ok, BGApiID} = freeswitch:bgapi(Node, 'originate', wh_util:to_list(Dialstrings)),

receive
Expand Down
1 change: 1 addition & 0 deletions lib/whistle-1.0.0/src/api/wapi_resource.erl
Expand Up @@ -63,6 +63,7 @@
-define(ORIGINATE_REQ_HEADERS, [<<"Endpoints">>, <<"Application-Name">>]).
-define(OPTIONAL_ORIGINATE_REQ_HEADERS, [<<"Application-Data">>, <<"Custom-Channel-Vars">>
,<<"Export-Custom-Channel-Vars">>, <<"Outbound-Call-ID">>
,<<"Existing-Call-ID">> % If set, use this node, otherwise ignore
%% Eavesdrop
,<<"Eavesdrop-Call-ID">>, <<"Eavesdrop-Mode">>, <<"Eavesdrop-Group-ID">>
| fun() ->
Expand Down
10 changes: 7 additions & 3 deletions whistle_apps/apps/acdc/src/acdc_agent.erl
Expand Up @@ -363,6 +363,7 @@ handle_cast({channel_hungup, CallId}, #state{call=Call
,record_calls=ShouldRecord
,is_thief=IsThief
,agent_call_id=ACallId
,agent_id=AgentId
}=State) ->
CCallId = call_id(Call),
case CallId of
Expand All @@ -372,6 +373,7 @@ handle_cast({channel_hungup, CallId}, #state{call=Call

maybe_stop_recording(Call, ShouldRecord),

put(callid, AgentId),
case IsThief of
false ->
{noreply, State#state{call=undefined
Expand All @@ -384,11 +386,11 @@ handle_cast({channel_hungup, CallId}, #state{call=Call
{stop, normal, State}
end;
ACallId ->
lager:debug("agent channel hungup"),
lager:debug("agent channel ~s hungup", [ACallId]),
acdc_util:unbind_from_call_events(ACallId),
{noreply, State#state{agent_call_id=undefined}};
_CallId ->
lager:debug("~s call id for channel_hungup, ignoring", [_CallId]),
lager:debug("unknown call id ~s for channel_hungup, ignoring", [_CallId]),
{noreply, State}
end;

Expand Down Expand Up @@ -447,6 +449,7 @@ handle_cast({bridge_to_member, Call, WinJObj, EPs}, #state{fsm_pid=FSM
,acct_id=AcctId
,agent_id=AgentId
}=State) ->
put(callid, whapps_call:call_id(Call)),
lager:debug("bridging to agent endpoints: ~p", [EPs]),

RingTimeout = wh_json:get_value(<<"Ring-Timeout">>, WinJObj),
Expand Down Expand Up @@ -482,7 +485,7 @@ handle_cast({originate_execute, JObj}, #state{my_q=Q}=State) ->
ACallId = wh_json:get_value(<<"Call-ID">>, JObj),
acdc_util:bind_to_call_events(ACallId),

lager:debug("execute the originate for agent callid ~s", [ACallId]),
lager:debug("execute the originate for agent call-id ~s", [ACallId]),

send_originate_execute(JObj, Q),
{noreply, State#state{agent_call_id=ACallId}};
Expand Down Expand Up @@ -736,6 +739,7 @@ maybe_connect_to_agent(FSM, EPs, Call, Timeout) ->
,{<<"Caller-ID-Number">>, whapps_call:caller_id_number(Call)}
,{<<"Outgoing-Caller-ID-Name">>, whapps_call:caller_id_name(Call)}
,{<<"Outgoing-Caller-ID-Number">>, whapps_call:caller_id_number(Call)}
,{<<"Existing-Call-ID">>, whapps_call:call_id(Call)}
| wh_api:default_headers(?APP_NAME, ?APP_VERSION)
]),

Expand Down
56 changes: 34 additions & 22 deletions whistle_apps/apps/acdc/src/acdc_agent_fsm.erl
Expand Up @@ -83,6 +83,7 @@
,caller_exit_key = <<"#">> :: ne_binary()
,agent_call_id :: ne_binary()
,next_status :: ne_binary()
,fsm_call_id :: ne_binary() % used when no call-ids are available
,endpoints = [] :: wh_json:objects()
}).

Expand Down Expand Up @@ -248,7 +249,8 @@ start_link(AcctId, AgentId, AgentProc, Props) ->
%% @end
%%--------------------------------------------------------------------
init([AcctId, AgentId, AgentProc, Props]) ->
put(callid, <<"fsm_", AcctId/binary, "_", AgentId/binary>>),
FSMCallId = <<"fsm_", AcctId/binary, "_", AgentId/binary>>,
put(callid, FSMCallId),
lager:debug("started acdc agent fsm"),

acdc_stats:agent_active(AcctId, AgentId),
Expand All @@ -267,6 +269,7 @@ init([AcctId, AgentId, AgentProc, Props]) ->
,agent_proc=AgentProc
,agent_proc_id=acdc_util:proc_id(AgentProc)
,sync_ref=SyncRef
,fsm_call_id=FSMCallId
}}.

%%--------------------------------------------------------------------
Expand Down Expand Up @@ -371,16 +374,20 @@ ready({sync_req, JObj}, #state{agent_proc=Srv}=State) ->
ready({member_connect_win, JObj}, #state{agent_proc=Srv
,endpoints=EPs
,agent_proc_id=MyId
,agent_id=AgentId
}=State) ->
Call = whapps_call:from_json(wh_json:get_value(<<"Call">>, JObj)),
CallId = whapps_call:call_id(Call),

put(callid, CallId),

WrapupTimer = wh_json:get_integer_value(<<"Wrapup-Timeout">>, JObj, 0),
CallerExitKey = wh_json:get_value(<<"Caller-Exit-Key">>, JObj, <<"#">>),
QueueId = wh_json:get_value(<<"Queue-ID">>, JObj),

case wh_json:get_value(<<"Agent-Process-ID">>, JObj) of
MyId ->
lager:debug("we won us a member: ~s", [CallId]),
lager:debug("trying to ring agent ~s to connect to caller", [AgentId]),

acdc_agent:bridge_to_member(Srv, Call, JObj, EPs),

Expand All @@ -392,7 +399,8 @@ ready({member_connect_win, JObj}, #state{agent_proc=Srv
,caller_exit_key=CallerExitKey
}};
_OtherId ->
lager:debug("one of our counterparts won us a member: ~s", [CallId]),
lager:debug("monitoring agent ~s connecting to caller", [AgentId]),

acdc_agent:monitor_call(Srv, Call),

{next_state, ringing, State#state{
Expand Down Expand Up @@ -425,6 +433,9 @@ ready({resume}, State) ->
ready({dtmf_pressed, _}, State) ->
{next_state, ready, State};

ready({originate_failed, _E}, State) ->
{next_state, ready, State};

ready(_Evt, State) ->
lager:debug("unhandled event: ~p", [_Evt]),
{next_state, ready, State}.
Expand All @@ -443,14 +454,14 @@ ringing({member_connect_req, _}, State) ->
{next_state, ringing, State};

ringing({member_connect_win, JObj}, #state{agent_proc=Srv}=State) ->
lager:debug("we won, but can't process this right now"),
lager:debug("agent won, but can't process this right now (already ringing)"),
acdc_agent:member_connect_retry(Srv, JObj),
{next_state, ringing, State};

ringing({originate_ready, JObj}, #state{agent_proc=Srv}=State) ->
CallId = wh_json:get_value(<<"Call-ID">>, JObj),

lager:debug("ready to originate to the agent: ~s", [CallId]),
lager:debug("ringing agent's phone with call-id ~s", [CallId]),
acdc_agent:originate_execute(Srv, JObj),
{next_state, ringing, State#state{agent_call_id=CallId}};

Expand All @@ -460,7 +471,7 @@ ringing({originate_failed, _E}, #state{agent_proc=Srv
,member_call_queue_id=QueueId
,member_call_id=CallId
}=State) ->
lager:debug("failed to execute originate to the agent: ~p", [_E]),
lager:debug("ringing agent failed: ~p", [_E]),
acdc_agent:member_connect_retry(Srv, CallId),

acdc_stats:call_missed(AcctId, QueueId, AgentId, CallId),
Expand All @@ -471,7 +482,7 @@ ringing({originate_failed, _E}, #state{agent_proc=Srv
ringing({channel_bridged, CallId}, #state{member_call_id=CallId
,agent_proc=Srv
}=State) ->
lager:debug("agent has connected to member"),
lager:debug("agent phone has been connected to caller"),
acdc_agent:member_connect_accepted(Srv),
{next_state, answered, State#state{call_status_ref=start_call_status_timer()
,call_status_failures=0
Expand All @@ -484,7 +495,7 @@ ringing({channel_hungup, CallId}, #state{agent_proc=Srv
,member_call_queue_id=QueueId
,member_call_id=MCallId
}=State) ->
lager:debug("agent channel was destroyed before we could connect: ~s", [CallId]),
lager:debug("agent did not answer their phone in time: ~s", [CallId]),

acdc_agent:channel_hungup(Srv, CallId),
acdc_agent:member_connect_retry(Srv, MCallId),
Expand All @@ -501,7 +512,7 @@ ringing({channel_hungup, CallId}, #state{agent_proc=Srv
,agent_call_id=AgentCallId
}=State
) ->
lager:debug("member channel (~s) has gone down, stop agent call", [CallId]),
lager:debug("caller's channel (~s) has gone down, stop agent's call", [CallId]),
acdc_agent:channel_hungup(Srv, AgentCallId),

acdc_stats:call_abandoned(AcctId, QueueId, CallId, ?ABANDON_HANGUP),
Expand All @@ -526,14 +537,14 @@ ringing({dtmf_pressed, DTMF}, #state{caller_exit_key=DTMF
ringing({channel_answered, ACallId}, #state{agent_call_id=ACallId
,agent_proc=Srv
}=State) ->
lager:debug("agent channel ready: ~s", [ACallId]),
lager:debug("agent answered phone on ~s, connecting to caller", [ACallId]),
acdc_agent:join_agent(Srv, ACallId),
{next_state, answered, State#state{call_status_ref=start_call_status_timer()
,call_status_failures=0
}};

ringing({channel_answered, MCallId}, #state{member_call_id=MCallId}=State) ->
lager:debug("member channel answered"),
lager:debug("caller's channel answered"),
{next_state, ringing, State};

ringing({sync_req, JObj}, #state{agent_proc=Srv}=State) ->
Expand All @@ -560,7 +571,7 @@ ringing(current_call, _, #state{member_call=Call
answered({member_connect_req, _}, State) ->
{next_state, answered, State};
answered({member_connect_win, JObj}, #state{agent_proc=Srv}=State) ->
lager:debug("we won, but can't process this right now"),
lager:debug("agent won, but can't process this right now (on the phone with someone)"),
acdc_agent:member_connect_retry(Srv, JObj),
{next_state, answered, State};

Expand All @@ -570,7 +581,7 @@ answered({dialplan_error, _App}, #state{agent_proc=Srv
,member_call_queue_id=QueueId
,member_call_id=CallId
}=State) ->
lager:debug("join failed, clearing call"),
lager:debug("connecting agent to caller failed, clearing call"),
acdc_agent:member_connect_retry(Srv, CallId),

acdc_stats:call_missed(AcctId, QueueId, AgentId, CallId),
Expand All @@ -582,28 +593,28 @@ answered({channel_bridged, CallId}, #state{member_call_id=CallId
,acct_id=_AcctId
,member_call=_Call
}=State) ->
lager:debug("member has connected to agent"),
lager:debug("agent has connected to caller"),
acdc_agent:member_connect_accepted(Srv),

{next_state, answered, State};

answered({channel_bridged, CallId}, #state{agent_call_id=CallId
,agent_proc=Srv
}=State) ->
lager:debug("agent has connected to member"),
lager:debug("agent has connected to caller"),
acdc_agent:member_connect_accepted(Srv),
{next_state, answered, State};

answered({channel_hungup, CallId}, #state{member_call_id=CallId}=State) ->
lager:debug("member call has hung up"),
lager:debug("caller's channel hung up"),
{next_state, wrapup, State#state{wrapup_timeout=0, wrapup_ref=hangup_call(State)}};

answered({channel_hungup, CallId}, #state{agent_call_id=CallId}=State) ->
lager:debug("agent call has hung up"),
lager:debug("agent's channel has hung up"),
{next_state, wrapup, State#state{wrapup_timeout=0, wrapup_ref=hangup_call(State)}};

answered({channel_hungup, CallId}, #state{agent_proc=Srv}=State) ->
lager:debug("someone(~s) hungup, who cares", [CallId]),
lager:debug("someone(~s) hungup, ignoring", [CallId]),
acdc_agent:channel_hungup(Srv, CallId),
{next_state, answered, State};

Expand All @@ -615,7 +626,7 @@ answered({sync_req, JObj}, #state{agent_proc=Srv
{next_state, answered, State};

answered({channel_unbridged, CallId}, #state{member_call_id=CallId}=State) ->
lager:debug("member channel unbridged"),
lager:debug("caller channel unbridged"),
{next_state, wrapup, State#state{wrapup_timeout=0, wrapup_ref=hangup_call(State)}};
answered({channel_unbridged, CallId}, #state{agent_call_id=CallId}=State) ->
lager:debug("agent channel unbridged"),
Expand Down Expand Up @@ -661,7 +672,7 @@ answered(current_call, _, #state{member_call=Call
wrapup({member_connect_req, _}, State) ->
{next_state, wrapup, State#state{wrapup_timeout=0}};
wrapup({member_connect_win, JObj}, #state{agent_proc=Srv}=State) ->
lager:debug("we won, but can't process this right now"),
lager:debug("agent won, but can't process this right now (in wrapup)"),
acdc_agent:member_connect_retry(Srv, JObj),
{next_state, wrapup, State#state{wrapup_timeout=0}};

Expand Down Expand Up @@ -754,7 +765,7 @@ paused({sync_req, JObj}, #state{agent_proc=Srv
paused({member_connect_req, _}, State) ->
{next_state, paused, State};
paused({member_connect_win, JObj}, #state{agent_proc=Srv}=State) ->
lager:debug("we won, but can't process this right now"),
lager:debug("agent won, but can't process this right now"),
acdc_agent:member_connect_retry(Srv, JObj),
{next_state, paused, State};
paused(_Evt, State) ->
Expand Down Expand Up @@ -929,7 +940,8 @@ time_left(Ref) when is_reference(Ref) ->
time_left(false) -> undefined;
time_left(Ms) when is_integer(Ms) -> Ms div 1000.

clear_call(State) ->
clear_call(#state{fsm_call_id=FSMCallId}=State) ->
put(callid, FSMCallId),
State#state{wrapup_timeout = 0
,wrapup_ref = undefined
,member_call = undefined
Expand Down

0 comments on commit 1dc0203

Please sign in to comment.