1# Copyright (C) 2024 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# 15# Licensed under the Apache License, Version 2.0 (the "License"); 16# you may not use this file except in compliance with the License. 17# You may obtain a copy of the License at 18# 19# http://www.apache.org/licenses/LICENSE-2.0 20# 21# Unless required by applicable law or agreed to in writing, software 22# distributed under the License is distributed on an "AS IS" BASIS, 23# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24# See the License for the specific language governing permissions and 25# limitations under the License. 26 27import base64 28import uuid 29 30from mobly import asserts 31from mobly.controllers import android_device 32 33 34class UpstreamType: 35 CELLULAR = 1 36 WIFI = 2 37 38 39def generate_uuid32_base64() -> str: 40 """Generates a UUID32 and encodes it in Base64. 41 42 Returns: 43 str: The Base64-encoded UUID32 string. Which is 22 characters. 44 """ 45 # Strip padding characters to make it safer for hotspot name length limit. 46 return base64.b64encode(uuid.uuid1().bytes).decode("utf-8").strip("=") 47 48 49def assume_hotspot_test_preconditions( 50 server_device: android_device, 51 client_device: android_device, 52 upstream_type: UpstreamType, 53) -> None: 54 server = server_device.connectivity_multi_devices_snippet 55 client = client_device.connectivity_multi_devices_snippet 56 57 # Assert pre-conditions specific to each upstream type. 58 asserts.skip_if(not client.hasWifiFeature(), "Client requires Wifi feature") 59 asserts.skip_if( 60 not server.hasHotspotFeature(), "Server requires hotspot feature" 61 ) 62 if upstream_type == UpstreamType.CELLULAR: 63 asserts.skip_if( 64 not server.hasTelephonyFeature(), "Server requires Telephony feature" 65 ) 66 elif upstream_type == UpstreamType.WIFI: 67 asserts.skip_if( 68 not server.isStaApConcurrencySupported(), 69 "Server requires Wifi AP + STA concurrency", 70 ) 71 else: 72 raise ValueError(f"Invalid upstream type: {upstream_type}") 73 74 75def setup_hotspot_and_client_for_upstream_type( 76 server_device: android_device, 77 client_device: android_device, 78 upstream_type: UpstreamType, 79) -> (str, int): 80 """Setup the hotspot with a connected client with the specified upstream type. 81 82 This creates a hotspot, make the client connect 83 to it, and verify the packet is forwarded by the hotspot. 84 And returns interface name of both if successful. 85 """ 86 server = server_device.connectivity_multi_devices_snippet 87 client = client_device.connectivity_multi_devices_snippet 88 89 if upstream_type == UpstreamType.CELLULAR: 90 server.requestCellularAndEnsureDefault() 91 elif upstream_type == UpstreamType.WIFI: 92 server.ensureWifiIsDefault() 93 else: 94 raise ValueError(f"Invalid upstream type: {upstream_type}") 95 96 # Generate ssid/passphrase with random characters to make sure nearby devices won't 97 # connect unexpectedly. Note that total length of ssid cannot go over 32. 98 test_ssid = "HOTSPOT-" + generate_uuid32_base64() 99 test_passphrase = generate_uuid32_base64() 100 101 # Create a hotspot with fixed SSID and password. 102 hotspot_interface = server.startHotspot(test_ssid, test_passphrase) 103 104 # Make the client connects to the hotspot. 105 client_network = client.connectToWifi(test_ssid, test_passphrase) 106 107 return hotspot_interface, client_network 108 109 110def cleanup_tethering_for_upstream_type( 111 server_device: android_device, upstream_type: UpstreamType 112) -> None: 113 server = server_device.connectivity_multi_devices_snippet 114 if upstream_type == UpstreamType.CELLULAR: 115 server.unregisterAll() 116 # Teardown the hotspot. 117 server.stopAllTethering() 118