blob: a2d703ca5612d7d23804eb91f9a5560c6bdd405c [file] [log] [blame]
# Copyright (C) 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import base64
import uuid
from mobly import asserts
from mobly.controllers import android_device
class UpstreamType:
CELLULAR = 1
WIFI = 2
def generate_uuid32_base64() -> str:
"""Generates a UUID32 and encodes it in Base64.
Returns:
str: The Base64-encoded UUID32 string. Which is 22 characters.
"""
# Strip padding characters to make it safer for hotspot name length limit.
return base64.b64encode(uuid.uuid1().bytes).decode("utf-8").strip("=")
def setup_hotspot_and_client_for_upstream_type(
server_device: android_device,
client_device: android_device,
upstream_type: UpstreamType,
) -> (str, int):
"""Setup the hotspot with a connected client with the specified upstream type.
This creates a hotspot, make the client connect
to it, and verify the packet is forwarded by the hotspot.
And returns interface name of both if successful.
"""
server = server_device.connectivity_multi_devices_snippet
client = client_device.connectivity_multi_devices_snippet
# Assert pre-conditions specific to each upstream type.
asserts.skip_if(not client.hasWifiFeature(), "Client requires Wifi feature")
asserts.skip_if(
not server.hasHotspotFeature(), "Server requires hotspot feature"
)
if upstream_type == UpstreamType.CELLULAR:
asserts.skip_if(
not server.hasTelephonyFeature(), "Server requires Telephony feature"
)
server.requestCellularAndEnsureDefault()
elif upstream_type == UpstreamType.WIFI:
asserts.skip_if(
not server.isStaApConcurrencySupported(),
"Server requires Wifi AP + STA concurrency",
)
server.ensureWifiIsDefault()
else:
raise ValueError(f"Invalid upstream type: {upstream_type}")
# Generate ssid/passphrase with random characters to make sure nearby devices won't
# connect unexpectedly. Note that total length of ssid cannot go over 32.
test_ssid = "HOTSPOT-" + generate_uuid32_base64()
test_passphrase = generate_uuid32_base64()
# Create a hotspot with fixed SSID and password.
hotspot_interface = server.startHotspot(test_ssid, test_passphrase)
# Make the client connects to the hotspot.
client_network = client.connectToWifi(test_ssid, test_passphrase)
return hotspot_interface, client_network
def cleanup_tethering_for_upstream_type(
server_device: android_device, upstream_type: UpstreamType
) -> None:
server = server_device.connectivity_multi_devices_snippet
if upstream_type == UpstreamType.CELLULAR:
server.unrequestCellular()
# Teardown the hotspot.
server.stopAllTethering()