1#!/usr/bin/env python3
2#
3#   Copyright 2021 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17
18import logging
19import time
20from acts import asserts
21from acts import signals
22from acts.test_decorators import test_tracker_info
23import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
24from acts_contrib.test_utils.wifi import wifi_constants
25from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
26from acts.controllers.ap_lib.hostapd_constants import BAND_2G
27from acts.controllers.ap_lib.hostapd_constants import BAND_5G
28from acts.controllers.ap_lib import hostapd_constants
29
30
31WifiEnums = wutils.WifiEnums
32# Each wait time add 5 seconds as buffer.
33BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS = 5
34BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES = 305
35BRIDGED_AP_SHUTDOWN_INTERVAL_5_SECONDS = 5
36SOFT_AP_SHUTDOWN_INTERVAL_10_MINUTES = 605
37INTERVAL_9_MINUTES = 545
38INTERVAL_2_MINUTES = 125
39INTERVAL_1_MINUTES = 65
40
41
42class WifiBridgedApTest(WifiBaseTest):
43    """WiFi BridgedAp test class.
44
45    Test Bed Requirement:
46        * Android device x 1 with BridgedAp supported.
47        * Android devices x2 as clients, at least Android 10.
48        * OpenWrt AP x 1.
49        * Google Wi-Fi x 2 as packet captures.
50    """
51
52    def setup_class(self):
53        super().setup_class()
54
55        if len(self.android_devices) == 3:
56            self.dut = self.android_devices[0]
57            self.client1 = self.android_devices[1]
58            self.client2 = self.android_devices[2]
59        else:
60            raise signals.TestFailure("WifiBridgedApTest requires 3 DUTs")
61
62        req_params = ["dbs_supported_models"]
63        opt_param = []
64
65        self.unpack_userparams(
66            req_param_names=req_params, opt_param_names=opt_param)
67
68    def setup_test(self):
69        super().setup_test()
70        asserts.skip_if(not self.dut.droid.wifiIsBridgedApConcurrencySupported(), "Phone %s doesn't support bridged AP." %  (self.dut.model))
71        for ad in self.android_devices:
72            wutils.reset_wifi(ad)
73        wutils.wifi_toggle_state(self.dut, False)
74        wutils.wifi_toggle_state(self.client1, True)
75        wutils.wifi_toggle_state(self.client2, True)
76
77    def teardown_test(self):
78        super().teardown_test()
79        # Reset unplugged status
80        self.dut.adb.shell("cmd battery reset")
81        if self.dut.droid.wifiIsApEnabled():
82            wutils.stop_wifi_tethering(self.dut)
83        for ad in self.android_devices:
84            wutils.reset_wifi(ad)
85            wutils.set_wifi_country_code(
86                ad, wutils.WifiEnums.CountryCode.US)
87
88        # Stop packet captures.
89        if hasattr(self, "sniffer_procs"):
90            for i in range(len(self.sniffer_procs)):
91                try:
92                    wutils.stop_pcap(
93                        self.packet_capture[i], self.sniffer_procs[i], False)
94                    logging.info("packet_capture[{}] is STOPPED".format(i))
95                except:
96                    logging.info("packet_capture[{}] is NOT STOPPED".format(i))
97
98    def teardown_class(self):
99        super().teardown_class()
100        for ad in self.android_devices:
101            wutils.reset_wifi(ad)
102        if "AccessPoint" in self.user_params:
103            del self.user_params["reference_networks"]
104            del self.user_params["open_network"]
105
106    def set_country_code_and_verify(self, ad, country_code):
107        wutils.set_wifi_country_code(ad, country_code)
108        # Wi-Fi ON and OFF to make sure country code take effect.
109        wutils.wifi_toggle_state(ad, True)
110        wutils.wifi_toggle_state(ad, False)
111
112        country = ad.droid.wifiGetCountryCode()
113        asserts.assert_true(country == country_code,
114                            "country code {} is not set".format(country_code))
115        ad.log.info("Country code set to : {}".format(country))
116
117    def verify_clients_support_wpa3_sae(self, *args):
118        """Check if clients support WPA3 SAE.
119
120        Args:
121            args: arbitrary number of clients. e.g., self.dut1, self.dut2, ...
122        """
123        duts = args
124        for dut in duts:
125            asserts.skip_if(not dut.droid.wifiIsWpa3SaeSupported(),
126                            "All DUTs support WPA3 SAE is required")
127
128    def verify_band_of_bridged_ap_instance(self, ad, infos, bands):
129        """Check bands enabled as expected.
130           This function won't be called directly.
131
132        Args:
133            infos: SoftAp info list.
134            bands: A list of bands.
135                   e,g,. [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
136                          WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G]
137        """
138        self.dut.log.info("Length of infos: {}, Length of bands: {}"
139                          .format(len(infos), len(bands)))
140        asserts.assert_true(len(infos) == len(bands),
141                            "There should be {} BridgedAp instance, "
142                            "instead of {}".format(len(bands), len(infos)))
143        if len(bands) == 1 and (bands[0] == WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G):
144            asserts.assert_true(infos[0][wifi_constants.
145                                SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
146                                in WifiEnums.softap_band_frequencies[bands[0]],
147                                "This should be a {} instance".format(bands[0]))
148        if len(bands) == 2 and (bands[0] == WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G):
149            asserts.assert_true((infos[0][wifi_constants.
150                                SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
151                                in WifiEnums.ALL_2G_FREQUENCIES and
152                                infos[1][wifi_constants.
153                                SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
154                                in WifiEnums.ALL_5G_FREQUENCIES) or
155                                (infos[0][wifi_constants.
156                                 SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
157                                 in WifiEnums.ALL_5G_FREQUENCIES and
158                                 infos[1][wifi_constants.
159                                 SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
160                                 in WifiEnums.ALL_2G_FREQUENCIES),
161                                "There should only be 2G and 5G instances")
162
163    def verify_softap_freq_equals_to_ap_freq(self, ad, infos):
164        """Verify if instance frequency equal to AP frequency.
165           This function won't be called directly.
166        Args:
167            infos: SoftAp info list.
168        """
169        wlan0_freq = wutils.get_wlan0_link(ad)["freq"]
170        softap_freqs = []
171        for i in range(len(infos)):
172            softap_freqs.append(infos[i][WifiEnums.frequency_key])
173        ad.log.info("softap_freqs : {}".format(softap_freqs))
174        asserts.assert_true(int(wlan0_freq) in softap_freqs,
175                            "AP freq != SoftAp freq")
176        ad.log.info("softap freq == AP freq")
177
178    def verify_number_band_freq_of_bridged_ap(self, ad, bands,
179                                              freq_equal=False):
180        """Verify every aspect of info list from BridgedAp.
181
182        Args:
183            bands: A list of bands,
184                   e,g,. [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
185                          WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G]
186            freq_equal: True if need to check SoftAp freq equals to STA freq.
187
188        Returns:
189            infos: A List of SoftAp info, e.g.,
190                [{'autoShutdownTimeoutMillis': 600000,
191                  'bandwidth': 4,
192                  'bssid': '12:dd:0b:b9:4b:cc',
193                  'frequency': 5180,
194                  'wifiStandard': 6},
195                 {'autoShutdownTimeoutMillis': 600000,
196                  'bandwidth': 2,
197                  'bssid': '12:22:f4:b9:4b:cc',
198                  'frequency': 2462,
199                  'wifiStandard': 4}]
200        """
201        callbackId = ad.droid.registerSoftApCallback()
202        infos = wutils.get_current_softap_infos(ad, callbackId, True)
203        self.verify_band_of_bridged_ap_instance(ad, infos, bands)
204        if freq_equal:
205            self.verify_softap_freq_equals_to_ap_freq(ad, infos)
206        ad.droid.unregisterSoftApCallback(callbackId)
207        return infos
208
209    def verify_expected_number_of_softap_clients(self, ad, number):
210        """Verify the number of softap clients.
211
212        Args:
213            number: expect number of client connect to SoftAp.
214        """
215        callbackId = self.dut.droid.registerSoftApCallback()
216        wutils.wait_for_expected_number_of_softap_clients(self.dut,
217                                                          callbackId, number)
218        ad.log.info("{} clients connect to soft ap".format(number))
219        self.dut.droid.unregisterSoftApCallback(callbackId)
220
221    def wait_interval(self, interval):
222        """print different messages with different intervals.
223
224        Args:
225            interval: different interval for different situation.
226        """
227        if interval == BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS:
228            logging.info("Wait {} seconds for BridgedAp launch"
229                         .format(interval))
230            time.sleep(interval)
231        elif interval == BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES:
232            logging.info("Wait {} minutes for BridgedAp shutdown"
233                         .format(interval/60))
234            time.sleep(interval)
235        elif interval == SOFT_AP_SHUTDOWN_INTERVAL_10_MINUTES:
236            logging.info("Wait {} minutes for SoftAp shutdown"
237                         .format(interval/60))
238            time.sleep(interval)
239        elif interval == INTERVAL_9_MINUTES:
240            logging.info("Wait {} minutes".format(interval/60))
241            time.sleep(interval)
242        elif interval == INTERVAL_2_MINUTES:
243            logging.info("Wait {} minutes".format(interval/60))
244            time.sleep(interval)
245        elif interval == INTERVAL_1_MINUTES:
246            logging.info("Wait {} minutes".format(interval/60))
247            time.sleep(interval)
248
249    def generate_softap_config(self, security):
250        """Return a soft ap config
251
252        Args:
253            security: String; represent certain security. e.g., "WPA3_SAE"
254        """
255        config = wutils.create_softap_config()
256        config[WifiEnums.SECURITY] = security
257        return config
258
259    def enable_bridged_ap(self, ad, security, bands, **kwargs):
260        """Enable BridgedAp.
261
262        Args:
263            security: String; represent certain security. e.g., "WPA3_SAE"
264            bands: specifies the band list for the soft ap.
265        """
266        self.config = self.generate_softap_config(security)
267        wutils.save_wifi_soft_ap_config(
268                                        ad,
269                                        self.config,
270                                        bands=bands,
271                                        **kwargs)
272        wutils.start_wifi_tethering_saved_config(self.dut)
273        # Wait 5 seconds for BridgedAp launch.
274        self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS)
275
276    def sniffing_bridgedap_channels(self, infos):
277        """Sniff BridgedAp channels.
278
279        Args:
280            infos: A List of SoftAp info. e.g.,
281                [{'autoShutdownTimeoutMillis': 600000,
282                  'bandwidth': 4,
283                  'bssid': '12:dd:0b:b9:4b:cc',
284                  'frequency': 5180,
285                  'wifiStandard': 6},
286                 {'autoShutdownTimeoutMillis': 600000,
287                  'bandwidth': 2,
288                  'bssid': '12:22:f4:b9:4b:cc',
289                  'frequency': 2462,
290                  'wifiStandard': 4}]
291        """
292        if hasattr(self, "packet_capture") and len(self.packet_capture) == 2:
293            # Create sniffer_config.
294            self.sniffer_config = {}
295            for i in range(len(infos)):
296                if (infos[i][WifiEnums.frequency_key] in
297                   WifiEnums.ALL_5G_FREQUENCIES):
298                    self.sniffer_config[BAND_5G] = WifiEnums.freq_to_channel[
299                        int(infos[i][WifiEnums.frequency_key])]
300                if (infos[i][WifiEnums.frequency_key] in
301                   WifiEnums.ALL_2G_FREQUENCIES):
302                    self.sniffer_config[BAND_2G] = WifiEnums.freq_to_channel[
303                        int(infos[i][WifiEnums.frequency_key])]
304            logging.info("sniffer_config : {}".format(self.sniffer_config))
305
306            # Enable sniffers.
307            self.sniffer_procs = []
308            for i in range(len(self.sniffer_config)):
309                self.packet_capture[i].log.info(
310                    "Enable packet_capture[{}]".format(i))
311                result = self.packet_capture[i].configure_monitor_mode(
312                    list(self.sniffer_config.keys())[i],
313                    list(self.sniffer_config.values())[i])
314                if not result:
315                    logging.error("Failed to enable packet_capture"
316                                  "on {}".format(self.packet_capture[i]))
317                self.pcap_procs = wutils.start_pcap(
318                    self.packet_capture[i],
319                    list(self.sniffer_config.keys())[i],
320                    self.test_name)
321                self.sniffer_procs.append(self.pcap_procs)
322            logging.info("sniffer_procs: {}".format(self.sniffer_procs))
323        else:
324            logging.warning("Packet_capture not enabled, "
325                            "because two packet_capture hardware required")
326
327    def sniffing_ap_channels(self, channel1, channel2):
328        """Sniff on two Wi-Fi channels.
329
330        Args:
331            channel1: Integer; a Wi-Fi channel, e.g., 6.
332            channel2: Integer; a Wi-Fi channel, e,g,. 36.
333        """
334        if not channel1:
335            channel1 = hostapd_constants.AP_DEFAULT_CHANNEL_2G
336        if not channel2:
337            channel2 = hostapd_constants.AP_DEFAULT_CHANNEL_5G
338
339        if hasattr(self, "packet_capture") and len(self.packet_capture) == 2:
340            # Create sniffer_config.
341            self.sniffer_config = {}
342            if channel1 in WifiEnums.channel_2G_to_freq:
343                self.sniffer_config[BAND_2G] = channel1
344            if channel1 in WifiEnums.channel_5G_to_freq:
345                self.sniffer_config[BAND_5G] = channel1
346            if channel2 in WifiEnums.channel_2G_to_freq:
347                self.sniffer_config[BAND_2G] = channel2
348            if channel2 in WifiEnums.channel_5G_to_freq:
349                self.sniffer_config[BAND_5G] = channel2
350            logging.info("sniffer_config : {}".format(self.sniffer_config))
351
352            # Enable sniffers.
353            self.sniffer_procs = []
354            for i in range(len(self.sniffer_config)):
355                self.packet_capture[i].log.info(
356                    "Enable packet_capture[{}]".format(i))
357                result = self.packet_capture[i].configure_monitor_mode(
358                    list(self.sniffer_config.keys())[i],
359                    list(self.sniffer_config.values())[i])
360                if not result:
361                    logging.error("Failed to enable packet_capture"
362                                  "on {}".format(self.packet_capture[i]))
363                self.pcap_procs = wutils.start_pcap(
364                    self.packet_capture[i],
365                    list(self.sniffer_config.keys())[i],
366                    self.test_name)
367                self.sniffer_procs.append(self.pcap_procs)
368            logging.info("sniffer_procs: {}".format(self.sniffer_procs))
369        else:
370            logging.debug("Packet_capture not enabled, "
371                          "because two packet_capture hardware required")
372
373    def start_ap(self, channel_2g, channel_5g):
374        """Enable OpenWrt AP with specific 2G/5G channels
375
376        Args:
377            channel_2g: Integer; a 2G channel, e.g., 6.
378            channel_5g: Integer; a 5G channel, e,g,. 36
379        """
380        if not channel_2g:
381            channel_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G
382        if not channel_5g:
383            channel_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G
384
385        # Enable OpenWrt AP.
386        if "OpenWrtAP" in self.user_params:
387            self.configure_openwrt_ap_and_start(wpa_network=True,
388                                                channel_2g=channel_2g,
389                                                channel_5g=channel_5g)
390
391    def two_clients_connect_to_wifi_network(self, dut1, dut2, config):
392        """Connect two clients to different BridgedAp instances.
393           This function will be called only when BridgedAp ON.
394
395        Args:
396            config: Wi-Fi config, e.g., {"SSID": "xxx", "password": "xxx"}
397        Steps:
398            Backup config.
399            Register SoftAp Callback.
400            Get SoftAp Infos.
401            Get BSSIDs from Infos.
402            Connect two clients to different BridgedAp instances.
403            Restore config.
404        """
405        # Make sure 2 instances enabled, and get BSSIDs from BridgedAp Infos.
406        callbackId = self.dut.droid.registerSoftApCallback()
407        infos = wutils.get_current_softap_infos(self.dut, callbackId, True)
408        self.dut.droid.unregisterSoftApCallback(callbackId)
409
410        if len(infos) == 0:
411            raise signals.TestFailure("No BridgedAp instance")
412        elif len(infos) == 1:
413            raise signals.TestFailure(
414                "Only one BridgedAp instance, should be two")
415        else:
416            bssid_5g = infos[0][wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
417            bssid_2g = infos[1][wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
418
419        # Two configs for BridgedAp 2G and 5G instances.
420        config_5g = config.copy()
421        config_2g = config.copy()
422        config_5g[WifiEnums.BSSID_KEY] = bssid_5g
423        config_2g[WifiEnums.BSSID_KEY] = bssid_2g
424
425        # Connect two clients to BridgedAp.
426        wutils.connect_to_wifi_network(dut1, config_5g,
427                                       check_connectivity=False)
428        wutils.connect_to_wifi_network(dut2, config_2g,
429                                       check_connectivity=False)
430
431        # Verify if Clients connect to the expected BridgedAp instances.
432        client1_bssid = wutils.get_wlan0_link(
433            self.client1)[wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
434        client2_bssid = wutils.get_wlan0_link(
435            self.client2)[wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
436        asserts.assert_true(client1_bssid == bssid_5g,
437                            "Client1 does not connect to the 5G instance")
438        asserts.assert_true(client2_bssid == bssid_2g,
439                            "Client2 does not connect to the 2G instance")
440
441    def client_connects_to_a_bridgeap(self, ad, band):
442        """One client connects to a BridgeAp instance
443
444        Args:
445            band: String; '2g' or '5g'.
446        """
447        callbackId = self.dut.droid.registerSoftApCallback()
448        infos = wutils.get_current_softap_infos(self.dut, callbackId, True)
449        self.dut.droid.unregisterSoftApCallback(callbackId)
450        # Make one client connects to 2G instance if band == '2g'.
451        if band == BAND_2G:
452            if (infos[0][wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
453               in WifiEnums.ALL_2G_FREQUENCIES):
454                bssid_2g = (infos[0][wifi_constants.
455                            SOFTAP_INFO_BSSID_CALLBACK_KEY])
456            else:
457                bssid_2g = (infos[1][wifi_constants.
458                            SOFTAP_INFO_BSSID_CALLBACK_KEY])
459            config_2g = self.config.copy()
460            config_2g[WifiEnums.BSSID_KEY] = bssid_2g
461            wutils.connect_to_wifi_network(ad, config_2g,
462                                           check_connectivity=False)
463        # Make one client connects to 5G instance if band == '5g'.
464        elif band == BAND_5G:
465            if (infos[0][wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
466               in WifiEnums.ALL_5G_FREQUENCIES):
467                bssid_5g = (infos[0][wifi_constants.
468                            SOFTAP_INFO_BSSID_CALLBACK_KEY])
469            else:
470                bssid_5g = (infos[1][wifi_constants.
471                            SOFTAP_INFO_BSSID_CALLBACK_KEY])
472            config_5g = self.config.copy()
473            config_5g[WifiEnums.BSSID_KEY] = bssid_5g
474            wutils.connect_to_wifi_network(ad, config_5g,
475                                           check_connectivity=False)
476
477    # Tests
478
479    @test_tracker_info(uuid="6f776b4a-b080-4b52-a330-52aa641b18f2")
480    def test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us(self):
481        """Test clients on different instances can ping each other.
482
483        Steps:
484            Backup config.
485            Make sure clients support WPA3 SAE.
486            Make sure DUT is able to enable BridgedAp.
487            Enable BridgedAp with bridged configuration.
488            RegisterSoftApCallback.
489            Check the bridged AP enabled succeed.
490            start sniffer and sniffing on BridgedAp channels.
491            Force client#1 connect to 5G.
492            Force client#2 connect to 2.4G.
493            Trigger client#1 and client#2 each other.
494            Stop sniffers.
495            Restore config.
496        """
497        # Backup config
498        original_softap_config = self.dut.droid.wifiGetApConfiguration()
499        # Make sure clients support WPA3 SAE.
500        self.verify_clients_support_wpa3_sae(self.client1, self.client2)
501        # Make sure DUT is able to enable BridgedAp.
502        is_supported = wutils.check_available_channels_in_bands_2_5(
503            self.dut, wutils.WifiEnums.CountryCode.US)
504        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
505
506        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
507        self.enable_bridged_ap(self.dut,
508                               WifiEnums.SoftApSecurityType.WPA3_SAE,
509                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
510                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
511        infos = self.verify_number_band_freq_of_bridged_ap(
512            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
513                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
514
515        self.sniffing_bridgedap_channels(infos)
516
517        self.two_clients_connect_to_wifi_network(self.client1, self.client2,
518                                                 self.config)
519        # Trigger client#1 and client#2 ping each other.
520        wutils.validate_ping_between_two_clients(self.client1, self.client2)
521
522        # Restore config
523        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
524    @test_tracker_info(uuid="8685a6cb-f7be-4384-b25b-23cecb4cb6dc")
525    def test_two_clients_ping_bridged_ap_5g_2g_wpa3_sae_transition_country_us(self):
526        """Test clients on different instances can ping each other.
527
528        Steps:
529            Refer to test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us,
530            but this case enable WPA3/WPA2-Personal SoftAp security type.
531        """
532        # Backup config
533        original_softap_config = self.dut.droid.wifiGetApConfiguration()
534        # Make sure clients support WPA3 SAE.
535        self.verify_clients_support_wpa3_sae(self.client1, self.client2)
536        # Make sure DUT is able to enable BridgedAp.
537        is_supported = wutils.check_available_channels_in_bands_2_5(
538            self.dut, wutils.WifiEnums.CountryCode.US)
539        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
540
541        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
542        self.enable_bridged_ap(self.dut,
543                               WifiEnums.SoftApSecurityType.WPA3_SAE_TRANSITION,
544                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
545                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
546        infos = self.verify_number_band_freq_of_bridged_ap(
547            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
548                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
549
550        self.sniffing_bridgedap_channels(infos)
551
552        self.two_clients_connect_to_wifi_network(self.client1, self.client2,
553                                                 self.config)
554        # Trigger client#1 and client#2 ping each other.
555        wutils.validate_ping_between_two_clients(self.client1, self.client2)
556
557        # Restore config
558        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
559
560    @test_tracker_info(uuid="b217d4de-cd09-4a8f-b27d-302ae5b86c7e")
561    def test_two_clients_ping_bridged_ap_5g_2g_wpa2_country_us(self):
562        """Test clients on different instances can ping each other.
563
564        Steps:
565            Refer to test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us,
566            but this case enable WPA2-Personal SoftAp security type.
567        """
568        # Backup config
569        original_softap_config = self.dut.droid.wifiGetApConfiguration()
570        # Make sure DUT is able to enable BridgedAp.
571        is_supported = wutils.check_available_channels_in_bands_2_5(
572            self.dut, wutils.WifiEnums.CountryCode.US)
573        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
574
575        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
576        self.enable_bridged_ap(self.dut,
577                               WifiEnums.SoftApSecurityType.WPA2,
578                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
579                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
580        infos = self.verify_number_band_freq_of_bridged_ap(
581            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
582                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
583
584        self.sniffing_bridgedap_channels(infos)
585
586        self.two_clients_connect_to_wifi_network(self.client1, self.client2,
587                                                 self.config)
588        # Trigger client#1 and client#2 ping each other.
589        wutils.validate_ping_between_two_clients(self.client1, self.client2)
590
591        # Restore config
592        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
593
594    @test_tracker_info(uuid="ef98a5ea-c7d5-4cc4-a2f8-e5fd44648788")
595    def test_two_clients_ping_bridged_ap_5g_2g_no_security_country_us(self):
596        """Test clients on different instances can ping each other.
597
598        Steps:
599            Refer to test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us,
600            but this case enable OPEN SoftAp security type.
601        """
602        # Backup config
603        original_softap_config = self.dut.droid.wifiGetApConfiguration()
604        # Make sure DUT is able to enable BridgedAp.
605        is_supported = wutils.check_available_channels_in_bands_2_5(
606            self.dut, wutils.WifiEnums.CountryCode.US)
607        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
608
609        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
610        self.enable_bridged_ap(self.dut,
611                               WifiEnums.SoftApSecurityType.OPEN,
612                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
613                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
614        infos = self.verify_number_band_freq_of_bridged_ap(
615            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
616                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
617
618        self.sniffing_bridgedap_channels(infos)
619
620        self.two_clients_connect_to_wifi_network(self.client1, self.client2,
621                                                 self.config)
622        # Trigger client#1 and client#2 ping each other.
623        wutils.validate_ping_between_two_clients(self.client1, self.client2)
624
625        # Restore config
626        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
627
628    @test_tracker_info(uuid="0325ee58-ed8e-489e-9dee-55740406f896")
629    def test_bridged_ap_5g_2g_and_sta_5g_dfs(self):
630        """Test if auto fallback to one single 2G AP mode when
631         BridgedAP enabled and STA connect to a 5G DFS channel.
632
633        Steps:
634            Backup config.
635            DUT enable BridgedAp.
636            start sniffer and sniffing on AP channels.
637            DUT connect to a 5G DFS channel Wi-Fi network.
638            Verify 5G instance is shutdown.
639            Stop sniffers.
640            Restore config.
641        """
642        # Backup config
643        original_softap_config = self.dut.droid.wifiGetApConfiguration()
644
645        # Make sure DUT is able to enable BridgedAp.
646        is_supported = wutils.check_available_channels_in_bands_2_5(
647            self.dut, wutils.WifiEnums.CountryCode.US)
648        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
649
650        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
651        self.enable_bridged_ap(self.dut,
652                               WifiEnums.SoftApSecurityType.WPA3_SAE,
653                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
654                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
655        self.verify_number_band_freq_of_bridged_ap(
656            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
657                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
658
659        self.sniffing_ap_channels(channel1=None, channel2=132)
660        self.start_ap(channel_2g=None, channel_5g=132)
661        wutils.wifi_toggle_state(self.dut, True)
662        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G])
663
664        self.verify_number_band_freq_of_bridged_ap(
665            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
666
667        # Restore config
668        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
669
670    @test_tracker_info(uuid="9a5d4ca9-67fc-412c-8114-01c43c34a76d")
671    def test_bridged_ap_5g_2g_and_sta_5g_non_dfs(self):
672        """Test 5G scc when BridgedAp enabled and 5G STA.
673
674        Steps:
675            Backup config.
676            DUT enable BridgedAp.
677            start sniffer and sniffing on AP channels.
678            DUT connect to a 5G non-DFS channel Wi-Fi network.
679            Verify STA frequency equals to 5G BridgedAp frequency.
680            Stop sniffers.
681            Restore config.
682        """
683        # Backup config
684        original_softap_config = self.dut.droid.wifiGetApConfiguration()
685
686        # Make sure DUT is able to enable BridgedAp.
687        is_supported = wutils.check_available_channels_in_bands_2_5(
688            self.dut, wutils.WifiEnums.CountryCode.US)
689        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
690
691        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
692        self.enable_bridged_ap(self.dut,
693                               WifiEnums.SoftApSecurityType.WPA3_SAE,
694                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
695                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
696        self.verify_number_band_freq_of_bridged_ap(
697            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
698                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
699
700        self.sniffing_ap_channels(channel1=None, channel2=36)
701        self.start_ap(channel_2g=None, channel_5g=36)
702        wutils.wifi_toggle_state(self.dut, True)
703        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G])
704
705        self.verify_number_band_freq_of_bridged_ap(
706            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
707                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], True)
708
709        # Restore config
710        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
711
712    @test_tracker_info(uuid="e26e8a72-3e21-47b3-8fd8-4c4db5fb2573")
713    def test_bridged_ap_5g_2g_and_sta_2g(self):
714        """ Test 2G SCC when BridgedAp enable and 2G STA.
715
716        Steps:
717            Backup config.
718            DUT enable BridgedAp.
719            start sniffer and sniffing on AP channels.
720            STA connect to a 2G Wi-Fi network.
721            Verify STA frequency equals to 2G BridgedAp frequency.
722            Stop sniffers.
723            Restore config.
724        """
725        # Backup config
726        original_softap_config = self.dut.droid.wifiGetApConfiguration()
727
728        # Make sure DUT is able to enable BridgedAp.
729        is_supported = wutils.check_available_channels_in_bands_2_5(
730            self.dut, wutils.WifiEnums.CountryCode.US)
731        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
732
733        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
734        self.enable_bridged_ap(self.dut,
735                               WifiEnums.SoftApSecurityType.WPA3_SAE,
736                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
737                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
738        self.verify_number_band_freq_of_bridged_ap(
739            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
740                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
741
742        self.sniffing_ap_channels(channel1=6, channel2=None)
743        self.start_ap(channel_2g=6, channel_5g=None)
744        wutils.wifi_toggle_state(self.dut, True)
745        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_2G])
746
747        self.verify_number_band_freq_of_bridged_ap(
748            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
749                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], True)
750
751        # Restore config
752        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
753
754    @test_tracker_info(uuid="b25f710a-2e53-456e-8280-dcdd37badd6c")
755    def test_sta_5g_dfs_and_bridged_ap_5g_2g(self):
756        """Test auto fallback to Single AP mode
757           when STA connect to a DFS channel.
758
759        Steps:
760            Backup config.
761            start sniffer and sniffing on AP channels.
762            Enable a Wi-Fi network.
763            DUT connect to a 5G DFS channel Wi-Fi network.
764            DUT enable BridgedAp.
765            Verify 5G instance is shutdown and only 2G instance enabled.
766            Stop sniffers.
767            Restore config.
768        """
769        # Backup config
770        original_softap_config = self.dut.droid.wifiGetApConfiguration()
771
772        # Make sure DUT is able to enable BridgedAp.
773        is_supported = wutils.check_available_channels_in_bands_2_5(
774            self.dut, wutils.WifiEnums.CountryCode.US)
775        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
776
777        self.sniffing_ap_channels(channel1=None, channel2=132)
778        self.start_ap(channel_2g=None, channel_5g=132)
779        wutils.wifi_toggle_state(self.dut, True)
780        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G])
781
782        # Enable BridgedAp
783        self.enable_bridged_ap(self.dut,
784                               WifiEnums.SoftApSecurityType.WPA3_SAE,
785                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
786                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
787        # # Verify only 2G instance enabled.
788        self.verify_number_band_freq_of_bridged_ap(
789            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
790
791        # Restore config
792        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
793
794    @test_tracker_info(uuid="6acaed3f-616f-4a03-a329-702e6cc537bd")
795    def test_sta_5g_non_dfs_and_bridged_ap_5g_2g(self):
796        """Test 5G scc when 5G STA and BridgedAp enabled.
797
798        Steps:
799            Backup config.
800            start sniffer and sniffing on AP channels.
801            Enable a Wi-Fi network.
802            DUT connect to a 5G non-DFS channel Wi-Fi network.
803            DUT enable BridgedAp.
804            Verify STA frequency equals to 5G BridgedAp frequency.
805            Stop sniffers.
806            Restore config.
807        """
808        # Backup config
809        original_softap_config = self.dut.droid.wifiGetApConfiguration()
810
811        # Make sure DUT is able to enable BridgedAp.
812        is_supported = wutils.check_available_channels_in_bands_2_5(
813            self.dut, wutils.WifiEnums.CountryCode.US)
814        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
815
816        self.sniffing_ap_channels(channel1=None, channel2=36)
817        self.start_ap(channel_2g=None, channel_5g=36)
818        wutils.wifi_toggle_state(self.dut, True)
819        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G])
820
821        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
822        self.enable_bridged_ap(self.dut,
823                               WifiEnums.SoftApSecurityType.WPA3_SAE,
824                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
825                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
826        # Verify STA frequency equals to 5G BridgedAp frequency.
827        self.verify_number_band_freq_of_bridged_ap(
828            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
829                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], True)
830
831        # Restore config
832        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
833
834    @test_tracker_info(uuid="e24e7f2d-f1d5-4dc7-aa6a-487677864d1d")
835    def test_sta_2g_and_bridged_ap_5g_2g(self):
836        """ Test 2G SCC when 2G STA and BridgedAp enable.
837
838        Steps:
839            Backup config.
840            start sniffer and sniffing on AP channels.
841            Enable a Wi-Fi network.
842            DUT connect to a 2G Wi-Fi network.
843            DUT enable BridgedAp.
844            Verify STA frequency equals to 2G BridgedAp frequency.
845            Stop sniffers.
846            Restore config.
847        """
848        # Backup config
849        original_softap_config = self.dut.droid.wifiGetApConfiguration()
850
851        # Make sure DUT is able to enable BridgedAp.
852        is_supported = wutils.check_available_channels_in_bands_2_5(
853            self.dut, wutils.WifiEnums.CountryCode.US)
854        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
855
856        self.sniffing_ap_channels(channel1=6, channel2=None)
857        self.start_ap(channel_2g=6, channel_5g=None)
858        wutils.wifi_toggle_state(self.dut, True)
859        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_2G])
860
861        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
862        self.enable_bridged_ap(self.dut,
863                               WifiEnums.SoftApSecurityType.WPA3_SAE,
864                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
865                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
866        self.verify_number_band_freq_of_bridged_ap(
867            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
868                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], True)
869
870        # Restore config
871        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
872
873    @test_tracker_info(uuid="927d564d-2ac4-4e6f-bb36-270efd519e0b")
874    def test_bridged_ap_5g_2g_shutdown_5g_2g_no_client(self):
875        """Test the BridgeAp shutdown mechanism with no client connect to it.
876
877        Steps:
878            Backup config.
879            DUT turns ON BridgedAp.
880            Verify no client connect to the BridgedAp.
881            Wait for 5 minutes.
882            Verify that 5G BridgedAp instance is shutdown.
883            Maks sure there is still no client connect to the BridgedAp.
884            Wait for 5 minutes.
885            Verify that 2G BridgedAp instance is shutdown.
886            Restore config.
887        """
888        # Backup config
889        original_softap_config = self.dut.droid.wifiGetApConfiguration()
890
891        # Make sure DUT is able to enable BridgedAp.
892        is_supported = wutils.check_available_channels_in_bands_2_5(
893            self.dut, wutils.WifiEnums.CountryCode.US)
894        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
895
896        # Simulate the unplugged scenario
897        self.dut.adb.shell("cmd battery unplug")
898        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
899        self.enable_bridged_ap(self.dut,
900                               WifiEnums.SoftApSecurityType.WPA3_SAE,
901                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
902                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
903        infos = self.verify_number_band_freq_of_bridged_ap(
904            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
905                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
906
907        # No client connection, wait 5 minutes, verify 5G is shutdown.
908        self.verify_expected_number_of_softap_clients(self.dut, 0)
909        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
910        self.verify_number_band_freq_of_bridged_ap(
911            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
912        # No client connection, wait 5 minutes, verify 2G is shutdown.
913        self.verify_expected_number_of_softap_clients(self.dut, 0)
914        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
915
916        self.verify_number_band_freq_of_bridged_ap(self.dut, [], False)
917
918        # Restore config
919        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
920
921    @test_tracker_info(uuid="4c5b210c-412f-40e4-84b6-2a12dbffa017")
922    def test_bridged_ap_5g_2g_shutdown_5g_auto_shutdown_2g(self):
923        """Test the BridgeAp shutdown mechanism with no client connect to it.
924
925        Steps:
926            Backup config.
927            DUT turns ON BridgedAp.
928            start sniffer and sniffing on BridgedAp channels.
929            Verify no client connect to the BridgedAp.
930            Wait for 5 minutes.
931            Verify that 5G BridgedAp instance is shutdown.
932            A client connect to the 2G BridgedAp.
933            The client disconnect from 2G BridgedAp.
934            Wait for 10 minutes.
935            Verify 2G BridgedAp is shutdown, no BridgedAp instance enabled.
936            Stop sniffers.
937            Restore config.
938        """
939        # Backup config
940        original_softap_config = self.dut.droid.wifiGetApConfiguration()
941
942        # Make sure DUT is able to enable BridgedAp.
943        is_supported = wutils.check_available_channels_in_bands_2_5(
944            self.dut, wutils.WifiEnums.CountryCode.US)
945        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
946
947        # Simulate the unplugged scenario
948        self.dut.adb.shell("cmd battery unplug")
949        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
950        self.enable_bridged_ap(self.dut,
951                               WifiEnums.SoftApSecurityType.WPA3_SAE,
952                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
953                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
954        infos = self.verify_number_band_freq_of_bridged_ap(
955            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
956                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
957
958        self.sniffing_bridgedap_channels(infos)
959
960        # Verify no connection to BridgedAp, wait for 5 mins, 5G shutdown.
961        self.verify_expected_number_of_softap_clients(self.dut, 0)
962        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
963        self.verify_number_band_freq_of_bridged_ap(
964            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
965
966        # A client connect to 2G BridgedAp instance.
967        callbackId = self.dut.droid.registerSoftApCallback()
968        infos = wutils.get_current_softap_infos(self.dut, callbackId, True)
969        self.dut.droid.unregisterSoftApCallback(callbackId)
970        bssid_2g = infos[0][wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
971        config_2g = self.config.copy()
972        config_2g[WifiEnums.BSSID_KEY] = bssid_2g
973        wutils.connect_to_wifi_network(self.client1, config_2g,
974                                       check_connectivity=False)
975        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_SECONDS)
976
977        # Client disconnect From 2G BridgedAp instance.
978        is_disconnect = self.client1.droid.wifiDisconnect()
979        self.client1.log.info("Disconnected from SoftAp")
980        if not is_disconnect:
981            raise signals.TestFailure("Wi-Fi is not disconnected as expect")
982        wutils.reset_wifi(self.client1)
983
984        # Verify 2G instance is still enabled.
985        self.wait_interval(INTERVAL_9_MINUTES)
986        self.verify_number_band_freq_of_bridged_ap(
987            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
988
989        # Verify all BridgedAp instances are shutdown after 10 minutes.
990        self.wait_interval(INTERVAL_1_MINUTES)
991        self.verify_number_band_freq_of_bridged_ap(self.dut, [], False)
992
993        # Restore config
994        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
995
996    @test_tracker_info(uuid="2b1b4579-d610-4983-83f4-5fc34b3cdd6b")
997    def test_bridged_ap_5g_2g_shutdown_5g_auto_shutdown_2g_after_10_mins(self):
998        """Test the BridgeAp shutdown mechanism with no client connect to it.
999
1000        Steps:
1001            Backup config.
1002            DUT turns ON BridgedAp.
1003            start sniffer and sniffing on BridgedAp channels.
1004            Verify no client connect to the BridgedAp.
1005            Wait for 5 minutes.
1006            Verify that 5G BridgedAp instance is shutdown.
1007            A client connect to the 2G BridgedAp at 7th minutes.
1008            The client disconnect from 2G BridgedAp at 9th minutes.
1009            Wait for 10 minutes.
1010            Verify 2G BridgedAp is shutdown, no BridgedAp instance enabled.
1011            Stop sniffers.
1012            Restore config.
1013        """
1014        # Backup config
1015        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1016
1017        # Make sure DUT is able to enable BridgedAp.
1018        is_supported = wutils.check_available_channels_in_bands_2_5(
1019            self.dut, wutils.WifiEnums.CountryCode.US)
1020        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
1021
1022        # Simulate the unplugged scenario
1023        self.dut.adb.shell("cmd battery unplug")
1024        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
1025        self.enable_bridged_ap(self.dut,
1026                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1027                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1028                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G],
1029                               bridged_opportunistic_shutdown_enabled=True,
1030                               shutdown_timeout_enable=True)
1031        infos = self.verify_number_band_freq_of_bridged_ap(
1032            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1033                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1034
1035        self.sniffing_bridgedap_channels(infos)
1036
1037        self.verify_expected_number_of_softap_clients(self.dut, 0)
1038        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
1039        self.verify_number_band_freq_of_bridged_ap(
1040            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
1041
1042        # Client connects to 2G instance at 7th mins.
1043        self.wait_interval(INTERVAL_2_MINUTES)
1044        callbackId = self.dut.droid.registerSoftApCallback()
1045        infos = wutils.get_current_softap_infos(self.dut, callbackId, True)
1046        self.dut.droid.unregisterSoftApCallback(callbackId)
1047        bssid_2g = infos[0][wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
1048        config_2g = self.config.copy()
1049        config_2g[WifiEnums.BSSID_KEY] = bssid_2g
1050        wutils.connect_to_wifi_network(self.client1, config_2g,
1051                                       check_connectivity=False)
1052        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_SECONDS)
1053
1054        # Client disconnect From 2G BridgedAp instance at 9th mins.
1055        self.wait_interval(INTERVAL_2_MINUTES)
1056        is_disconnect = self.client1.droid.wifiDisconnect()
1057        self.client1.log.info("Disconnected from SoftAp")
1058        if not is_disconnect:
1059            raise signals.TestFailure("Wi-Fi is not disconnected as expect")
1060        wutils.reset_wifi(self.client1)
1061
1062        # Make sure 2G instance is still enabled.
1063        self.wait_interval(INTERVAL_9_MINUTES)
1064        self.verify_number_band_freq_of_bridged_ap(
1065            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
1066
1067        self.wait_interval(INTERVAL_1_MINUTES)
1068        self.verify_number_band_freq_of_bridged_ap(self.dut, [], False)
1069
1070        # Restore config
1071        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1072
1073    @test_tracker_info(uuid="1785a487-dd95-4c17-852d-3c9b7b7dd4c3")
1074    def test_bridged_ap_5g_2g_fallback_2g_country_jp(self):
1075        """Test BridgedAp fallback to Single AP mode with JP country code.
1076
1077        Steps:
1078            Backup config.
1079            Set DUT country code to "JP".
1080            DUT turns ON BridgedAp.
1081            Verify only 2G BridgedAp instance is enabled.
1082            Restore config.
1083        """
1084        asserts.skip_if(not self.dut.droid.wifiIsBridgedApConcurrencySupported(),
1085                        "DUT %s doesn't support bridged AP." %  (self.dut.model))
1086        # Backup config
1087        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1088
1089        # Set country code to JP and enable BridgedAp
1090        self.set_country_code_and_verify(self.dut, WifiEnums.CountryCode.JAPAN)
1091
1092        # Enable BridgedAp
1093        self.enable_bridged_ap(self.dut,
1094                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1095                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1096                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
1097        # Verify only 2G BridgedAp instance enabled.
1098        infos = self.verify_number_band_freq_of_bridged_ap(
1099            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
1100        self.sniffing_bridgedap_channels(infos)
1101
1102        # Restore config
1103        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1104
1105    @test_tracker_info(uuid="b5c7c6df-b181-4bba-a7b3-48fad0d7fa98")
1106    def test_bridged_ap_5g_2g_shutdown_2g_after_5_minutes(self):
1107        """Test the BridgeAp shutdown mechanism.
1108
1109        Steps:
1110            Backup config.
1111            DUT turns ON BridgedAp.
1112            start sniffer and sniffing on BridgedAp channels.
1113            A Client connect to BridgeAp 5G instance.
1114            Wait for 5 minutes.
1115            Verify 2G instance is shutdown and only 5G instance exists.
1116            Stop sniffers.
1117            Restore config."""
1118        # Backup config
1119        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1120
1121        # Make sure DUT is able to enable BridgedAp.
1122        is_supported = wutils.check_available_channels_in_bands_2_5(
1123            self.dut, wutils.WifiEnums.CountryCode.US)
1124        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
1125
1126        # Simulate the unplugged scenario
1127        self.dut.adb.shell("cmd battery unplug")
1128        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
1129        self.enable_bridged_ap(self.dut,
1130                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1131                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1132                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
1133        infos = self.verify_number_band_freq_of_bridged_ap(
1134            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1135                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1136
1137        self.sniffing_bridgedap_channels(infos)
1138
1139        # Client connects to the 5G BridgedAp instance.
1140        self.client_connects_to_a_bridgeap(self.client1, BAND_5G)
1141        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
1142        # Verify there is only one client connects to the BridgedAp.
1143        self.verify_expected_number_of_softap_clients(self.dut, 1)
1144        # Verify the BridgedAp instance is 5G.
1145        self.verify_number_band_freq_of_bridged_ap(
1146            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1147        # Restore config
1148        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1149
1150    @test_tracker_info(uuid="683b2c7f-7f24-4324-be09-0b6554d5d7a8")
1151    def test_bridged_ap_5g_2g_shutdown_5g_after_5_minutes(self):
1152        """Test the BridgeAp shutdown mechanism.
1153
1154        Steps:
1155            Backup config.
1156            DUT turns ON BridgedAp.
1157            start sniffer and sniffing on BridgedAp channels.
1158            A Client connect to BridgeAp 2G instance.
1159            Wait for 5 minutes.
1160            Verify 5G instance is shutdown and only 2G instance exists.
1161            Stop sniffers.
1162            Restore config."""
1163        # Backup config
1164        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1165
1166        # Make sure DUT is able to enable BridgedAp.
1167        is_supported = wutils.check_available_channels_in_bands_2_5(
1168            self.dut, wutils.WifiEnums.CountryCode.US)
1169        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
1170
1171        # Simulate the unplugged scenario
1172        self.dut.adb.shell("cmd battery unplug")
1173        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
1174        self.enable_bridged_ap(self.dut,
1175                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1176                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1177                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
1178        infos = self.verify_number_band_freq_of_bridged_ap(
1179            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1180                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1181        self.sniffing_bridgedap_channels(infos)
1182
1183        # Client connects to the 2G BridgedAp instance.
1184        self.client_connects_to_a_bridgeap(self.client1, BAND_2G)
1185        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
1186        # Verify there is only one client connects to the BridgedAp.
1187        self.verify_expected_number_of_softap_clients(self.dut, 1)
1188        # Verify the BridgedAp instance is 2G.
1189        self.verify_number_band_freq_of_bridged_ap(
1190            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False)
1191        # Restore config
1192        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1193
1194    @test_tracker_info(uuid="6de46e5b-04c3-4fba-a21d-e914a3e34e24")
1195    def test_bridged_ap_5g_2g_no_shutdown_after_5_minutes(self):
1196        """Test clients on different instances can ping each other.
1197
1198        Steps:
1199            Backup config.
1200            Make sure clients support WPA3 SAE.
1201            Make sure DUT is able to enable BridgedAp.
1202            Enable BridgedAp with bridged configuration.
1203            RegisterSoftApCallback.
1204            Check the bridged AP enabled succeed.
1205            start sniffer and sniffing on BridgedAp channels.
1206            Client#1 connect to 5G instance.
1207            Client#2 connect to 2G instance.
1208            Wait for 5 minutes.
1209            Verify both 2G/5G BridgedAp instances are exist.
1210            Stop sniffers.
1211            Restore config.
1212        """
1213        # Backup config
1214        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1215        # Make sure clients support WPA3 SAE.
1216        self.verify_clients_support_wpa3_sae(self.client1, self.client2)
1217        # Make sure DUT is able to enable BridgedAp.
1218        is_supported = wutils.check_available_channels_in_bands_2_5(
1219            self.dut, wutils.WifiEnums.CountryCode.US)
1220        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
1221
1222        # Simulate the unplugged scenario
1223        self.dut.adb.shell("cmd battery unplug")
1224        # Enable BridgedAp and verify both 2G,5G instances have been enabled.
1225        self.enable_bridged_ap(self.dut,
1226                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1227                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1228                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
1229        infos = self.verify_number_band_freq_of_bridged_ap(
1230            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1231                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1232
1233        self.sniffing_bridgedap_channels(infos)
1234
1235        self.two_clients_connect_to_wifi_network(self.client1, self.client2,
1236                                                 self.config)
1237        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
1238        # Verify there are two clients connect to the BridgedAp.
1239        self.verify_expected_number_of_softap_clients(self.dut, 2)
1240        # Verify both 2G/5G BridgedAp instances are exist.
1241        self.verify_number_band_freq_of_bridged_ap(
1242            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1243                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1244        # Restore config
1245        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1246
1247    @test_tracker_info(uuid="f8742dfb-5232-4fe8-b568-3a99a9356d59")
1248    def test_bridged_ap_5g_2g_extend_compatibility_on_no_shutdown_5g(self):
1249        """Test BridgedAp mechanism when "Extend compatibility is ON.
1250
1251        Steps:
1252            Backup config.
1253            Make sure clients support WPA3 SAE.
1254            Make sure DUT is able to enable BridgedAp.
1255            Enable BridgedAp with Extend compatibility is ON.
1256            RegisterSoftApCallback.
1257            Check the bridged AP enabled succeed.
1258            start sniffer and sniffing on BridgedAp channels.
1259            Client#1 connect to 2G.
1260            Verify both 2G/5G instances are exist.
1261            Stop sniffers.
1262            Restore config.
1263        """
1264        # Backup config
1265        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1266        # Make sure clients support WPA3 SAE.
1267        self.verify_clients_support_wpa3_sae(self.client1, self.client2)
1268        # Make sure DUT is able to enable BridgedAp.
1269        is_supported = wutils.check_available_channels_in_bands_2_5(
1270            self.dut, wutils.WifiEnums.CountryCode.US)
1271        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
1272
1273        # Simulate the unplugged scenario
1274        self.dut.adb.shell("cmd battery unplug")
1275        # Enable BridgedAp with "Extend compatibility set to ON".
1276        self.enable_bridged_ap(self.dut,
1277                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1278                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1279                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G],
1280                               bridged_opportunistic_shutdown_enabled=False)
1281        # Client connects to the 2G BridgedAp instance and wait 5 minutes.
1282        self.client_connects_to_a_bridgeap(self.client1, BAND_2G)
1283        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
1284        # Verify both 2G/5G BridgedAp instances exist.
1285        self.verify_number_band_freq_of_bridged_ap(
1286            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1287                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1288        # Restore config
1289        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1290
1291    @test_tracker_info(uuid="050f8dd8-ed38-4f7a-87a9-9dbdade58cc7")
1292    def test_bridged_ap_5g_2g_extend_compatibility_on_no_shutdown_2g(self):
1293        """Test BridgedAp mechanism when "Extend compatibility is ON.
1294
1295        Steps:
1296            Backup config.
1297            Make sure clients support WPA3 SAE.
1298            Make sure DUT is able to enable BridgedAp.
1299            Enable BridgedAp with Extend compatibility is ON.
1300            RegisterSoftApCallback.
1301            Check the bridged AP enabled succeed.
1302            start sniffer and sniffing on BridgedAp channels.
1303            Client#1 connect to 5G.
1304            Verify both 2G/5G instances are exist.
1305            Stop sniffers.
1306            Restore config.
1307        """
1308        # Backup config
1309        original_softap_config = self.dut.droid.wifiGetApConfiguration()
1310        # Make sure clients support WPA3 SAE.
1311        self.verify_clients_support_wpa3_sae(self.client1, self.client2)
1312        # Make sure DUT is able to enable BridgedAp.
1313        is_supported = wutils.check_available_channels_in_bands_2_5(
1314            self.dut, wutils.WifiEnums.CountryCode.US)
1315        asserts.skip_if(not is_supported, "BridgedAp is not supported.")
1316
1317        # Simulate the unplugged scenario
1318        self.dut.adb.shell("cmd battery unplug")
1319        # Enable BridgedAp with "Extend compatibility set to ON".
1320        self.enable_bridged_ap(self.dut,
1321                               WifiEnums.SoftApSecurityType.WPA3_SAE,
1322                               bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1323                                      WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G],
1324                               bridged_opportunistic_shutdown_enabled=False)
1325        # Client connects to the 5G BridgedAp instance and wait 5 minutes.
1326        self.client_connects_to_a_bridgeap(self.client1, BAND_5G)
1327        self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES)
1328        # Verify both 2G/5G BridgedAp instances exist.
1329        self.verify_number_band_freq_of_bridged_ap(
1330            self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
1331                       WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False)
1332        # Restore config
1333        wutils.save_wifi_soft_ap_config(self.dut, original_softap_config)
1334