1 package com.android.server.wifi.hotspot2.anqp;
2 
3 import com.android.internal.annotations.VisibleForTesting;
4 
5 import java.net.ProtocolException;
6 import java.nio.BufferUnderflowException;
7 import java.nio.ByteBuffer;
8 import java.nio.charset.StandardCharsets;
9 import java.util.ArrayList;
10 import java.util.Collections;
11 import java.util.List;
12 
13 /**
14  * The Operator Friendly Name vendor specific ANQP Element,
15  * Wi-Fi Alliance Hotspot 2.0 (Release 2) Technical Specification - Version 5.00,
16  * section 4.3.
17  *
18  * Format:
19  *
20  * | Operator Name Duple #1 (optional) | ...
21  *          variable
22  *
23  * | Operator Name Duple #N (optional) |
24  *             variable
25  */
26 public class HSFriendlyNameElement extends ANQPElement {
27     /**
28      * Maximum length for an Operator Name.  Refer to Hotspot 2.0 (Release 2) Technical
29      * Specification section 4.3 for more info.
30      */
31     @VisibleForTesting
32     public static final int MAXIMUM_OPERATOR_NAME_LENGTH = 252;
33 
34     private final List<I18Name> mNames;
35 
36     @VisibleForTesting
HSFriendlyNameElement(List<I18Name> names)37     public HSFriendlyNameElement(List<I18Name> names) {
38         super(Constants.ANQPElementType.HSFriendlyName);
39         mNames = names;
40     }
41 
42     /**
43      * Parse a HSFriendlyNameElement from the given buffer.
44      *
45      * @param payload The buffer to read from
46      * @return {@link HSFriendlyNameElement}
47      * @throws BufferUnderflowException
48      * @throws ProtocolException
49      */
parse(ByteBuffer payload)50     public static HSFriendlyNameElement parse(ByteBuffer payload)
51             throws ProtocolException {
52         List<I18Name> names = new ArrayList<I18Name>();
53         while (payload.hasRemaining()) {
54             I18Name name = I18Name.parse(payload);
55             // Verify that the number of bytes for the operator name doesn't exceed the max
56             // allowed.
57             int textBytes = name.getText().getBytes(StandardCharsets.UTF_8).length;
58             if (textBytes > MAXIMUM_OPERATOR_NAME_LENGTH) {
59                 throw new ProtocolException("Operator Name exceeds the maximum allowed "
60                         + textBytes);
61             }
62             names.add(name);
63         }
64         return new HSFriendlyNameElement(names);
65     }
66 
getNames()67     public List<I18Name> getNames() {
68         return Collections.unmodifiableList(mNames);
69     }
70 
71     @Override
equals(Object thatObject)72     public boolean equals(Object thatObject) {
73         if (this == thatObject) {
74             return true;
75         }
76         if (!(thatObject instanceof HSFriendlyNameElement)) {
77             return false;
78         }
79         HSFriendlyNameElement that = (HSFriendlyNameElement) thatObject;
80         return mNames.equals(that.mNames);
81     }
82 
83     @Override
hashCode()84     public int hashCode() {
85         return mNames.hashCode();
86     }
87 
88     @Override
toString()89     public String toString() {
90         return "HSFriendlyName{" +
91                 "mNames=" + mNames +
92                 '}';
93     }
94 }
95