aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/inline_SUITE_data/bsdecode.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/compiler/test/inline_SUITE_data/bsdecode.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/compiler/test/inline_SUITE_data/bsdecode.erl')
-rw-r--r--lib/compiler/test/inline_SUITE_data/bsdecode.erl1188
1 files changed, 1188 insertions, 0 deletions
diff --git a/lib/compiler/test/inline_SUITE_data/bsdecode.erl b/lib/compiler/test/inline_SUITE_data/bsdecode.erl
new file mode 100644
index 0000000000..ae134ad02e
--- /dev/null
+++ b/lib/compiler/test/inline_SUITE_data/bsdecode.erl
@@ -0,0 +1,1188 @@
+%%
+%% %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%
+%%
+-module(bsdecode).
+-export([?MODULE/0]).
+
+-record(protocolErrors, {invalidManIE = false,
+ outOfSequence = false,
+ incorrectOptIE = false}).
+
+-record(mvsT_msisdn, {value}).
+
+
+-record(mvsgT_pdpAddressType, {pdpTypeNbr,
+ address}).
+
+-record(mvsgT_ipAddress, {version,
+ a1,
+ a2,
+ a3,
+ a4,
+ a5,
+ a6,
+ a7,
+ a8}).
+
+-record(mvsgT_imsi, {value}).
+
+-record(mvsgT_tid, {imsi,
+ nsapi}).
+
+-record(sesT_qualityOfServiceV0, {delayClass,
+ reliabilityClass,
+ peakThroughput,
+ precedenceClass,
+ meanThroughput}).
+
+-record(sesT_deleteReqV0, {tid}).
+
+-record(sesT_deleteResV0, {tid,
+ cause}).
+
+-record(sesT_createReqV0, {tid,
+ tidRaw,
+ qos,
+ recovery,
+ selMode,
+ flowLblData,
+ flowLblSig,
+ endUserAdd,
+ accPointName,
+ protConOpt,
+ sgsnAddSig,
+ sgsnAddUser,
+ msisdn}).
+
+-record(sesT_updateReqV0, {tid,
+ tidRaw,
+ qos,
+ recovery,
+ flowLblData,
+ flowLblSig,
+ sgsnAddSig,
+ sgsnAddUser}).
+
+-record(masT_ipcpData, {type,
+ ipAddress,
+ rawMessage}).
+
+-record(masT_ipcp, {exists,
+ code,
+ id,
+ ipcpList}).
+
+-record(masT_pap, {exists,
+ code,
+ id,
+ username,
+ password}).
+
+-record(masT_chap, {code,
+ id,
+ value,
+ name}).
+
+-record(masT_protocolConfigOptions, {chap,
+ pap,
+ ipcp}).
+
+?MODULE() ->
+ Res = test(),
+ {Res,Res =:=
+ {ok,{sesT_createReqV0,{mvsgT_tid,{mvsgT_imsi,<<81,67,101,7,0,0,0,240>>},6},
+ [81,67,101,7,0,0,0,96],
+ {sesT_qualityOfServiceV0,1,4,9,2,18},0,
+ subscribed,0,0,{mvsgT_pdpAddressType,ietf_ipv4,[]},
+ [<<97,112,110,48,49,51,97>>,<<101,114,105,99,115,115,111,110>>,<<115,101>>],
+ {masT_protocolConfigOptions,[],
+ {masT_pap,true,1,5,[117,115,101,114,53],[112,97,115,115,53]},[]},
+ {mvsgT_ipAddress,ipv4,172,28,12,1,0,0,0,0},
+ {mvsgT_ipAddress,ipv4,172,28,12,3,0,0,0,0},
+ {mvsT_msisdn,<<145,148,113,129,0,0,0,0>>}},1}}.
+
+test() ->
+ Pdu = <<30,
+ 16,
+ 0,
+ 90,
+ 0,
+ 1,
+ 0,
+ 0,
+ 255,
+ 255,
+ 255,
+ 255,
+ 81,
+ 67,
+ 101,
+ 7,
+ 0,
+ 0,
+ 0,
+ 96,
+ 6,
+ 12,
+ 146,
+ 18,
+ 14,
+ 0,
+ 15,
+ 252,
+ 16,
+ 0,
+ 0,
+ 17,
+ 0,
+ 0,
+ 128,
+ 0,
+ 2,
+ 241,
+ 33,
+ 131,
+ 0,
+ 20,
+ 7,
+ 97,
+ 112,
+ 110,
+ 48,
+ 49,
+ 51,
+ 97,
+ 8,
+ 101,
+ 114,
+ 105,
+ 99,
+ 115,
+ 115,
+ 111,
+ 110,
+ 2,
+ 115,
+ 101,
+ 132,
+ 0,
+ 20,
+ 128,
+ 192,
+ 35,
+ 16,
+ 1,
+ 5,
+ 0,
+ 16,
+ 5,
+ 117,
+ 115,
+ 101,
+ 114,
+ 53,
+ 5,
+ 112,
+ 97,
+ 115,
+ 115,
+ 53,
+ 133,
+ 0,
+ 4,
+ 172,
+ 28,
+ 12,
+ 1,
+ 133,
+ 0,
+ 4,
+ 172,
+ 28,
+ 12,
+ 3,
+ 134,
+ 0,
+ 8,
+ 145,
+ 148,
+ 113,
+ 129,
+ 0,
+ 0,
+ 0,
+ 0>>,
+ decode_v0_opt(10,Pdu).
+
+decode_v0_opt(0,Pdu) ->
+ decode_gtpc_msg(Pdu);
+decode_v0_opt(N,Pdu) ->
+ decode_gtpc_msg(Pdu),
+ decode_v0_opt(N - 1,Pdu).
+
+decode_gtpc_msg(<<0:3,
+ _:4,
+ 0:1,
+ 16:8,
+ _Length:16,
+ SequenceNumber:16,
+ _FlowLabel:16,
+ _SNDCP_N_PDU_Number:8,
+ _:3/binary-unit:8,
+ TID:8/binary-unit:8,
+ InformationElements/binary>>) ->
+ Errors = #protocolErrors{},
+ {ok,TID2} = tid_internal_storage(TID,[]),
+ EmptyCreateReq = #sesT_createReqV0{tid = TID2,
+ tidRaw = binary_to_list(TID)},
+ case catch decode_ie_create(InformationElements,0,Errors,EmptyCreateReq) of
+ {ok,CreateReq} ->
+ {ok,CreateReq,SequenceNumber};
+ {fault,Cause,CreateReq} ->
+ {fault,Cause,CreateReq,SequenceNumber};
+ {'EXIT',_Reason} ->
+ {fault,193,EmptyCreateReq,SequenceNumber}
+ end;
+decode_gtpc_msg(<<0:3,
+ _:4,
+ 0:1,
+ 18:8,
+ _Length:16,
+ SequenceNumber:16,
+ _FlowLabel:16,
+ _SNDCP_N_PDU_Number:8,
+ _:3/binary-unit:8,
+ TID:8/binary-unit:8,
+ InformationElements/binary>>) ->
+ io:format("hej",[]),
+ Errors = #protocolErrors{},
+ {ok,TID2} = tid_internal_storage(TID,[]),
+ EmptyUpdateReq = #sesT_updateReqV0{tid = TID2,
+ tidRaw = binary_to_list(TID)},
+ case catch decode_ie_update(InformationElements,0,Errors,EmptyUpdateReq) of
+ {ok,UpdateReq} ->
+ {ok,UpdateReq,SequenceNumber};
+ {fault,Cause,UpdateReq} ->
+ {fault,Cause,UpdateReq,SequenceNumber};
+ {'EXIT',Reason} ->
+ io:format("hej",[]),
+ {fault,193,EmptyUpdateReq,SequenceNumber,Reason}
+ end;
+decode_gtpc_msg(<<0:3,
+ _:4,
+ 0:1,
+ 20:8,
+ _Length:16,
+ SequenceNumber:16,
+ _FlowLabel:16,
+ _SNDCP_N_PDU_Number:8,
+ _:3/binary-unit:8,
+ TID:8/binary-unit:8,
+ _InformationElements/binary>>) ->
+ {ok,TID2} = tid_internal_storage(TID,[]),
+ DeleteReq = #sesT_deleteReqV0{tid = TID2},
+ {ok,DeleteReq,SequenceNumber};
+decode_gtpc_msg(<<0:3,
+ _:4,
+ 0:1,
+ 21:8,
+ _Length:16,
+ SequenceNumber:16,
+ _FlowLabel:16,
+ _SNDCP_N_PDU_Number:8,
+ _:3/binary-unit:8,
+ TID:8/binary-unit:8,
+ InformationElements/binary>>) ->
+ Errors = #protocolErrors{},
+ {ok,TID2} = tid_internal_storage(TID,[]),
+ EmptyDeleteRes = #sesT_deleteResV0{tid = TID2},
+ case catch decode_ie_delete_res(InformationElements,0,Errors,EmptyDeleteRes) of
+ {ok,DeleteRes} ->
+ {ok,DeleteRes,SequenceNumber};
+ {fault,Cause,DeleteRes} ->
+ {fault,Cause,DeleteRes,SequenceNumber};
+ {'EXIT',_Reason} ->
+ {fault,193,EmptyDeleteRes,SequenceNumber}
+ end;
+decode_gtpc_msg(_GTP_C_Message) ->
+ {fault}.
+
+decode_ie_create(<<>>,PresentIEs,Errors,CreateReq) ->
+ if
+ PresentIEs band 1917 /= 1917 ->
+ {fault,202,CreateReq};
+ true ->
+ case Errors of
+ #protocolErrors{invalidManIE = true} ->
+ {fault,201,CreateReq};
+ #protocolErrors{outOfSequence = true} ->
+ {fault,193,CreateReq};
+ #protocolErrors{incorrectOptIE = true} ->
+ {fault,203,CreateReq};
+ _ ->
+ {ok,CreateReq}
+ end
+ end;
+decode_ie_create(<<6:8,
+ QoSElement:3/binary-unit:8,
+ Rest/binary>>,PresentIEs,Errors,CreateReq) ->
+ if
+ PresentIEs band 1 == 1 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 1 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ <<_:2,
+ DelayClass:3,
+ ReliabilityClass:3,
+ PeakThroughput:4,
+ _:1,
+ PrecedenceClass:3,
+ _:3,
+ MeanThroughput:5>> = QoSElement,
+ QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
+ reliabilityClass = ReliabilityClass,
+ peakThroughput = PeakThroughput,
+ precedenceClass = PrecedenceClass,
+ meanThroughput = MeanThroughput},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{qos = QoS},
+ decode_ie_create(Rest,PresentIEs bor 1,UpdatedErrors,UpdatedCreateReq);
+ true ->
+ <<_:2,
+ DelayClass:3,
+ ReliabilityClass:3,
+ PeakThroughput:4,
+ _:1,
+ PrecedenceClass:3,
+ _:3,
+ MeanThroughput:5>> = QoSElement,
+ QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
+ reliabilityClass = ReliabilityClass,
+ peakThroughput = PeakThroughput,
+ precedenceClass = PrecedenceClass,
+ meanThroughput = MeanThroughput},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{qos = QoS},
+ decode_ie_create(Rest,PresentIEs bor 1,Errors,UpdatedCreateReq)
+ end;
+decode_ie_create(<<14:8,
+ Recovery:8,
+ Rest/binary>>,PresentIEs,Errors,CreateReq) ->
+ if
+ PresentIEs band 2 == 2 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 2 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{recovery = Recovery},
+ decode_ie_create(Rest,PresentIEs bor 2,UpdatedErrors,UpdatedCreateReq);
+ true ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{recovery = Recovery},
+ decode_ie_create(Rest,PresentIEs bor 2,Errors,UpdatedCreateReq)
+ end;
+decode_ie_create(<<15:8,
+ _:6,
+ SelectionMode:2,
+ Rest/binary>>,PresentIEs,Errors,CreateReq) ->
+ if
+ PresentIEs band 4 == 4 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 4 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{selMode = selection_mode_internal_storage(SelectionMode)},
+ decode_ie_create(Rest,PresentIEs bor 4,UpdatedErrors,UpdatedCreateReq);
+ true ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{selMode = selection_mode_internal_storage(SelectionMode)},
+ decode_ie_create(Rest,PresentIEs bor 4,Errors,UpdatedCreateReq)
+ end;
+decode_ie_create(<<16:8,
+ FlowLabel:16,
+ Rest/binary>>,PresentIEs,Errors,CreateReq) ->
+ if
+ PresentIEs band 8 == 8 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 8 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblData = FlowLabel},
+ decode_ie_create(Rest,PresentIEs bor 8,UpdatedErrors,UpdatedCreateReq);
+ true ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblData = FlowLabel},
+ decode_ie_create(Rest,PresentIEs bor 8,Errors,UpdatedCreateReq)
+ end;
+decode_ie_create(<<17:8,
+ FlowLabel:16,
+ Rest/binary>>,PresentIEs,Errors,CreateReq) ->
+ if
+ PresentIEs band 16 == 16 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 16 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblSig = FlowLabel},
+ decode_ie_create(Rest,PresentIEs bor 16,UpdatedErrors,UpdatedCreateReq);
+ true ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblSig = FlowLabel},
+ decode_ie_create(Rest,PresentIEs bor 16,Errors,UpdatedCreateReq)
+ end;
+decode_ie_create(<<128:8,
+ Length:16,
+ More/binary>>,PresentIEs,Errors,CreateReq) ->
+ <<PDPElement:Length/binary-unit:8,
+ Rest/binary>> = More,
+ if
+ PresentIEs band 32 == 32 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 32 ->
+ case pdp_addr_internal_storage(PDPElement) of
+ {ok,PDPAddress} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{endUserAdd = PDPAddress},
+ decode_ie_create(Rest,PresentIEs bor 32,UpdatedErrors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
+ outOfSequence = true},
+ decode_ie_create(Rest,PresentIEs bor 32,UpdatedErrors,CreateReq)
+ end;
+ true ->
+ case pdp_addr_internal_storage(PDPElement) of
+ {ok,PDPAddress} ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{endUserAdd = PDPAddress},
+ decode_ie_create(Rest,PresentIEs bor 32,Errors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
+ decode_ie_create(Rest,PresentIEs bor 32,UpdatedErrors,CreateReq)
+ end
+ end;
+decode_ie_create(<<131:8,
+ Length:16,
+ More/binary>>,PresentIEs,Errors,CreateReq) ->
+ <<APNElement:Length/binary-unit:8,
+ Rest/binary>> = More,
+ if
+ PresentIEs band 64 == 64 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 64 ->
+ case catch apn_internal_storage(APNElement,[]) of
+ {ok,APN} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{accPointName = APN},
+ decode_ie_create(Rest,PresentIEs bor 64,UpdatedErrors,UpdatedCreateReq);
+ _ ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true,
+ invalidManIE = true},
+ decode_ie_create(Rest,PresentIEs bor 64,UpdatedErrors,CreateReq)
+ end;
+ true ->
+ case catch apn_internal_storage(APNElement,[]) of
+ {ok,APN} ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{accPointName = APN},
+ decode_ie_create(Rest,PresentIEs bor 64,Errors,UpdatedCreateReq);
+ _ ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
+ decode_ie_create(Rest,PresentIEs bor 64,UpdatedErrors,CreateReq)
+ end
+ end;
+decode_ie_create(<<132:8,
+ Length:16,
+ More/binary>>,PresentIEs,Errors,CreateReq) ->
+ <<ConfigurationElement:Length/binary-unit:8,
+ Rest/binary>> = More,
+ if
+ PresentIEs band 128 == 128 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 128 ->
+ case catch pco_internal_storage(ConfigurationElement) of
+ {ok,PCO} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{protConOpt = PCO},
+ decode_ie_create(Rest,PresentIEs bor 128,UpdatedErrors,UpdatedCreateReq);
+ _ ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true,
+ incorrectOptIE = true},
+ decode_ie_create(Rest,PresentIEs bor 128,UpdatedErrors,CreateReq)
+ end;
+ true ->
+ case catch pco_internal_storage(ConfigurationElement) of
+ {ok,PCO} ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{protConOpt = PCO},
+ decode_ie_create(Rest,PresentIEs bor 128,Errors,UpdatedCreateReq);
+ _ ->
+ UpdatedErrors = Errors#protocolErrors{incorrectOptIE = true},
+ decode_ie_create(Rest,PresentIEs bor 128,UpdatedErrors,CreateReq)
+ end
+ end;
+decode_ie_create(<<133:8,
+ Length:16,
+ More/binary>>,PresentIEs,Errors,CreateReq) ->
+ <<AddressElement:Length/binary-unit:8,
+ Rest/binary>> = More,
+ if
+ PresentIEs band 768 == 768 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 512 ->
+ if
+ PresentIEs band 256 == 0 ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddSig = GSNAddr},
+ decode_ie_create(Rest,PresentIEs bor 256,UpdatedErrors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
+ outOfSequence = true},
+ decode_ie_create(Rest,PresentIEs bor 256,UpdatedErrors,CreateReq)
+ end;
+ true ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddUser = GSNAddr},
+ decode_ie_create(Rest,PresentIEs bor 512,UpdatedErrors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
+ outOfSequence = true},
+ decode_ie_create(Rest,PresentIEs bor 512,UpdatedErrors,CreateReq)
+ end
+ end;
+ PresentIEs < 256 ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddSig = GSNAddr},
+ decode_ie_create(Rest,PresentIEs bor 256,Errors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
+ decode_ie_create(Rest,PresentIEs bor 256,UpdatedErrors,CreateReq)
+ end;
+ true ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddUser = GSNAddr},
+ decode_ie_create(Rest,PresentIEs bor 512,Errors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
+ decode_ie_create(Rest,PresentIEs bor 512,UpdatedErrors,CreateReq)
+ end
+ end;
+decode_ie_create(<<134:8,
+ Length:16,
+ More/binary>>,PresentIEs,Errors,CreateReq) ->
+ <<MSISDNElement:Length/binary-unit:8,
+ Rest/binary>> = More,
+ if
+ PresentIEs band 1024 == 1024 ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ PresentIEs > 1024 ->
+ case msisdn_internal_storage(MSISDNElement,[]) of
+ {ok,MSISDN} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{msisdn = MSISDN},
+ decode_ie_create(Rest,PresentIEs bor 1024,UpdatedErrors,UpdatedCreateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true,
+ invalidManIE = true},
+ decode_ie_create(Rest,PresentIEs bor 1024,UpdatedErrors,CreateReq)
+ end;
+ true ->
+ UpdatedCreateReq = CreateReq#sesT_createReqV0{msisdn = #mvsT_msisdn{value = MSISDNElement}},
+ decode_ie_create(Rest,PresentIEs bor 1024,Errors,UpdatedCreateReq)
+ end;
+decode_ie_create(UnexpectedIE,PresentIEs,Errors,CreateReq) ->
+ case check_ie(UnexpectedIE) of
+ {defined_ie,Rest} ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ {handled_ie,Rest} ->
+ decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
+ {unhandled_ie} ->
+ {fault,193,CreateReq}
+ end.
+
+decode_ie_update(<<>>,PresentIEs,Errors,UpdateReq) ->
+ if
+ PresentIEs band 61 /= 61 ->
+ {fault,202,UpdateReq};
+ true ->
+ case Errors of
+ #protocolErrors{invalidManIE = true} ->
+ {fault,201,UpdateReq};
+ #protocolErrors{outOfSequence = true} ->
+ {fault,193,UpdateReq};
+ #protocolErrors{incorrectOptIE = true} ->
+ {fault,203,UpdateReq};
+ _ ->
+ {ok,UpdateReq}
+ end
+ end;
+decode_ie_update(<<6:8,
+ QoSElement:3/binary-unit:8,
+ Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
+ if
+ PresentIEs band 1 == 1 ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ PresentIEs > 1 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ <<_:2,
+ DelayClass:3,
+ ReliabilityClass:3,
+ PeakThroughput:4,
+ _:1,
+ PrecedenceClass:3,
+ _:3,
+ MeanThroughput:5>> = QoSElement,
+ QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
+ reliabilityClass = ReliabilityClass,
+ peakThroughput = PeakThroughput,
+ precedenceClass = PrecedenceClass,
+ meanThroughput = MeanThroughput},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{qos = QoS},
+ decode_ie_update(Rest,PresentIEs bor 1,UpdatedErrors,UpdatedUpdateReq);
+ true ->
+ <<_:2,
+ DelayClass:3,
+ ReliabilityClass:3,
+ PeakThroughput:4,
+ _:1,
+ PrecedenceClass:3,
+ _:3,
+ MeanThroughput:5>> = QoSElement,
+ QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
+ reliabilityClass = ReliabilityClass,
+ peakThroughput = PeakThroughput,
+ precedenceClass = PrecedenceClass,
+ meanThroughput = MeanThroughput},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{qos = QoS},
+ decode_ie_update(Rest,PresentIEs bor 1,Errors,UpdatedUpdateReq)
+ end;
+decode_ie_update(<<14:8,
+ Recovery:8,
+ Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
+ if
+ PresentIEs band 2 == 2 ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ PresentIEs > 2 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{recovery = Recovery},
+ decode_ie_update(Rest,PresentIEs bor 2,UpdatedErrors,UpdatedUpdateReq);
+ true ->
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{recovery = Recovery},
+ decode_ie_update(Rest,PresentIEs bor 2,Errors,UpdatedUpdateReq)
+ end;
+decode_ie_update(<<16:8,
+ FlowLabel:16,
+ Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
+ if
+ PresentIEs band 4 == 4 ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ PresentIEs > 4 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblData = FlowLabel},
+ decode_ie_update(Rest,PresentIEs bor 4,UpdatedErrors,UpdatedUpdateReq);
+ true ->
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblData = FlowLabel},
+ decode_ie_update(Rest,PresentIEs bor 4,Errors,UpdatedUpdateReq)
+ end;
+decode_ie_update(<<17:8,
+ FlowLabel:16,
+ Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
+ if
+ PresentIEs band 8 == 8 ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ PresentIEs > 8 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblSig = FlowLabel},
+ decode_ie_update(Rest,PresentIEs bor 8,UpdatedErrors,UpdatedUpdateReq);
+ true ->
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblSig = FlowLabel},
+ decode_ie_update(Rest,PresentIEs bor 8,Errors,UpdatedUpdateReq)
+ end;
+decode_ie_update(<<133:8,
+ Length:16,
+ More/binary>>,PresentIEs,Errors,UpdateReq) ->
+ <<AddressElement:Length/binary-unit:8,
+ Rest/binary>> = More,
+ if
+ PresentIEs band 48 == 48 ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ PresentIEs > 32 ->
+ if
+ PresentIEs band 16 == 0 ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddSig = GSNAddr},
+ decode_ie_update(Rest,PresentIEs bor 16,UpdatedErrors,UpdatedUpdateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
+ outOfSequence = true},
+ decode_ie_update(Rest,PresentIEs bor 16,UpdatedErrors,UpdateReq)
+ end;
+ true ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddUser = GSNAddr},
+ decode_ie_update(Rest,PresentIEs bor 32,UpdatedErrors,UpdatedUpdateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
+ outOfSequence = true},
+ decode_ie_update(Rest,PresentIEs bor 32,UpdatedErrors,UpdateReq)
+ end
+ end;
+ PresentIEs < 16 ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddSig = GSNAddr},
+ decode_ie_update(Rest,PresentIEs bor 16,Errors,UpdatedUpdateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
+ decode_ie_update(Rest,PresentIEs bor 16,UpdatedErrors,UpdateReq)
+ end;
+ true ->
+ case gsn_addr_internal_storage(AddressElement) of
+ {ok,GSNAddr} ->
+ UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddUser = GSNAddr},
+ decode_ie_update(Rest,PresentIEs bor 32,Errors,UpdatedUpdateReq);
+ {fault} ->
+ UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
+ decode_ie_update(Rest,PresentIEs bor 32,UpdatedErrors,UpdateReq)
+ end
+ end;
+decode_ie_update(UnexpectedIE,PresentIEs,Errors,UpdateReq) ->
+ case check_ie(UnexpectedIE) of
+ {defined_ie,Rest} ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ {handled_ie,Rest} ->
+ decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
+ {unhandled_ie} ->
+ {fault,193,UpdateReq}
+ end.
+
+decode_ie_delete_res(<<>>,PresentIEs,Errors,DeleteRes) ->
+ if
+ PresentIEs band 1 /= 1 ->
+ {fault,202,DeleteRes};
+ true ->
+ case Errors of
+ #protocolErrors{invalidManIE = true} ->
+ {fault,201,DeleteRes};
+ #protocolErrors{outOfSequence = true} ->
+ {fault,193,DeleteRes};
+ #protocolErrors{incorrectOptIE = true} ->
+ {fault,203,DeleteRes};
+ _ ->
+ {ok,DeleteRes}
+ end
+ end;
+decode_ie_delete_res(<<1:8,
+ Cause:8,
+ Rest/binary>>,PresentIEs,Errors,DeleteRes) ->
+ if
+ PresentIEs band 1 == 1 ->
+ decode_ie_delete_res(Rest,PresentIEs,Errors,DeleteRes);
+ PresentIEs > 1 ->
+ UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
+ UpdatedDeleteRes = DeleteRes#sesT_deleteResV0{cause = Cause},
+ decode_ie_delete_res(Rest,PresentIEs bor 1,UpdatedErrors,UpdatedDeleteRes);
+ true ->
+ UpdatedDeleteRes = DeleteRes#sesT_deleteResV0{cause = Cause},
+ decode_ie_delete_res(Rest,PresentIEs bor 1,Errors,UpdatedDeleteRes)
+ end;
+decode_ie_delete_res(UnexpectedIE,PresentIEs,Errors,DeleteRes) ->
+ case check_ie(UnexpectedIE) of
+ {defined_ie,Rest} ->
+ decode_ie_delete_res(Rest,PresentIEs,Errors,DeleteRes);
+ {handled_ie,Rest} ->
+ decode_ie_delete_res(Rest,PresentIEs,Errors,DeleteRes);
+ {unhandled_ie} ->
+ {fault,193,DeleteRes}
+ end.
+
+check_ie(<<1:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<2:8,
+ _:8/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<3:8,
+ _:6/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<4:8,
+ _:4/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<5:8,
+ _:4/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<6:8,
+ _:3/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<8:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<9:8,
+ _:28/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<11:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<12:8,
+ _:3/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<13:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<14:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<15:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<16:8,
+ _:16,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<17:8,
+ _:16,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<18:8,
+ _:32,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<19:8,
+ _:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<127:8,
+ _:4/binary-unit:8,
+ Rest/binary>>) ->
+ {defined_ie,Rest};
+check_ie(<<1:1,
+ _:7,
+ Length:16,
+ More/binary>>) ->
+ if
+ Length > size(More) ->
+ {unhandled_ie};
+ true ->
+ <<_:Length/binary-unit:8,
+ Rest/binary>> = More,
+ {handled_ie,Rest}
+ end;
+check_ie(_UnhandledIE) ->
+ {unhandled_ie}.
+
+tid_internal_storage(Bin,_) ->
+ Size = size(Bin) - 1,
+ <<Front:Size/binary,
+ NSAPI:4,
+ DigitN:4>> = Bin,
+ Result = case DigitN of
+ 15 ->
+ #mvsgT_tid{imsi = #mvsgT_imsi{value = Front},
+ nsapi = NSAPI};
+ _ ->
+ #mvsgT_tid{imsi = #mvsgT_imsi{value = <<Front/binary,
+ 15:4,
+ DigitN:4>>},
+ nsapi = NSAPI}
+ end,
+ {ok,Result}.
+
+selection_mode_internal_storage(0) ->
+ subscribed;
+selection_mode_internal_storage(1) ->
+ msRequested;
+selection_mode_internal_storage(2) ->
+ sgsnSelected;
+selection_mode_internal_storage(3) ->
+ sgsnSelected.
+
+pdp_addr_internal_storage(<<_:4,
+ 0:4,
+ 1:8>>) ->
+ {ok,#mvsgT_pdpAddressType{pdpTypeNbr = etsi_ppp,
+ address = []}};
+pdp_addr_internal_storage(<<_:4,
+ 0:4,
+ 2:8>>) ->
+ {ok,#mvsgT_pdpAddressType{pdpTypeNbr = etsi_osp_ihoss,
+ address = []}};
+pdp_addr_internal_storage(<<_:4,
+ 1:4,
+ 33:8>>) ->
+ {ok,#mvsgT_pdpAddressType{pdpTypeNbr = ietf_ipv4,
+ address = []}};
+pdp_addr_internal_storage(<<_:4,
+ 1:4,
+ 33:8,
+ IP_A:8,
+ IP_B:8,
+ IP_C:8,
+ IP_D:8>>) ->
+ {ok,#mvsgT_pdpAddressType{pdpTypeNbr = ietf_ipv4,
+ address = [IP_A,IP_B,IP_C,IP_D]}};
+pdp_addr_internal_storage(<<_:4,
+ 1:4,
+ 87:8,
+ IP_A:16,
+ IP_B:16,
+ IP_C:16,
+ IP_D:16,
+ IP_E:16,
+ IP_F:16,
+ IP_G:16,
+ IP_H:16>>) ->
+ {ok,#mvsgT_pdpAddressType{pdpTypeNbr = ietf_ipv6,
+ address = [IP_A,IP_B,IP_C,IP_D,IP_E,IP_F,IP_G,IP_H]}};
+pdp_addr_internal_storage(_PDP_ADDR) ->
+ {fault}.
+
+apn_internal_storage(<<>>,APN) ->
+ {ok,lists:reverse(APN)};
+apn_internal_storage(<<Length:8,
+ Rest/binary>>,APN) ->
+ <<Label:Length/binary-unit:8,
+ MoreAPNLabels/binary>> = Rest,
+ apn_internal_storage(MoreAPNLabels,[Label|APN]).
+
+pco_internal_storage(<<1:1,
+ _:4,
+ 0:3,
+ PPPConfigurationOptions/binary>>) ->
+ case ppp_configuration_options(PPPConfigurationOptions,#masT_pap{exists = false},[],[]) of
+ {ok,PAP,CHAP,IPCP} ->
+ {ok,#masT_protocolConfigOptions{pap = PAP,
+ chap = CHAP,
+ ipcp = IPCP}};
+ {fault} ->
+ {fault}
+ end;
+pco_internal_storage(<<1:1,
+ _:4,
+ 1:3,
+ _OSP_IHOSSConfigurationOptions/binary>>) ->
+ {ok,osp_ihoss};
+pco_internal_storage(_UnknownConfigurationOptions) ->
+ {fault}.
+
+ppp_configuration_options(<<>>,PAP,CHAP,IPCP) ->
+ {ok,PAP,CHAP,IPCP};
+ppp_configuration_options(<<49185:16,
+ Length:8,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ <<_LCP:Length/binary-unit:8,
+ Rest/binary>> = More,
+ ppp_configuration_options(Rest,PAP,CHAP,IPCP);
+ppp_configuration_options(<<49187:16,
+ _Length:8,
+ 1:8,
+ Identifier:8,
+ DataLength:16,
+ More/binary>>,_PAP,CHAP,IPCP) ->
+ ActualDataLength = DataLength - 4,
+ <<Data:ActualDataLength/binary-unit:8,
+ Rest/binary>> = More,
+ <<PeerIDLength:8,
+ PeerData/binary>> = Data,
+ <<PeerID:PeerIDLength/binary-unit:8,
+ PasswdLength:8,
+ PasswordData/binary>> = PeerData,
+ <<Password:PasswdLength/binary,
+ _Padding/binary>> = PasswordData,
+ ppp_configuration_options(Rest,#masT_pap{exists = true,
+ code = 1,
+ id = Identifier,
+ username = binary_to_list(PeerID),
+ password = binary_to_list(Password)},CHAP,IPCP);
+ppp_configuration_options(<<49187:16,
+ Length:8,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ <<PAP:Length/binary-unit:8,
+ Rest/binary>> = More,
+ ppp_configuration_options(Rest,PAP,CHAP,IPCP);
+ppp_configuration_options(<<49699:16,
+ _Length:8,
+ 1:8,
+ Identifier:8,
+ DataLength:16,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ ActualDataLength = DataLength - 4,
+ <<Data:ActualDataLength/binary-unit:8,
+ Rest/binary>> = More,
+ <<ValueSize:8,
+ ValueAndName/binary>> = Data,
+ <<Value:ValueSize/binary-unit:8,
+ Name/binary>> = ValueAndName,
+ ppp_configuration_options(Rest,PAP,[#masT_chap{code = 1,
+ id = Identifier,
+ value = binary_to_list(Value),
+ name = binary_to_list(Name)}|CHAP],IPCP);
+ppp_configuration_options(<<49699:16,
+ _Length:8,
+ 2:8,
+ Identifier:8,
+ DataLength:16,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ ActualDataLength = DataLength - 4,
+ <<Data:ActualDataLength/binary-unit:8,
+ Rest/binary>> = More,
+ <<ValueSize:8,
+ ValueAndName/binary>> = Data,
+ <<Value:ValueSize/binary-unit:8,
+ Name/binary>> = ValueAndName,
+ ppp_configuration_options(Rest,PAP,[#masT_chap{code = 2,
+ id = Identifier,
+ value = binary_to_list(Value),
+ name = binary_to_list(Name)}|CHAP],IPCP);
+ppp_configuration_options(<<49699:16,
+ Length:8,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ <<CHAP:Length/binary-unit:8,
+ Rest/binary>> = More,
+ ppp_configuration_options(Rest,PAP,CHAP,IPCP);
+ppp_configuration_options(<<32801:16,
+ _Length:8,
+ 1:8,
+ Identifier:8,
+ OptionsLength:16,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ ActualOptionsLength = OptionsLength - 4,
+ <<Options:ActualOptionsLength/binary-unit:8,
+ Rest/binary>> = More,
+ case Options of
+ <<3:8,
+ 6:8,
+ A1:8,
+ A2:8,
+ A3:8,
+ A4:8>> ->
+ ppp_configuration_options(Rest,PAP,CHAP,[#masT_ipcp{exists = true,
+ code = 1,
+ id = Identifier,
+ ipcpList = [#masT_ipcpData{type = 3,
+ ipAddress = #mvsgT_ipAddress{version = ipv4,
+ a1 = A1,
+ a2 = A2,
+ a3 = A3,
+ a4 = A4,
+ a5 = 0,
+ a6 = 0,
+ a7 = 0,
+ a8 = 0},
+ rawMessage = binary_to_list(Options)}]}|IPCP]);
+ <<129:8,
+ 6:8,
+ B1:8,
+ B2:8,
+ B3:8,
+ B4:8>> ->
+ ppp_configuration_options(Rest,PAP,CHAP,[#masT_ipcp{exists = true,
+ code = 1,
+ id = Identifier,
+ ipcpList = [#masT_ipcpData{type = 129,
+ ipAddress = #mvsgT_ipAddress{version = ipv4,
+ a1 = B1,
+ a2 = B2,
+ a3 = B3,
+ a4 = B4},
+ rawMessage = binary_to_list(Options)}]}|IPCP]);
+ <<131:8,
+ 6:8,
+ C1:8,
+ C2:8,
+ C3:8,
+ C4:8>> ->
+ ppp_configuration_options(Rest,PAP,CHAP,[#masT_ipcp{exists = true,
+ code = 1,
+ id = Identifier,
+ ipcpList = [#masT_ipcpData{type = 131,
+ ipAddress = #mvsgT_ipAddress{version = ipv4,
+ a1 = C1,
+ a2 = C2,
+ a3 = C3,
+ a4 = C4},
+ rawMessage = binary_to_list(Options)}]}|IPCP]);
+ _ ->
+ ppp_configuration_options(Rest,PAP,CHAP,IPCP)
+ end;
+ppp_configuration_options(<<_UnknownProtocolID:16,
+ Length:8,
+ More/binary>>,PAP,CHAP,IPCP) ->
+ <<_Skipped:Length/binary-unit:8,
+ Rest/binary>> = More,
+ ppp_configuration_options(Rest,PAP,CHAP,IPCP);
+ppp_configuration_options(_Unhandled,_PAP,_CHAP,_IPCP) ->
+ {fault}.
+
+gsn_addr_internal_storage(<<IP_A:8,
+ IP_B:8,
+ IP_C:8,
+ IP_D:8>>) ->
+ {ok,#mvsgT_ipAddress{version = ipv4,
+ a1 = IP_A,
+ a2 = IP_B,
+ a3 = IP_C,
+ a4 = IP_D,
+ a5 = 0,
+ a6 = 0,
+ a7 = 0,
+ a8 = 0}};
+gsn_addr_internal_storage(<<IP_A:16,
+ IP_B:16,
+ IP_C:16,
+ IP_D:16,
+ IP_E:16,
+ IP_F:16,
+ IP_G:16,
+ IP_H:16>>) ->
+ {ok,#mvsgT_ipAddress{version = ipv6,
+ a1 = IP_A,
+ a2 = IP_B,
+ a3 = IP_C,
+ a4 = IP_D,
+ a5 = IP_E,
+ a6 = IP_F,
+ a7 = IP_G,
+ a8 = IP_H}};
+gsn_addr_internal_storage(_GSN_ADDR) ->
+ {fault}.
+
+msisdn_internal_storage(<<>>,MSISDN) ->
+ {ok,#mvsT_msisdn{value = lists:reverse(MSISDN)}};
+msisdn_internal_storage(<<255:8,
+ _Rest/binary>>,MSISDN) ->
+ {ok,#mvsT_msisdn{value = lists:reverse(MSISDN)}};
+msisdn_internal_storage(<<15:4,
+ DigitN:4,
+ _Rest/binary>>,MSISDN) when DigitN < 10 ->
+ {ok,#mvsT_msisdn{value = lists:reverse([DigitN bor 240|MSISDN])}};
+msisdn_internal_storage(<<DigitNplus1:4,
+ DigitN:4,
+ Rest/binary>>,MSISDN) when DigitNplus1 < 10, DigitN < 10 ->
+ NewMSISDN = [DigitNplus1 bsl 4 bor DigitN|MSISDN],
+ msisdn_internal_storage(Rest,NewMSISDN);
+msisdn_internal_storage(_Rest,_MSISDN) ->
+ {fault}.