📄 megaco_messenger.erl
字号:
%% Been removed already? ignore end;do_handle_long_request(_, {error, Reason}, ConnData, TransId) -> ?report_trace(ConnData, "send trans reply", [TransId, {error, Reason}]), ignore. handle_request_abort_callback(ConnData, TransId, Pid) -> ?report_trace(ConnData, "callback: trans request aborted", [TransId, Pid]), ConnHandle = ConnData#conn_data.conn_handle, Version = ConnData#conn_data.protocol_version, UserMod = ConnData#conn_data.user_mod, UserArgs = ConnData#conn_data.user_args, Serial = TransId#trans_id.serial, Res = (catch apply(UserMod, handle_trans_request_abort, [ConnHandle, Version, Serial, Pid | UserArgs])), ?report_debug(ConnData, "return: trans request aborted", [TransId, {return, Res}]), case Res of ok -> ok; _ -> warning_msg("transaction request abort callback failed: ~w", [Res]), ok end.handle_request_callback(ConnData, TransId, Actions, T) -> ?report_trace(ConnData, "callback: trans request", [T]), ConnHandle = ConnData#conn_data.conn_handle, Version = ConnData#conn_data.protocol_version, UserMod = ConnData#conn_data.user_mod, UserArgs = ConnData#conn_data.user_args, Res = (catch apply(UserMod, handle_trans_request, [ConnHandle, Version, Actions | UserArgs])), ?report_debug(ConnData, "return: trans request", [T, {return, Res}]), case Res of ignore -> %% NOTE: Only used for testing!! {discard_ack, ignore}; ignore_trans_request -> {discard_ack, ignore_trans_request}; {discard_ack, Replies} when is_list(Replies) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {discard_ack, SendReply}; {discard_ack, Error} when is_record(Error, 'ErrorDescriptor') -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {discard_ack, SendReply}; {discard_ack, Replies, SendOpts} when is_list(Replies) and is_list(SendOpts) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, asn1_NOVALUE), {discard_ack, SendReply}; {discard_ack, Error, SendOpts} when is_record(Error, 'ErrorDescriptor') and is_list(SendOpts) -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, asn1_NOVALUE), {discard_ack, SendReply}; {{handle_pending_ack, AckData}, Replies} when is_list(Replies) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], when_pending_sent), {{handle_ack, AckData}, SendReply}; {{handle_pending_ack, AckData}, Error} when is_record(Error, 'ErrorDescriptor') -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], when_pending_sent), {{handle_ack, AckData}, SendReply}; {{handle_pending_ack, AckData}, Replies, SendOpts} when is_list(Replies) and is_list(SendOpts) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, when_pending_sent), {{handle_ack, AckData}, SendReply}; {{handle_pending_ack, AckData}, Error, SendOpts} when is_record(Error, 'ErrorDescriptor') and is_list(SendOpts) -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, when_pending_sent), {{handle_ack, AckData}, SendReply}; {{handle_ack, AckData}, Replies} when is_list(Replies) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], 'NULL'), {{handle_ack, AckData}, SendReply}; {{handle_ack, AckData}, Error} when is_record(Error, 'ErrorDescriptor') -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], 'NULL'), {{handle_ack, AckData}, SendReply}; {{handle_ack, AckData}, Replies, SendOpts} when is_list(Replies) and is_list(SendOpts) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, 'NULL'), {{handle_ack, AckData}, SendReply}; {{handle_ack, AckData}, Error, SendOpts} when is_record(Error, 'ErrorDescriptor') and is_list(SendOpts) -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, 'NULL'), {{handle_ack, AckData}, SendReply}; {{handle_sloppy_ack, AckData}, Replies} when is_list(Replies) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {{handle_ack, AckData}, SendReply}; {{handle_sloppy_ack, AckData}, Error} when is_record(Error, 'ErrorDescriptor') -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {{handle_ack, AckData}, SendReply}; {{handle_sloppy_ack, AckData}, Replies, SendOpts} when is_list(Replies) and is_list(SendOpts) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, asn1_NOVALUE), {{handle_ack, AckData}, SendReply}; {{handle_sloppy_ack, AckData}, Error, SendOpts} when is_record(Error, 'ErrorDescriptor') and is_list(SendOpts) -> Reply = {transactionError, Error}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, asn1_NOVALUE), {{handle_ack, AckData}, SendReply}; {pending, RequestData} -> %% The user thinks that this request will take %% quite a while to evaluate. Maybe respond with %% a pending trans (depends on the pending limit) SendReply = maybe_send_pending(ConnData, TransId), {{pending, RequestData}, SendReply}; Error -> ErrorText = atom_to_list(UserMod), ED = #'ErrorDescriptor'{ errorCode = ?megaco_internal_gateway_error, errorText = ErrorText}, ?report_important(ConnData, "callback: <ERROR> trans request", [ED, {error, Error}]), error_msg("transaction request callback failed: ~w", [Error]), Reply = {transactionError, ED}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {discard_ack, SendReply} end.handle_long_request_callback(ConnData, TransId, RequestData) -> ?report_trace(ConnData, "callback: trans long request", [RequestData]), ConnHandle = ConnData#conn_data.conn_handle, Version = ConnData#conn_data.protocol_version, UserMod = ConnData#conn_data.user_mod, UserArgs = ConnData#conn_data.user_args, Res = (catch apply(UserMod, handle_trans_long_request, [ConnHandle, Version, RequestData | UserArgs])), ?report_debug(ConnData, "return: trans long request", [{request_data, RequestData}, {return, Res}]), case Res of ignore -> {discard_ack, ignore}; {discard_ack, Replies} when is_list(Replies) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {discard_ack, SendReply}; {discard_ack, Replies, SendOpts} when is_list(Replies) and is_list(SendOpts) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, asn1_NOVALUE), {discard_ack, SendReply}; {{handle_ack, AckData}, Replies} when is_list(Replies) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], 'NULL'), {{handle_ack, AckData}, SendReply}; {{handle_ack, AckData}, Replies, SendOpts} when is_list(Replies) and is_list(SendOpts) -> Reply = {actionReplies, Replies}, SendReply = maybe_send_reply(ConnData, TransId, Reply, SendOpts, 'NULL'), {{handle_ack, AckData}, SendReply}; Error -> ErrorText = atom_to_list(UserMod), ED = #'ErrorDescriptor'{errorCode = ?megaco_internal_gateway_error, errorText = ErrorText}, ?report_important(ConnData, "callback: <ERROR> trans long request", [ED, {error, Error}]), error_msg("long transaction request callback failed: ~w", [Error]), Reply = {transactionError, ED}, SendReply = maybe_send_reply(ConnData, TransId, Reply, [], asn1_NOVALUE), {discard_ack, SendReply} end.handle_pending(ConnData, T) -> TransId = to_local_trans_id(ConnData), ?rt2("handle pending", [T, TransId]), case megaco_monitor:lookup_request(TransId) of [Req] -> %% ------------------------------------------ %% %% Check received pending limit %% %% ------------------------------------------ Limit = ConnData#conn_data.recv_pending_limit, case check_and_maybe_incr_pending_limit(Limit, recv, TransId) of ok -> %% ---------------------------------------------------- %% %% Received pending limit not exceeded %% %% ---------------------------------------------------- handle_recv_pending(ConnData, TransId, Req, T); error -> %% ---------------------------------------------------- %% %% Received pending limit exceeded %% %% Time to give up on this transaction %% 1) Delete request record %% 2) Cancel timers %% 3) Delete the (receive) pending counter %% 4) Inform the user (handle_trans_reply) %% %% ---------------------------------------------------- handle_recv_pending_error(ConnData, TransId, Req, T); aborted -> %% ---------------------------------------------------- %% %% Received pending limit already exceeded %% %% BMK BMK BMK -- can this really happen? %% %% The user has already been notified about this %% (see error above) %% %% ---------------------------------------------------- ok end; [] -> ?report_trace(ConnData, "remote pending (no receiver)", [T]), return_unexpected_trans(ConnData, T) end.handle_recv_pending(#conn_data{long_request_resend = LRR, conn_handle = ConnHandle} = ConnData, TransId, #request{timer_ref = {short, Ref}, init_long_timer = InitTimer} = Req, T) -> ?rt2("handle pending - long request", [LRR, InitTimer]), %% The request seems to take a while, %% let's reset our transmission timer. %% We now know the other side has got %% the request and is working on it, %% so there is no need to keep the binary %% message for re-transmission. %% Start using the long timer. %% We can now drop the "bytes", since we will %% not resend from now on. megaco_monitor:cancel_apply_after(Ref), {WaitFor, CurrTimer} = megaco_timer:init(InitTimer), ConnHandle = ConnData#conn_data.conn_handle, M = ?MODULE, F = request_timeout, A = [ConnHandle, TransId], Ref2 = megaco_monitor:apply_after(M, F, A, WaitFor), Req2 = case LRR of true -> Req#request{timer_ref = {long, Ref2}, curr_timer = CurrTimer}; false -> Req#request{bytes = {no_send, garb_binary}, timer_ref = {long, Ref2}, curr_timer = CurrTimer} end, ?report_trace(ConnData, "trans pending (timer restarted)", [T]), megaco_monitor:insert_request(Req2); % Timing problem? handle_recv_pending(_ConnData, _TransId, #request{timer_ref = {long, _Ref}, curr_timer = timeout}, _T) -> ?rt3("handle pending - timeout"), %% The request seems to take a while, %% let's reset our transmission timer. %% We now know the other side has got %% the request and is working on it, %% so there is no need to keep the binary %% message for re-transmission. %% This can happen if the timer is running for the last %% time. I.e. next time it expires, will be the last. %% Therefor we really do not need to do anything here. %% The cleanup will be done in request_timeout. ok;handle_recv_pending(#conn_data{conn_handle = ConnHandle} = ConnData, TransId, #request{timer_ref = {long, Ref}, curr_timer = CurrTimer} = Req, T) -> ?rt2("handle pending - still waiting", [CurrTimer]), %% The request seems to take a while, %% let's reset our transmission timer. %% We now know the other side has got %% the request and is working on it, %% so there is no need to keep the binary %% message for re-transmission. %% We just need to recalculate the timer, i.e. %% increment the timer (one "slot" has been consumed). megaco_monitor:cancel_apply_after(Ref), {WaitFor, Timer2} = megaco_timer:restart(CurrTimer), ConnHandle = ConnData#conn_data.conn_handle, M = ?MODULE, F = request_timeout, A = [ConnHandle, TransId], Ref2 = megaco_monitor:apply_after(M, F, A, WaitFor), Req2 = Req#request{timer_ref = {long, Ref2}, curr_timer = Timer2}, ?repo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -