diff options
Diffstat (limited to 'lib/megaco/src/engine/megaco_erl_dist_encoder.erl')
-rw-r--r-- | lib/megaco/src/engine/megaco_erl_dist_encoder.erl | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/lib/megaco/src/engine/megaco_erl_dist_encoder.erl b/lib/megaco/src/engine/megaco_erl_dist_encoder.erl new file mode 100644 index 0000000000..e8ade615df --- /dev/null +++ b/lib/megaco/src/engine/megaco_erl_dist_encoder.erl @@ -0,0 +1,275 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-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: Externalize/internalize Megaco/H.248 messages +%%---------------------------------------------------------------------- + +-module(megaco_erl_dist_encoder). + +-behaviour(megaco_encoder). + +-export([encode_message/3, decode_message/3, + decode_mini_message/3, + + encode_transaction/3, + encode_action_requests/3, + encode_action_request/3, + encode_command_request/3, + encode_action_reply/3 + ]). +-export([version_of/2]). + +%% Backward compatible funcs: +-export([encode_message/2, decode_message/2]). + + +-include("megaco_message_internal.hrl"). + +-define(MC_MOD, megaco_erl_dist_encoder_mc). + + +%%---------------------------------------------------------------------- +%% Convert a 'MegacoMessage' record into a binary +%% Return {ok, DeepIoList} | {error, Reason} +%%---------------------------------------------------------------------- + +encode_message(Config, + #'MegacoMessage'{mess = #'Message'{version = V}} = MegaMsg) -> + encode_message(Config, V, MegaMsg). + +encode_message([{version3, _}|EC], Vsn, MegaMsg) -> + encode_message(EC, Vsn, MegaMsg); +encode_message([megaco_compressed|Config], Vsn, MegaMsg) + when is_record(MegaMsg, 'MegacoMessage') -> + {ok, erlang:term_to_binary(?MC_MOD:encode(MegaMsg, Vsn), Config)}; +encode_message([{megaco_compressed, Mod}|Config], Vsn, MegaMsg) + when is_atom(Mod) and is_record(MegaMsg, 'MegacoMessage') -> + {ok, erlang:term_to_binary(Mod:encode(MegaMsg, Vsn), Config)}; +encode_message(Config, _Vsn, MegaMsg) + when is_record(MegaMsg, 'MegacoMessage') -> + {ok, erlang:term_to_binary(MegaMsg, Config)}; +encode_message(_Config, _Vsn, _MegaMsg) -> + {error, not_a_megaco_message}. + + +%%---------------------------------------------------------------------- +%% Convert a transaction record into a binary +%% Return {ok, Bin} | {error, Reason} +%%---------------------------------------------------------------------- + +encode_transaction([{version3, _}|EC], Vsn, Trans) -> + encode_transaction(EC, Vsn, Trans); +encode_transaction([megaco_compressed|Config], _Vsn, Trans) -> + {ok, erlang:term_to_binary(?MC_MOD:encode(Trans), Config)}; +encode_transaction([{megaco_compressed, Mod}|Config], _Vsn, Trans) -> + {ok, erlang:term_to_binary(Mod:encode(Trans), Config)}; +encode_transaction(Config, _Vsn, Trans) -> + {ok, erlang:term_to_binary(Trans, Config)}. + + +%%---------------------------------------------------------------------- +%% Convert a list of ActionRequest record's into a binary +%% Return {ok, Binary} | {error, Reason} +%%---------------------------------------------------------------------- +encode_action_requests([{version3, _}|EC], Vsn, ActReqs) -> + encode_action_requests(EC, Vsn, ActReqs); +encode_action_requests([megaco_compressed|Config], Vsn, ActReqs0) + when is_list(ActReqs0) -> + ActReqs = [?MC_MOD:encode(AR, Vsn) || AR <- ActReqs0], + {ok, erlang:term_to_binary(ActReqs, Config)}; +encode_action_requests([{megaco_compressed, Mod}|Config], Vsn, ActReqs0) + when is_list(ActReqs0) -> + ActReqs = [Mod:encode(AR, Vsn) || AR <- ActReqs0], + {ok, erlang:term_to_binary(ActReqs, Config)}; +encode_action_requests(Config, _Vsn, ActReqs) + when is_list(ActReqs) -> + {ok, erlang:term_to_binary(ActReqs, Config)}. + + + +%%---------------------------------------------------------------------- +%% Convert a ActionRequest record into a binary +%% Return {ok, Binary} | {error, Reason} +%%---------------------------------------------------------------------- +encode_action_request([{version3, _}|EC], Vsn, ActReq) -> + encode_action_request(EC, Vsn, ActReq); +encode_action_request([megaco_compressed|Config], Vsn, ActReq) + when is_tuple(ActReq) -> + {ok, erlang:term_to_binary(?MC_MOD:encode(ActReq, Vsn), Config)}; +encode_action_request([{megaco_compressed, Mod}|Config], Vsn, ActReq) + when is_tuple(ActReq) -> + {ok, erlang:term_to_binary(Mod:encode(ActReq, Vsn), Config)}; +encode_action_request(Config, _Vsn, ActReq) + when is_tuple(ActReq) -> + {ok, erlang:term_to_binary(ActReq, Config)}. + + + +%%---------------------------------------------------------------------- +%% Convert a CommandRequest record into a binary +%% Return {ok, DeepIoList} | {error, Reason} +%%---------------------------------------------------------------------- +encode_command_request([{version3, _}|EC], Vsn, CmdReq) -> + encode_command_request(EC, Vsn, CmdReq); +encode_command_request([megaco_compressed|Config], Vsn, CmdReq) + when is_tuple(CmdReq) -> + {ok, erlang:term_to_binary(?MC_MOD:encode(CmdReq, Vsn), Config)}; +encode_command_request([{megaco_compressed, Mod}|Config], Vsn, CmdReq) + when is_tuple(CmdReq) -> + {ok, erlang:term_to_binary(Mod:encode(CmdReq, Vsn), Config)}; +encode_command_request(Config, _Vsn, CmdReq) + when is_tuple(CmdReq) -> + {ok, erlang:term_to_binary(CmdReq, Config)}. + + +%%---------------------------------------------------------------------- +%% Convert a action reply into a binary +%% Return {ok, DeepIoList} | {error, Reason} +%%---------------------------------------------------------------------- +encode_action_reply([{version3, _}|EC], Vsn, ActRep) -> + encode_action_reply(EC, Vsn, ActRep); +encode_action_reply([megaco_compressed|Config], Vsn, ActRep) + when is_tuple(ActRep) -> + {ok, erlang:term_to_binary(?MC_MOD:encode(ActRep, Vsn), Config)}; +encode_action_reply([{megaco_compressed, Mod}|Config], Vsn, ActRep) + when is_tuple(ActRep) -> + {ok, erlang:term_to_binary(Mod:encode(ActRep, Vsn), Config)}; +encode_action_reply(Config, _Vsn, ActRep) + when is_tuple(ActRep) -> + {ok, erlang:term_to_binary(ActRep, Config)}. + + +%%---------------------------------------------------------------------- +%% Get the megaco version of the message +%% Return {ok, Version} | {error, Reason} +%%---------------------------------------------------------------------- + +version_of(Config, Bin) when is_binary(Bin) -> + case decode_message(Config, 1, Bin) of + {ok, M} -> + V = (M#'MegacoMessage'.mess)#'Message'.version, + {ok, V}; + Error -> + Error + end. + +decode_message(Config, Bin) -> + decode_message(Config, 1, Bin). + +decode_message([{version3, _}|EC], V, Bin) -> + decode_message(EC, V, Bin); +decode_message([megaco_compressed = MC|_Config], Vsn, Bin) -> + case catch erlang:binary_to_term(Bin) of + Msg when is_tuple(Msg) -> + case (?MC_MOD:decode(Msg, Vsn)) of + MegaMsg when is_record(MegaMsg, 'MegacoMessage') -> + {ok, dm(MegaMsg, MC, Vsn)}; + _ -> + {error, {bad_message, Msg}} + end; + {'EXIT', _Reason} -> + {error, bad_binary} + end; +decode_message([{megaco_compressed, Mod} = MC|_Config], Vsn, Bin) + when is_atom(Mod) -> + case catch erlang:binary_to_term(Bin) of + Msg when is_tuple(Msg) -> + case (Mod:decode(Msg, Vsn)) of + MegaMsg when is_record(MegaMsg, 'MegacoMessage') -> + {ok, dm(MegaMsg, MC, Vsn)}; + _ -> + {error, {bad_message, Msg}} + end; + {'EXIT', _Reason} -> + {error, bad_binary} + end; +decode_message(_Config, Vsn, Bin) -> + case catch erlang:binary_to_term(Bin) of + MegaMsg when is_record(MegaMsg, 'MegacoMessage') -> + {ok, dm(MegaMsg, undefined, Vsn)}; + {'EXIT', _Reason} -> + {error, bad_binary} + end. + + +decode_mini_message(EC, Vsn, Bin) when is_binary(Bin) -> + decode_message(EC, Vsn, Bin). + + +%% This crap is because the transactions or the action-requests +%% might have been encoded separetely + +dm(#'MegacoMessage'{mess = Mess} = M, MC, Vsn) -> + #'Message'{messageBody = Body} = Mess, + case Body of + {transactions, Transactions} -> + Body2 = {transactions, dmt(Transactions, [], MC, Vsn)}, + Mess2 = Mess#'Message'{messageBody = Body2}, + M#'MegacoMessage'{mess = Mess2}; + _ -> + M + end. + +dmt([], Acc, _, _Vsn) -> + lists:reverse(Acc); +dmt([Trans0|Transactions], Acc, MC, Vsn) when is_binary(Trans0) -> + Trans1 = erlang:binary_to_term(Trans0), + Trans2 = dmt1(Trans1, MC, Vsn), + dmt(Transactions, [Trans2|Acc], MC, Vsn); +dmt([{Tag, Trans0}|Transactions], Acc, MC, Vsn) when is_binary(Trans0) -> + Trans1 = erlang:binary_to_term(Trans0), + Trans2 = dmt1(Trans1, MC, Vsn), + dmt(Transactions, [{Tag, Trans2}|Acc], MC, Vsn); +dmt([{transactionRequest, + #'TransactionRequest'{actions = Acts0} = TR0}|Transactions], + Acc, MC, Vsn) + when is_binary(Acts0) -> + Acts1 = erlang:binary_to_term(Acts0), + Acts2 = dmt1(Acts1, MC, Vsn), + TR1 = TR0#'TransactionRequest'{actions = Acts2}, + dmt(Transactions, [{transactionRequest, TR1}|Acc], MC, Vsn); +dmt([{transactionRequest, + #'TransactionRequest'{actions = Acts0} = TR0}|Transactions], + Acc, MC, Vsn) -> + Acts2 = [dmt2(AR, MC, Vsn) || AR <- Acts0], + TR1 = TR0#'TransactionRequest'{actions = Acts2}, + dmt(Transactions, [{transactionRequest, TR1}|Acc], MC, Vsn); +dmt([Trans|Transactions], Acc, MC, Vsn) -> + dmt(Transactions, [Trans|Acc], MC, Vsn). + +dmt1(L, megaco_compressed, Vsn) when is_list(L) -> + [?MC_MOD:decode(E, Vsn) || E <- L]; +dmt1(L, {megaco_compressed, Mod}, Vsn) when is_list(L) -> + [Mod:decode(E, Vsn) || E <- L]; +dmt1(T, megaco_compressed, Vsn) when is_tuple(T) -> + ?MC_MOD:decode(T, Vsn); +dmt1(T, {megaco_compressed, Mod}, Vsn) when is_tuple(T) -> + Mod:decode(T, Vsn); +dmt1(Else, _, _Vsn) -> + Else. + +dmt2(Bin, MC, Vsn) when is_binary(Bin) -> + AR = erlang:binary_to_term(Bin), + dmt1(AR, MC, Vsn); +dmt2(AR, _MC, _Vsn) -> + AR. + + |