1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi.hotspot2;
18 
19 import com.android.internal.annotations.VisibleForTesting;
20 import com.android.server.wifi.Clock;
21 import com.android.server.wifi.hotspot2.anqp.ANQPElement;
22 import com.android.server.wifi.hotspot2.anqp.Constants;
23 import com.android.server.wifi.hotspot2.anqp.HSWanMetricsElement;
24 
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28 
29 /**
30  * Class for maintaining ANQP elements and managing the lifetime of the elements.
31  */
32 public class ANQPData {
33     /**
34      * Entry lifetime.
35      */
36     @VisibleForTesting
37     public static final long DATA_LIFETIME_MILLISECONDS = 3_600_000L; // One hour
38     public static final long DATA_SHORT_LIFETIME_MILLISECONDS = 600_000L; // Ten minutes
39 
40     private final Clock mClock;
41     private final Map<Constants.ANQPElementType, ANQPElement> mANQPElements;
42     private long mExpiryTime;
43 
ANQPData(Clock clock, Map<Constants.ANQPElementType, ANQPElement> anqpElements)44     public ANQPData(Clock clock, Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
45         mClock = clock;
46         mANQPElements = new HashMap<>();
47         long dataLifetime = DATA_LIFETIME_MILLISECONDS;
48 
49         if (anqpElements != null) {
50             mANQPElements.putAll(anqpElements);
51 
52             HSWanMetricsElement hsWanMetricsElement =
53                     (HSWanMetricsElement) anqpElements.get(Constants.ANQPElementType.HSWANMetrics);
54 
55             if (hsWanMetricsElement != null) {
56                 // If the WAN Metrics ANQP-element is initialized, and signals that the AP is at
57                 // capacity or its link status is down, then send a new ANQP-request sooner, because
58                 // its status may change.
59                 if (hsWanMetricsElement.isElementInitialized()
60                         && (hsWanMetricsElement.getStatus() != HSWanMetricsElement.LINK_STATUS_UP
61                         || hsWanMetricsElement.isAtCapacity())) {
62                     dataLifetime = DATA_SHORT_LIFETIME_MILLISECONDS;
63                 }
64             }
65         }
66         mExpiryTime = mClock.getElapsedSinceBootMillis() + dataLifetime;
67     }
68 
69     /**
70      * Update an entry with post association ANQP elelemtns
71      *
72      * @param anqpElements ANQP elements to add
73      */
update(Map<Constants.ANQPElementType, ANQPElement> anqpElements)74     public void update(Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
75         mANQPElements.putAll(anqpElements);
76         mExpiryTime = mClock.getElapsedSinceBootMillis() + DATA_LIFETIME_MILLISECONDS;
77     }
78 
79     /**
80      * Return the ANQP elements.
81      *
82      * @return Map of ANQP elements
83      */
getElements()84     public Map<Constants.ANQPElementType, ANQPElement> getElements() {
85         return Collections.unmodifiableMap(mANQPElements);
86     }
87 
88     /**
89      * Check if this entry is expired at the specified time.
90      *
91      * @param at The time to check for
92      * @return true if it is expired at the given time
93      */
expired(long at)94     public boolean expired(long at) {
95         return mExpiryTime <= at;
96     }
97 
98     @Override
toString()99     public String toString() {
100         StringBuilder sb = new StringBuilder();
101         sb.append(mANQPElements.size()).append(" elements, ");
102         long now = mClock.getElapsedSinceBootMillis();
103         sb.append(" expires in ").append(Utils.toHMS(mExpiryTime - now)).append(' ');
104         sb.append(expired(now) ? 'x' : '-').append("\n");
105         for (Map.Entry<Constants.ANQPElementType, ANQPElement> entry: mANQPElements.entrySet()) {
106             sb.append(entry.getValue()).append("\n");
107         }
108         return sb.toString();
109     }
110 }
111