📄 megaco_session_impl.erl.tmp
字号:
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%%%% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%%%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%%%% $Id$%%%%----------------------------------------------------------------------%% Purpose : Actual implementation of the Megaco Session interface.%%-----------------------------------------------------------------------module('Megaco_Session_impl').-behaviour(megaco_user).%% Megaco user callbacks:-export([ handle_connect/3, handle_disconnect/4, handle_syntax_error/4, handle_message_error/4, handle_trans_request/4, handle_trans_long_request/4, handle_trans_reply/5, handle_trans_ack/5, handle_unexpected_trans/4 ]).%% Genserver callbacks:-export([init/1, terminate/2, code_change/3, handle_info/2]).%% Requests from the (C-) user:-export([ systemInfo/4, startUser/5, stopUser/4, userInfo/5, updateUserInfo/5, connInfo/5, updateConnInfo/5, connect/7, disconnect/5, sendTransRequest/6, cancel/5 ]).%% Reponses from the (C-) user:%% -export([%% handleConnectResponse/3,%% handleDisconnectResponse/3,%% handleSyntaxErrorResponse/5,%% handleMessageErrorResponse/3,%% handleTransRequestPending/2,%% handleTransRequestResponse/5%% ]).-include_lib("megaco/include/megaco.hrl").-include_lib("megaco/include/megaco_message_v1.hrl").-include_lib("megaco_session/include/Megaco.hrl").-include_lib("megaco_session/include/MegacoMessage.hrl").%% Records:-record(state, {parent_pid}).-record(reply_data, {request_ref, reply_to}).-record(pending_data, {local_pid, remote_pid, request_ref, mon_ref}).-record(ack_data, {local_pid, remote_pid, request_ref}).-define(EXT(Fun, Value), megaco_session_externalizer:Fun(Value, undefined)).-define(INT(Fun, Value), megaco_session_internalizer:Fun(Value, undefined)).-ifdef(debug).-define(d(F,A),dbg(F,A)).-else.-define(d(F,A),ok).-endif.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Gen-server callbacks:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%init([{parent_pid, ParentPid}]) when pid(ParentPid) -> put(debug,true), ?d("init -> entry with" "~n ParentPid: ~p", [ParentPid]), process_flag(trap_exit, true), {ok, #state{parent_pid = ParentPid}};init(BadEnv) -> {stop, {bad_env, BadEnv}}.terminate(Reason, State) -> ?d("terminate -> entry with" "~n Reason: ~p", [Reason]), ok.code_change({down, Vsn}, State, Extra) -> {ok, State};code_change(Vsn, State, Extra) -> {ok, State}.handle_info({'EXIT', Pid, Reason}, State) when Pid == State#state.parent_pid -> ?d("handle_info(EXIT) -> entry when parent (~p) dies" "~n Reason: ~p", [Pid, Reason]), {stop, Reason, State};handle_info(Info, State) -> ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n", [?MODULE, self(), Info, State]), {noreply, State}.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Requests from the (C-) user:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%systemInfo(State, Ref, ReplyTo, Item) -> ?d("systemInfo -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n Item: ~w", [Ref, ReplyTo, Item]), case catch system_info_wrapper(Item) of {'EXIT', Reason} -> Status = ?EXT(tr_Status, {'EXIT', Reason}), Dummy = #'Megaco_SystemInfoValue'{label = 'Megaco_SystemInfo_connections', value = []}, 'Megaco_SessionUser':systemInfoResponse(Ref, Status, Dummy), {noreply, State}; Value -> Status = ?EXT(tr_Status, ok), V = #'Megaco_SystemInfoValue'{label = Item, value = Value}, 'Megaco_SessionUser':systemInfoResponse(Ref, Status, V), {noreply, State} end.system_info_wrapper(Item) -> %% Will exit at error case Item of 'Megaco_SystemInfo_connections' -> [?EXT(tr_conn_handle, CH) || CH <- megaco:system_info(connections)]; 'Megaco_SystemInfo_users' -> [?EXT(tr_MId, Mid) || Mid <- megaco:system_info(users)]; 'Megaco_SystemInfo_NActiveRequests' -> megaco:system_info(n_active_requests); 'Megaco_SystemInfo_NActiveReplies' -> megaco:system_info(n_active_replies); 'Megaco_SystemInfo_NActiveConnections' -> megaco:system_info(n_active_connections) end.%% ----------------------------------------------------------------------startUser(State, Ref, ReplyTo, Mid, Config) -> ?d("startUser -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n Mid: ~w" "~n Config: ~w", [Ref, ReplyTo, Mid, Config]), M = ?INT(tr_MId, Mid), ?d("startUser -> M: ~p", [M]), C = [?INT(tr_user_info_value, V) || V <- Config], ?d("startUser -> start megaco user", []), Res = megaco:start_user(M, [{user_mod, ?MODULE}, {user_args, [self()]} | C]), ?d("startUser -> megaco user registration: ~w", [Res]), Status = ?EXT(tr_Status, Res), 'Megaco_SessionUser':startUserResponse(ReplyTo, Ref, Status), ?d("startUser -> done", []), {noreply, State}.%% ----------------------------------------------------------------------stopUser(State, Ref, ReplyTo, Mid) -> ?d("stopUser -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n Mid: ~w", [Ref, ReplyTo, Mid]), M = ?INT(tr_MId, Mid), Res = megaco:stop_user(M), Status = ?EXT(tr_Status, Res), 'Megaco_SessionUser':stopUserResponse(ReplyTo, Ref, Status), {noreply, State}.%% ----------------------------------------------------------------------userInfo(State, Ref, ReplyTo, Mid, Item) -> ?d("userInfo -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n Mid: ~w" "~n Item: ~w", [Ref, ReplyTo, Mid, Item]), case catch user_info_wrapper(Mid, Item) of {'EXIT', Reason} -> Status = ?EXT(tr_Status, {'EXIT', Reason}), Dummy = #'Megaco_UserInfoValue'{label = 'Megaco_UserInfo_connections', value = []}, 'Megaco_SessionUser':userInfoResponse(ReplyTo, Ref, Status, Dummy), {noreply, State}; Value -> Status = ?EXT(tr_Status, ok), V = #'Megaco_UserInfoValue'{label = Item, value = Value}, 'Megaco_SessionUser':userInfoResponse(ReplyTo, Ref, Status, V), {noreply, State} end.user_info_wrapper(ExternalMid, Item) -> Mid = ?INT(tr_MId, ExternalMid), %% Will exit at error case Item of 'Megaco_UserInfo_connections' -> [?EXT(tr_conn_handle, CH) || CH <- megaco:user_info(Mid, connections)]; 'Megaco_UserInfo_receiveHandle' -> ?EXT(tr_receive_handle, megaco:user_info(Mid, receive_handle)); 'Megaco_UserInfo_minTransId' -> megaco:user_info(Mid, min_trans_id); 'Megaco_UserInfo_maxTransId' -> megaco:user_info(Mid, max_trans_id); 'Megaco_UserInfo_requestTimer' -> ?EXT(tr_timer, megaco:user_info(Mid, request_timer)); 'Megaco_UserInfo_longRequestTimer' -> ?EXT(tr_timer, megaco:user_info(Mid, long_request_timer)); 'Megaco_UserInfo_autoAck' -> megaco:user_info(Mid, auto_ack); 'Megaco_UserInfo_replyTimer' -> ?EXT(tr_timer, megaco:user_info(Mid, reply_timer)); 'Megaco_UserInfo_pendingTimer' -> ?EXT(tr_timer, megaco:user_info(Mid, pending_timer)); 'Megaco_UserInfo_sendMod' -> ?EXT(tr_atom, megaco:user_info(Mid, send_mod)); 'Megaco_UserInfo_encodingMod' -> ?EXT(tr_atom, megaco:user_info(Mid, encoding_mod)); 'Megaco_UserInfo_encodingConfig' -> ?EXT(tr_term, megaco:user_info(Mid, encoding_config)); 'Megaco_UserInfo_protocolVersion' -> megaco:user_info(Mid, protocol_version); 'Megaco_UserInfo_replyData' -> ?EXT(tr_term, megaco:user_info(Mid, reply_data)); 'Megaco_UserInfo_userMod' -> ?EXT(tr_atom, megaco:user_info(Mid, user_mod)); 'Megaco_UserInfo_userArgs' -> ?EXT(tr_term, megaco:user_info(Mid, user_args)) end.%% ----------------------------------------------------------------------updateUserInfo(State, Ref, ReplyTo, Mid, ItemValue) -> ?d("updateUserInfo -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n Mid: ~w" "~n ItemValue: ~w", [Ref, ReplyTo, Mid, ItemValue]), M = ?INT(tr_MId, Mid), {I, V} = ?INT(tr_user_item_value, ItemValue), Res = megaco:update_user_info(M, I, V), Status = ?EXT(tr_Status, Res), 'Megaco_SessionUser':updateUserInfoResponse(ReplyTo, Ref, Status), {noreply, State}.%% ----------------------------------------------------------------------connInfo(State, Ref, ReplyTo, ConnHandle, Item) -> ?d("connInfo -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n ConnHandle: ~w" "~n Item: ~w", [Ref, ReplyTo, ConnHandle, Item]), case catch conn_info_wrapper(ConnHandle, Item) of {'EXIT', Reason} -> Status = ?EXT(tr_Status, {'EXIT', Reason}), Dummy = #'Megaco_ConnInfoValue'{label = 'Megaco_ConnInfo_replyData', value = []}, 'Megaco_SessionConn':connInfoResponse(ReplyTo, Ref, Status, Dummy), {noreply, State}; Value -> Status = ?EXT(tr_Status, ok), V = #'Megaco_ConnInfoValue'{label = Item, value = Value}, 'Megaco_SessionConn':connInfoResponse(ReplyTo, Ref, Status, V), {noreply, State} end.conn_info_wrapper(ConnHandle, Item) -> CH = ?INT(tr_MId, ConnHandle), %% Will exit at error case Item of 'Megaco_ConnInfo_controlPid' -> megaco:conn_info(CH, control_pid); 'Megaco_ConnInfo_sendHandle' -> ?EXT(tr_term, megaco:conn_info(CH, send_handle)); 'Megaco_ConnInfo_receiveHandle' -> ?EXT(tr_receive_handle, megaco:conn_info(CH, receive_handle)); 'Megaco_ConnInfo_minTransId' -> megaco:conn_info(CH, min_trans_id); 'Megaco_ConnInfo_maxTransId' -> megaco:conn_info(CH, max_trans_id); 'Megaco_ConnInfo_requestTimer' -> ?EXT(tr_timer, megaco:conn_info(CH, request_timer)); 'Megaco_ConnInfo_longRequestTimer' -> ?EXT(tr_timer, megaco:conn_info(CH, long_request_timer)); 'Megaco_ConnInfo_autoAck' -> megaco:conn_info(CH, auto_ack); 'Megaco_ConnInfo_replyTimer' -> ?EXT(tr_timer, megaco:conn_info(CH, reply_timer)); 'Megaco_ConnInfo_pendingTimer' -> ?EXT(tr_timer, megaco:conn_info(CH, pending_timer)); 'Megaco_ConnInfo_sendMod' -> ?EXT(tr_atom, megaco:conn_info(CH, send_mod)); 'Megaco_ConnInfo_encodingMod' -> ?EXT(tr_atom, megaco:conn_info(CH, encoding_mod)); 'Megaco_ConnInfo_encodingConfig' -> ?EXT(tr_term, megaco:conn_info(CH, encoding_config)); 'Megaco_ConnInfo_protocolVersion' -> megaco:conn_info(CH, protocol_version); 'Megaco_ConnInfo_replyData' -> ?EXT(tr_term, megaco:conn_info(CH, reply_data)) end.%% ----------------------------------------------------------------------updateConnInfo(State, Ref, ReplyTo, ConnHandle, ItemValue) -> ?d("updateConnInfo -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n ConnHandle: ~w" "~n ItemValue: ~w", [Ref, ReplyTo, ConnHandle, ItemValue]), CH = ?INT(tr_conn_handle, ConnHandle), {I, V} = ?INT(tr_conn_info_value, ItemValue), Res = megaco:update_conn_info(CH, I, V), Status = ?EXT(tr_Status, Res), 'Megaco_SessionUser':updateConnInfoResponse(ReplyTo, Ref, Status), {noreply, State}.%% ----------------------------------------------------------------------connect(State, Ref, ReplyTo, ReceiveHandle, RemoteMid, SendHandle, ControlPid) -> ?d("connect -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n ReceiveHandle: ~w" "~n RemoteMid: ~w" "~n SendHandle: ~w" "~n ControlPid: ~w", [Ref, ReplyTo, ReceiveHandle, RemoteMid, SendHandle, ControlPid]), RH = ?INT(tr_receive_handle, ReceiveHandle), RM = ?INT(tr_MId, RemoteMid), SH = ?INT(tr_send_handle, SendHandle), ?d("connect -> call megaco:connect with" "~n RH: ~w" "~n RM: ~w" "~n SH: ~w", [RH, RM, SH]), %% Res = megaco:connect(RH, RM, SH, ControlPid), {Status0, CH0} = case megaco:connect(RH, RM, SH, ControlPid) of {ok, ConnHandle} -> ?d("connect -> connected: ~p", [ConnHandle]), {ok, ConnHandle}; Error -> ?d("connect -> connection faild: ~p", [Error]), %% BUGBUG %% Don't really know what to reply with here, %% so i send a dummy megaco conn handle for now!! %% BUGBUG {Error, #megaco_conn_handle{}} end, Status = ?EXT(tr_Status, Status0), CH = ?EXT(tr_conn_handle, CH0), ?d("connect -> send connectResponse", []), 'Megaco_SessionUser':connectResponse(ReplyTo, Ref, Status, CH), {noreply, State}.%% ----------------------------------------------------------------------disconnect(State, Ref, ReplyTo, ConnHandle, DiscoReason) -> ?d("connect -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n ConnHandle: ~w" "~n DiscoReason: ~w", [Ref, ReplyTo, ConnHandle, DiscoReason]), CH = ?INT(tr_conn_handle, ConnHandle), Res = megaco:disconnect(CH, DiscoReason), Status = ?EXT(tr_Status, Res), 'Megaco_SessionUser':disconnectResponse(ReplyTo, Ref, Status), {noreply, State}.%% ----------------------------------------------------------------------sendTransRequest(State, Ref, ReplyTo, ConnHandle, ActionRequests, Options) -> ?d("sendTransRequest -> entry with" "~n Ref: ~w" "~n ReplyTo: ~w" "~n ConnHandle: ~w" "~n ActionRequests: ~w" "~n Options: ~w", [Ref, ReplyTo, ConnHandle, ActionRequests, Options]), CH = ?INT(tr_conn_handle, ConnHandle), A = [?INT(tr_ActionRequest, Req) || Req <- ActionRequests],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -