private void initiateQuery(long bssid) { LinkedList<QuerySet> queryEntries = mBssQueues.get(bssid); if (queryEntries == null) { return; } else if (queryEntries.isEmpty()) { mBssQueues.remove(bssid); return; } QuerySet querySet = queryEntries.getFirst(); QueryEntry queryEntry = querySet.peek(); if (queryEntry.bumpRetry() >= RetryCount) { QueryEntry newEntry = querySet.pop(); if (newEntry == null) { // No more entries in this QuerySet, advance to the next set. querySet.getOsuInfo().setIconStatus(OSUInfo.IconStatus.NotAvailable); queryEntries.removeFirst(); if (queryEntries.isEmpty()) { // No further QuerySet on this BSSID, drop the bucket and bail. mBssQueues.remove(bssid); return; } else { querySet = queryEntries.getFirst(); queryEntry = querySet.peek(); queryEntry.bumpRetry(); } } } mOSUManager.doIconQuery(bssid, queryEntry.getKey().getFileName()); }
public void tickle(boolean wifiOff) { synchronized (mCache) { if (wifiOff) { mBssQueues.clear(); } else { long now = System.currentTimeMillis(); Iterator<Map.Entry<Long, LinkedList<QuerySet>>> bssIterator = mBssQueues.entrySet().iterator(); while (bssIterator.hasNext()) { // Get the list of entries for this BSSID Map.Entry<Long, LinkedList<QuerySet>> bssEntries = bssIterator.next(); Iterator<QuerySet> querySetIterator = bssEntries.getValue().iterator(); while (querySetIterator.hasNext()) { QuerySet querySet = querySetIterator.next(); QueryEntry queryEntry = querySet.peek(); long age = queryEntry.age(now); if (age > RequeryTimeHigh) { // Timed out entry, move on to the next. queryEntry = querySet.pop(); if (queryEntry == null) { // Empty query set, update status and remove it. querySet.getOsuInfo().setIconStatus(OSUInfo.IconStatus.NotAvailable); querySetIterator.remove(); } else { // Start a query on the next entry and bail out of the set iteration initiateQuery(querySet.getBssid()); break; } } else if (age > RequeryTimeLow) { // Re-issue queries for qualified entries and bail out of set iteration initiateQuery(querySet.getBssid()); break; } } if (bssEntries.getValue().isEmpty()) { // Kill the whole bucket if the set list is empty bssIterator.remove(); } } } } }
public void notifyIconReceived(long bssid, String fileName, byte[] iconData) { Log.d( "ZXZ", String.format( "Icon '%s':%d received from %012x", fileName, iconData != null ? iconData.length : -1, bssid)); IconKey key; HSIconFileElement iconFileElement = null; List<OSUInfo> updates = new ArrayList<>(); LinkedList<QuerySet> querySets = mBssQueues.get(bssid); if (querySets == null || querySets.isEmpty()) { Log.d( OSUManager.TAG, String.format( "Spurious icon response from %012x for '%s' (%d) bytes", bssid, fileName, iconData != null ? iconData.length : -1)); Log.d( "ZXZ", "query set: " + querySets + ", BSS queues: " + Utils.bssidsToString(mBssQueues.keySet())); return; } else { QuerySet querySet = querySets.removeFirst(); if (iconData != null) { try { iconFileElement = new HSIconFileElement( HSIconFile, ByteBuffer.wrap(iconData).order(ByteOrder.LITTLE_ENDIAN)); } catch (ProtocolException | BufferUnderflowException e) { Log.e(OSUManager.TAG, "Failed to parse ANQP icon file: " + e); } } key = querySet.updateIcon(fileName, iconFileElement); if (key == null) { Log.d( OSUManager.TAG, String.format( "Spurious icon response from %012x for '%s' (%d) bytes", bssid, fileName, iconData != null ? iconData.length : -1)); Log.d( "ZXZ", "query set: " + querySets + ", BSS queues: " + Utils.bssidsToString(mBssQueues.keySet())); querySets.addFirst(querySet); return; } if (iconFileElement != null) { mCache.put(key, iconFileElement); } if (querySet.isEmpty()) { mBssQueues.remove(bssid); } updates.add(querySet.getOsuInfo()); } // Update any other pending entries that matches the ESS of the currently resolved icon Iterator<Map.Entry<Long, LinkedList<QuerySet>>> bssIterator = mBssQueues.entrySet().iterator(); while (bssIterator.hasNext()) { Map.Entry<Long, LinkedList<QuerySet>> bssEntries = bssIterator.next(); Iterator<QuerySet> querySetIterator = bssEntries.getValue().iterator(); while (querySetIterator.hasNext()) { QuerySet querySet = querySetIterator.next(); if (querySet.updateIcon(key, iconFileElement)) { querySetIterator.remove(); updates.add(querySet.getOsuInfo()); } } if (bssEntries.getValue().isEmpty()) { bssIterator.remove(); } } initiateQuery(bssid); mOSUManager.iconResults(updates); }