%%
%% %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%
%%
%----------------------------------------------------------------------
% decode1.erl (new version)
%----------------------------------------------------------------------
% -*- Erlang -*-
% File: decode1.erl (~jb/decode/decode1.erl)
% Author: Johan Bevemyr
% Created: Tue Jan 14 09:33:49 1997
% Purpose:
% Notes: Rewritten for use in ETOS. (Happi)
-module(decode1).
-export([?MODULE/0,
decode_ie_heads_setup/1,
run_dummy/2,
run_orig/2]).
?MODULE() ->
FrameList = [89,128,0,8,132,0,26,133,133,0,38,148,94,
128,0,2,129,128,92,128,0,2,0,0,112,128,0,
10,194,69,0,0,0,0,0,18,52,95],
Frame = concat_binary([list_to_binary([89]),list_to_binary([128]),
list_to_binary([0]),list_to_binary([8]),
list_to_binary([132]),list_to_binary([0]),
list_to_binary([26]),list_to_binary([133]),
list_to_binary([133]),list_to_binary([0]),
list_to_binary([38]),list_to_binary([148]),
list_to_binary([94]),list_to_binary([128]),
list_to_binary([0]),list_to_binary([2]),
list_to_binary([129]),list_to_binary([128]),
list_to_binary([92]),list_to_binary([128]),
list_to_binary([0]),list_to_binary([2]),
list_to_binary([0]),list_to_binary([0]),
list_to_binary([112]),list_to_binary([128]),
list_to_binary([0]),list_to_binary([10]),
list_to_binary([194]),list_to_binary([69]),
list_to_binary([0]),list_to_binary([0]),
list_to_binary([0]),list_to_binary([0]),
list_to_binary([0]),list_to_binary([18]),
list_to_binary([52]),list_to_binary([95])]),
R = loop(2,0,Frame),
{R,R =:= {0,[{ie,112,itu_t_standard,ignore,10,<<194,69,0,0,0,0,0,18,52,95>>},
{ie,92,itu_t_standard,ignore,2,<<0,0>>},
{ie,94,itu_t_standard,ignore,2,<<129,128>>},
{ie,89,itu_t_standard,ignore,8,<<132,0,26,133,133,0,38,148>>}]}}.
loop(0,R,_) -> R;
loop(N,R,Frame) -> loop(N-1, decode1:decode_ie_heads_setup(Frame),Frame).
run_dummy(0,Frame) ->
done;
run_dummy(N,Frame) ->
parse_dummy(Frame),
run_dummy(N-1,Frame).
parse_dummy(Frame) -> true.
run_orig(0,Frame) ->
done;
run_orig(N,Frame) ->
decode1:decode_ie_heads_setup(Frame),
run_orig(N-1,Frame).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Macros
%
-define(VALID_ACTION(Flag), if ((Flag) band 16#10) == 16#10 -> true;
true -> false
end).
-define(GET_ACTION(Flag), ((Flag) band 16#03)).
-define(getint16(X1,X0), (16#100*X1 + X0)).
-define(IS_EXTENDED(X), (if ((X) band 16#80) == 16#80 -> false;
true -> true
end)).
%%% ----------------------------------------------------------
%%% # ie
%%% Description: Used to encapsulate the ie head
%%% ----------------------------------------------------------
-record(ie,{identifier,
coding,
action_ind,
length,
ie_body = binary}).
%%% ----------------------------------------------------------
%%% # bbc
%%% Description: BROADBAND BEARER CAPABILITY
%%% ----------------------------------------------------------
-record(scct_bbc,
{scct_pci, % parameter compatibility info
scct_bearer_class,
scct_atm_transfer_capability,
scct_user_plane_connection_configuration,
scct_susceptibility_to_clipping}).
%%% ----------------------------------------------------------
%%% # cause
%%% Description: CAUSE
%%% ----------------------------------------------------------
-record(scct_cause,
{scct_pci, % parameter compatibility info
scct_location,
scct_cause_value,
scct_diagnostics_list = []}).
%%% ----------------------------------------------------------
%%% # release_complete_uni
%%% Description:
%%% ----------------------------------------------------------
-record(release_complete_uni,
{scct_cause_list=[], % Cause IE's in a list where each element
% is a record of scct_cause{}
scct_geidt_list=[]}). % Generic Identifier Transport IE's in a list
% where each element is a record of scct_geidt{}
-define(IE_BB_BEARER_CAPABILITY, 16#5e).
-define(SCCT_PUB_NETW_SERV_LOCAL_USR, 2).
-define(SCCT_ERR_INVALID_IE_CONT, 100).
-define(DECRES_THROW_RELCOMP, error_throw_relcomp).
-define(SCCT_P_TO_P, 0).
-define(SCCT_P_TO_MP, 1).
-define(IE_ENDPT_REF, 16#54).
-define(IE_BB_REPEAT_INDICATOR, 16#63).
-define(SCCT_ERR_MAND_IE_MISSING, 96).
-define(A_CLEAR_CALL, 0).
-define(A_DISCARD_PROCEED, 1).
-define(A_DISCARD_PROCEED_STATUS, 2).
-define(SCCT_BCOB_A, 1).
-define(SCCT_BCOB_C, 3).
-define(SCCT_BCOB_X, 16).
-define(SCCT_TRANSP_VP_SERV, 24).
-define(SCCT_CBR, 5).
-define(SCCT_CBR_WITH_CLR_CLP_0_1, 7).
-define(SCCT_RT_VBR, 9).
-define(SCCT_RT_VBR_WITH_CLR_CLP_0_1, 19).
-define(SCCT_NON_RT_VBR, 10).
-define(SCCT_NON_RT_VBR_WITH_CLR_CLP_0_1, 11).
-define(SCCT_ABR, 12).
-define(SCCT_NOT_SUSCEPT_TO_CLIPPING, 0).
-define(SCCT_SUSCEPT_TO_CLIPPING, 1).
%%% ----------------------------------------------------------
%%% -type decode_ie_heads_setup(Bin)->
%%%
%%% Input: Binary to body of incoming Message
%%% Output:
%%%
%%% Exceptions:
%%% Description:decode_ie_heads_setup is used both p-p and p-mp setup
%%% Never fails. Needs to be exported to be able to check
%%% if setup is p-p or p-mp.
%%% Note that if broadband rep indicator is present
%%% order must be incoming IE's must be preserved, this
%%% only applicable in msg setup
%%% ----------------------------------------------------------
decode_ie_heads_setup(Bin)->
decode_ie_heads_setup(Bin,no_bbc_ie,no_epr,[],no_brep).
decode_ie_heads_setup(Bin,TypeOfCall,EprFlag,IEList,BrepFlag) when is_binary(Bin),size(Bin) >= 4 ->
{Bin1,Bin2} = split_binary(Bin,4),
[Id,F,L1,L0]= binary_to_list(Bin1),
Action = decode_action(F),
Coding = decode_ie_coding(F),
case ?getint16(L1,L0) of
Len when Len >0 ->
%%catch needed we cannot trust indata
case catch split_binary(Bin2,Len) of
{'EXIT',_} -> %%binary unpacked as far as possible
decode_ie_heads_setup(not_a_binary,TypeOfCall,EprFlag,
IEList,BrepFlag);
{Bin3,Bin4} ->
IE= #ie {identifier = Id,
coding = Coding,
action_ind= Action,
length= Len,
ie_body= Bin3},
case Id of
?IE_BB_BEARER_CAPABILITY ->
BbcRec=#scct_bbc{},
%%catch needed we cannot trust indata
case catch
dec_bearer_capability(BbcRec,
binary_to_list(Bin3)) of
{'EXIT',_} -> %mand content error
CauseRec=#scct_cause{scct_location=
?SCCT_PUB_NETW_SERV_LOCAL_USR,
scct_cause_value=
?SCCT_ERR_INVALID_IE_CONT,
scct_diagnostics_list=
[?IE_BB_BEARER_CAPABILITY]},
RelCompUniMsg =
#release_complete_uni{scct_cause_list=
[CauseRec]},
{?DECRES_THROW_RELCOMP,RelCompUniMsg};
NewBbcRec ->
case NewBbcRec
#scct_bbc.scct_user_plane_connection_configuration of
?SCCT_P_TO_P ->
decode_ie_heads_setup(Bin4,
?SCCT_P_TO_P,
EprFlag,
[IE|IEList],
BrepFlag);
?SCCT_P_TO_MP ->
decode_ie_heads_setup(Bin4,
?SCCT_P_TO_MP,
EprFlag,
[IE|IEList],
BrepFlag)
end
end;
?IE_ENDPT_REF ->
decode_ie_heads_setup(Bin4,TypeOfCall,yes_epr,
[IE|IEList],BrepFlag);
?IE_BB_REPEAT_INDICATOR ->
decode_ie_heads_setup(Bin4,TypeOfCall,EprFlag,
[IE|IEList],yes_brep);
_ ->
decode_ie_heads_setup(Bin4,TypeOfCall,EprFlag,
[IE|IEList],BrepFlag)
end
end;
Len when Len == 0 ->%ie body empty, treat as if whole ie was missing
decode_ie_heads_setup(Bin2,TypeOfCall,EprFlag,IEList,BrepFlag)
end;
decode_ie_heads_setup(_,?SCCT_P_TO_MP,yes_epr,IEList,no_brep) ->
{?SCCT_P_TO_MP,IEList};
decode_ie_heads_setup(_,?SCCT_P_TO_MP,yes_epr,IEList,yes_brep) ->
%Order of incoming IEs must be preserved since BroadB Repeat Ind is present
{?SCCT_P_TO_MP,reverse(IEList)};
decode_ie_heads_setup(_,?SCCT_P_TO_MP,no_epr,_,no_brep) ->
CauseRec=#scct_cause{scct_location=?SCCT_PUB_NETW_SERV_LOCAL_USR,
scct_cause_value=?SCCT_ERR_MAND_IE_MISSING,
scct_diagnostics_list=[?IE_ENDPT_REF]},
RelCompUniMsg =#release_complete_uni{scct_cause_list=[CauseRec]},
{?DECRES_THROW_RELCOMP,RelCompUniMsg};
decode_ie_heads_setup(_,?SCCT_P_TO_P,_,IEList,no_brep) ->
{?SCCT_P_TO_P,IEList};
decode_ie_heads_setup(_,?SCCT_P_TO_P,_,IEList,yes_brep) ->
%Order of incoming IEs must be preserved since BrodB Repeat Ind is present
{?SCCT_P_TO_P,reverse(IEList)};
decode_ie_heads_setup(_,no_bbc_ie,_,_,_) ->
CauseRec=#scct_cause{scct_location=?SCCT_PUB_NETW_SERV_LOCAL_USR,
scct_cause_value=?SCCT_ERR_MAND_IE_MISSING,
scct_diagnostics_list=[?IE_BB_BEARER_CAPABILITY]},
RelCompUniMsg =#release_complete_uni{scct_cause_list=[CauseRec]},
{?DECRES_THROW_RELCOMP,RelCompUniMsg}.
%%%
%%% Decode message type and header
%%%
decode_action(Flag) ->
case ?VALID_ACTION(Flag) of
true ->
case ?GET_ACTION(Flag) of
?A_CLEAR_CALL -> clear_call;
?A_DISCARD_PROCEED -> discard_proceed;
?A_DISCARD_PROCEED_STATUS -> discard_proceed_status;
_ -> undefined
end;
false ->
ignore
end.
%%%
%%% Decode ie coding
%%%
decode_ie_coding(F) ->
case F band 16#60 of
0 -> itu_t_standard;
16#60 -> atm_forum_specific;
_ -> undefined
end.
%%% --------------------------------------------------------------------------
%%%
%%% Decode of INFORMATION ELEMENT: Broadband Bearer Capability
%%%
%%% --------------------------------------------------------------------------
dec_bearer_capability(BbcRec, [Octet5 | Rest]) ->
NewBbcRec =
case Octet5 band 16#1f of
16#01 ->
BbcRec#scct_bbc{scct_bearer_class = ?SCCT_BCOB_A};
16#03 ->
BbcRec#scct_bbc{scct_bearer_class = ?SCCT_BCOB_C};
16#10 ->
BbcRec#scct_bbc{scct_bearer_class = ?SCCT_BCOB_X};
16#18 ->
BbcRec#scct_bbc{scct_bearer_class = ?SCCT_TRANSP_VP_SERV}
end,
case ?IS_EXTENDED(Octet5) of
true ->
dec_bearer_capability_5a(NewBbcRec, Rest);
false ->
dec_bearer_capability_6(NewBbcRec, Rest)
end.
dec_bearer_capability_5a(BbcRec,[Octet5a | Rest]) ->
NewBbcRec =
case Octet5a band 16#7f of
16#05 ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_CBR};
16#07 ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_CBR_WITH_CLR_CLP_0_1};
16#09 ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_RT_VBR};
16#13 ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_RT_VBR_WITH_CLR_CLP_0_1};
16#0a ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_NON_RT_VBR};
16#0b ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_NON_RT_VBR_WITH_CLR_CLP_0_1};
16#0c ->
BbcRec#scct_bbc{scct_atm_transfer_capability =
?SCCT_ABR}
end,
dec_bearer_capability_6(NewBbcRec,Rest).
dec_bearer_capability_6(BbcRec, [Octet6]) ->
STC =
case (Octet6 bsr 5) band 16#03 of
16#00 ->
?SCCT_NOT_SUSCEPT_TO_CLIPPING;
16#01 ->
?SCCT_SUSCEPT_TO_CLIPPING
end,
UPCC =
case Octet6 band 16#03 of
16#00 ->
?SCCT_P_TO_P;
16#01 ->
?SCCT_P_TO_MP
end,
NewBbcRec = BbcRec#scct_bbc{scct_susceptibility_to_clipping = STC,
scct_user_plane_connection_configuration = UPCC}.
reverse(L) ->
reverse(L,[]).
reverse([E|Rest],Acc) ->
reverse(Rest,[E|acc]);
reverse([],Acc) -> Acc.