1package com.android.server.wifi.anqp; 2 3import java.net.ProtocolException; 4import java.nio.ByteBuffer; 5import java.nio.ByteOrder; 6import java.nio.charset.StandardCharsets; 7import java.util.ArrayList; 8import java.util.List; 9 10import static com.android.server.wifi.anqp.Constants.BYTE_MASK; 11import static com.android.server.wifi.anqp.Constants.SHORT_MASK; 12 13/** 14 * An OSU Provider, as specified in 15 * Wi-Fi Alliance Hotspot 2.0 (Release 2) Technical Specification - Version 5.00, 16 * section 4.8.1 17 */ 18public class OSUProvider { 19 20 public enum OSUMethod {OmaDm, SoapXml} 21 22 private final List<I18Name> mNames; 23 private final String mOSUServer; 24 private final List<OSUMethod> mOSUMethods; 25 private final List<IconInfo> mIcons; 26 private final String mOsuNai; 27 private final List<I18Name> mServiceDescriptions; 28 private final int mHashCode; 29 30 public OSUProvider(ByteBuffer payload) throws ProtocolException { 31 if (payload.remaining() < 11) { 32 throw new ProtocolException("Truncated OSU provider: " + payload.remaining()); 33 } 34 35 int length = payload.getShort() & SHORT_MASK; 36 int namesLength = payload.getShort() & SHORT_MASK; 37 38 ByteBuffer namesBuffer = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN); 39 namesBuffer.limit(namesBuffer.position() + namesLength); 40 payload.position(payload.position() + namesLength); 41 42 mNames = new ArrayList<>(); 43 44 while (namesBuffer.hasRemaining()) { 45 mNames.add(new I18Name(namesBuffer)); 46 } 47 48 mOSUServer = Constants.getPrefixedString(payload, 1, StandardCharsets.UTF_8); 49 int methodLength = payload.get() & BYTE_MASK; 50 mOSUMethods = new ArrayList<>(methodLength); 51 while (methodLength > 0) { 52 int methodID = payload.get() & BYTE_MASK; 53 mOSUMethods.add(methodID < OSUMethod.values().length ? 54 OSUMethod.values()[methodID] : 55 null); 56 methodLength--; 57 } 58 59 int iconsLength = payload.getShort() & SHORT_MASK; 60 ByteBuffer iconsBuffer = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN); 61 iconsBuffer.limit(iconsBuffer.position() + iconsLength); 62 payload.position(payload.position() + iconsLength); 63 64 mIcons = new ArrayList<>(); 65 66 while (iconsBuffer.hasRemaining()) { 67 mIcons.add(new IconInfo(iconsBuffer)); 68 } 69 70 mOsuNai = Constants.getPrefixedString(payload, 1, StandardCharsets.UTF_8, true); 71 72 int descriptionsLength = payload.getShort() & SHORT_MASK; 73 ByteBuffer descriptionsBuffer = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN); 74 descriptionsBuffer.limit(descriptionsBuffer.position() + descriptionsLength); 75 payload.position(payload.position() + descriptionsLength); 76 77 mServiceDescriptions = new ArrayList<>(); 78 79 while (descriptionsBuffer.hasRemaining()) { 80 mServiceDescriptions.add(new I18Name(descriptionsBuffer)); 81 } 82 83 int result = mNames.hashCode(); 84 result = 31 * result + mOSUServer.hashCode(); 85 result = 31 * result + mOSUMethods.hashCode(); 86 result = 31 * result + mIcons.hashCode(); 87 result = 31 * result + (mOsuNai != null ? mOsuNai.hashCode() : 0); 88 result = 31 * result + mServiceDescriptions.hashCode(); 89 mHashCode = result; 90 } 91 92 public List<I18Name> getNames() { 93 return mNames; 94 } 95 96 public String getOSUServer() { 97 return mOSUServer; 98 } 99 100 public List<OSUMethod> getOSUMethods() { 101 return mOSUMethods; 102 } 103 104 public List<IconInfo> getIcons() { 105 return mIcons; 106 } 107 108 public String getOsuNai() { 109 return mOsuNai; 110 } 111 112 public List<I18Name> getServiceDescriptions() { 113 return mServiceDescriptions; 114 } 115 116 @Override 117 public boolean equals(Object o) { 118 if (this == o) return true; 119 if (o == null || getClass() != o.getClass()) return false; 120 121 OSUProvider that = (OSUProvider) o; 122 123 if (!mOSUServer.equals(that.mOSUServer)) return false; 124 if (!mNames.equals(that.mNames)) return false; 125 if (!mServiceDescriptions.equals(that.mServiceDescriptions)) return false; 126 if (!mIcons.equals(that.mIcons)) return false; 127 if (!mOSUMethods.equals(that.mOSUMethods)) return false; 128 if (mOsuNai != null ? !mOsuNai.equals(that.mOsuNai) : that.mOsuNai != null) return false; 129 130 return true; 131 } 132 133 @Override 134 public int hashCode() { 135 return mHashCode; 136 } 137 138 @Override 139 public String toString() { 140 return "OSUProvider{" + 141 "names=" + mNames + 142 ", OSUServer='" + mOSUServer + '\'' + 143 ", OSUMethods=" + mOSUMethods + 144 ", icons=" + mIcons + 145 ", NAI='" + mOsuNai + '\'' + 146 ", serviceDescriptions=" + mServiceDescriptions + 147 '}'; 148 } 149} 150