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