1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi.hotspot2.anqp;
18
19import com.android.internal.annotations.VisibleForTesting;
20
21import java.net.ProtocolException;
22import java.nio.BufferUnderflowException;
23import java.nio.ByteBuffer;
24import java.util.ArrayList;
25import java.util.Collections;
26import java.util.List;
27
28
29/**
30 * The 3GPP Cellular Network ANQP Element, IEEE802.11-2012 section 8.4.4.11.
31 * The value is embedded in a Generic container User Data (GUD).
32 * Refer to Annex A of 3GPP TS 24.234 version 11.3.0 for more info:
33 * (http://www.etsi.org/deliver/etsi_ts/124200_124299/124234/11.03.00_60/ts_124234v110300p.pdf).
34 *
35 * Format:
36 * | GUD Version | Length | IEI 1 | ... | IEI N|
37 *        1           1    variable
38 *
39 */
40public class ThreeGPPNetworkElement extends ANQPElement {
41    /**
42     * The expected protocol version number of the Generic container User Data (GUD).
43     */
44    @VisibleForTesting
45    public static final int GUD_VERSION_1 = 0;
46
47    private final List<CellularNetwork> mNetworks;
48
49    @VisibleForTesting
50    public ThreeGPPNetworkElement(List<CellularNetwork> networks) {
51        super(Constants.ANQPElementType.ANQP3GPPNetwork);
52        mNetworks = networks;
53    }
54
55    /**
56     * Parse a ThreeGPPNetworkElement from the given buffer.
57     *
58     * @param payload The byte buffer to read from
59     * @return {@link ThreeGPPNetworkElement}
60     * @throws BufferUnderflowException
61     * @throws ProtocolException
62     */
63    public static ThreeGPPNetworkElement parse(ByteBuffer payload)
64            throws ProtocolException {
65        // Verify version.
66        int gudVersion = payload.get() & 0xFF;
67        if (gudVersion != GUD_VERSION_1) {
68            throw new ProtocolException("Unsupported GUD version: " + gudVersion);
69        }
70
71        // Verify length.
72        int length = payload.get() & 0xFF;
73        if (length != payload.remaining()) {
74            throw new ProtocolException("Mismatch length and buffer size: length=" + length
75                    + " bufferSize=" + payload.remaining());
76        }
77
78        // Parse each IEI (Information Element Identity) content.
79        List<CellularNetwork> networks = new ArrayList<>();
80        while (payload.hasRemaining()) {
81            CellularNetwork network = CellularNetwork.parse(payload);
82            if (network != null) {
83                networks.add(network);
84            }
85        }
86        return new ThreeGPPNetworkElement(networks);
87    }
88
89    public List<CellularNetwork> getNetworks() {
90        return Collections.unmodifiableList(mNetworks);
91    }
92
93    @Override
94    public boolean equals(Object thatObject) {
95        if (this == thatObject) {
96            return true;
97        }
98        if (!(thatObject instanceof ThreeGPPNetworkElement)) {
99            return false;
100        }
101        ThreeGPPNetworkElement that = (ThreeGPPNetworkElement) thatObject;
102        return mNetworks.equals(that.mNetworks);
103
104    }
105
106    @Override
107    public int hashCode() {
108        return mNetworks.hashCode();
109    }
110
111    @Override
112    public String toString() {
113        return "ThreeGPPNetwork{mNetworks=" + mNetworks + "}";
114    }
115}
116