• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 android.net.wifi;
18 
19 import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
20 import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;
21 import static android.net.wifi.WifiScanner.WIFI_BAND_6_GHZ;
22 
23 import android.annotation.IntDef;
24 import android.annotation.IntRange;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.net.MacAddress;
28 import android.net.NetworkCapabilities;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 import java.util.Objects;
35 
36 /**
37  * Data structure class representing a Wi-Fi Multi-Link Operation (MLO) link
38  * This is only used by 802.11be capable devices
39  */
40 public final class MloLink implements Parcelable {
41 
42     /**
43      * Invalid link id. Used in {link #getLinkId()}
44      */
45     public static final int INVALID_MLO_LINK_ID = -1;
46 
47     /**
48      * Lower limit for MLO link id
49      * As described in IEEE 802.11be Specification, section 9.4.2.295b.2.
50      *
51      * @hide
52      */
53     public static final int MIN_MLO_LINK_ID = 0;
54 
55     /**
56      * Upper limit for MLO link id
57      * As described in IEEE 802.11be Specification, section 9.4.2.295b.2.
58      *
59      * @hide
60      */
61     public static final int MAX_MLO_LINK_ID = 15;
62 
63     /**
64      * MLO link state: Invalid link state. Used in {link #getState()}
65      */
66     public static final int MLO_LINK_STATE_INVALID = 0;
67     /**
68      * MLO link state: Link is not associated with the access point. Used in {link #getState()}
69      */
70     public static final int MLO_LINK_STATE_UNASSOCIATED = 1;
71     /**
72      * MLO link state: Link is associated to the access point but not mapped to any traffic stream.
73      * Used in {link #getState()}
74      */
75     public static final int MLO_LINK_STATE_IDLE = 2;
76     /**
77      * MLO link state: Link is associated to the access point and mapped to at least one traffic
78      * stream. {link #getState()}
79      * Note that an MLO link could be in that state but in power save mode.
80      */
81     public static final int MLO_LINK_STATE_ACTIVE = 3;
82 
83     /**
84      * @hide
85      */
86     @Retention(RetentionPolicy.SOURCE)
87     @IntDef(prefix = {"MLO_LINK_STATE_"}, value = {
88             MLO_LINK_STATE_INVALID,
89             MLO_LINK_STATE_UNASSOCIATED,
90             MLO_LINK_STATE_IDLE,
91             MLO_LINK_STATE_ACTIVE})
92     public @interface MloLinkState {};
93 
94     private int mLinkId;
95     private MacAddress mApMacAddress;
96     private MacAddress mStaMacAddress;
97     private @MloLinkState int mState;
98     private @WifiAnnotations.WifiBandBasic int mBand;
99     private int mChannel;
100 
101     /**
102      * Constructor for a MloLInk.
103      */
MloLink()104     public MloLink() {
105         mBand = WifiScanner.WIFI_BAND_UNSPECIFIED;
106         mChannel = 0;
107         mState = MLO_LINK_STATE_UNASSOCIATED;
108         mApMacAddress = null;
109         mStaMacAddress = null;
110         mLinkId = INVALID_MLO_LINK_ID;
111     }
112 
113     /**
114      * Copy Constructor
115      *
116      * @hide
117      */
MloLink(MloLink source, long redactions)118     public MloLink(MloLink source, long redactions) {
119         mBand = source.mBand;
120         mChannel = source.mChannel;
121         mLinkId = source.mLinkId;
122         mState = source.mState;
123 
124         mStaMacAddress = ((redactions & NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS) != 0)
125                 || source.mStaMacAddress == null
126                 ? null :  MacAddress.fromString(source.mStaMacAddress.toString());
127 
128         mApMacAddress = ((redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0)
129                 || source.mApMacAddress == null
130                 ? null : MacAddress.fromString(source.mApMacAddress.toString());
131     }
132 
133     /** Returns the Wi-Fi band of this link as one of:
134      *      {@link WifiScanner#WIFI_BAND_UNSPECIFIED},
135      *      {@link WifiScanner#WIFI_BAND_24_GHZ},
136      *      {@link WifiScanner#WIFI_BAND_5_GHZ},
137      *      {@link WifiScanner#WIFI_BAND_6_GHZ}
138      */
getBand()139     public @WifiAnnotations.WifiBandBasic int getBand() {
140         return mBand;
141     }
142 
143     /**
144      * Returns the channel number of this link.
145      * A valid value is based on the 802.11 specification in sections 19.3.15 and 27.3.23
146      */
147     @IntRange(from = 1)
getChannel()148     public int getChannel() {
149         return mChannel;
150     }
151 
152     /**
153      * Returns the link id of this link.
154      * Valid values are 0-15, as described in IEEE 802.11be Specification, section 9.4.2.295b.2.
155      *
156      * @return {@link #INVALID_MLO_LINK_ID} or a valid value (0-15).
157      */
158     @IntRange(from = INVALID_MLO_LINK_ID, to = MAX_MLO_LINK_ID)
getLinkId()159     public int getLinkId() {
160         return mLinkId;
161     }
162 
163     /** Returns the state of this link as one of:
164      *     {@link #MLO_LINK_STATE_INVALID}
165      *     {@link #MLO_LINK_STATE_UNASSOCIATED}
166      *     {@link #MLO_LINK_STATE_IDLE}
167      *     {@link #MLO_LINK_STATE_ACTIVE}
168      */
getState()169     public @MloLinkState int getState() {
170         return mState;
171     }
172 
173     /**
174      * Returns the AP MAC address of this link.
175      *
176      * @return AP MAC address for this link or null when the caller has insufficient
177      * permissions to access the access point MAC Address.
178      */
getApMacAddress()179     public @Nullable MacAddress getApMacAddress() {
180         return mApMacAddress;
181     }
182 
183     /**
184      * Returns the STA MAC address of this link.
185      *
186      * @return STA MAC address assigned for this link, or null in the following cases:
187      * <ul>
188      *     <li> The caller has insufficient permissions to access the STA MAC Address </li>
189      *     <li> Link is not associated, hence no MAC address is assigned to it by STA </li>
190      * </ul>
191      */
getStaMacAddress()192     public @Nullable MacAddress getStaMacAddress() {
193         return mStaMacAddress;
194     }
195 
196     /**
197      * Sets the channel number of this link.
198      *
199      * @hide
200      */
setChannel(int channel)201     public void setChannel(int channel) {
202         mChannel = channel;
203     }
204 
205     /**
206      * Sets the band for this link
207      *
208      * @hide
209      */
setBand(@ifiAnnotations.WifiBandBasic int band)210     public void setBand(@WifiAnnotations.WifiBandBasic int band) {
211         mBand = band;
212     }
213 
214     /**
215      * Sets the linkId of this link
216      *
217      * @hide
218      */
setLinkId(int linkId)219     public void setLinkId(int linkId) {
220         mLinkId = linkId;
221     }
222 
223     /**
224      * Sets the state of this link
225      *
226      * @hide
227      */
setState(@loLinkState int state)228     public void setState(@MloLinkState int state) {
229         mState = state;
230     }
231 
232     /**
233      * set the AP MAC Address for this link
234      *
235      * @hide
236      */
setApMacAddress(MacAddress address)237     public void setApMacAddress(MacAddress address) {
238         mApMacAddress = address;
239     }
240 
241     /**
242      * set the STA MAC Address for this link
243      *
244      * @hide
245      */
setStaMacAddress(MacAddress address)246     public void setStaMacAddress(MacAddress address) {
247         mStaMacAddress = address;
248     }
249 
250     @Override
equals(@ullable Object o)251     public boolean equals(@Nullable Object o) {
252         if (this == o) return true;
253         if (o == null || getClass() != o.getClass()) return false;
254         MloLink that = (MloLink) o;
255         return mBand == that.mBand
256                 && mChannel == that.mChannel
257                 && mLinkId == that.mLinkId
258                 && Objects.equals(mApMacAddress, that.mApMacAddress)
259                 && Objects.equals(mStaMacAddress, that.mStaMacAddress)
260                 && mState == that.mState;
261     }
262 
263     @Override
hashCode()264     public int hashCode() {
265         return Objects.hash(mBand, mChannel, mLinkId, mApMacAddress, mStaMacAddress, mState);
266     }
267 
getStateString(@loLinkState int state)268     private String getStateString(@MloLinkState int state) {
269         switch(state) {
270             case MLO_LINK_STATE_INVALID:
271                 return "MLO_LINK_STATE_INVALID";
272             case MLO_LINK_STATE_UNASSOCIATED:
273                 return "MLO_LINK_STATE_UNASSOCIATED";
274             case MLO_LINK_STATE_IDLE:
275                 return "MLO_LINK_STATE_IDLE";
276             case MLO_LINK_STATE_ACTIVE:
277                 return "MLO_LINK_STATE_ACTIVE";
278             default:
279                 return "Unknown MLO link state";
280         }
281     }
282 
283     /**
284      * @hide
285      */
isValidState(@loLinkState int state)286     public static boolean isValidState(@MloLinkState int state) {
287         switch(state) {
288             case MLO_LINK_STATE_INVALID:
289             case MLO_LINK_STATE_UNASSOCIATED:
290             case MLO_LINK_STATE_IDLE:
291             case MLO_LINK_STATE_ACTIVE:
292                 return true;
293         }
294         return false;
295     }
296 
297     @Override
toString()298     public String toString() {
299         StringBuilder sb = new StringBuilder("MloLink{");
300         if (mBand == WIFI_BAND_24_GHZ) {
301             sb.append("2.4GHz");
302         } else if (mBand == WIFI_BAND_5_GHZ) {
303             sb.append("5GHz");
304         } else if (mBand == WIFI_BAND_6_GHZ) {
305             sb.append("6GHz");
306         } else {
307             sb.append("UNKNOWN BAND");
308         }
309         sb.append(", channel: ").append(mChannel);
310         sb.append(", id: ").append(mLinkId);
311         sb.append(", state: ").append(getStateString(mState));
312         if (mApMacAddress != null) {
313             sb.append(", AP MAC Address: ").append(mApMacAddress.toString());
314         }
315         if (mStaMacAddress != null) {
316             sb.append(", STA MAC Address: ").append(mStaMacAddress.toString());
317         }
318         sb.append('}');
319         return sb.toString();
320     }
321 
322     /** Implement the Parcelable interface */
323     @Override
describeContents()324     public int describeContents() {
325         return 0;
326     }
327 
328     /** Implement the Parcelable interface */
329     @Override
writeToParcel(@onNull Parcel dest, int flags)330     public void writeToParcel(@NonNull Parcel dest, int flags) {
331         dest.writeInt(mBand);
332         dest.writeInt(mChannel);
333         dest.writeInt(mLinkId);
334         dest.writeInt(mState);
335         dest.writeParcelable(mApMacAddress, flags);
336         dest.writeParcelable(mStaMacAddress, flags);
337     }
338 
339     /** Implement the Parcelable interface */
340     public static final @NonNull Creator<MloLink> CREATOR =
341             new Creator<MloLink>() {
342                 public MloLink createFromParcel(Parcel in) {
343                     MloLink link = new MloLink();
344                     link.mBand = in.readInt();
345                     link.mChannel = in.readInt();
346                     link.mLinkId = in.readInt();
347                     link.mState = in.readInt();
348                     link.mApMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
349                     link.mStaMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
350                     return link;
351                 }
352 
353                 public MloLink[] newArray(int size) {
354                     return new MloLink[size];
355                 }
356             };
357 }
358