16a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistpackage com.android.server.wifi.anqp;
26a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
36a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.net.ProtocolException;
46a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.nio.ByteBuffer;
57b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvistimport java.nio.ByteOrder;
66a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.nio.charset.StandardCharsets;
76a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.ArrayList;
86a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.List;
96a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
106a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport static com.android.server.wifi.anqp.Constants.BYTE_MASK;
116a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport static com.android.server.wifi.anqp.Constants.SHORT_MASK;
126a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
136a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist/**
146a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist * An OSU Provider, as specified in
156a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist * Wi-Fi Alliance Hotspot 2.0 (Release 2) Technical Specification - Version 5.00,
166a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist * section 4.8.1
176a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist */
186a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistpublic class OSUProvider {
196a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
206a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public enum OSUMethod {OmaDm, SoapXml}
216a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
226a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    private final List<I18Name> mNames;
236a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    private final String mOSUServer;
246a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    private final List<OSUMethod> mOSUMethods;
256a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    private final List<IconInfo> mIcons;
266a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    private final String mOsuNai;
276a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    private final List<I18Name> mServiceDescriptions;
281d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    private final int mHashCode;
296a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
306a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public OSUProvider(ByteBuffer payload) throws ProtocolException {
316a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        if (payload.remaining() < 11) {
326a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            throw new ProtocolException("Truncated OSU provider: " + payload.remaining());
336a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        }
346a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
356a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        int length = payload.getShort() & SHORT_MASK;
366a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        int namesLength = payload.getShort() & SHORT_MASK;
376a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
387b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist        ByteBuffer namesBuffer = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN);
396a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        namesBuffer.limit(namesBuffer.position() + namesLength);
406a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        payload.position(payload.position() + namesLength);
416a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
421d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        mNames = new ArrayList<>();
436a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
446a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        while (namesBuffer.hasRemaining()) {
456a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            mNames.add(new I18Name(namesBuffer));
466a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        }
476a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
486a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        mOSUServer = Constants.getPrefixedString(payload, 1, StandardCharsets.UTF_8);
496a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        int methodLength = payload.get() & BYTE_MASK;
501d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        mOSUMethods = new ArrayList<>(methodLength);
516a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        while (methodLength > 0) {
526a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            int methodID = payload.get() & BYTE_MASK;
536a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            mOSUMethods.add(methodID < OSUMethod.values().length ?
546a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist                    OSUMethod.values()[methodID] :
556a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist                    null);
566a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            methodLength--;
576a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        }
586a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
596a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        int iconsLength = payload.getShort() & SHORT_MASK;
607b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist        ByteBuffer iconsBuffer = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN);
616a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        iconsBuffer.limit(iconsBuffer.position() + iconsLength);
626a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        payload.position(payload.position() + iconsLength);
636a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
641d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        mIcons = new ArrayList<>();
656a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
666a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        while (iconsBuffer.hasRemaining()) {
676a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            mIcons.add(new IconInfo(iconsBuffer));
686a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        }
696a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
70777f4fc037d3ebd555f10041f8acfb41515b2f4bJan Nordqvist        mOsuNai = Constants.getPrefixedString(payload, 1, StandardCharsets.UTF_8, true);
716a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
726a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        int descriptionsLength = payload.getShort() & SHORT_MASK;
737b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist        ByteBuffer descriptionsBuffer = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN);
746a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        descriptionsBuffer.limit(descriptionsBuffer.position() + descriptionsLength);
756a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        payload.position(payload.position() + descriptionsLength);
766a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
771d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        mServiceDescriptions = new ArrayList<>();
786a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
796a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        while (descriptionsBuffer.hasRemaining()) {
806a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist            mServiceDescriptions.add(new I18Name(descriptionsBuffer));
816a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        }
821d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist
831d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        int result = mNames.hashCode();
841d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        result = 31 * result + mOSUServer.hashCode();
851d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        result = 31 * result + mOSUMethods.hashCode();
861d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        result = 31 * result + mIcons.hashCode();
871d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        result = 31 * result + (mOsuNai != null ? mOsuNai.hashCode() : 0);
881d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        result = 31 * result + mServiceDescriptions.hashCode();
891d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        mHashCode = result;
906a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
916a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
926a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public List<I18Name> getNames() {
936a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return mNames;
946a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
956a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
966a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public String getOSUServer() {
976a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return mOSUServer;
986a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
996a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
1006a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public List<OSUMethod> getOSUMethods() {
1016a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return mOSUMethods;
1026a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
1036a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
1046a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public List<IconInfo> getIcons() {
1056a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return mIcons;
1066a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
1076a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
1086a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public String getOsuNai() {
1096a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return mOsuNai;
1106a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
1116a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
1126a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public List<I18Name> getServiceDescriptions() {
1136a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return mServiceDescriptions;
1146a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
1156a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist
1166a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    @Override
1171d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    public boolean equals(Object o) {
1181d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (this == o) return true;
1191d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (o == null || getClass() != o.getClass()) return false;
1201d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist
1211d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        OSUProvider that = (OSUProvider) o;
1221d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist
1231d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (!mOSUServer.equals(that.mOSUServer)) return false;
1241d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (!mNames.equals(that.mNames)) return false;
1251d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (!mServiceDescriptions.equals(that.mServiceDescriptions)) return false;
1261d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (!mIcons.equals(that.mIcons)) return false;
1271d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (!mOSUMethods.equals(that.mOSUMethods)) return false;
1281d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        if (mOsuNai != null ? !mOsuNai.equals(that.mOsuNai) : that.mOsuNai != null) return false;
1291d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist
1301d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        return true;
1311d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    }
1321d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist
1331d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    @Override
1341d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    public int hashCode() {
1351d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist        return mHashCode;
1361d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    }
1371d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist
1381d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist    @Override
1396a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    public String toString() {
1406a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist        return "OSUProvider{" +
1411d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist                "names=" + mNames +
1421d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist                ", OSUServer='" + mOSUServer + '\'' +
1431d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist                ", OSUMethods=" + mOSUMethods +
1441d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist                ", icons=" + mIcons +
1451d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist                ", NAI='" + mOsuNai + '\'' +
1461d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist                ", serviceDescriptions=" + mServiceDescriptions +
1476a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist                '}';
1486a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist    }
1496a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist}
150