1 package com.android.anqp;
2 
3 import android.os.Parcel;
4 
5 import com.android.hotspot2.Utils;
6 
7 import java.net.ProtocolException;
8 import java.nio.ByteBuffer;
9 import java.nio.charset.StandardCharsets;
10 import java.util.Arrays;
11 
12 import static com.android.anqp.Constants.BYTE_MASK;
13 import static com.android.anqp.Constants.SHORT_MASK;
14 
15 /**
16  * The Icon Binary File vendor specific ANQP Element,
17  * Wi-Fi Alliance Hotspot 2.0 (Release 2) Technical Specification - Version 5.00,
18  * section 4.11
19  */
20 public class HSIconFileElement extends ANQPElement {
21 
22     public enum StatusCode {Success, FileNotFound, Unspecified}
23 
24     private final StatusCode mStatusCode;
25     private final String mType;
26     private final byte[] mIconData;
27 
HSIconFileElement(Constants.ANQPElementType infoID, ByteBuffer payload)28     public HSIconFileElement(Constants.ANQPElementType infoID, ByteBuffer payload)
29             throws ProtocolException {
30         super(infoID);
31 
32         if (payload.remaining() < 4) {
33             throw new ProtocolException("Truncated icon file: " + payload.remaining());
34         }
35 
36         int statusID = payload.get() & BYTE_MASK;
37         mStatusCode = statusID < StatusCode.values().length ? StatusCode.values()[statusID] : null;
38         mType = Constants.getPrefixedString(payload, 1, StandardCharsets.US_ASCII);
39 
40         int dataLength = payload.getShort() & SHORT_MASK;
41         mIconData = new byte[dataLength];
42         payload.get(mIconData);
43     }
44 
45     public StatusCode getStatusCode() {
46         return mStatusCode;
47     }
48 
49     public String getType() {
50         return mType;
51     }
52 
53     public byte[] getIconData() {
54         return mIconData;
55     }
56 
57     @Override
58     public boolean equals(Object thatObject) {
59         if (thatObject == this) {
60             return true;
61         } else if (thatObject.getClass() != HSIconFileElement.class) {
62             return false;
63         }
64         HSIconFileElement that = (HSIconFileElement) thatObject;
65         if (getStatusCode() != that.getStatusCode() || getStatusCode() != StatusCode.Success) {
66             return false;
67         }
68         return getType().equals(that.getType()) && Arrays.equals(getIconData(), that.getIconData());
69     }
70 
71     @Override
72     public String toString() {
73         return "HSIconFile{" +
74                 "statusCode=" + mStatusCode +
75                 ", type='" + mType + '\'' +
76                 ", iconData=" + mIconData.length + " bytes }";
77     }
78 
79     public HSIconFileElement(Parcel in) {
80         super(Constants.ANQPElementType.HSIconFile);
81         mStatusCode = Utils.mapEnum(in.readInt(), StatusCode.class);
82         mType = in.readString();
83         mIconData = in.readBlob();
84     }
85 
86     public void writeParcel(Parcel out) {
87         out.writeInt(mStatusCode.ordinal());
88         out.writeString(mType);
89         out.writeBlob(mIconData);
90     }
91 }
92