1 /* 2 * Copyright (C) 2018 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 com.android.settings.wifi.dpp; 18 19 import android.annotation.NonNull; 20 import android.net.wifi.UriParserResults; 21 import android.net.wifi.WifiConfiguration; 22 import android.net.wifi.WifiUriParser; 23 import android.text.TextUtils; 24 import android.util.Log; 25 26 /** 27 * Supports to parse 2 types of QR code 28 * 29 * 1. Standard Wi-Fi DPP bootstrapping information or 30 * 2. ZXing reader library's Wi-Fi Network config format described in 31 * https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11 32 * 33 * ZXing reader library's Wi-Fi Network config format example: 34 * 35 * WIFI:T:WPA;S:mynetwork;P:mypass;; 36 * 37 * parameter Example Description 38 * T WPA Authentication type; can be WEP or WPA, or 'nopass' for no password. Or, 39 * omit for no password. 40 * S mynetwork Network SSID. Required. Enclose in double quotes if it is an ASCII name, 41 * but could be interpreted as hex (i.e. "ABCD") 42 * P mypass Password, ignored if T is "nopass" (in which case it may be omitted). 43 * Enclose in double quotes if it is an ASCII name, but could be interpreted as 44 * hex (i.e. "ABCD") 45 * H true Optional. True if the network SSID is hidden. 46 * 47 */ 48 public class WifiQrCode { 49 private static final String TAG = "WifiQrCode"; 50 static final String SCHEME_DPP = "DPP"; 51 static final String SCHEME_ZXING_WIFI_NETWORK_CONFIG = "WIFI"; 52 static final String PREFIX_DPP = "DPP:"; 53 static final String PREFIX_ZXING_WIFI_NETWORK_CONFIG = "WIFI:"; 54 55 static final String PREFIX_DPP_PUBLIC_KEY = "K:"; 56 static final String PREFIX_DPP_INFORMATION = "I:"; 57 58 static final String PREFIX_ZXING_SECURITY = "T:"; 59 static final String PREFIX_ZXING_SSID = "S:"; 60 static final String PREFIX_ZXING_PASSWORD = "P:"; 61 static final String PREFIX_ZXING_HIDDEN_SSID = "H:"; 62 63 static final String DELIMITER_QR_CODE = ";"; 64 65 // Ignores password if security is SECURITY_NO_PASSWORD or absent 66 static final String SECURITY_NO_PASSWORD = "nopass"; //open network or OWE 67 static final String SECURITY_WEP = "WEP"; 68 static final String SECURITY_WPA_PSK = "WPA"; 69 static final String SECURITY_SAE = "SAE"; 70 71 private String mQrCode; 72 @NonNull 73 private UriParserResults mUriParserResults; 74 WifiQrCode(String qrCode)75 public WifiQrCode(String qrCode) throws IllegalArgumentException { 76 if (TextUtils.isEmpty(qrCode)) { 77 throw new IllegalArgumentException("Empty QR code"); 78 } 79 80 mQrCode = qrCode; 81 try { 82 mUriParserResults = WifiUriParser.parseUri(mQrCode); 83 Log.i("WifiQrCode", "mUriParserResults = " + mUriParserResults); 84 } catch (IllegalArgumentException ie) { 85 throw new IllegalArgumentException("Invalid scheme"); 86 } 87 } 88 getQrCode()89 String getQrCode() { 90 return mQrCode; 91 } 92 93 /** 94 * Uses to check type of QR code 95 * 96 * SCHEME_DPP for standard Wi-Fi device provision protocol; SCHEME_ZXING_WIFI_NETWORK_CONFIG 97 * for ZXing reader library' Wi-Fi Network config format 98 */ getScheme()99 public int getScheme() { 100 return mUriParserResults.getUriScheme(); 101 } 102 103 /** Available when {@code getScheme()} returns SCHEME_DPP */ getPublicKey()104 String getPublicKey() { 105 return mUriParserResults.getPublicKey(); 106 } 107 108 /** May be available when {@code getScheme()} returns SCHEME_DPP */ getInformation()109 public String getInformation() { 110 return mUriParserResults.getInformation(); 111 } 112 113 /** Available when {@code getScheme()} returns SCHEME_ZXING_WIFI_NETWORK_CONFIG */ getWifiConfiguration()114 WifiConfiguration getWifiConfiguration() { 115 return mUriParserResults.getWifiConfiguration(); 116 } 117 getValidWifiDppQrCodeOrNull(String qrCode)118 static WifiQrCode getValidWifiDppQrCodeOrNull(String qrCode) { 119 WifiQrCode wifiQrCode; 120 try { 121 wifiQrCode = new WifiQrCode(qrCode); 122 } catch(IllegalArgumentException e) { 123 Log.e(TAG, "Failed to create WifiQrCode!", e); 124 return null; 125 } 126 if (wifiQrCode.getScheme() != UriParserResults.URI_SCHEME_DPP) { 127 Log.e(TAG, "wifiQrCode scheme is not DPP!"); 128 return null; 129 } 130 return wifiQrCode; 131 } 132 } 133