• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.google.android.iwlan.epdg;
2 
3 import android.support.annotation.NonNull;
4 import android.telephony.data.NetworkSliceInfo;
5 import android.util.Log;
6 
7 import java.util.Arrays;
8 import java.util.List;
9 
10 public class NetworkSliceSelectionAssistanceInformation {
11     private static final String TAG =
12             NetworkSliceSelectionAssistanceInformation.class.getSimpleName();
13     static final List<Integer> VALID_LENGTHS = Arrays.asList(1, 2, 4, 5, 8);
14 
getSliceInfo(byte[] snssai)15     public static NetworkSliceInfo getSliceInfo(byte[] snssai) {
16         if (snssai == null) {
17             return null;
18         }
19         /**
20          * From 3GPP TS 24.501 Section 9.11.2.8, Content structure of the Value of S-NSSAI
21          *
22          * <p>Slice Service Type - 1 byte
23          * Slice Differentiator - 3 bytes
24          * Mapped HPLMN Slice Service Type - 1 byte
25          * Mapped HPLMN Slice Differentiator - 3 bytes
26          *
27          * <p>Depending on the value of the length field the following S-NSSAI contents are
28          * included:
29          * Bits 8 7 6 5 4 3 2 1
30          * 0 0 0 0 0 0 0 1 SST
31          * 0 0 0 0 0 0 1 0 SST and mapped HPLMN SST
32          * 0 0 0 0 0 1 0 0 SST and SD
33          * 0 0 0 0 0 1 0 1 SST, SD and mapped HPLMN SST
34          * 0 0 0 0 1 0 0 0 SST, SD, mapped HPLMN SST and mapped HPLMN SD
35          * All other values are reserved.
36          */
37         NetworkSliceInfo.Builder siBuilder = new NetworkSliceInfo.Builder();
38         int len = snssai.length;
39         // validity checks. See TS 24.501 Section 9.11.2.8
40         // length should be valid
41         if (!VALID_LENGTHS.contains(len)) {
42             Log.d(TAG, "Invalid S-NSSAI length : " + snssai.length);
43             return null;
44         }
45 
46         switch (len) {
47             case 1: // get SST
48                 siBuilder.setSliceServiceType(getSST(snssai, 0));
49                 break;
50             case 2: // get SST and mapped SST
51                 siBuilder.setSliceServiceType(getSST(snssai, 0));
52                 siBuilder.setMappedHplmnSliceServiceType(getSST(snssai, 1));
53                 break;
54             case 4: // get SST and SD
55                 siBuilder.setSliceServiceType(getSST(snssai, 0));
56                 siBuilder.setSliceDifferentiator(getSD(snssai, 1));
57                 break;
58             case 5: // get SST, SD and mapped SST
59                 siBuilder.setSliceServiceType(getSST(snssai, 0));
60                 siBuilder.setSliceDifferentiator(getSD(snssai, 1));
61                 siBuilder.setMappedHplmnSliceServiceType(getSST(snssai, 4));
62                 break;
63             case 8: // get SST, SD, mapped SST, mapped SD
64                 siBuilder.setSliceServiceType(getSST(snssai, 0));
65                 siBuilder.setSliceDifferentiator(getSD(snssai, 1));
66                 siBuilder.setMappedHplmnSliceServiceType(getSST(snssai, 4));
67                 siBuilder.setMappedHplmnSliceDifferentiator(getSD(snssai, 5));
68                 break;
69         }
70 
71         return siBuilder.build();
72     }
73 
getSST(@onNull byte[] snssai, int offset)74     private static int getSST(@NonNull byte[] snssai, int offset) {
75         if (offset < 0 || snssai.length < offset + 1) {
76             return NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
77         }
78         /**
79          * From 3GPP TS 23.003: Values 0 to 127 belong to the standardized SST range and they are
80          * defined in 3GPP TS 23.501. Values 128 to 255 belong to the Operator-specific range
81          */
82         return Byte.toUnsignedInt(snssai[offset]);
83     }
84 
getSD(byte[] snssai, int offset)85     private static int getSD(byte[] snssai, int offset) {
86         int sliceDescriptor = NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
87         /*
88          * Slice Descriptor is 3 bytes long
89          * The SD field has a reserved value "no SD value associated with the SST"
90          * defined as hexadecimal FFFFFF
91          */
92         if (offset >= 0 && snssai.length >= offset + 3) {
93             int sd = 0;
94             sd =
95                     (sd | snssai[offset + 2])
96                             | ((sd | snssai[offset + 1]) << 8)
97                             | ((sd | snssai[offset]) << 16);
98             if (sd != 0xFFFFFF) {
99                 sliceDescriptor = sd;
100             }
101         }
102         return sliceDescriptor;
103     }
104 }
105