1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(bsdecode).
21-export([?MODULE/0]).
22
23-record(protocolErrors, {invalidManIE = false,
24                         outOfSequence = false,
25                         incorrectOptIE = false}).
26
27-record(mvsT_msisdn, {value}).
28
29
30-record(mvsgT_pdpAddressType, {pdpTypeNbr,
31                               address}).
32
33-record(mvsgT_ipAddress, {version,
34                          a1,
35                          a2,
36                          a3,
37                          a4,
38                          a5,
39                          a6,
40                          a7,
41                          a8}).
42
43-record(mvsgT_imsi, {value}).
44
45-record(mvsgT_tid, {imsi,
46                    nsapi}).
47
48-record(sesT_qualityOfServiceV0, {delayClass,
49                                  reliabilityClass,
50                                  peakThroughput,
51                                  precedenceClass,
52                                  meanThroughput}).
53
54-record(sesT_deleteReqV0, {tid}).
55
56-record(sesT_deleteResV0, {tid,
57                           cause}).
58
59-record(sesT_createReqV0, {tid,
60                           tidRaw,
61                           qos,
62                           recovery,
63                           selMode,
64                           flowLblData,
65                           flowLblSig,
66                           endUserAdd,
67                           accPointName,
68                           protConOpt,
69                           sgsnAddSig,
70                           sgsnAddUser,
71                           msisdn}).
72
73-record(sesT_updateReqV0, {tid,
74                           tidRaw,
75                           qos,
76                           recovery,
77                           flowLblData,
78                           flowLblSig,
79                           sgsnAddSig,
80                           sgsnAddUser}).
81
82-record(masT_ipcpData, {type,
83                        ipAddress,
84                        rawMessage}).
85
86-record(masT_ipcp, {exists,
87                    code,
88                    id,
89                    ipcpList}).
90
91-record(masT_pap, {exists,
92                   code,
93                   id,
94                   username,
95                   password}).
96
97-record(masT_chap, {code,
98                    id,
99                    value,
100                    name}).
101
102-record(masT_protocolConfigOptions, {chap,
103                                     pap,
104                                     ipcp}).
105
106?MODULE() ->
107    Res = test(),
108    {Res,Res =:=
109     {ok,{sesT_createReqV0,{mvsgT_tid,{mvsgT_imsi,<<81,67,101,7,0,0,0,240>>},6},
110	  [81,67,101,7,0,0,0,96],
111	  {sesT_qualityOfServiceV0,1,4,9,2,18},0,
112	  subscribed,0,0,{mvsgT_pdpAddressType,ietf_ipv4,[]},
113	  [<<97,112,110,48,49,51,97>>,<<101,114,105,99,115,115,111,110>>,<<115,101>>],
114	  {masT_protocolConfigOptions,[],
115	   {masT_pap,true,1,5,[117,115,101,114,53],[112,97,115,115,53]},[]},
116	  {mvsgT_ipAddress,ipv4,172,28,12,1,0,0,0,0},
117	  {mvsgT_ipAddress,ipv4,172,28,12,3,0,0,0,0},
118	  {mvsT_msisdn,<<145,148,113,129,0,0,0,0>>}},1}}.
119
120test() ->
121    Pdu = <<30,
122            16,
123            0,
124            90,
125            0,
126            1,
127            0,
128            0,
129            255,
130            255,
131            255,
132            255,
133            81,
134            67,
135            101,
136            7,
137            0,
138            0,
139            0,
140            96,
141            6,
142            12,
143            146,
144            18,
145            14,
146            0,
147            15,
148            252,
149            16,
150            0,
151            0,
152            17,
153            0,
154            0,
155            128,
156            0,
157            2,
158            241,
159            33,
160            131,
161            0,
162            20,
163            7,
164            97,
165            112,
166            110,
167            48,
168            49,
169            51,
170            97,
171            8,
172            101,
173            114,
174            105,
175            99,
176            115,
177            115,
178            111,
179            110,
180            2,
181            115,
182            101,
183            132,
184            0,
185            20,
186            128,
187            192,
188            35,
189            16,
190            1,
191            5,
192            0,
193            16,
194            5,
195            117,
196            115,
197            101,
198            114,
199            53,
200            5,
201            112,
202            97,
203            115,
204            115,
205            53,
206            133,
207            0,
208            4,
209            172,
210            28,
211            12,
212            1,
213            133,
214            0,
215            4,
216            172,
217            28,
218            12,
219            3,
220            134,
221            0,
222            8,
223            145,
224            148,
225            113,
226            129,
227            0,
228            0,
229            0,
230            0>>,
231    decode_v0_opt(10,Pdu).
232
233decode_v0_opt(0,Pdu) ->
234    decode_gtpc_msg(Pdu);
235decode_v0_opt(N,Pdu) ->
236    decode_gtpc_msg(Pdu),
237    decode_v0_opt(N - 1,Pdu).
238
239decode_gtpc_msg(<<0:3,
240                  _:4,
241                  0:1,
242                  16:8,
243                  _Length:16,
244                  SequenceNumber:16,
245                  _FlowLabel:16,
246                  _SNDCP_N_PDU_Number:8,
247                  _:3/binary-unit:8,
248                  TID:8/binary-unit:8,
249                  InformationElements/binary>>) ->
250    Errors = #protocolErrors{},
251    {ok,TID2} = tid_internal_storage(TID,[]),
252    EmptyCreateReq = #sesT_createReqV0{tid = TID2,
253                                       tidRaw = binary_to_list(TID)},
254    case catch decode_ie_create(InformationElements,0,Errors,EmptyCreateReq) of
255        {ok,CreateReq} ->
256            {ok,CreateReq,SequenceNumber};
257        {fault,Cause,CreateReq} ->
258            {fault,Cause,CreateReq,SequenceNumber};
259        {'EXIT',_Reason} ->
260            {fault,193,EmptyCreateReq,SequenceNumber}
261    end;
262decode_gtpc_msg(<<0:3,
263                  _:4,
264                  0:1,
265                  18:8,
266                  _Length:16,
267                  SequenceNumber:16,
268                  _FlowLabel:16,
269                  _SNDCP_N_PDU_Number:8,
270                  _:3/binary-unit:8,
271                  TID:8/binary-unit:8,
272                  InformationElements/binary>>) ->
273    io:format("hej",[]),
274    Errors = #protocolErrors{},
275    {ok,TID2} = tid_internal_storage(TID,[]),
276    EmptyUpdateReq = #sesT_updateReqV0{tid = TID2,
277                                       tidRaw = binary_to_list(TID)},
278    case catch decode_ie_update(InformationElements,0,Errors,EmptyUpdateReq) of
279        {ok,UpdateReq} ->
280            {ok,UpdateReq,SequenceNumber};
281        {fault,Cause,UpdateReq} ->
282            {fault,Cause,UpdateReq,SequenceNumber};
283        {'EXIT',Reason} ->
284            io:format("hej",[]),
285            {fault,193,EmptyUpdateReq,SequenceNumber,Reason}
286    end;
287decode_gtpc_msg(<<0:3,
288                  _:4,
289                  0:1,
290                  20:8,
291                  _Length:16,
292                  SequenceNumber:16,
293                  _FlowLabel:16,
294                  _SNDCP_N_PDU_Number:8,
295                  _:3/binary-unit:8,
296                  TID:8/binary-unit:8,
297                  _InformationElements/binary>>) ->
298    {ok,TID2} = tid_internal_storage(TID,[]),
299    DeleteReq = #sesT_deleteReqV0{tid = TID2},
300    {ok,DeleteReq,SequenceNumber};
301decode_gtpc_msg(<<0:3,
302                  _:4,
303                  0:1,
304                  21:8,
305                  _Length:16,
306                  SequenceNumber:16,
307                  _FlowLabel:16,
308                  _SNDCP_N_PDU_Number:8,
309                  _:3/binary-unit:8,
310                  TID:8/binary-unit:8,
311                  InformationElements/binary>>) ->
312    Errors = #protocolErrors{},
313    {ok,TID2} = tid_internal_storage(TID,[]),
314    EmptyDeleteRes = #sesT_deleteResV0{tid = TID2},
315    case catch decode_ie_delete_res(InformationElements,0,Errors,EmptyDeleteRes) of
316        {ok,DeleteRes} ->
317            {ok,DeleteRes,SequenceNumber};
318        {fault,Cause,DeleteRes} ->
319            {fault,Cause,DeleteRes,SequenceNumber};
320        {'EXIT',_Reason} ->
321            {fault,193,EmptyDeleteRes,SequenceNumber}
322    end;
323decode_gtpc_msg(_GTP_C_Message) ->
324    {fault}.
325
326decode_ie_create(<<>>,PresentIEs,Errors,CreateReq) ->
327    if
328        PresentIEs band 1917 /= 1917 ->
329            {fault,202,CreateReq};
330        true ->
331            case Errors of
332                #protocolErrors{invalidManIE = true} ->
333                    {fault,201,CreateReq};
334                #protocolErrors{outOfSequence = true} ->
335                    {fault,193,CreateReq};
336                #protocolErrors{incorrectOptIE = true} ->
337                    {fault,203,CreateReq};
338                _ ->
339                    {ok,CreateReq}
340            end
341    end;
342decode_ie_create(<<6:8,
343                   QoSElement:3/binary-unit:8,
344                   Rest/binary>>,PresentIEs,Errors,CreateReq) ->
345    if
346        PresentIEs band 1 == 1 ->
347            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
348        PresentIEs > 1 ->
349            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
350            <<_:2,
351              DelayClass:3,
352              ReliabilityClass:3,
353              PeakThroughput:4,
354              _:1,
355              PrecedenceClass:3,
356              _:3,
357              MeanThroughput:5>> = QoSElement,
358            QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
359                                           reliabilityClass = ReliabilityClass,
360                                           peakThroughput = PeakThroughput,
361                                           precedenceClass = PrecedenceClass,
362                                           meanThroughput = MeanThroughput},
363            UpdatedCreateReq = CreateReq#sesT_createReqV0{qos = QoS},
364            decode_ie_create(Rest,PresentIEs bor 1,UpdatedErrors,UpdatedCreateReq);
365        true ->
366            <<_:2,
367              DelayClass:3,
368              ReliabilityClass:3,
369              PeakThroughput:4,
370              _:1,
371              PrecedenceClass:3,
372              _:3,
373              MeanThroughput:5>> = QoSElement,
374            QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
375                                           reliabilityClass = ReliabilityClass,
376                                           peakThroughput = PeakThroughput,
377                                           precedenceClass = PrecedenceClass,
378                                           meanThroughput = MeanThroughput},
379            UpdatedCreateReq = CreateReq#sesT_createReqV0{qos = QoS},
380            decode_ie_create(Rest,PresentIEs bor 1,Errors,UpdatedCreateReq)
381    end;
382decode_ie_create(<<14:8,
383                   Recovery:8,
384                   Rest/binary>>,PresentIEs,Errors,CreateReq) ->
385    if
386        PresentIEs band 2 == 2 ->
387            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
388        PresentIEs > 2 ->
389            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
390            UpdatedCreateReq = CreateReq#sesT_createReqV0{recovery = Recovery},
391            decode_ie_create(Rest,PresentIEs bor 2,UpdatedErrors,UpdatedCreateReq);
392        true ->
393            UpdatedCreateReq = CreateReq#sesT_createReqV0{recovery = Recovery},
394            decode_ie_create(Rest,PresentIEs bor 2,Errors,UpdatedCreateReq)
395    end;
396decode_ie_create(<<15:8,
397                   _:6,
398                   SelectionMode:2,
399                   Rest/binary>>,PresentIEs,Errors,CreateReq) ->
400    if
401        PresentIEs band 4 == 4 ->
402            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
403        PresentIEs > 4 ->
404            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
405            UpdatedCreateReq = CreateReq#sesT_createReqV0{selMode = selection_mode_internal_storage(SelectionMode)},
406            decode_ie_create(Rest,PresentIEs bor 4,UpdatedErrors,UpdatedCreateReq);
407        true ->
408            UpdatedCreateReq = CreateReq#sesT_createReqV0{selMode = selection_mode_internal_storage(SelectionMode)},
409            decode_ie_create(Rest,PresentIEs bor 4,Errors,UpdatedCreateReq)
410    end;
411decode_ie_create(<<16:8,
412                   FlowLabel:16,
413                   Rest/binary>>,PresentIEs,Errors,CreateReq) ->
414    if
415        PresentIEs band 8 == 8 ->
416            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
417        PresentIEs > 8 ->
418            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
419            UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblData = FlowLabel},
420            decode_ie_create(Rest,PresentIEs bor 8,UpdatedErrors,UpdatedCreateReq);
421        true ->
422            UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblData = FlowLabel},
423            decode_ie_create(Rest,PresentIEs bor 8,Errors,UpdatedCreateReq)
424    end;
425decode_ie_create(<<17:8,
426                   FlowLabel:16,
427                   Rest/binary>>,PresentIEs,Errors,CreateReq) ->
428    if
429        PresentIEs band 16 == 16 ->
430            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
431        PresentIEs > 16 ->
432            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
433            UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblSig = FlowLabel},
434            decode_ie_create(Rest,PresentIEs bor 16,UpdatedErrors,UpdatedCreateReq);
435        true ->
436            UpdatedCreateReq = CreateReq#sesT_createReqV0{flowLblSig = FlowLabel},
437            decode_ie_create(Rest,PresentIEs bor 16,Errors,UpdatedCreateReq)
438    end;
439decode_ie_create(<<128:8,
440                   Length:16,
441                   More/binary>>,PresentIEs,Errors,CreateReq) ->
442    <<PDPElement:Length/binary-unit:8,
443      Rest/binary>> = More,
444    if
445        PresentIEs band 32 == 32 ->
446            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
447        PresentIEs > 32 ->
448            case pdp_addr_internal_storage(PDPElement) of
449                {ok,PDPAddress} ->
450                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
451                    UpdatedCreateReq = CreateReq#sesT_createReqV0{endUserAdd = PDPAddress},
452                    decode_ie_create(Rest,PresentIEs bor 32,UpdatedErrors,UpdatedCreateReq);
453                {fault} ->
454                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
455                                                          outOfSequence = true},
456                    decode_ie_create(Rest,PresentIEs bor 32,UpdatedErrors,CreateReq)
457            end;
458        true ->
459            case pdp_addr_internal_storage(PDPElement) of
460                {ok,PDPAddress} ->
461                    UpdatedCreateReq = CreateReq#sesT_createReqV0{endUserAdd = PDPAddress},
462                    decode_ie_create(Rest,PresentIEs bor 32,Errors,UpdatedCreateReq);
463                {fault} ->
464                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
465                    decode_ie_create(Rest,PresentIEs bor 32,UpdatedErrors,CreateReq)
466            end
467    end;
468decode_ie_create(<<131:8,
469                   Length:16,
470                   More/binary>>,PresentIEs,Errors,CreateReq) ->
471    <<APNElement:Length/binary-unit:8,
472      Rest/binary>> = More,
473    if
474        PresentIEs band 64 == 64 ->
475            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
476        PresentIEs > 64 ->
477            case catch apn_internal_storage(APNElement,[]) of
478                {ok,APN} ->
479                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
480                    UpdatedCreateReq = CreateReq#sesT_createReqV0{accPointName = APN},
481                    decode_ie_create(Rest,PresentIEs bor 64,UpdatedErrors,UpdatedCreateReq);
482                _ ->
483                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true,
484                                                          invalidManIE = true},
485                    decode_ie_create(Rest,PresentIEs bor 64,UpdatedErrors,CreateReq)
486            end;
487        true ->
488            case catch apn_internal_storage(APNElement,[]) of
489                {ok,APN} ->
490                    UpdatedCreateReq = CreateReq#sesT_createReqV0{accPointName = APN},
491                    decode_ie_create(Rest,PresentIEs bor 64,Errors,UpdatedCreateReq);
492                _ ->
493                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
494                    decode_ie_create(Rest,PresentIEs bor 64,UpdatedErrors,CreateReq)
495            end
496    end;
497decode_ie_create(<<132:8,
498                   Length:16,
499                   More/binary>>,PresentIEs,Errors,CreateReq) ->
500    <<ConfigurationElement:Length/binary-unit:8,
501      Rest/binary>> = More,
502    if
503        PresentIEs band 128 == 128 ->
504            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
505        PresentIEs > 128 ->
506            case catch pco_internal_storage(ConfigurationElement) of
507                {ok,PCO} ->
508                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
509                    UpdatedCreateReq = CreateReq#sesT_createReqV0{protConOpt = PCO},
510                    decode_ie_create(Rest,PresentIEs bor 128,UpdatedErrors,UpdatedCreateReq);
511                _ ->
512                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true,
513                                                          incorrectOptIE = true},
514                    decode_ie_create(Rest,PresentIEs bor 128,UpdatedErrors,CreateReq)
515            end;
516        true ->
517            case catch pco_internal_storage(ConfigurationElement) of
518                {ok,PCO} ->
519                    UpdatedCreateReq = CreateReq#sesT_createReqV0{protConOpt = PCO},
520                    decode_ie_create(Rest,PresentIEs bor 128,Errors,UpdatedCreateReq);
521                _ ->
522                    UpdatedErrors = Errors#protocolErrors{incorrectOptIE = true},
523                    decode_ie_create(Rest,PresentIEs bor 128,UpdatedErrors,CreateReq)
524            end
525    end;
526decode_ie_create(<<133:8,
527                   Length:16,
528                   More/binary>>,PresentIEs,Errors,CreateReq) ->
529    <<AddressElement:Length/binary-unit:8,
530      Rest/binary>> = More,
531    if
532        PresentIEs band 768 == 768 ->
533            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
534        PresentIEs > 512 ->
535            if
536                PresentIEs band 256 == 0 ->
537                    case gsn_addr_internal_storage(AddressElement) of
538                        {ok,GSNAddr} ->
539                            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
540                            UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddSig = GSNAddr},
541                            decode_ie_create(Rest,PresentIEs bor 256,UpdatedErrors,UpdatedCreateReq);
542                        {fault} ->
543                            UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
544                                                                  outOfSequence = true},
545                            decode_ie_create(Rest,PresentIEs bor 256,UpdatedErrors,CreateReq)
546                    end;
547                true ->
548                    case gsn_addr_internal_storage(AddressElement) of
549                        {ok,GSNAddr} ->
550                            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
551                            UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddUser = GSNAddr},
552                            decode_ie_create(Rest,PresentIEs bor 512,UpdatedErrors,UpdatedCreateReq);
553                        {fault} ->
554                            UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
555                                                                  outOfSequence = true},
556                            decode_ie_create(Rest,PresentIEs bor 512,UpdatedErrors,CreateReq)
557                    end
558            end;
559        PresentIEs < 256 ->
560            case gsn_addr_internal_storage(AddressElement) of
561                {ok,GSNAddr} ->
562                    UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddSig = GSNAddr},
563                    decode_ie_create(Rest,PresentIEs bor 256,Errors,UpdatedCreateReq);
564                {fault} ->
565                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
566                    decode_ie_create(Rest,PresentIEs bor 256,UpdatedErrors,CreateReq)
567            end;
568        true ->
569            case gsn_addr_internal_storage(AddressElement) of
570                {ok,GSNAddr} ->
571                    UpdatedCreateReq = CreateReq#sesT_createReqV0{sgsnAddUser = GSNAddr},
572                    decode_ie_create(Rest,PresentIEs bor 512,Errors,UpdatedCreateReq);
573                {fault} ->
574                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
575                    decode_ie_create(Rest,PresentIEs bor 512,UpdatedErrors,CreateReq)
576            end
577    end;
578decode_ie_create(<<134:8,
579                   Length:16,
580                   More/binary>>,PresentIEs,Errors,CreateReq) ->
581    <<MSISDNElement:Length/binary-unit:8,
582      Rest/binary>> = More,
583    if
584        PresentIEs band 1024 == 1024 ->
585            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
586        PresentIEs > 1024 ->
587            case msisdn_internal_storage(MSISDNElement,[]) of
588                {ok,MSISDN} ->
589                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
590                    UpdatedCreateReq = CreateReq#sesT_createReqV0{msisdn = MSISDN},
591                    decode_ie_create(Rest,PresentIEs bor 1024,UpdatedErrors,UpdatedCreateReq);
592                {fault} ->
593                    UpdatedErrors = Errors#protocolErrors{outOfSequence = true,
594                                                          invalidManIE = true},
595                    decode_ie_create(Rest,PresentIEs bor 1024,UpdatedErrors,CreateReq)
596            end;
597        true ->
598            UpdatedCreateReq = CreateReq#sesT_createReqV0{msisdn = #mvsT_msisdn{value = MSISDNElement}},
599            decode_ie_create(Rest,PresentIEs bor 1024,Errors,UpdatedCreateReq)
600    end;
601decode_ie_create(UnexpectedIE,PresentIEs,Errors,CreateReq) ->
602    case check_ie(UnexpectedIE) of
603        {defined_ie,Rest} ->
604            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
605        {handled_ie,Rest} ->
606            decode_ie_create(Rest,PresentIEs,Errors,CreateReq);
607        {unhandled_ie} ->
608            {fault,193,CreateReq}
609    end.
610
611decode_ie_update(<<>>,PresentIEs,Errors,UpdateReq) ->
612    if
613        PresentIEs band 61 /= 61 ->
614            {fault,202,UpdateReq};
615        true ->
616            case Errors of
617                #protocolErrors{invalidManIE = true} ->
618                    {fault,201,UpdateReq};
619                #protocolErrors{outOfSequence = true} ->
620                    {fault,193,UpdateReq};
621                #protocolErrors{incorrectOptIE = true} ->
622                    {fault,203,UpdateReq};
623                _ ->
624                    {ok,UpdateReq}
625            end
626    end;
627decode_ie_update(<<6:8,
628                   QoSElement:3/binary-unit:8,
629                   Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
630    if
631        PresentIEs band 1 == 1 ->
632            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
633        PresentIEs > 1 ->
634            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
635            <<_:2,
636              DelayClass:3,
637              ReliabilityClass:3,
638              PeakThroughput:4,
639              _:1,
640              PrecedenceClass:3,
641              _:3,
642              MeanThroughput:5>> = QoSElement,
643            QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
644                                           reliabilityClass = ReliabilityClass,
645                                           peakThroughput = PeakThroughput,
646                                           precedenceClass = PrecedenceClass,
647                                           meanThroughput = MeanThroughput},
648            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{qos = QoS},
649            decode_ie_update(Rest,PresentIEs bor 1,UpdatedErrors,UpdatedUpdateReq);
650        true ->
651            <<_:2,
652              DelayClass:3,
653              ReliabilityClass:3,
654              PeakThroughput:4,
655              _:1,
656              PrecedenceClass:3,
657              _:3,
658              MeanThroughput:5>> = QoSElement,
659            QoS = #sesT_qualityOfServiceV0{delayClass = DelayClass,
660                                           reliabilityClass = ReliabilityClass,
661                                           peakThroughput = PeakThroughput,
662                                           precedenceClass = PrecedenceClass,
663                                           meanThroughput = MeanThroughput},
664            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{qos = QoS},
665            decode_ie_update(Rest,PresentIEs bor 1,Errors,UpdatedUpdateReq)
666    end;
667decode_ie_update(<<14:8,
668                   Recovery:8,
669                   Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
670    if
671        PresentIEs band 2 == 2 ->
672            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
673        PresentIEs > 2 ->
674            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
675            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{recovery = Recovery},
676            decode_ie_update(Rest,PresentIEs bor 2,UpdatedErrors,UpdatedUpdateReq);
677        true ->
678            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{recovery = Recovery},
679            decode_ie_update(Rest,PresentIEs bor 2,Errors,UpdatedUpdateReq)
680    end;
681decode_ie_update(<<16:8,
682                   FlowLabel:16,
683                   Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
684    if
685        PresentIEs band 4 == 4 ->
686            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
687        PresentIEs > 4 ->
688            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
689            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblData = FlowLabel},
690            decode_ie_update(Rest,PresentIEs bor 4,UpdatedErrors,UpdatedUpdateReq);
691        true ->
692            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblData = FlowLabel},
693            decode_ie_update(Rest,PresentIEs bor 4,Errors,UpdatedUpdateReq)
694    end;
695decode_ie_update(<<17:8,
696                   FlowLabel:16,
697                   Rest/binary>>,PresentIEs,Errors,UpdateReq) ->
698    if
699        PresentIEs band 8 == 8 ->
700            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
701        PresentIEs > 8 ->
702            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
703            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblSig = FlowLabel},
704            decode_ie_update(Rest,PresentIEs bor 8,UpdatedErrors,UpdatedUpdateReq);
705        true ->
706            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{flowLblSig = FlowLabel},
707            decode_ie_update(Rest,PresentIEs bor 8,Errors,UpdatedUpdateReq)
708    end;
709decode_ie_update(<<133:8,
710                   Length:16,
711                   More/binary>>,PresentIEs,Errors,UpdateReq) ->
712    <<AddressElement:Length/binary-unit:8,
713      Rest/binary>> = More,
714    if
715        PresentIEs band 48 == 48 ->
716            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
717        PresentIEs > 32 ->
718            if
719                PresentIEs band 16 == 0 ->
720                    case gsn_addr_internal_storage(AddressElement) of
721                        {ok,GSNAddr} ->
722                            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
723                            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddSig = GSNAddr},
724                            decode_ie_update(Rest,PresentIEs bor 16,UpdatedErrors,UpdatedUpdateReq);
725                        {fault} ->
726                            UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
727                                                                  outOfSequence = true},
728                            decode_ie_update(Rest,PresentIEs bor 16,UpdatedErrors,UpdateReq)
729                    end;
730                true ->
731                    case gsn_addr_internal_storage(AddressElement) of
732                        {ok,GSNAddr} ->
733                            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
734                            UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddUser = GSNAddr},
735                            decode_ie_update(Rest,PresentIEs bor 32,UpdatedErrors,UpdatedUpdateReq);
736                        {fault} ->
737                            UpdatedErrors = Errors#protocolErrors{invalidManIE = true,
738                                                                  outOfSequence = true},
739                            decode_ie_update(Rest,PresentIEs bor 32,UpdatedErrors,UpdateReq)
740                    end
741            end;
742        PresentIEs < 16 ->
743            case gsn_addr_internal_storage(AddressElement) of
744                {ok,GSNAddr} ->
745                    UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddSig = GSNAddr},
746                    decode_ie_update(Rest,PresentIEs bor 16,Errors,UpdatedUpdateReq);
747                {fault} ->
748                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
749                    decode_ie_update(Rest,PresentIEs bor 16,UpdatedErrors,UpdateReq)
750            end;
751        true ->
752            case gsn_addr_internal_storage(AddressElement) of
753                {ok,GSNAddr} ->
754                    UpdatedUpdateReq = UpdateReq#sesT_updateReqV0{sgsnAddUser = GSNAddr},
755                    decode_ie_update(Rest,PresentIEs bor 32,Errors,UpdatedUpdateReq);
756                {fault} ->
757                    UpdatedErrors = Errors#protocolErrors{invalidManIE = true},
758                    decode_ie_update(Rest,PresentIEs bor 32,UpdatedErrors,UpdateReq)
759            end
760    end;
761decode_ie_update(UnexpectedIE,PresentIEs,Errors,UpdateReq) ->
762    case check_ie(UnexpectedIE) of
763        {defined_ie,Rest} ->
764            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
765        {handled_ie,Rest} ->
766            decode_ie_update(Rest,PresentIEs,Errors,UpdateReq);
767        {unhandled_ie} ->
768            {fault,193,UpdateReq}
769    end.
770
771decode_ie_delete_res(<<>>,PresentIEs,Errors,DeleteRes) ->
772    if
773        PresentIEs band 1 /= 1 ->
774            {fault,202,DeleteRes};
775        true ->
776            case Errors of
777                #protocolErrors{invalidManIE = true} ->
778                    {fault,201,DeleteRes};
779                #protocolErrors{outOfSequence = true} ->
780                    {fault,193,DeleteRes};
781                #protocolErrors{incorrectOptIE = true} ->
782                    {fault,203,DeleteRes};
783                _ ->
784                    {ok,DeleteRes}
785            end
786    end;
787decode_ie_delete_res(<<1:8,
788                       Cause:8,
789                       Rest/binary>>,PresentIEs,Errors,DeleteRes) ->
790    if
791        PresentIEs band 1 == 1 ->
792            decode_ie_delete_res(Rest,PresentIEs,Errors,DeleteRes);
793        PresentIEs > 1 ->
794            UpdatedErrors = Errors#protocolErrors{outOfSequence = true},
795            UpdatedDeleteRes = DeleteRes#sesT_deleteResV0{cause = Cause},
796            decode_ie_delete_res(Rest,PresentIEs bor 1,UpdatedErrors,UpdatedDeleteRes);
797        true ->
798            UpdatedDeleteRes = DeleteRes#sesT_deleteResV0{cause = Cause},
799            decode_ie_delete_res(Rest,PresentIEs bor 1,Errors,UpdatedDeleteRes)
800    end;
801decode_ie_delete_res(UnexpectedIE,PresentIEs,Errors,DeleteRes) ->
802    case check_ie(UnexpectedIE) of
803        {defined_ie,Rest} ->
804            decode_ie_delete_res(Rest,PresentIEs,Errors,DeleteRes);
805        {handled_ie,Rest} ->
806            decode_ie_delete_res(Rest,PresentIEs,Errors,DeleteRes);
807        {unhandled_ie} ->
808            {fault,193,DeleteRes}
809    end.
810
811check_ie(<<1:8,
812           _:8,
813           Rest/binary>>) ->
814    {defined_ie,Rest};
815check_ie(<<2:8,
816           _:8/binary-unit:8,
817           Rest/binary>>) ->
818    {defined_ie,Rest};
819check_ie(<<3:8,
820           _:6/binary-unit:8,
821           Rest/binary>>) ->
822    {defined_ie,Rest};
823check_ie(<<4:8,
824           _:4/binary-unit:8,
825           Rest/binary>>) ->
826    {defined_ie,Rest};
827check_ie(<<5:8,
828           _:4/binary-unit:8,
829           Rest/binary>>) ->
830    {defined_ie,Rest};
831check_ie(<<6:8,
832           _:3/binary-unit:8,
833           Rest/binary>>) ->
834    {defined_ie,Rest};
835check_ie(<<8:8,
836           _:8,
837           Rest/binary>>) ->
838    {defined_ie,Rest};
839check_ie(<<9:8,
840           _:28/binary-unit:8,
841           Rest/binary>>) ->
842    {defined_ie,Rest};
843check_ie(<<11:8,
844           _:8,
845           Rest/binary>>) ->
846    {defined_ie,Rest};
847check_ie(<<12:8,
848           _:3/binary-unit:8,
849           Rest/binary>>) ->
850    {defined_ie,Rest};
851check_ie(<<13:8,
852           _:8,
853           Rest/binary>>) ->
854    {defined_ie,Rest};
855check_ie(<<14:8,
856           _:8,
857           Rest/binary>>) ->
858    {defined_ie,Rest};
859check_ie(<<15:8,
860           _:8,
861           Rest/binary>>) ->
862    {defined_ie,Rest};
863check_ie(<<16:8,
864           _:16,
865           Rest/binary>>) ->
866    {defined_ie,Rest};
867check_ie(<<17:8,
868           _:16,
869           Rest/binary>>) ->
870    {defined_ie,Rest};
871check_ie(<<18:8,
872           _:32,
873           Rest/binary>>) ->
874    {defined_ie,Rest};
875check_ie(<<19:8,
876           _:8,
877           Rest/binary>>) ->
878    {defined_ie,Rest};
879check_ie(<<127:8,
880           _:4/binary-unit:8,
881           Rest/binary>>) ->
882    {defined_ie,Rest};
883check_ie(<<1:1,
884           _:7,
885           Length:16,
886           More/binary>>) ->
887    if
888        Length > size(More) ->
889            {unhandled_ie};
890        true ->
891            <<_:Length/binary-unit:8,
892              Rest/binary>> = More,
893            {handled_ie,Rest}
894    end;
895check_ie(_UnhandledIE) ->
896    {unhandled_ie}.
897
898tid_internal_storage(Bin,_) ->
899    Size = size(Bin) - 1,
900    <<Front:Size/binary,
901      NSAPI:4,
902      DigitN:4>> = Bin,
903    Result = case DigitN of
904                 15 ->
905                     #mvsgT_tid{imsi = #mvsgT_imsi{value = Front},
906                                nsapi = NSAPI};
907                 _ ->
908                     #mvsgT_tid{imsi = #mvsgT_imsi{value = <<Front/binary,
909                                                             15:4,
910                                                             DigitN:4>>},
911                                nsapi = NSAPI}
912             end,
913    {ok,Result}.
914
915selection_mode_internal_storage(0) ->
916    subscribed;
917selection_mode_internal_storage(1) ->
918    msRequested;
919selection_mode_internal_storage(2) ->
920    sgsnSelected;
921selection_mode_internal_storage(3) ->
922    sgsnSelected.
923
924pdp_addr_internal_storage(<<_:4,
925                            0:4,
926                            1:8>>) ->
927    {ok,#mvsgT_pdpAddressType{pdpTypeNbr = etsi_ppp,
928                           address = []}};
929pdp_addr_internal_storage(<<_:4,
930                            0:4,
931                            2:8>>) ->
932    {ok,#mvsgT_pdpAddressType{pdpTypeNbr = etsi_osp_ihoss,
933                           address = []}};
934pdp_addr_internal_storage(<<_:4,
935                            1:4,
936                            33:8>>) ->
937    {ok,#mvsgT_pdpAddressType{pdpTypeNbr = ietf_ipv4,
938                           address = []}};
939pdp_addr_internal_storage(<<_:4,
940                            1:4,
941                            33:8,
942                            IP_A:8,
943                            IP_B:8,
944                            IP_C:8,
945                            IP_D:8>>) ->
946    {ok,#mvsgT_pdpAddressType{pdpTypeNbr = ietf_ipv4,
947                           address = [IP_A,IP_B,IP_C,IP_D]}};
948pdp_addr_internal_storage(<<_:4,
949                            1:4,
950                            87:8,
951                            IP_A:16,
952                            IP_B:16,
953                            IP_C:16,
954                            IP_D:16,
955                            IP_E:16,
956                            IP_F:16,
957                            IP_G:16,
958                            IP_H:16>>) ->
959    {ok,#mvsgT_pdpAddressType{pdpTypeNbr = ietf_ipv6,
960                           address = [IP_A,IP_B,IP_C,IP_D,IP_E,IP_F,IP_G,IP_H]}};
961pdp_addr_internal_storage(_PDP_ADDR) ->
962    {fault}.
963
964apn_internal_storage(<<>>,APN) ->
965    {ok,lists:reverse(APN)};
966apn_internal_storage(<<Length:8,
967                       Rest/binary>>,APN) ->
968    <<Label:Length/binary-unit:8,
969      MoreAPNLabels/binary>> = Rest,
970    apn_internal_storage(MoreAPNLabels,[Label|APN]).
971
972pco_internal_storage(<<1:1,
973                       _:4,
974                       0:3,
975                       PPPConfigurationOptions/binary>>) ->
976    case ppp_configuration_options(PPPConfigurationOptions,#masT_pap{exists = false},[],[]) of
977        {ok,PAP,CHAP,IPCP} ->
978            {ok,#masT_protocolConfigOptions{pap = PAP,
979                                         chap = CHAP,
980                                         ipcp = IPCP}};
981        {fault} ->
982            {fault}
983    end;
984pco_internal_storage(<<1:1,
985                       _:4,
986                       1:3,
987                       _OSP_IHOSSConfigurationOptions/binary>>) ->
988    {ok,osp_ihoss};
989pco_internal_storage(_UnknownConfigurationOptions) ->
990    {fault}.
991
992ppp_configuration_options(<<>>,PAP,CHAP,IPCP) ->
993    {ok,PAP,CHAP,IPCP};
994ppp_configuration_options(<<49185:16,
995                            Length:8,
996                            More/binary>>,PAP,CHAP,IPCP) ->
997    <<_LCP:Length/binary-unit:8,
998      Rest/binary>> = More,
999    ppp_configuration_options(Rest,PAP,CHAP,IPCP);
1000ppp_configuration_options(<<49187:16,
1001                            _Length:8,
1002                            1:8,
1003                            Identifier:8,
1004                            DataLength:16,
1005                            More/binary>>,_PAP,CHAP,IPCP) ->
1006    ActualDataLength = DataLength - 4,
1007    <<Data:ActualDataLength/binary-unit:8,
1008      Rest/binary>> = More,
1009    <<PeerIDLength:8,
1010      PeerData/binary>> = Data,
1011    <<PeerID:PeerIDLength/binary-unit:8,
1012      PasswdLength:8,
1013      PasswordData/binary>> = PeerData,
1014    <<Password:PasswdLength/binary,
1015      _Padding/binary>> = PasswordData,
1016    ppp_configuration_options(Rest,#masT_pap{exists = true,
1017                                        code = 1,
1018                                        id = Identifier,
1019                                        username = binary_to_list(PeerID),
1020                                        password = binary_to_list(Password)},CHAP,IPCP);
1021ppp_configuration_options(<<49187:16,
1022                            Length:8,
1023                            More/binary>>,PAP,CHAP,IPCP) ->
1024    <<PAP:Length/binary-unit:8,
1025      Rest/binary>> = More,
1026    ppp_configuration_options(Rest,PAP,CHAP,IPCP);
1027ppp_configuration_options(<<49699:16,
1028                            _Length:8,
1029                            1:8,
1030                            Identifier:8,
1031                            DataLength:16,
1032                            More/binary>>,PAP,CHAP,IPCP) ->
1033    ActualDataLength = DataLength - 4,
1034    <<Data:ActualDataLength/binary-unit:8,
1035      Rest/binary>> = More,
1036    <<ValueSize:8,
1037      ValueAndName/binary>> = Data,
1038    <<Value:ValueSize/binary-unit:8,
1039      Name/binary>> = ValueAndName,
1040    ppp_configuration_options(Rest,PAP,[#masT_chap{code = 1,
1041                                          id = Identifier,
1042                                          value = binary_to_list(Value),
1043                                          name = binary_to_list(Name)}|CHAP],IPCP);
1044ppp_configuration_options(<<49699:16,
1045                            _Length:8,
1046                            2:8,
1047                            Identifier:8,
1048                            DataLength:16,
1049                            More/binary>>,PAP,CHAP,IPCP) ->
1050    ActualDataLength = DataLength - 4,
1051    <<Data:ActualDataLength/binary-unit:8,
1052      Rest/binary>> = More,
1053    <<ValueSize:8,
1054      ValueAndName/binary>> = Data,
1055    <<Value:ValueSize/binary-unit:8,
1056      Name/binary>> = ValueAndName,
1057    ppp_configuration_options(Rest,PAP,[#masT_chap{code = 2,
1058                                          id = Identifier,
1059                                          value = binary_to_list(Value),
1060                                          name = binary_to_list(Name)}|CHAP],IPCP);
1061ppp_configuration_options(<<49699:16,
1062                            Length:8,
1063                            More/binary>>,PAP,CHAP,IPCP) ->
1064    <<CHAP:Length/binary-unit:8,
1065      Rest/binary>> = More,
1066    ppp_configuration_options(Rest,PAP,CHAP,IPCP);
1067ppp_configuration_options(<<32801:16,
1068                            _Length:8,
1069                            1:8,
1070                            Identifier:8,
1071                            OptionsLength:16,
1072                            More/binary>>,PAP,CHAP,IPCP) ->
1073    ActualOptionsLength = OptionsLength - 4,
1074    <<Options:ActualOptionsLength/binary-unit:8,
1075      Rest/binary>> = More,
1076    case Options of
1077        <<3:8,
1078          6:8,
1079          A1:8,
1080          A2:8,
1081          A3:8,
1082          A4:8>> ->
1083            ppp_configuration_options(Rest,PAP,CHAP,[#masT_ipcp{exists = true,
1084                                                  code = 1,
1085                                                  id = Identifier,
1086                                                  ipcpList = [#masT_ipcpData{type = 3,
1087                                                                             ipAddress = #mvsgT_ipAddress{version = ipv4,
1088                                                                                                          a1 = A1,
1089                                                                                                          a2 = A2,
1090                                                                                                          a3 = A3,
1091                                                                                                          a4 = A4,
1092                                                                                                          a5 = 0,
1093                                                                                                          a6 = 0,
1094                                                                                                          a7 = 0,
1095                                                                                                          a8 = 0},
1096                                                                             rawMessage = binary_to_list(Options)}]}|IPCP]);
1097        <<129:8,
1098          6:8,
1099          B1:8,
1100          B2:8,
1101          B3:8,
1102          B4:8>> ->
1103            ppp_configuration_options(Rest,PAP,CHAP,[#masT_ipcp{exists = true,
1104                                                  code = 1,
1105                                                  id = Identifier,
1106                                                  ipcpList = [#masT_ipcpData{type = 129,
1107                                                                             ipAddress = #mvsgT_ipAddress{version = ipv4,
1108                                                                                                          a1 = B1,
1109                                                                                                          a2 = B2,
1110                                                                                                          a3 = B3,
1111                                                                                                          a4 = B4},
1112                                                                             rawMessage = binary_to_list(Options)}]}|IPCP]);
1113        <<131:8,
1114          6:8,
1115          C1:8,
1116          C2:8,
1117          C3:8,
1118          C4:8>> ->
1119            ppp_configuration_options(Rest,PAP,CHAP,[#masT_ipcp{exists = true,
1120                                                  code = 1,
1121                                                  id = Identifier,
1122                                                  ipcpList = [#masT_ipcpData{type = 131,
1123                                                                             ipAddress = #mvsgT_ipAddress{version = ipv4,
1124                                                                                                          a1 = C1,
1125                                                                                                          a2 = C2,
1126                                                                                                          a3 = C3,
1127                                                                                                          a4 = C4},
1128                                                                             rawMessage = binary_to_list(Options)}]}|IPCP]);
1129        _ ->
1130            ppp_configuration_options(Rest,PAP,CHAP,IPCP)
1131    end;
1132ppp_configuration_options(<<_UnknownProtocolID:16,
1133                            Length:8,
1134                            More/binary>>,PAP,CHAP,IPCP) ->
1135    <<_Skipped:Length/binary-unit:8,
1136      Rest/binary>> = More,
1137    ppp_configuration_options(Rest,PAP,CHAP,IPCP);
1138ppp_configuration_options(_Unhandled,_PAP,_CHAP,_IPCP) ->
1139    {fault}.
1140
1141gsn_addr_internal_storage(<<IP_A:8,
1142                            IP_B:8,
1143                            IP_C:8,
1144                            IP_D:8>>) ->
1145    {ok,#mvsgT_ipAddress{version = ipv4,
1146                      a1 = IP_A,
1147                      a2 = IP_B,
1148                      a3 = IP_C,
1149                      a4 = IP_D,
1150                      a5 = 0,
1151                      a6 = 0,
1152                      a7 = 0,
1153                      a8 = 0}};
1154gsn_addr_internal_storage(<<IP_A:16,
1155                            IP_B:16,
1156                            IP_C:16,
1157                            IP_D:16,
1158                            IP_E:16,
1159                            IP_F:16,
1160                            IP_G:16,
1161                            IP_H:16>>) ->
1162    {ok,#mvsgT_ipAddress{version = ipv6,
1163                      a1 = IP_A,
1164                      a2 = IP_B,
1165                      a3 = IP_C,
1166                      a4 = IP_D,
1167                      a5 = IP_E,
1168                      a6 = IP_F,
1169                      a7 = IP_G,
1170                      a8 = IP_H}};
1171gsn_addr_internal_storage(_GSN_ADDR) ->
1172    {fault}.
1173
1174msisdn_internal_storage(<<>>,MSISDN) ->
1175    {ok,#mvsT_msisdn{value = lists:reverse(MSISDN)}};
1176msisdn_internal_storage(<<255:8,
1177                          _Rest/binary>>,MSISDN) ->
1178    {ok,#mvsT_msisdn{value = lists:reverse(MSISDN)}};
1179msisdn_internal_storage(<<15:4,
1180                          DigitN:4,
1181                          _Rest/binary>>,MSISDN) when DigitN < 10 ->
1182    {ok,#mvsT_msisdn{value = lists:reverse([DigitN bor 240|MSISDN])}};
1183msisdn_internal_storage(<<DigitNplus1:4,
1184                          DigitN:4,
1185                          Rest/binary>>,MSISDN) when DigitNplus1 < 10, DigitN < 10 ->
1186    NewMSISDN = [DigitNplus1 bsl 4 bor DigitN|MSISDN],
1187    msisdn_internal_storage(Rest,NewMSISDN);
1188msisdn_internal_storage(_Rest,_MSISDN) ->
1189    {fault}.
1190