19fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu/* 29fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Copyright (C) 2017 The Android Open Source Project 39fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 49fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Licensed under the Apache License, Version 2.0 (the "License"); 59fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * you may not use this file except in compliance with the License. 69fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * You may obtain a copy of the License at 79fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 89fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * http://www.apache.org/licenses/LICENSE-2.0 99fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 109fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Unless required by applicable law or agreed to in writing, software 119fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * distributed under the License is distributed on an "AS IS" BASIS, 129fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * See the License for the specific language governing permissions and 149fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * limitations under the License. 159fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 169fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 179fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiupackage com.android.server.wifi.hotspot2.anqp; 189fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 199fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport android.net.Uri; 209fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 219fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport java.io.ByteArrayOutputStream; 229fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport java.io.IOException; 239fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport java.nio.charset.StandardCharsets; 249fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport java.util.Arrays; 259fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport java.util.List; 269fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiuimport java.util.Locale; 279fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 289fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu/** 299fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Utility class containing test data and object for {@link OsuProviderInfo}. 309fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 319fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiupublic class OsuProviderInfoTestUtil { 329fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Test data 339fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static final List<I18Name> TEST_FRIENDLY_NAMES = 349fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu Arrays.asList(new I18Name("en", Locale.forLanguageTag("en"), "FriendlyName")); 359fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static final String TEST_SERVER_URI = "test.server.com"; 369fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static final List<Integer> TEST_METHOD_LIST = Arrays.asList(0, 1); 379fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static final List<IconInfo> TEST_ICON_INFO_LIST = 389fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu Arrays.asList(IconInfoTestUtil.TEST_ICON_INFO); 399fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static final String TEST_NAI = "network_access@test.com"; 409fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static final List<I18Name> TEST_SERVICE_DESCRIPTIONS = 419fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu Arrays.asList(new I18Name("en", Locale.forLanguageTag("en"), "Test Service")); 429fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 439fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 449fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * {@link IconInfo} object with pre-defined test data. 459fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 469fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu public static final OsuProviderInfo TEST_OSU_PROVIDER_INFO = 479fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu new OsuProviderInfo(TEST_FRIENDLY_NAMES, Uri.parse(TEST_SERVER_URI), TEST_METHOD_LIST, 489fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu TEST_ICON_INFO_LIST, TEST_NAI, TEST_SERVICE_DESCRIPTIONS); 499fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 509fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 519fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Raw bytes of icon info with pre-defined test data. 529fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 539fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu public static final byte[] TEST_OSU_PROVIDER_INFO_RAW_BYTES = getTestData(); 549fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 559fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu public static final byte[] TEST_OSU_PROVIDER_INFO_RAW_BYTES_WITH_INVALID_LENGTH = 569fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu getTestDataWithInvalidLength(); 579fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 589fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 599fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Generate and return the raw data based on pre-defined test data. 609fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 619fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @return byte[] 629fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 639fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static byte[] getTestData() { 649fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu try { 659fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu ByteArrayOutputStream out = new ByteArrayOutputStream(); 669fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu byte[] payload = getTestPayload(); 679fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeShortLE(out, payload.length); 689fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(payload); 699fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return out.toByteArray(); 709fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } catch (Exception e) { 719fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return null; 729fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 739fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 749fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 759fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 769fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Generate and return the raw data based on pre-defined test data. 779fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 789fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @return byte[] 799fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 809fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static byte[] getTestDataWithInvalidLength() { 819fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu try { 829fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu ByteArrayOutputStream out = new ByteArrayOutputStream(); 839fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu byte[] payload = getTestPayload(); 849fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Set length to less than the minimum required. 859fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeShortLE(out, OsuProviderInfo.MINIMUM_LENGTH - 1); 869fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(payload); 879fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return out.toByteArray(); 889fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } catch (Exception e) { 899fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return null; 909fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 919fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 929fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 939fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 949fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Generate and return the payload containing OSU provider test data, excluding the length 959fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * field. 969fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 979fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @return byte[] 989fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @throws IOException 999fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 1009fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static byte[] getTestPayload() throws IOException { 1019fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu ByteArrayOutputStream out = new ByteArrayOutputStream(); 1029fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1039fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Write friendly name list. 1049fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu byte[] friendlyNamesData = getI18NameListData(TEST_FRIENDLY_NAMES); 1059fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeShortLE(out, friendlyNamesData.length); 1069fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(friendlyNamesData); 1079fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1089fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Write server URI. 1099fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeByteArrayWithLength(out, TEST_SERVER_URI.getBytes(StandardCharsets.UTF_8)); 1109fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1119fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Write method list. 1129fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write((byte) TEST_METHOD_LIST.size()); 1139fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu for (Integer method : TEST_METHOD_LIST) { 1149fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write((byte) method.intValue()); 1159fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1169fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1179fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Write icon info list. 1189fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeShortLE(out, IconInfoTestUtil.TEST_ICON_INFO_RAW_BYTES.length); 1199fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(IconInfoTestUtil.TEST_ICON_INFO_RAW_BYTES); 1209fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1219fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Write NAI. 1229fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeByteArrayWithLength(out, TEST_NAI.getBytes(StandardCharsets.UTF_8)); 1239fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1249fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu // Write service descriptions. 1259fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu byte[] serviceDescriptionsData = getI18NameListData(TEST_SERVICE_DESCRIPTIONS); 1269fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu writeShortLE(out, serviceDescriptionsData.length); 1279fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(serviceDescriptionsData); 1289fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1299fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return out.toByteArray(); 1309fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1319fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1329fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static byte[] getI18NameListData(List<I18Name> nameList) throws IOException { 1339fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu ByteArrayOutputStream out = new ByteArrayOutputStream(); 1349fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu for (I18Name name : nameList) { 1359fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu byte[] data = getI18NameData(name); 1369fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write((byte) data.length); 1379fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(data); 1389fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1399fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return out.toByteArray(); 1409fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1419fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1429fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 1439fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Format the raw bytes for the given {@link I18Name}. 1449fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 1459fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @param value The {@link I18Name} to serialize 1469fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @return byte[] 1479fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @throws IOException 1489fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 1499fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static byte[] getI18NameData(I18Name value) throws IOException { 1509fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu ByteArrayOutputStream out = new ByteArrayOutputStream(); 1519fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(value.getLanguage().getBytes(StandardCharsets.US_ASCII)); 1529fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write((byte) 0); // Padding for language code. 1539fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(value.getText().getBytes(StandardCharsets.UTF_8)); 1549fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu return out.toByteArray(); 1559fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1569fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1579fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 1589fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Write the lower 2-bytes of an integer to the given output stream in Little-Endian. 1599fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 1609fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @param out The output stream to write to 1619fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @param value The integer value to write 1629fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 1639fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static void writeShortLE(ByteArrayOutputStream out, int value) { 1649fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(value & 0xFF); 1659fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write((value >> 8) & 0xFF); 1669fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1679fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu 1689fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu /** 1699fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * Write the given byte array to the given output stream, the array data is prefixed with a 1709fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * byte specifying the length of the byte array. 1719fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * 1729fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @param out The output stream to write to 1739fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @param data The byte array to write 1749fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu * @throws IOException 1759fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu */ 1769fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu private static void writeByteArrayWithLength(ByteArrayOutputStream out, byte[] data) 1779fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu throws IOException { 1789fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write((byte) data.length); 1799fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu out.write(data); 1809fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu } 1819fa8195087be42baed9f21ebdedadda9f509c7c6Peter Qiu} 182