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 + -
显示快捷键?