aboutsummaryrefslogtreecommitdiffstats
path: root/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/megaco/examples/meas/megaco_codec_mstone_lib.erl')
-rw-r--r--lib/megaco/examples/meas/megaco_codec_mstone_lib.erl534
1 files changed, 534 insertions, 0 deletions
diff --git a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl
new file mode 100644
index 0000000000..31df945777
--- /dev/null
+++ b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl
@@ -0,0 +1,534 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%%
+%% 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 online 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Misc utility functions for the mstone modules
+%%----------------------------------------------------------------------
+
+-module(megaco_codec_mstone_lib).
+
+
+%% API
+-export([start_flex_scanner/0, stop_flex_scanner/1,
+ expanded_messages/2, expanded_messages/3,
+ set_default_sched_bind/0,
+ display_os_info/0,
+ display_system_info/0,
+ display_alloc_info/0,
+ display_app_info/0,
+ detect_version/3]).
+
+%% Internal exports
+-export([flex_scanner_handler/1]).
+
+-include_lib("kernel/include/file.hrl").
+
+
+%%----------------------------------------------------------------------
+%%
+%% D e t e c t V e r s i o n
+%%
+%%----------------------------------------------------------------------
+
+detect_version(Codec, Conf, Bin) ->
+ case (catch Codec:version_of(Conf, Bin)) of
+ {ok, V} ->
+ case (catch Codec:decode_message(Conf, V, Bin)) of
+ {ok, M} ->
+ case (catch Codec:encode_message(Conf, V, M)) of
+ {ok, NewBin} ->
+ {V, NewBin};
+ Error1 ->
+ error({encode_failed, Error1, Codec, Conf, M})
+ end;
+ Error2 ->
+ error({decode_failed, Error2, Codec, Conf, Bin})
+ end;
+ Error3 ->
+ error({version_of_failed, Error3, Codec, Conf, Bin})
+ end.
+
+
+%%----------------------------------------------------------------------
+%%
+%% S c h e d u l e r b i n d t y p e
+%%
+%%----------------------------------------------------------------------
+
+set_default_sched_bind() ->
+ (catch erlang:system_flag(scheduler_bind_type, default_bind)).
+
+
+%%----------------------------------------------------------------------
+%%
+%% D i s p l a y O s I n f o
+%%
+%%----------------------------------------------------------------------
+
+display_os_info() ->
+ V = case os:version() of
+ {Major, Minor, Release} ->
+ lists:flatten(
+ io_lib:format("~w.~w.~w", [Major, Minor, Release]));
+ Str ->
+ Str
+ end,
+ case os:type() of
+ {OsFam, OsName} ->
+ io:format("OS: ~p-~p: ~s~n", [OsFam, OsName, V]);
+ OsFam ->
+ io:format("OS: ~p: ~s~n", [OsFam, V])
+ end.
+
+
+%%----------------------------------------------------------------------
+%%
+%% D i s p l a y S y s t e m I n f o
+%%
+%%----------------------------------------------------------------------
+
+display_system_info() ->
+ SysArch = system_architecture(),
+ OtpRel = otp_release(),
+ SysVer = system_version(),
+ SysHT = heap_type(),
+ SysGHSz = global_heaps_size(),
+ SysSMP = smp_support(),
+ SysNumSched = schedulers(),
+ SysProcLimit = process_limit(),
+ SysThreads = threads(),
+ SysTPSz = thread_pool_size(),
+ SchedBindings = scheduler_bindings(),
+ SchedBindType = scheduler_bind_type(),
+ CpuTopology = cpu_topology(),
+ io:format("System architecture: ~s~n", [SysArch]),
+ io:format("OTP release: ~s~n", [OtpRel]),
+ io:format("System version: ~s~n", [SysVer]),
+ io:format("Heap type: ~s~n", [SysHT]),
+ io:format("Global heap size: ~s~n", [SysGHSz]),
+ io:format("Thread support: ~s~n", [SysThreads]),
+ io:format("Thread pool size: ~s~n", [SysTPSz]),
+ io:format("Process limit: ~s~n", [SysProcLimit]),
+ io:format("SMP support: ~s~n", [SysSMP]),
+ io:format("Num schedulers: ~s~n", [SysNumSched]),
+ io:format("Scheduler bindings: ~s~n", [SchedBindings]),
+ io:format("Scheduler bind type: ~s~n", [SchedBindType]),
+ io:format("Cpu topology: ~s~n", [CpuTopology]),
+ ok.
+
+
+system_architecture() ->
+ string:strip(system_info(system_architecture, string),right,$\n).
+
+otp_release() ->
+ system_info(otp_release, string).
+
+system_version() ->
+ string:strip(system_info(system_version, string),right,$\n).
+
+heap_type() ->
+ system_info(heap_type, any).
+
+global_heaps_size() ->
+ system_info(global_heaps_size, any).
+
+smp_support() ->
+ system_info(smp_support, any).
+
+schedulers() ->
+ system_info(schedulers, any).
+
+process_limit() ->
+ system_info(process_limit, any).
+
+threads() ->
+ system_info(threads, any).
+
+thread_pool_size() ->
+ system_info(thread_pool_size, any).
+
+scheduler_bindings() ->
+ system_info(scheduler_bindings, any).
+
+scheduler_bind_type() ->
+ system_info(scheduler_bind_type, any).
+
+cpu_topology() ->
+ system_info(cpu_topology, any).
+
+system_info(Tag, Type) ->
+ case (catch erlang:system_info(Tag)) of
+ {'EXIT', _} ->
+ "-";
+ Info when is_list(Info) andalso (Type =:= string) ->
+ Info;
+ Info ->
+ lists:flatten(io_lib:format("~w", [Info]))
+ end.
+
+
+
+%%----------------------------------------------------------------------
+%%
+%% D i s p l a y A l l o c a t o r I n f o
+%%
+%%----------------------------------------------------------------------
+
+display_alloc_info() ->
+ io:format("Allocator memory information:~n", []),
+ AllocInfo = alloc_info(),
+ display_alloc_info(AllocInfo).
+
+display_alloc_info([]) ->
+ ok;
+display_alloc_info([{Alloc, Mem}|AllocInfo]) ->
+ io:format(" ~15w: ~10w~n", [Alloc, Mem]),
+ display_alloc_info(AllocInfo).
+
+alloc_info() ->
+ case erlang:system_info(allocator) of
+ {_Allocator, _Version, Features, _Settings} ->
+ alloc_info(Features);
+ _ ->
+ []
+ end.
+
+alloc_info(Allocators) ->
+ Allocs = [temp_alloc, sl_alloc, std_alloc, ll_alloc, eheap_alloc,
+ ets_alloc, binary_alloc, driver_alloc],
+ alloc_info(Allocators, Allocs, []).
+
+alloc_info([], _, Acc) ->
+ lists:reverse(Acc);
+alloc_info([Allocator | Allocators], Allocs, Acc) ->
+ case lists:member(Allocator, Allocs) of
+ true ->
+ Instances0 = erlang:system_info({allocator, Allocator}),
+ Instances =
+ if
+ is_list(Instances0) ->
+ [Instance || Instance <- Instances0,
+ element(1, Instance) =:= instance];
+ true ->
+ []
+ end,
+ AllocatorMem = alloc_mem_info(Instances),
+ alloc_info(Allocators, Allocs, [{Allocator, AllocatorMem} | Acc]);
+
+ false ->
+ alloc_info(Allocators, Allocs, Acc)
+ end.
+
+
+alloc_mem_info(Instances) ->
+ alloc_mem_info(Instances, []).
+
+alloc_mem_info([], Acc) ->
+ lists:sum([Mem || {instance, _, Mem} <- Acc]);
+alloc_mem_info([{instance, N, Info}|Instances], Acc) ->
+ InstanceMemInfo = alloc_instance_mem_info(Info),
+ alloc_mem_info(Instances, [{instance, N, InstanceMemInfo} | Acc]).
+
+alloc_instance_mem_info(InstanceInfo) ->
+ MBCS = alloc_instance_mem_info(mbcs, InstanceInfo),
+ SBCS = alloc_instance_mem_info(sbcs, InstanceInfo),
+ MBCS + SBCS.
+
+alloc_instance_mem_info(Key, InstanceInfo) ->
+ case lists:keysearch(Key, 1, InstanceInfo) of
+ {value, {Key, Info}} ->
+ case lists:keysearch(blocks_size, 1, Info) of
+ {value, {blocks_size, Mem, _, _}} ->
+ Mem;
+ _ ->
+ 0
+ end;
+ _ ->
+ 0
+ end.
+
+
+%%----------------------------------------------------------------------
+%%
+%% D i s p l a y A p p I n f o
+%%
+%%----------------------------------------------------------------------
+
+display_app_info() ->
+ display_megaco_info(),
+ display_asn1_info().
+
+display_megaco_info() ->
+ MI = megaco:module_info(),
+ {value, {attributes, Attr}} = lists:keysearch(attributes, 1, MI),
+ {value, {app_vsn, Ver}} = lists:keysearch(app_vsn, 1, Attr),
+ io:format("Megaco version: ~s~n", [Ver]).
+
+display_asn1_info() ->
+ AI = megaco_ber_bin_drv_media_gateway_control_v1:info(),
+ Vsn =
+ case lists:keysearch(vsn, 1, AI) of
+ {value, {vsn, V}} when is_atom(V) ->
+ atom_to_list(V);
+ {value, {vsn, V}} when is_list(V) ->
+ V;
+ _ ->
+ "unknown"
+ end,
+ io:format("ASN.1 version: ~s~n", [Vsn]).
+
+
+%%----------------------------------------------------------------------
+%%
+%% E x p a n d M e s s a g e s
+%%
+%%----------------------------------------------------------------------
+
+expanded_messages(Codecs, DrvInclude) ->
+ MessagePackage = time_test,
+ expanded_messages(MessagePackage, Codecs, DrvInclude).
+
+expanded_messages(MessagePackage, Codecs, DrvInclude) ->
+ ECodecs = expand_codecs(Codecs, DrvInclude),
+ Messages = megaco_codec_transform:messages(MessagePackage),
+ expanded_messages2(ECodecs, Messages, []).
+
+expanded_messages2([], _Messages, EMessages) ->
+ lists:reverse(EMessages);
+expanded_messages2([{Codec, Mod, Conf}|ECodecs], Messages, EMessages) ->
+ case lists:keysearch(Codec, 1, Messages) of
+ {value, {Codec, Msgs}} ->
+ expanded_messages2(ECodecs, Messages,
+ [{Codec, Mod, Conf, Msgs}|EMessages]);
+ false ->
+ exit({error, {no_such_codec_data, Codec}})
+ end.
+
+
+%%----------------------------------------------------------------------
+%%
+%% E x p a n d C o d e c s
+%%
+%%----------------------------------------------------------------------
+
+expand_codecs(Codecs, DrvInclude) ->
+ expand_codecs(Codecs, DrvInclude, []).
+
+expand_codecs([], _, ECodecs) ->
+ lists:reverse(lists:flatten(ECodecs));
+expand_codecs([Codec|Codecs], DrvInclude, ECodecs) when is_atom(Codec) ->
+ ECodec = expand_codec(Codec, DrvInclude),
+ expand_codecs(Codecs, DrvInclude, [ECodec|ECodecs]).
+
+expand_codec(Codec, flex) ->
+ case Codec of
+ pretty ->
+ [{Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]}];
+ compact ->
+ [{Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]}];
+ ber ->
+ [];
+ per ->
+ [];
+ erlang ->
+ [];
+ Else ->
+ error({invalid_codec, Else})
+ end;
+expand_codec(Codec, only_drv) ->
+ case Codec of
+ pretty ->
+ [{Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, [flex_scanner]}];
+ compact ->
+ [{Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, [flex_scanner]}];
+ ber ->
+ [{Codec, megaco_ber_bin_encoder, [driver,native]},
+ {Codec, megaco_ber_bin_encoder, [driver]},
+ {Codec, megaco_ber_bin_encoder, [driver,native]},
+ {Codec, megaco_ber_bin_encoder, [driver]}];
+ per ->
+ [{Codec, megaco_per_bin_encoder, [driver,native]},
+ {Codec, megaco_per_bin_encoder, [native]},
+ {Codec, megaco_per_bin_encoder, [driver,native]},
+ {Codec, megaco_per_bin_encoder, [native]}];
+ erlang ->
+ Encoder = megaco_erl_dist_encoder,
+ [
+ {Codec, Encoder, [megaco_compressed,compressed]},
+ {Codec, Encoder, [compressed]},
+ {Codec, Encoder, [megaco_compressed,compressed]},
+ {Codec, Encoder, [compressed]}
+ ];
+ Else ->
+ error({invalid_codec, Else})
+ end;
+expand_codec(Codec, no_drv) ->
+ case Codec of
+ pretty ->
+ [{Codec, megaco_pretty_text_encoder, []},
+ {Codec, megaco_pretty_text_encoder, []}];
+ compact ->
+ [{Codec, megaco_compact_text_encoder, []},
+ {Codec, megaco_compact_text_encoder, []}];
+ ber ->
+ [{Codec, megaco_ber_bin_encoder, [native]},
+ {Codec, megaco_ber_bin_encoder, []},
+ {Codec, megaco_ber_bin_encoder, [native]},
+ {Codec, megaco_ber_bin_encoder, []}];
+ per ->
+ [{Codec, megaco_per_bin_encoder, [native]},
+ {Codec, megaco_per_bin_encoder, []},
+ {Codec, megaco_per_bin_encoder, [native]},
+ {Codec, megaco_per_bin_encoder, []}];
+ erlang ->
+ Encoder = megaco_erl_dist_encoder,
+ [
+ {Codec, Encoder, [megaco_compressed]},
+ {Codec, Encoder, []},
+ {Codec, Encoder, [megaco_compressed]},
+ {Codec, Encoder, []}
+ ];
+ Else ->
+ error({invalid_codec, Else})
+ end;
+expand_codec(Codec, _) ->
+ case Codec of
+ pretty ->
+ [{Codec, megaco_pretty_text_encoder, [flex_scanner]},
+ {Codec, megaco_pretty_text_encoder, []}];
+ compact ->
+ [{Codec, megaco_compact_text_encoder, [flex_scanner]},
+ {Codec, megaco_compact_text_encoder, []}];
+ ber ->
+ [{Codec, megaco_ber_bin_encoder, [driver,native]},
+ {Codec, megaco_ber_bin_encoder, [native]},
+ {Codec, megaco_ber_bin_encoder, [driver]},
+ {Codec, megaco_ber_bin_encoder, []}];
+ per ->
+ [{Codec, megaco_per_bin_encoder, [driver,native]},
+ {Codec, megaco_per_bin_encoder, [native]},
+ {Codec, megaco_per_bin_encoder, [driver]},
+ {Codec, megaco_per_bin_encoder, []}];
+ erlang ->
+ Encoder = megaco_erl_dist_encoder,
+ [
+ {Codec, Encoder, [megaco_compressed,compressed]},
+ {Codec, Encoder, [compressed]},
+ {Codec, Encoder, [megaco_compressed]},
+ {Codec, Encoder, []}
+ ];
+ Else ->
+ error({invalid_codec, Else})
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%----------------------------------------------------------------------
+%%
+%% S t a r t F l e x S c a n n e r H a n d l e r
+%%
+%%----------------------------------------------------------------------
+
+start_flex_scanner() ->
+ Pid = proc_lib:spawn(?MODULE, flex_scanner_handler, [self()]),
+ receive
+ {flex_scanner_started, Pid, Conf} ->
+ {Pid, [Conf]};
+ {flex_scanner_error, {failed_loading_flex_scanner_driver, Reason}} ->
+ error({failed_loading_flex_scanner_driver, Reason});
+ {flex_scanner_error, Reason} ->
+ error({failed_loading_flex_scanner_driver, Reason})
+ after 10000 ->
+ exit(Pid, kill),
+ error({failed_starting_flex_scanner, timeout})
+ end.
+
+%%----------------------------------------------------------------------
+%%
+%% S t o p F l e x S c a n n e r H a n d l e r
+%%
+%%----------------------------------------------------------------------
+
+stop_flex_scanner(Pid) ->
+ Pid ! stop_flex_scanner.
+
+flex_scanner_handler(Pid) ->
+ case (catch megaco_flex_scanner:start()) of
+ {ok, PortOrPorts} ->
+ Pid ! {flex_scanner_started, self(), {flex, PortOrPorts}},
+ flex_scanner_handler_loop(Pid, PortOrPorts);
+ {error, {load_driver, {open_error, Reason}}} ->
+ Error = {failed_loading_flex_scanner_driver, Reason},
+ Pid ! {flex_scanner_error, Error},
+ exit(Error);
+ Else ->
+ Error = {unknown_result_from_start_flex_scanner, Else},
+ Pid ! {flex_scanner_error, Error},
+ exit(Error)
+ end.
+
+flex_scanner_handler_loop(Pid, PortOrPorts) ->
+ receive
+ {ping, Pinger} ->
+ Pinger ! {pong, self()},
+ flex_scanner_handler_loop(Pid, PortOrPorts);
+ {'EXIT', Port, Reason} when (Port =:= PortOrPorts) ->
+ Pid ! {flex_scanner_exit, Reason},
+ exit({flex_scanner_exit, Reason});
+ {'EXIT', Port, Reason} when is_port(Port) ->
+ case megaco_flex_scanner:is_scanner_port(Port, PortOrPorts) of
+ true ->
+ Pid ! {flex_scanner_exit, Reason},
+ exit({flex_scanner_exit, Reason});
+ false ->
+ %% Just ignore this crap
+ flex_scanner_handler_loop(Pid, PortOrPorts)
+ end;
+ stop_flex_scanner ->
+ megaco_flex_scanner:stop(PortOrPorts),
+ exit(normal);
+ _Other ->
+ flex_scanner_handler_loop(Pid, PortOrPorts)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+error(Reason) ->
+ throw({error, Reason}).
+