1package com.android.server.wifi.hotspot2.pps;
2
3import com.android.server.wifi.hotspot2.Utils;
4import com.android.server.wifi.hotspot2.omadm.OMAException;
5import com.android.server.wifi.hotspot2.omadm.OMANode;
6import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager;
7
8import java.util.ArrayList;
9import java.util.HashMap;
10import java.util.List;
11import java.util.Map;
12
13import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_Country;
14import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_DLBandwidth;
15import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_FQDN_Match;
16import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_IPProtocol;
17import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_MaximumBSSLoadValue;
18import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_MinBackhaulThreshold;
19import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_NetworkType;
20import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_PolicyUpdate;
21import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_PortNumber;
22import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_PreferredRoamingPartnerList;
23import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_Priority;
24import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_RequiredProtoPortTuple;
25import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_SPExclusionList;
26import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_SSID;
27import static com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager.TAG_ULBandwidth;
28
29public class Policy {
30    private final List<PreferredRoamingPartner> mPreferredRoamingPartners;
31    private final List<MinBackhaul> mMinBackhaulThresholds;
32    private final UpdateInfo mPolicyUpdate;
33    private final List<String> mSPExclusionList;
34    private final Map<Integer, List<Integer>> mRequiredProtos;
35    private final int mMaxBSSLoad;
36
37    public Policy(OMANode node) throws OMAException {
38
39        OMANode rpNode = node.getChild(TAG_PreferredRoamingPartnerList);
40        if (rpNode == null) {
41            mPreferredRoamingPartners = null;
42        }
43        else {
44            mPreferredRoamingPartners = new ArrayList<>(rpNode.getChildren().size());
45            for (OMANode instance : rpNode.getChildren()) {
46                if (instance.isLeaf()) {
47                    throw new OMAException("Not expecting leaf node in " +
48                            TAG_PreferredRoamingPartnerList);
49                }
50                mPreferredRoamingPartners.add(new PreferredRoamingPartner(instance));
51            }
52        }
53
54        OMANode bhtNode = node.getChild(TAG_MinBackhaulThreshold);
55        if (bhtNode == null) {
56            mMinBackhaulThresholds = null;
57        }
58        else {
59            mMinBackhaulThresholds = new ArrayList<>(bhtNode.getChildren().size());
60            for (OMANode instance : bhtNode.getChildren()) {
61                if (instance.isLeaf()) {
62                    throw new OMAException("Not expecting leaf node in " +
63                            TAG_MinBackhaulThreshold);
64                }
65                mMinBackhaulThresholds.add(new MinBackhaul(instance));
66            }
67        }
68
69        mPolicyUpdate = new UpdateInfo(node.getChild(TAG_PolicyUpdate));
70
71        OMANode sxNode = node.getChild(TAG_SPExclusionList);
72        if (sxNode == null) {
73            mSPExclusionList = null;
74        }
75        else {
76            mSPExclusionList = new ArrayList<>(sxNode.getChildren().size());
77            for (OMANode instance : sxNode.getChildren()) {
78                if (instance.isLeaf()) {
79                    throw new OMAException("Not expecting leaf node in " + TAG_SPExclusionList);
80                }
81                mSPExclusionList
82                        .add(PasspointManagementObjectManager.getString(instance, TAG_SSID));
83            }
84        }
85
86        OMANode rptNode = node.getChild(TAG_RequiredProtoPortTuple);
87        if (rptNode == null) {
88            mRequiredProtos = null;
89        }
90        else {
91            mRequiredProtos = new HashMap<>(rptNode.getChildren().size());
92            for (OMANode instance : rptNode.getChildren()) {
93                if (instance.isLeaf()) {
94                    throw new OMAException("Not expecting leaf node in " +
95                            TAG_RequiredProtoPortTuple);
96                }
97                int protocol =
98                        (int) PasspointManagementObjectManager
99                                .getLong(instance, TAG_IPProtocol, null);
100                String[] portSegments =
101                        PasspointManagementObjectManager
102                                .getString(instance, TAG_PortNumber).split(",");
103                List<Integer> ports = new ArrayList<>(portSegments.length);
104                for (String portSegment : portSegments) {
105                    try {
106                        ports.add(Integer.parseInt(portSegment));
107                    }
108                    catch (NumberFormatException nfe) {
109                        throw new OMAException("Port is not a number: " + portSegment);
110                    }
111                }
112                mRequiredProtos.put(protocol, ports);
113            }
114        }
115
116        mMaxBSSLoad = (int) PasspointManagementObjectManager.getLong(node,
117                TAG_MaximumBSSLoadValue, Long.MAX_VALUE);
118    }
119
120    public List<PreferredRoamingPartner> getPreferredRoamingPartners() {
121        return mPreferredRoamingPartners;
122    }
123
124    public List<MinBackhaul> getMinBackhaulThresholds() {
125        return mMinBackhaulThresholds;
126    }
127
128    public UpdateInfo getPolicyUpdate() {
129        return mPolicyUpdate;
130    }
131
132    public List<String> getSPExclusionList() {
133        return mSPExclusionList;
134    }
135
136    public Map<Integer, List<Integer>> getRequiredProtos() {
137        return mRequiredProtos;
138    }
139
140    public int getMaxBSSLoad() {
141        return mMaxBSSLoad;
142    }
143
144    private static class PreferredRoamingPartner {
145        private final List<String> mDomain;
146        private final Boolean mIncludeSubDomains;
147        private final int mPriority;
148        private final String mCountry;
149
150        private PreferredRoamingPartner(OMANode node)
151                throws OMAException {
152
153            String[] segments =
154                    PasspointManagementObjectManager.getString(node, TAG_FQDN_Match).split(",");
155            if (segments.length != 2) {
156                throw new OMAException("Bad FQDN match string: " + TAG_FQDN_Match);
157            }
158            mDomain = Utils.splitDomain(segments[0]);
159            mIncludeSubDomains =
160                    PasspointManagementObjectManager.getSelection(TAG_FQDN_Match, segments[1]);
161            mPriority = (int) PasspointManagementObjectManager.getLong(node, TAG_Priority, null);
162            mCountry = PasspointManagementObjectManager.getString(node, TAG_Country);
163        }
164
165        @Override
166        public String toString() {
167            return "PreferredRoamingPartner{" +
168                    "domain=" + mDomain +
169                    ", includeSubDomains=" + mIncludeSubDomains +
170                    ", priority=" + mPriority +
171                    ", country='" + mCountry + '\'' +
172                    '}';
173        }
174    }
175
176    private static class MinBackhaul {
177        private final Boolean mHome;
178        private final long mDL;
179        private final long mUL;
180
181        private MinBackhaul(OMANode node) throws OMAException {
182            mHome = PasspointManagementObjectManager.getSelection(node, TAG_NetworkType);
183            mDL = PasspointManagementObjectManager.getLong(node, TAG_DLBandwidth, Long.MAX_VALUE);
184            mUL = PasspointManagementObjectManager.getLong(node, TAG_ULBandwidth, Long.MAX_VALUE);
185        }
186
187        @Override
188        public String toString() {
189            return "MinBackhaul{" +
190                    "home=" + mHome +
191                    ", DL=" + mDL +
192                    ", UL=" + mUL +
193                    '}';
194        }
195    }
196
197    @Override
198    public String toString() {
199        return "Policy{" +
200                "preferredRoamingPartners=" + mPreferredRoamingPartners +
201                ", minBackhaulThresholds=" + mMinBackhaulThresholds +
202                ", policyUpdate=" + mPolicyUpdate +
203                ", SPExclusionList=" + mSPExclusionList +
204                ", requiredProtos=" + mRequiredProtos +
205                ", maxBSSLoad=" + mMaxBSSLoad +
206                '}';
207    }
208}
209