• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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;
18 
19 import static android.net.wifi.WifiManager.WIFI_FEATURE_MBO;
20 import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
21 
22 import android.telephony.PhoneStateListener;
23 import android.telephony.TelephonyManager;
24 import android.util.Log;
25 
26 import com.android.server.wifi.SupplicantStaIfaceHal.MboAssocDisallowedReasonCode;
27 
28 /**
29  * MboOceController is responsible for controlling MBO and OCE operations.
30  */
31 public class MboOceController {
32     private static final String TAG = "MboOceController";
33 
34     /** State of MBO/OCE module. */
35     private boolean mEnabled = false;
36     private boolean mIsMboSupported = false;
37     private boolean mIsOceSupported = false;
38     private boolean mVerboseLoggingEnabled = false;
39 
40     private final TelephonyManager mTelephonyManager;
41     private final ActiveModeWarden mActiveModeWarden;
42 
43     /**
44      * Create new instance of MboOceController.
45      */
MboOceController(TelephonyManager telephonyManager, ActiveModeWarden activeModeWarden)46     public MboOceController(TelephonyManager telephonyManager, ActiveModeWarden activeModeWarden) {
47         mTelephonyManager = telephonyManager;
48         mActiveModeWarden = activeModeWarden;
49     }
50 
51     /**
52      * Enable MBO and OCE functionality.
53      */
enable()54     public void enable() {
55         ClientModeManager clientModeManager =
56                 mActiveModeWarden.getPrimaryClientModeManagerNullable();
57         if (clientModeManager == null) {
58             return;
59         }
60         long supportedFeatures = clientModeManager.getSupportedFeatures();
61         mIsMboSupported = (supportedFeatures & WIFI_FEATURE_MBO) != 0;
62         mIsOceSupported = (supportedFeatures & WIFI_FEATURE_OCE) != 0;
63         mEnabled = true;
64         if (mVerboseLoggingEnabled) {
65             Log.d(TAG, "Enable MBO-OCE MBO support: " + mIsMboSupported
66                     + " OCE support: " + mIsOceSupported);
67         }
68         if (mIsMboSupported) {
69             // Register for data connection state change events (Cellular).
70             mTelephonyManager.listen(mDataConnectionStateListener,
71                     PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
72         }
73     }
74 
75     /**
76      * Disable MBO and OCE functionality.
77      */
disable()78     public void disable() {
79         if (mVerboseLoggingEnabled) {
80             Log.d(TAG, "Disable MBO-OCE");
81         }
82         if (mIsMboSupported) {
83             // Un-register for data connection state change events (Cellular).
84             mTelephonyManager.listen(mDataConnectionStateListener, PhoneStateListener.LISTEN_NONE);
85         }
86         mEnabled = false;
87     }
88 
89     /**
90      * Enable/Disable verbose logging.
91      *
92      * @param verbose true to enable and false to disable.
93      */
enableVerboseLogging(boolean verbose)94     public void enableVerboseLogging(boolean verbose) {
95         mVerboseLoggingEnabled = verbose;
96     }
97 
98     /**
99      * Listen for changes to the data connection state (Cellular).
100      */
101     private PhoneStateListener mDataConnectionStateListener = new PhoneStateListener(){
102         public void onDataConnectionStateChanged(int state, int networkType) {
103             boolean dataAvailable;
104 
105             ClientModeManager clientModeManager =
106                     mActiveModeWarden.getPrimaryClientModeManagerNullable();
107             if (clientModeManager == null) {
108                 return;
109             }
110             if (!mEnabled) {
111                 Log.e(TAG, "onDataConnectionStateChanged called when MBO is disabled!!");
112                 return;
113             }
114             if (state == TelephonyManager.DATA_CONNECTED) {
115                 dataAvailable = true;
116             } else if (state == TelephonyManager.DATA_DISCONNECTED) {
117                 dataAvailable = false;
118             } else {
119                 Log.e(TAG, "onDataConnectionStateChanged unexpected State: " + state);
120                 return;
121             }
122             if (mVerboseLoggingEnabled) {
123                 Log.d(TAG, "Cell Data: " + dataAvailable);
124             }
125             clientModeManager.setMboCellularDataStatus(dataAvailable);
126         }
127     };
128 
129     /**
130      * BtmFrameData carries the data retried from received BTM
131      * request frame handled in supplicant.
132      */
133     public static class BtmFrameData {
134         public @MboOceConstants.BtmResponseStatus int mStatus =
135                 MboOceConstants.BTM_RESPONSE_STATUS_INVALID;
136         public int mBssTmDataFlagsMask = 0;
137         public long mBlockListDurationMs = 0;
138         public @MboOceConstants.MboTransitionReason int mTransitionReason =
139                 MboOceConstants.MBO_TRANSITION_REASON_INVALID;
140         public @MboOceConstants.MboCellularDataConnectionPreference int mCellPreference =
141                 MboOceConstants.MBO_CELLULAR_DATA_CONNECTION_INVALID;
142 
143         @Override
toString()144         public String toString() {
145             return new StringBuilder("BtmFrameData status=").append(mStatus).append(
146                     ", flags=").append(mBssTmDataFlagsMask).append(
147                     ", assocRetryDelay=").append(mBlockListDurationMs).append(
148                     ", transitionReason=").append(mTransitionReason).append(
149                     ", cellPref=").append(mCellPreference).toString();
150         }
151     }
152 
153     /**
154      * OceRssiBasedAssocRejectAttr is extracted from (Re-)Association response frame from an OCE AP
155      * to indicate that the AP has rejected the (Re-)Association request on the basis of
156      * insufficient RSSI.
157      * Refer OCE spec v1.0 section 4.2.2 Table 7.
158      */
159     public static class OceRssiBasedAssocRejectAttr {
160         /*
161          * Delta RSSI - The difference in dB between the minimum RSSI at which
162          * the AP would accept a (Re-)Association request from the STA before
163          * Retry Delay expires and the AP's measurement of the RSSI at which the
164          * (Re-)Association request was received.
165          */
166         public int mDeltaRssi;
167         /*
168          * Retry Delay - The time period in seconds for which the AP will not
169          * accept any subsequent (Re-)Association requests from the STA, unless
170          * the received RSSI has improved by Delta RSSI.
171          */
172         public int mRetryDelayS;
173 
OceRssiBasedAssocRejectAttr(int deltaRssi, int retryDelayS)174         public OceRssiBasedAssocRejectAttr(int deltaRssi, int retryDelayS) {
175             this.mDeltaRssi = deltaRssi;
176             this.mRetryDelayS = retryDelayS;
177         }
178 
179         @Override
toString()180         public String toString() {
181             return new StringBuilder("OceRssiBasedAssocRejectAttr Delta Rssi=")
182                     .append(mDeltaRssi).append(
183                     ", Retry Delay=").append(mRetryDelayS).toString();
184         }
185     }
186 
187     /**
188      * MboAssocDisallowedAttr is extracted from (Re-)Association response frame from the MBO AP
189      * to indicate that the AP is not accepting new associations.
190      * Refer MBO spec v1.2 section 4.2.4 Table 13 for the details of reason code.
191      */
192     public static class MboAssocDisallowedAttr {
193         /*
194          * Reason Code - The reason why the AP is not accepting new
195          * associations.
196          */
197         public @MboOceConstants.MboAssocDisallowedReasonCode int mReasonCode;
198 
MboAssocDisallowedAttr(int reasonCode)199         public MboAssocDisallowedAttr(int reasonCode) {
200             mReasonCode = halToFrameworkMboAssocRDisallowedReasonCode(reasonCode);
201         }
202 
203         @Override
toString()204         public String toString() {
205             return new StringBuilder("MboAssocDisallowedAttr Reason code=")
206                     .append(mReasonCode).toString();
207         }
208 
209         private @MboOceConstants.MboAssocDisallowedReasonCode int
halToFrameworkMboAssocRDisallowedReasonCode(int reasonCode)210                 halToFrameworkMboAssocRDisallowedReasonCode(int reasonCode) {
211             switch (reasonCode) {
212                 case MboAssocDisallowedReasonCode.RESERVED:
213                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_RESERVED_0;
214                 case MboAssocDisallowedReasonCode.UNSPECIFIED:
215                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_UNSPECIFIED;
216                 case MboAssocDisallowedReasonCode.MAX_NUM_STA_ASSOCIATED:
217                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_MAX_NUM_STA_ASSOCIATED;
218                 case MboAssocDisallowedReasonCode.AIR_INTERFACE_OVERLOADED:
219                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_AIR_INTERFACE_OVERLOADED;
220                 case MboAssocDisallowedReasonCode.AUTH_SERVER_OVERLOADED:
221                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_AUTH_SERVER_OVERLOADED;
222                 case MboAssocDisallowedReasonCode.INSUFFICIENT_RSSI:
223                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_INSUFFICIENT_RSSI;
224                 default:
225                     return MboOceConstants.MBO_ASSOC_DISALLOWED_REASON_RESERVED;
226             }
227         }
228     }
229 }
230