1package com.android.anqp;
2
3import android.os.Parcel;
4
5import com.android.hotspot2.Utils;
6
7import java.net.ProtocolException;
8import java.nio.ByteBuffer;
9import java.nio.charset.StandardCharsets;
10import java.util.Arrays;
11
12import static com.android.anqp.Constants.BYTE_MASK;
13import 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 */
20public 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
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