megaco_config.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,844 行 · 第 1/5 页

ERL
1,844
字号
	    exit({no_such_item, BadItem})    end.get_env(Env, Default) ->    case application:get_env(megaco, Env) of        {ok, Val} -> Val;        undefined -> Default    end.lookup_local_conn(Handle) ->    ets:lookup(megaco_local_conn, Handle).connect(RH, RemoteMid, SendHandle, ControlPid) ->    ?d("connect -> entry with "	"~n   RH:         ~p"	"~n   RemoteMid:  ~p"	"~n   SendHandle: ~p"	"~n   ControlPid: ~p", [RH, RemoteMid, SendHandle, ControlPid]),    case RemoteMid of	{MidType, _MidValue} when is_atom(MidType) ->	    call({connect, RH, RemoteMid, SendHandle, ControlPid});	preliminary_mid ->	    call({connect, RH, RemoteMid, SendHandle, ControlPid});	BadMid ->	    {error, {bad_remote_mid, BadMid}}    end.connect_remote(ConnHandle, UserNode, Ref) ->    call({connect_remote, ConnHandle, UserNode, Ref}).disconnect(ConnHandle) ->    call({disconnect, ConnHandle}).disconnect_remote(ConnHandle, UserNode) ->    call({disconnect_remote, ConnHandle, UserNode}).incr_counter(Item, Incr) ->    case (catch ets:update_counter(megaco_config, Item, Incr)) of        {'EXIT', _} ->	    cre_counter(Item, Incr);        NewVal ->            NewVal    end.cre_counter(Item, Initial) ->    case whereis(?SERVER) == self() of	false ->	    call({cre_counter, Item, Initial});	true ->	    ets:insert(megaco_config, {Item, Initial}),	    Initial    end.    cre_pending_counter(TransId) ->    cre_pending_counter(sent, TransId, 0).cre_pending_counter(Direction, TransId, Initial) ->%     ?report_trace(ignore, "create pending counter", % 		  [Direction, TransId, Initial]),    Counter = {pending_counter, Direction, TransId},    cre_counter(Counter, Initial).incr_pending_counter(TransId) ->    incr_pending_counter(sent, TransId).incr_pending_counter(Direction, TransId) ->%     ?report_trace(ignore, "increment pending counter", [Direction, TransId]),    Counter = {pending_counter, Direction, TransId},    incr_counter(Counter, 1).get_pending_counter(TransId) ->    get_pending_counter(sent, TransId).get_pending_counter(Direction, TransId) ->%     ?report_trace(ignore, "get pending counter", [Direction, TransId]),    Counter = {pending_counter, Direction, TransId},    [{Counter, Val}] = ets:lookup(megaco_config, Counter),    Val.del_pending_counter(TransId) ->    del_pending_counter(sent, TransId).del_pending_counter(Direction, TransId) ->%     ?report_trace(ignore, "delete pending counter", [Direction, TransId]),    Counter = {pending_counter, Direction, TransId},    ets:delete(megaco_config, Counter).%% A wrapping transaction id counterincr_trans_id_counter(ConnHandle) ->    incr_trans_id_counter(ConnHandle, 1).incr_trans_id_counter(ConnHandle, Incr) when is_integer(Incr) and (Incr > 0) ->    case megaco_config:lookup_local_conn(ConnHandle) of        [] ->            {error, {no_such_connection, ConnHandle}};        [ConnData] ->            LocalMid  = ConnHandle#megaco_conn_handle.local_mid,            Item      = {LocalMid, trans_id_counter},            case (catch ets:update_counter(megaco_config, Item, Incr)) of                {'EXIT', _} ->                    %% The transaction counter needs to be initiated                    reset_trans_id_counter(ConnData, ConnHandle, LocalMid, 					   Item, Incr);                Serial ->                    ConnData2 = ConnData#conn_data{serial = Serial},                    Max       = ConnData#conn_data.max_serial,                    if                        Max == infinity, Serial =< 4294967295 ->                            {ok, ConnData2};                        Serial =< Max ->                            {ok, ConnData2};                        true ->                            %% The transaction id range is exhausted                            %% Let's wrap the counter                            reset_trans_id_counter(ConnData2, ConnHandle, 						   LocalMid, Item, Incr)                    end            end    end.% reset_trans_id_counter(ConnData, ConnHandle, LocalMid, Item) ->%     reset_trans_id_counter(ConnData, ConnHandle, LocalMid, Item, 1).reset_trans_id_counter(ConnData, ConnHandle, LocalMid, Item, Incr) ->    case whereis(?SERVER) == self() of        false ->            call({incr_trans_id_counter, ConnHandle});        true ->            Serial    = user_info(LocalMid, min_trans_id),            ConnData2 = ConnData#conn_data{serial = Serial + (Incr-1)},            Max       = ConnData#conn_data.max_serial,            if                Max == infinity,                integer(Serial), Serial > 0, Serial =< 4294967295 ->                    ets:insert(megaco_config, {Item, Serial}),                    {ok, ConnData2};                integer(Max), Max > 0,                integer(Serial), Serial > 0, Serial =< 4294967295 ->                    ets:insert(megaco_config, {Item, Serial}),                    {ok, ConnData2};                true ->                     {error, {bad_trans_id, Serial, Max}}            end    end.trans_sender_exit(Reason, CH) ->    ?d("trans_sender_exit -> entry with"	"~n   Reason: ~p"	"~n   CH: ~p", [Reason, CH]),    cast({trans_sender_exit, Reason, CH}).call(Request) ->    case (catch gen_server:call(?SERVER, Request, infinity)) of	{'EXIT', _} ->	    {error, megaco_not_started};	Res ->	    Res    end.cast(Msg) ->    case (catch gen_server:cast(?SERVER, Msg)) of	{'EXIT', _} ->	    {error, megaco_not_started};	Res ->	    Res    end.%%%----------------------------------------------------------------------%%% Callback functions from gen_server%%%----------------------------------------------------------------------%%----------------------------------------------------------------------%% Func: init/1%% Returns: {ok, State}          |%%          {ok, State, Timeout} |%%          ignore               |%%          {stop, Reason}%%----------------------------------------------------------------------init([Parent]) ->    ?d("init -> entry with "	"~n   Parent: ~p", [Parent]),    process_flag(trap_exit, true),    case (catch do_init()) of	ok ->	    ?d("init -> init ok", []),	    {ok, #state{parent_pid = Parent}};	Else ->	    ?d("init -> init error: ~p", [Else]),	    {stop, Else}    end.do_init() ->    ?megaco_test_init(),    ets:new(megaco_config,      [public, named_table, {keypos, 1}]),    ets:new(megaco_local_conn,  [public, named_table, {keypos, 2}]),    ets:new(megaco_remote_conn, [public, named_table, {keypos, 2}, bag]),    megaco_stats:init(megaco_stats, global_snmp_counters()),    init_scanner(),    init_user_defaults(),    init_users().    init_scanner() ->    case get_env(scanner, undefined) of	undefined ->	    Key  = text_config,	    Data = [],	    ets:insert(megaco_config, {Key, Data});	flex ->	    start_scanner(megaco_flex_scanner_handler, 			  start_link, [], [gen_server]);	{M, F, A, Mods} when is_atom(M) and 			     is_atom(F) and 			     is_list(A) and 			     is_list(Mods) ->	    start_scanner(M, F, A, Mods)    end.start_scanner(M, F, A, Mods) ->    case megaco_misc_sup:start_permanent_worker(M, F, A, Mods) of	{ok, Pid, Conf} when  is_pid(Pid) ->	    Key  = text_config,	    Data = [Conf],	    ets:insert(megaco_config, {Key, Data});	Else ->	    throw({scanner_start_failed, Else})    end.init_user_defaults() ->    init_user_default(min_trans_id,         1),    init_user_default(max_trans_id,         infinity),     init_user_default(request_timer,        #megaco_incr_timer{}),    init_user_default(long_request_timer,   infinity),    init_user_default(auto_ack,             false),    init_user_default(trans_ack,            false),    init_user_default(trans_ack_maxcount,   10),    init_user_default(trans_req,            false),    init_user_default(trans_req_maxcount,   10),    init_user_default(trans_req_maxsize,    2048),    init_user_default(trans_timer,          0),    init_user_default(trans_sender,         undefined),    init_user_default(pending_timer,        timer:seconds(30)),    init_user_default(sent_pending_limit,   infinity),    init_user_default(recv_pending_limit,   infinity),    init_user_default(reply_timer,          timer:seconds(30)),    init_user_default(send_mod,             megaco_tcp),    init_user_default(encoding_mod,         megaco_pretty_text_encoder),    init_user_default(protocol_version,     1),    init_user_default(auth_data,            asn1_NOVALUE),    init_user_default(encoding_config,      []),    init_user_default(user_mod,             megaco_user_default),    init_user_default(user_args,            []),    init_user_default(reply_data,           undefined),    init_user_default(threaded,             false),    init_user_default(strict_version,       true),    init_user_default(long_request_resend,  false),    init_user_default(cancel,               false),    init_user_default(resend_indication,    false).init_user_default(Item, Default) when Item /= mid ->    Val = get_env(Item, Default),    case do_update_user(default, Item, Val) of	ok ->	    ok;	{error, Reason} ->	    throw(Reason)    end.init_users() ->    Users = get_env(users, []),    init_users(Users).init_users([]) ->    ok;init_users([{UserMid, Config} | Rest]) ->    case handle_start_user(UserMid, Config) of        ok ->            init_users(Rest);        Else ->            throw({bad_user, UserMid, Else})    end;init_users(BadConfig) ->    throw({bad_config, users, BadConfig}).%%----------------------------------------------------------------------%% Func: handle_call/3%% Returns: {reply, Reply, State}          |%%          {reply, Reply, State, Timeout} |%%          {noreply, State}               |%%          {noreply, State, Timeout}      |%%          {stop, Reason, Reply, State}   | (terminate/2 is called)%%          {stop, Reason, State}            (terminate/2 is called)%%----------------------------------------------------------------------handle_call({cre_counter, Item, Incr}, _From, S) ->    Reply = cre_counter(Item, Incr),    {reply, Reply, S};handle_call({del_counter, Item, Incr}, _From, S) ->    Reply = cre_counter(Item, Incr),    {reply, Reply, S};handle_call({incr_trans_id_counter, ConnHandle}, _From, S) ->    Reply = incr_trans_id_counter(ConnHandle),    {reply, Reply, S};handle_call({receive_handle, UserMid}, _From, S) ->    case catch make_receive_handle(UserMid) of	{'EXIT', _} ->	    {reply, {error, {no_receive_handle, UserMid}}, S};	RH ->	    {reply, {ok, RH}, S}    end;handle_call({connect, RH, RemoteMid, SendHandle, ControlPid}, _From, S) ->    Reply = handle_connect(RH, RemoteMid, SendHandle, ControlPid),    {reply, Reply, S};handle_call({connect_remote, CH, UserNode, Ref}, _From, S) ->    Reply = handle_connect_remote(CH, UserNode, Ref),    {reply, Reply, S};handle_call({disconnect, ConnHandle}, _From, S) ->    Reply = handle_disconnect(ConnHandle),    {reply, Reply, S};handle_call({disconnect_remote, CH, UserNode}, _From, S) ->    Reply = handle_disconnect_remote(CH, UserNode),    {reply, Reply, S};handle_call({start_user, UserMid, Config}, _From, S) ->    Reply = handle_start_user(UserMid, Config),    {reply, Reply, S};handle_call({stop_user, UserMid}, _From, S) ->    Reply = handle_stop_user(UserMid),    {reply, Reply, S};handle_call({update_conn_data, CH, Item, Val}, _From, S) ->    case lookup_local_conn(CH) of        [] ->            {reply, {error, {no_such_connection, CH}}, S};        [CD] ->            Reply = handle_update_conn_data(CD, Item, Val),            {reply, Reply, S}    end;handle_call({update_user_info, UserMid, Item, Val}, _From, S) ->    case catch user_info(UserMid, mid) of        {'EXIT', _} ->            {reply, {error, {no_such_user, UserMid}}, S};        _ ->            Reply = do_update_user(UserMid, Item, Val),            {reply, Reply, S}    end;handle_call(Req, From, S) ->    warning_msg("received unexpected request from ~p: "		"~n~w", [From, Req]),    {reply, {error, {bad_request, Req}}, S}.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?