2016-04-21 3 views
14

Начиная с Android 5.0.0 вы можете долго нажимать на соединение WiFi и записывать это соединение с тегом («Write to NFC tag»). Здесь вы можете найти источник этой операции: WriteWifiConfigToNfcDialog.java. Соответствующая линия, которая принимает соединение Wi-Fi и создает полезную нагрузку ЦНК, как представляется, здесь:Создание записи NDEF WiFi с использованием приложения/vnd.wfa.wsc в Android

String wpsNfcConfigurationToken = mWifiManager.getWpsNfcConfigurationToken(mAccessPoint.networkId);

mWifiManager является экземпляром WifiManager, однако getWpsNfcConfigurationToken не является частью API. Отслеживая этот метод, мы можем найти его фиксацию здесь: Add calls for NFC WSC token creation, который, к сожалению, не поможет. Вот где закончилось мое расследование. Edit: Я узнал следующий стек вызовов:

WifiServiceImpl.java звонки mWifiStateMachine.syncGetWpsNfcConfigurationToken(netId);

WifiStateMachine.java звонки mWifiNative.getNfcWpsConfigurationToken(netId);

WifiNative.java, наконец, есть метод

public String getNfcWpsConfigurationToken(int netId) { return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId); }

, который затем вызывает

String result = doStringCommandNative(mInterfacePrefix + command);

где doStringCommandNative делает системный вызов (не может найти код для этого никуда).

Который сейчас заканчивается расследованием.

Надеюсь, что кто-то может вмешаться и показать мне метод, который создает NdefRecord, который имеет тип application/vnd.wfa.wsc с идентификатором SSID, Password, Encryption/Auth.

Я, конечно же, проверил байты фактической записи application/vnd.wfa.wsc, созданной Android, но ручное воссоздание этого процесса с байтами кажется потенциально очень ненадежным и невероятно утомительным.

ответ

10

Ответ лежит на альянсе Wi-Fi «Техническая спецификация Wi-Fi Simple Configuration v2.0.5» (доступна для скачивания here).Android использует этот стандартный формат для настройки сетей Wi-Fi, я ошибочно предположил, что он является собственностью.

Во-первых, я создал класс-помощник NFC (метко названный NFCHelper.java), который имеет все байт-константы, необходимые для создания записи. Затем я создал хакерский метод для создания одной из двух требуемых записей. Спектр фактически бесполезен здесь, что я сделал, было проверено множество полезных тегов, которые были успешно настроены через ОС Android. Наконец, у вас должен быть механизм для добавления «Handover Select Record (NFC WKT Hs)» (см. Стр. 90 спецификации WiFi). Я считаю, что эта запись «говорит» Android зарегистрировать сеть в следующем токене.

Как создать запись о передаче обслуживания:

ndefRecords = new NdefRecord[2]; 
byte[] version = new byte[] { (0x1 << 4) | (0x2)}; 
ndefRecords[0] = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_HANDOVER_REQUEST, new byte[0], version); 
// and then obviously add the record you create with the method below. 

метод для создания маркеров конфигурации:

private NdefRecord createWifiRecord(String[] data) { 
    String ssid = data[0]; 
    String password = data[1]; 
    String auth = data[2]; 
    String crypt = data[3]; 
    byte[] authByte = getAuthBytes(auth); 
    byte[] cryptByte = getCryptBytes(crypt); 
    byte[] ssidByte = ssid.getBytes(); 
    byte[] passwordByte = password.getBytes(); 
    byte[] ssidLength = {(byte)((int)Math.floor(ssid.length()/256)), (byte)(ssid.length()%256)}; 
    byte[] passwordLength = {(byte)((int)Math.floor(password.length()/256)), (byte)(password.length()%256)}; 
    byte[] cred = {0x00, 0x36}; 
    byte[] idx = {0x00, 0x01, 0x01}; 
    byte[] mac = {0x00, 0x06}; 
    byte[] keypad = {0x00, 0x0B}; 

    byte[] payload = concat(NFCHelper.CREDENTIAL, cred, 
      NFCHelper.NETWORK_IDX, idx, 
      NFCHelper.NETWORK_NAME, ssidLength, ssidByte, 
      NFCHelper.AUTH_TYPE, NFCHelper.AUTH_WPA_PERSONAL, authByte, 
      NFCHelper.CRYPT_TYPE, NFCHelper.CRYPT_WEP, NFCHelper.CRYPT_AES_TKIP, 
      NFCHelper.NETWORK_KEY, passwordLength, passwordByte); 
      // NFCHelper.MAC_ADDRESS, mac); 
    return NdefRecord.createMime(NFC_TOKEN_MIME_TYPE, payload); 
} 

Лицензии и GIST here. Вы можете найти реализацию метода concat в любом месте сети или просто написать свой собственный.

Примечание: это довольно хакерская реализация (как вы можете заметить). Я включаю байты AES и AES/TKIP, которые я обнаружил при тестировании, которые он работал в различных сетях с использованием различных методов шифрования/аутентификации под Android 5. * Не стесняйтесь изменять прототип функции, массив String просто хорошо работал с что я делал.

Используя две записи, созданные в первом фрагменте выше, вы должны передать это в NdefMessage и записать его в свой тег.

В один прекрасный день я собираюсь писать и гораздо лучше/здраво, с графикой и т. Д., Поэтому я обновлю этот ответ.

+1

Спасибо за ответ и ваш код. Это не так сложно, как я ожидал. : D – noone

7

Звонок doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId) в конце обрабатывается модулем wpa_supplicant. Эта функция описана here. Я думаю, что фактическую реализацию этого можно найти в wps_supplicant.c.

То, что вы на самом деле пытаетесь сделать, это не то, на что конкретно зависит Android. Он определен в «Технической спецификации простой конфигурации WiFi», которую вы можете загрузить, заполнив this form. Соответствующая часть должна быть 10.1.2 Ток настройки.

NfcUtils.java имеет рабочую реализацию для этого! Есть несколько FIXME и TODO, но в целом это работает и должно дать вам довольно хорошее представление о том, что вам нужно делать.

Если вы хотите разобрать такие NdefRecords и сделать что-то с SSID и ключом, то NfcWifiProtectedSetup.java показывает, как это сделать.

+0

Прежде всего, спасибо за отслеживание 'wps_supplicant.c'. Во-вторых, хотя я не обновлял оригинальный вопрос за какое-то время, мне удалось создать Wifi-запись! Я просто был не очень доволен решением (и не слишком гордым, поскольку он довольно хаки). Я действительно приобрел копию «Технической спецификации простой конфигурации WiFi» (версия 2.0.0) и смог выполнить спецификацию - самой важной частью была запись передачи обслуживания, о которой я даже не думал. Я отправлю свой код в качестве ответа. – henrycjc

+0

@Henry У меня были некоторые проблемы с чтением и пониманием спецификации до сих пор. Поскольку я в настоящее время пытаюсь это сделать, я с нетерпением жду, как вы это сделали! – noone