ANQPData.java revision 1d5cd3938f9191184cd9aea3059a3b62bf3a0372
1package com.android.server.wifi.hotspot2; 2 3import com.android.server.wifi.anqp.ANQPElement; 4import com.android.server.wifi.anqp.Constants; 5 6import java.util.ArrayList; 7import java.util.Collections; 8import java.util.HashMap; 9import java.util.List; 10import java.util.Map; 11 12public class ANQPData { 13 /** 14 * The regular cache time for entries with a non-zero domain id. 15 */ 16 private static final long ANQP_QUALIFIED_CACHE_TIMEOUT = 3600000L; 17 /** 18 * The cache time for entries with a zero domain id. The zero domain id indicates that ANQP 19 * data from the AP may change at any time, thus a relatively short cache time is given to 20 * such data, but still long enough to avoid excessive querying. 21 */ 22 private static final long ANQP_UNQUALIFIED_CACHE_TIMEOUT = 300000L; 23 /** 24 * This is the hold off time for pending queries, i.e. the time during which subsequent queries 25 * are squelched. 26 */ 27 private static final long ANQP_HOLDOFF_TIME = 10000L; 28 29 /** 30 * Max value for the retry counter for unanswered queries. This limits the maximum time-out to 31 * ANQP_HOLDOFF_TIME * 2^MAX_RETRY. With current values this results in 640s. 32 */ 33 private static final int MAX_RETRY = 6; 34 35 private final NetworkDetail mNetwork; 36 private final Map<Constants.ANQPElementType, ANQPElement> mANQPElements; 37 private final long mCtime; 38 private final long mExpiry; 39 private final int mRetry; 40 41 public ANQPData(NetworkDetail network, 42 Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 43 44 mNetwork = network; 45 mANQPElements = anqpElements != null ? new HashMap<>(anqpElements) : null; 46 mCtime = System.currentTimeMillis(); 47 mRetry = 0; 48 if (anqpElements == null) { 49 mExpiry = mCtime + ANQP_HOLDOFF_TIME; 50 } 51 else if (network.getAnqpDomainID() == 0) { 52 mExpiry = mCtime + ANQP_UNQUALIFIED_CACHE_TIMEOUT; 53 } 54 else { 55 mExpiry = mCtime + ANQP_QUALIFIED_CACHE_TIMEOUT; 56 } 57 } 58 59 public ANQPData(NetworkDetail network, ANQPData existing) { 60 mNetwork = network; 61 mANQPElements = null; 62 mCtime = System.currentTimeMillis(); 63 if (existing == null) { 64 mRetry = 0; 65 mExpiry = mCtime + ANQP_HOLDOFF_TIME; 66 } 67 else { 68 mRetry = Math.max(existing.getRetry() + 1, MAX_RETRY); 69 mExpiry = ANQP_HOLDOFF_TIME * (1<<mRetry); 70 } 71 } 72 73 public List<Constants.ANQPElementType> disjoint(List<Constants.ANQPElementType> querySet) { 74 if (mANQPElements == null) { 75 // Ignore the query set for pending responses, it has minimal probability to happen 76 // and a new query will be reissued on the next round anyway. 77 return null; 78 } 79 else { 80 List<Constants.ANQPElementType> additions = new ArrayList<>(); 81 for (Constants.ANQPElementType element : querySet) { 82 if (!mANQPElements.containsKey(element)) { 83 additions.add(element); 84 } 85 } 86 return additions.isEmpty() ? null : additions; 87 } 88 } 89 90 public Map<Constants.ANQPElementType, ANQPElement> getANQPElements() { 91 return Collections.unmodifiableMap(mANQPElements); 92 } 93 94 public NetworkDetail getNetwork() { 95 return mNetwork; 96 } 97 98 public boolean expired() { 99 return expired(System.currentTimeMillis()); 100 } 101 102 public boolean expired(long at) { 103 return mExpiry <= at; 104 } 105 106 protected boolean hasData() { 107 return mANQPElements != null; 108 } 109 110 protected void merge(Map<Constants.ANQPElementType, ANQPElement> data) { 111 if (data != null) { 112 mANQPElements.putAll(data); 113 } 114 } 115 116 protected boolean isValid(NetworkDetail nwk) { 117 return mANQPElements != null && 118 nwk.getAnqpDomainID() == mNetwork.getAnqpDomainID() && 119 mExpiry > System.currentTimeMillis(); 120 } 121 122 private int getRetry() { 123 return mRetry; 124 } 125 126 public String toString(boolean brief) { 127 StringBuilder sb = new StringBuilder(); 128 sb.append(mNetwork.toKeyString()).append(", domid ").append(mNetwork.getAnqpDomainID()); 129 if (mANQPElements == null) { 130 sb.append(", unresolved, "); 131 } 132 else { 133 sb.append(", ").append(mANQPElements.size()).append(" elements, "); 134 } 135 long now = System.currentTimeMillis(); 136 sb.append(Utils.toHMS(now-mCtime)).append(" old, expires in "). 137 append(Utils.toHMS(mExpiry-now)).append(' '); 138 if (brief) { 139 sb.append(expired(now) ? 'x' : '-'); 140 sb.append(mANQPElements == null ? 'u' : '-'); 141 } 142 else if (mANQPElements != null) { 143 sb.append(" data=").append(mANQPElements); 144 } 145 return sb.toString(); 146 } 147 148 @Override 149 public String toString() { 150 return toString(true); 151 } 152} 153