- Введение в разработку nfc под android
- Изнанка работы платежных технологий на основе nfc и mst
- Listview
- Бесконтактная технология оплаты mastercard − это всех касается
- Беспроводные метки nfc
- Взаимодействие
- Запись
- Какое будущее ждёт web nfc?
- Обходные пути
- Персонализация апплетов
- Пишем свой класс для smart poster
- Пример 1. разработка nfc приложения для чтения/записи меток.
- Установка апплетов
- Установление соединения
- Чтение
Введение в разработку nfc под android
Android поддерживает NFC с помощью двух пакетов: android.nfc и android.nfc.tech.
Основными классами в android.nfc являются:
NfcManager: Устройства под Android могут быть использованы для управления любыми обнаруженными NFC адаптерами, но поскольку большинство Android устройств поддерживают только один NFC адаптер, NfcManager обычно вызывается с getDefaultAdapter для доступа к конкретному адаптеру.
NfcAdapter работает как NFC агент, подобно сетевому адаптеру на ПК. С его помощью телефон получает доступ к аппаратной части NFC для инициализации NFC соединения.
NDEF: Стандарты NFC определяют общий формат данных, называемый NFC Data Exchange Format (NDEF), способный хранить и передавать различные типы объектов, начиная с MIME и заканчивая ультра-короткими RTD-документами, такими как URL. NdefMessage и NdefRecord – два типа NDEF для определенных NFC форумом форматов данных, которые будут использоваться в коде-примере.
Tag: Когда устройство Android обнаруживает пассивный объект типа ярлыка, карты и т.д., он создает объект типа «метка», помещая его далее в целевой объект и в заключении пересылая в соответствующий процесс.
Пакет android.nfc.tech также содержит множество важных подклассов. Эти подклассы обеспечивают доступ к функциям работы с метками, включающими в себя операции чтения и записи. В зависимости от используемого типа технологий, эти классы разбиты на различные категории, такие как NfcA, NfcB, NfcF, MifareClassic и так далее.
Когда телефон со включенным NFC обнаруживает метку, система доставки автоматически создает пакет целевой информации. Если в телефоне имеется несколько приложений, способных работать с этой целевой информаций, пользователю будет показано окно с предложением выбрать одно из списка.
Здесь мы используем целевой фильтр для работы со всеми типами информации начиная с TECH_DISCOVERED до ACTION_TECH_DISCOVERED. Файл nfc_tech_filter.xml используется для всех типов, определенных в метке. Подробности можно найти в
. Рисунок ниже показывает схему действий при обнаружении метки.
Изнанка работы платежных технологий на основе nfc и mst
С учетом популярности и распространенности платежных технологий на основе NFC и имитации магнитного сигнала — MST, мы в команде платежного провайдера
Fondy
, публикуем пост, в котором описан механизм работы этих решений: от точки А (взаимодействия с платежным терминалом) до точки Б (исполнения транзакции).
По результатам выдачи Яндекса, главным вопросом пользователей на тему NFC остается «Что такое NFC и как научиться им пользоваться?». Это сильно контрастирует с тем же Google, где вопрос уже другой. Что такое NFC, там уже знают — NFC там есть в каждом домохозяйстве. Вопрос — как применить то, что дано? Что можно делать, используя NFC? Что делать обычному непродвинутому пользователю с технологией ближнего поля?
Для начала вот список нескольких смарт-устройств, совместимых с NFC: Nexus 6, Sony Xperia Z3, iPhone 6/7, Samsung Galaxy Note 4, LG G3, HTC One M9. Для любителей изучения и сравнения девайсов, вот полный список.
Очень скоро чипы NFC будут встроены в смартфоны всех производителей, и даже фитнес-трекеры будут работать на основе NFC. Apple использует данную технологию в Apple Watch, и уже сейчас вы можете оплатить товары через Apple Pay взмахом руки.
Вот так выглядит считывание карты с чипом EMV:
Для чего был сделан экскурс в EMV? Чтобы наглядно показать, что с появлением NFC почти все предшествующие шаги (действия) должны были быть каким-то образом повторены, реплицированы, перенесены в телефон или другое бесконтактное устройство.
Дальше мы поговорим о том, что такое TSM и SecureElement, которые делают NFC транзакции более безопасными. Ведь если карту не эмулировать в телефоне при помощи HCE (HostCardEmulation), тогда данные нужно где-то хранить. SecureElement как раз занят решением этой задачи.
OTA — удаленное управление элементами безопасности.
TSM — TrustedServiceManager — уникальный посредник, который владеет ключами. Это аппаратно-программный комплекс, предоставляющий технологические отношения между операторами связи и поставщиками услуг.
Ключевые услуги доверенной третьей стороны включают защищенную загрузку и менеджмент контента элемента безопасности, выполняемый при взаимодействии с провайдерами мобильных сервисов. Это могут быть банки, транспортные компании, поставщики и агрегаторы услуг. Удаленное управление приложениями, обычно выполняемое с использованием технологий беспроводной сотовой связи (over-the-air, OTA), включает установку и персонализацию приложений в элементе безопасности мобильного телефона, а также дальнейшее обслуживание установленных приложений на всем протяжении их жизненного цикла, равно как и сервисную поддержку. Подробнее о роли и месте TSM в экосистеме NFC можно прочесть здесь.
SecureElement — безопасный элемент в устройстве NFC — данные, размещенные в кошельке устройства. Это отдельный микропроцессор, отвечающий за безопасное хранение и работоспособность платежных приложений Mastercard Mobile PayPass/VisaPayWave. Либо его делают встроенным (установленным на материнской плате телефона), либо он размещен на отделяемом модуле: UICC SIM-карта/SD карта памяти.
Для более наглядного понимания ежедневного применения TSM-платформы процитируем отрывок из пресс-релиза МТС от 03 марта 2021 года:
«С появлением TSM-платформы снимается последнее инфраструктурное ограничение на пути массового развития в России NFC-сервисов — мы получим связующее звено в экосистеме NFC, единую «точку входа» для быстрого подключения широкого круга поставщиков услуг… Для пользователя наш новый технический комплекс дает возможность быстрой и безопасной загрузки «по воздуху» прямо на SIM-карту электронного образа банковских и транспортных карт, проездных билетов, карт лояльности, пропусков. Скоро абоненту МТС будет достаточно единожды получить в салоне МТС SIM-карту с поддержкой NFC, чтобы в дальнейшем оформлять дубликаты пластиковых банковских карт без визита в банк или покупать проездные билеты, получать скидочные купоны, не обращаясь в точки продаж. И все это уместится в одном смартфоне в окружении дружественного интерфейса с полной информацией обо всех доступных бесконтактных картах».
Сейчас можно сверить часы и посмотреть, насколько оправдались планы. Технологически очень даже оправдались. Воплотить удалось многое.
NFC-чипы уже настолько на слуху, что даже новость об их подкожном вживлении людям уже не новость.
До Евгения Черешнева (2 года назад россиянин вживил себе в руку NFC-биочип, «который позволит открывать двери, хранить данные, расплачиваться в кафе и многое другое») был Мартин Висмейер, известный как MrBitcoin. Он имплантировал два NFC-чипа, чтобы хранить криптовалюту. Московский инженер Влад Зайцев вшил себе чип от московской транспортной карты «Тройка»: теперь с помощью руки он оплачивает проезд в транспорте, а также открывает дверь офиса.
NFC-чипы на фото вшиты в кисти рук. Но есть и другие NFC-устройства, как, например, платежное кольцо: медицинский титан, вшитый чип (режим чтения, поддержка записи, передачи визитных карточек), брелок, стикер, наклеиваемый на гаджет, чехол для смартфонов, NFC-часы — все эти устройства будут поддерживать передачу данных при условии вшитого в них NFC-устройства, которое будет служить для передачи финансовых, либо других информационных данных.
Если раньше для защиты карты и транзакции опирались на шифрование данных на магнитной полосе карты, а потом все надежды были связаны с апплетами самого чипа, то сейчас безопасность платежных транзакций связана с токенизацией. Как NFС технология усилила и одновременно упростила метод передачи данных, так токенизация посредством NFC сильно усилила безопасность карточных транзакций.
Евгений Черешнев, побывавший на TED в Нью-Йорке, опубликовал свои размышления на тему современных биочипов (а NFC-чип, вшитый подкожно, суть биочип) в Facebook.
Человек, успешно проживший с биочипом под кожей более двух лет исходя из своего опыта вводит новый термин «цифровой ДНК». На таком фоне не покажется ли нам уже привычный NFC пережитком и технологическим рудиментом? Впрочем, пока до этого далеко.
Пока важно продолжить работу над безопасностью в сфере финансовых транзакций, в том числе, NFC-транзакций. Токенизация тут незаменимый спутник NFC-транзакций.
Токенизация — это метод защиты данных вашей карты, при котором номер карты (PAN) заменяется на виртуальный (токен), уникальный и случайно сгенерированным набор чисел. Сами токены могут быть как одноразового, так и многоразового использования. Эта технология вытекает из технологии NFC.
Токенизация позволила пользователю привязывать свои карты к мобильным кошелькам, при этом не сообщая интернет-мерчантам реальный номер карты, а подменяя его токенизированным. Таким образом, отправлять транзакции с телефона или оплачивать покупку при помощи телефона, с применением токенизации становится безопасно.
Замена реквизитов платежных карт на случайно выбранные символы/цифры (токены), которые будут сохраняться в базе магазинов, где пользователь совершает оплату, удобна для дальнейших покупок — всего лишь одним нажатием пальца вы совершаете платеж. При этом для каждого интернет-магазина может формироваться свой набор символов. Например, сервис VISAToken сначала работал только на iOS-устройствах (первой платформой для экспериментов стала Apple Pay), однако в дальнейшем токенизация стала поддерживаться и на других NFC-устройствах.
Как происходит обмен данными при использовании токена?
А вот как при этом выглядит авторизационный запрос:
Уже разработан токенизированный платежный шлюз, например, Rambus Bell ID. Он представляет собой софтверную платформу, которая управляет всеми транзакциями, совершенными посредством токенов (ключей), между эмитентами и «многоканальными» провайдерами токенизированных сервисов через единый платежный шлюз. На смену PSP (payment service providers) приходят TSP (tokenized service providers).
Платежная система VISA ввела сервис Visa Token Service для европейских банков. Основной платформой, на которой будет работать VTS, станет Apple Pay. Тем не менее, поддерживать эту систему смогут все устройства с чипом NFC. В 2021 году Mastercard запустила платформу Digital Enablement Express (Express), чтобы ускорить предоставление миллионам покупателей дополнительных возможностей при совершении безопасных электронных платежей. Сервис Express ускоряет процесс цифрового преобразования и токенизации по картам Mastercard через платформу Mastercard Digital Enablement Service (MDES). Эта технология позволит превратить любой аксессуар, гаджет или предмет бытовой техники, в устройство с функцией оплаты.
Платежная система Apple Pay использует NFC. Samsung, выстраивая свою платежную систему, опирается как на технологию NFC, так и на технологию MST (Magnetic Secure Transmission) — магнитно-безопасную передачу. Если в первой принимающие устройства должны быть оснащены NFC-приемником, то MST имитирует передаваемое магнитное поле при помощи индукционной петли, встроенной в устройство, что и создает магнитное поле, легко считываемое MAG — терминалом, как если бы была совершена обыкновенная карточная транзакция.
По информации рынка, обе технологии страдают от невнимания пользователей. Если NFC-транзакции страдают от того, что только 10% терминалов оснащены одноименным приемником, то с MST картина хоть и лучше, но тоже странная: вероятно, что до 10% принимающих устройств не смогут считывать MST-транзакции. Между тем, как первая, так и вторая технологии вполне надежны: обе используют токенизацию и берегут номер карты от чужих глаз, обе поддерживают NFC для передачи информации по карте. Samsung сделал шаг на опережение, предложив MST, но пользователь слишком ленив и консервативен, чтобы оценить это сейчас по достоинству.
Бесконтактные платежи получили название «наличные 2.0», а между тем, от Банка 2.0 все давно устремились к Банку 3.0. «Банк сегодня — это не то место, куда вы ходите, а то, что вы делаете». Бретт Кинг пишет быстро, но новости из мира финансовых технологий устаревают и становятся общим местом еще быстрее. Когда очередной шедевр Кинга будет опубликован, скорее всего токенизация, MST, NFC, RFID-метки — все это станет классической топонимикой Банка 3.0.
Listview
На главном экране мы можем наблюдать список действий которые можно выполнить, подобный список делается так:
ListView {
id: actionList
....
delegate: ListDelegate {
anchors {
left : parent.left
leftMargin: 20
}
onClicked: {
pageStack.push(Qt.resolvedUrl(model.source))
}
MoreIndicator {
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: 30
}
}
}
model: ListModel {
ListElement {
title: "Read Tag"
subtitle: ""
source: "ReadPage.qml"
}
......
}
}
Элемент
ListView
является собственно самим списком, у которого есть два ключевых свойства
delegate
— делегат для отрисовки одного элемента списка и
model
— модель данных для списка.
Пакет
com.nokia.extras
содержит уже готовый компонент
ListDelegate
для создания простого делегата. Элемент
ListModel
позволяет задать простую модель данных. А
ListElement
— ни что иное как одна запись этой модели.
Бесконтактная технология оплаты mastercard − это всех касается
течение буквально последнего года бесконтактная технология MasterCard появилась в смартфонах с поддержкой ряда платёжных платформ.
▪ Apple Pay — платёжная система, интегрированная в устройства Apple и представленная 9 сентября 2021 года. Владельцы устройств Apple могут использовать кредитные и дебетовые карты MasterCard напрямую через Apple Pay. В магазине для подтверждения оплаты достаточно поднести iPhone к бесконтактному считывающему устройству платежного терминала и одновременно коснуться пальцем сканера Touch ID (шаг к биометрической идентификации). Безопасность обеспечивается стандартом EMV (Europay, MasterCard, Visa) и использованием платформы MDES (MasterCard Digital Enablement Service).
▪ Samsung Pay. Держатели карт MasterCard могут использовать свои смартфоны (флагманские модели, например, Samsung Galaxy S6) в качестве мобильного платёжного устройства. Безопасность и удобство платежей обеспечивается механизмом токенизации, использованием платформы MDES, а также криптографическим алгоритмом EMV.
▪ Android Pay анонсиован и ещё готовится к релизу, однако уже сейчас реализована связка Android Pay и MasterCard PayPass, основанная на всё том же механизме токенизации. Настоящий номер карты пользователя не передаётся, поэтому потребителю обеспечивается дополнительный уровень безопасности. Решение вскоре будет доступно для пользователей устройств с Android KitKat и выше.
▪ «Кошелёк». В России развивается проект, связанный с технологией MasterCard и мобильными платежами. В 2021 году MasterCard и CardsMobile представили новые возможности мобильного приложения «Кошелёк». «Кошелёк» доступен для скачивания на более чем 100 моделях телефонов за счет облачной NFC-технологии.
Мобильное приложение «Кошелёк» позволяет владельцам совместимых Android-смартфонов выпускать, безопасно хранить и использовать непосредственно в приложении мобильные банковские карты MasterCard PayPass для платежей в онлайн- и офлайн-магазинах, транспортные карты для оплаты проезда в общественном транспорте и электронные купоны на скидку. В процессе оплаты пользователю нужно только приложить свой смартфон с установленным приложением «Кошелёк» к бесконтактному платежному терминалу.
Одна из ключевых инноваций – запуск «облачной» версии «Кошелька», ранее доступного только в предустановленном виде. Сегодня загрузить в телефон виртуальную бесконтактную карту банков Тинькофф Банк, Русский Стандарт и Банка Санкт-Петербург можно «по воздуху», не посещая банк, используя приложение «Кошелек. Банковские карты» от CardsMobile для Samsung, HTC, LG, Nexus, Sony, Huawei, OnePlus с операционной системой Android 4.4 KitKat и выше. Приложение можно бесплатно скачать в Google.Play.
Беспроводные метки nfc
Технический прогресс не стоит на месте, появляющиеся новые технологии со временем дешевеют и становятся доступны практически всем желающим. Как пример можно привести мобильные телефоны. Середина 80-ых — начало 90-ых были переносные таксофоны с ручками или кирпичи стоимостью несколько тысяч $, конец 90-ых — большого размера трубки, с торчащими антеннами со стоимостью от 100$ Такую же аналогию можно провести с NFC метками, используемыми в учетных целях.
В идеальном варианте и оборудование и расходники (метки) могут ничего не стоить при условии, что у работника имеется смартфон с поддержкой NFC и сам работник не против его использования. Ну и, конечно же, удалось раздобыть необходимое количество использованных билетов. На Ali стоимость от 6 рублей с лишним за метку.
Основные затраты по внедрению описанной технологии это только время программиста.
В задачи программиста входит реализовать в мобильном приложении требуемую вашим учетом логику инвентаризации и или складского учета, а также реализовать обмен данными с основной учетной базой данных.
Для обмена можно использовать http или web сервисы, ботов телеграмм или иное месенджероподобное решение.
Описанное нигде не подглядывал, видел когда-то статью про запись пароля wifi на билет, а также имел опыт работы с ТСД (штрих.кодами rdp на винмобайл), огромным и дорогим, на мой взгляд неудобным. С тех пор было желание повторить что-то подобное на более удобном смартфоне.
Группы из 4 байтов называются страницами. Первые несколько страниц, как правило заняты служебной информацией, на одном из скриншотов можно увидеть ID метки NFC на первых двух страницах.
Кроме ID также может содержаться информация о заблокированных readonly байтах. А также масса другой информации все зависит от типа метки и поддерживаемых возможностей. Также служебная информация может быть записана в конце метки на последних страницах. Более подробно описанное можно увидеть программе для чтения меток, например TagInfo.
Рекомендуется записывать данные с 8 страницы для пустых — купленных меток.
Для билетов рекомендуется записывать с 16 страницы. Длина имени справочника не должна превышать 60 символов, в случае использования билета.
Некоторые билеты, как правило проездные на много поездок, имеют всего 20 страниц, с учетом блокированных служебных записать на такой билет не получиться.
Данная разработка позволит быстро интегрировать в ваше мобильное приложение функционал чтения записи NFC.a меток.
Возможные варианты использования:
Складской учет номенклатуры, упаковок, ячеек, мест хранения.
Учет ОС, МБП: шкафов, столов, компьютеров.
Мобильный пропускной пункт.
И так далее.
Исходники приложения доступны по ссылке https://github.com/PloAl/RfIdTool
Приложение является «служебным» и не имеет основной activity, также нет в меню приложений android. Запуск происходит из других приложений, туда же передаются считанные данные или передаются данные для записи в метку.
Ниже на картинке видна, полупрозрачная область «Запись метки NFC» это единственная activity приложения.
Пример использование в android приложении:
protected void nfcStart(boolean read, String readedId) {
if (read)) {
Intent intent = new Intent("com.ploal.rfidtool.NFCREAD");
intent.putExtra("IdLabel", readedId); //множественное чтение, предыдущий id метки
}
else{
Intent intent = new Intent("com.ploal.rfidtool.NFCWRITE");
intent.putExtra("PageNumber", PageNumber); //глоб. переменная номер страницы
intent.putExtra("WriteString", WriteString); //глоб. переменная текст для записи
}
startActivityForResult(intent, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (null != data) {
String event = data.getStringExtra("event");
String uid = data.getStringExtra("uid");
String result = data.getStringExtra("result");
String text = data.getStringExtra("text");
String[] techArr = data.getStringArrayExtra("tech");
//обработка полученных данных ...
}
}
Пример использование в мобильном приложении(клиенте) 1с:
&НаКлиенте
Процедура ЗапускПриложенияNFC(Чтение=Истина,ПрочитанныйID="")
ЗПМУ = Новый ЗапускПриложенияМобильногоУстройства();
Если Чтение Тогда
ЗПМУ.Действие = "com.ploal.rfidtool.NFCREAD";
ЗПМУ.ДополнительныеДанные.Добавить("IdLabel",ПрочитанныйID);
Иначе
ЗПМУ.Действие = "com.ploal.rfidtool.NFCWRITE";
ЗПМУ.ДополнительныеДанные.Добавить("PageNumber","" НомерСтраницы);
ЗПМУ.ДополнительныеДанные.Добавить("WriteString",ТекстЗаписи);
КонецЕсли;
Если ЗПМУ.ПоддерживаетсяЗапуск() Тогда
ЗПМУ.Запустить(Истина);
Событие = "";
Для Каждого Стр Из ЗПМУ.ДополнительныеДанные Цикл
Если Стр.Ключ = "event" Тогда
Событие = Стр.Значение;
ИначеЕсли Стр.Ключ = "uid" Тогда
УИД = Стр.Значение;
ИначеЕсли Стр.Ключ = "result" Тогда
Результат = Стр.Значение; //HEX строка
ИначеЕсли Стр.Ключ = "text" Тогда
Текст = Стр.Значение;
ИначеЕсли Стр.Ключ = "tech" Тогда
Техлист = Стр.Значение;
КонецЕсли;
КонецЦикла;
//обработка полученных данных ...
КонецЕсли;
КонецПроцедуры
Взаимодействие
Когда пользователь попадает на страницу для записи или чтения метки, мы должны выполнить следующий код:
Для чтения
function tagWasRead(container) {
NfcManager.stopDetection()
readPage.dataContainer = container
pageStack.push(Qt.resolvedUrl("ReadResultPage.qml"), {dataContainer: readPage.dataContainer})
}
function readError(string) {
errorBanner.text = string
errorBanner.show()
}
Component.onCompleted: {
NfcManager.tagReadFinished.connect(readPage.tagWasRead)
NfcManager.accessError.connect(readPage.readError)
NfcManager.setReadMode()
NfcManager.startDetection()
}
Метод
Component.onCompleted
выполняется когда страница полностью создана. В этом методе мы цепляем обработчики для ошибки и для успешного результата к нашим сигналам из NfcManager (обратите внимание на синтаксис подключения С сигнала к QML слоту)
После, мы выставляем режим для чтения и сообщаем нашему менеджеру, что следует ожидать прикладывания тега.
Также обратите внимание на вызов push
pageStack.push(Qt.resolvedUrl("ReadResultPage.qml"), {dataContainer: readPage.dataContainer})
второй параметр, позволяет нам передать контейнер с данными на следущую страницу, которая просто его обработает
пример:
.....
Label {
id: rawDataLabel
width: parent.width
font.pixelSize: 30
font.family: "Courier New"
text: readPage.dataContainer.rawHexData()
wrapMode: Text.WrapAnywhere
}
.....
Для записи
function tagWasWritten() {
.....
}
function writeError(string) {
.....
}
Component.onCompleted: {
NfcManager.tagWriteFinished.connect(writePage.tagWasWritten)
NfcManager.accessError.connect(writePage.writeError)
NfcManager.setWriteMode()
NfcManager.setDataForWrite(writePage.text, writePage.uri)
NfcManager.startDetection()
}
Очень похоже, не правда ли? Единственным отличием является вызов метода
setDataForWrite
, который передает данные для записи.
Запись
void NfcManager::setDataForWrite(const QString &text, const QString &uri)
{
m_textForWrite = text;
m_uriForWrite = uri;
}
Этот метод должен вызываться перед попыткой записи для того, чтобы установить новые значения Uri и/или Text. Если его не вызвать на тег будут записаны предыдущие данные (такой подход пригодится, если нужно записать много однотипных тегов)
void NfcManager::writeTarget(QNearFieldTarget *target)
{
if (m_textForWrite.isEmpty() && m_uriForWrite.isEmpty())
return;
m_cachedTarget = target;
QNdefMessage message;
if (!m_textForWrite.isEmpty() && !m_uriForWrite.isEmpty()) {
NdefNfcSmartPosterRecord smartPosterRecord;
smartPosterRecord.setTitle(m_textForWrite);
smartPosterRecord.setUri(QUrl(m_uriForWrite));
message.append(smartPosterRecord);
} else if (!m_textForWrite.isEmpty()) {
QNdefNfcTextRecord textRecord;
textRecord.setText(m_textForWrite);
message.append(textRecord);
} else {
QNdefNfcUriRecord uriRecord;
uriRecord.setUri(QUrl(m_uriForWrite));
message.append(uriRecord);
}
connect(target, SIGNAL(error(QNearFieldTarget::Error,QNearFieldTarget::RequestId)), this, SLOT(errorHandler(QNearFieldTarget::Error,QNearFieldTarget::RequestId)));
connect(target, SIGNAL(ndefMessagesWritten()), this, SIGNAL(tagWriteFinished()));
target->writeNdefMessages(QList<QNdefMessage>() << message);
}
Главный метод записи не сложнее чем метод чтения. В блоке условий мы просто выбираем вид записи. Если присутствует только Uri или Text, то создается соответствующий тип, если же заполнены оба поля то создается запись типа Smart Poster.
После этого мы снова подключаем обработчик ошибок. Но, обратите внимание, поскольку в бэкенде нам не нужно никакой логики обработки успешного завершения чтения, мы пробрасываем сигнал на сигнал, который в дальнейшем поймаем в QML.
Какое будущее ждёт web nfc?
Сегодня Web NFC доступен только на телефонах Android через браузер Chrome. Сложно сказать, когда большинство браузеров на мобильных ОС начнут поддерживать Web NFC. Но физические теги NFC просто использовать, и скоро появятся поводы применять технологию для обслуживания клиентов.
Это не та технология, которую мир ждал
Александр Котлячков, ведущий разработчик X5 RETAIL GROUP
Александр обосновал позицию: веб-технологии довольно тугие, у подавляющего большинства не получается обеспечить плавную и бесшовную работу веб-приложения. Сейчас есть возможность считывать штрихкоды камерой, для чего теоретически можно использовать NFC, только вместо бумажки с кодом придётся ставить метку.
Подозреваю, что это дороже и сложнее, а профит эфемерный. Будет очень сложно построить работу с NFC метками так же гладко, как это делают платёжные приложения. Скорее всего, касание метки будет сопровождаться фризами и артефактами загрузки.
У бесконтактных пассивных меток, и желательно с регулируемой дальнобойностью, можно придумать 100500 вариантов использования. А вот у веб API для Web NFC сложно придумать. Если даже что-то придумают, то, скорее всего, напишут обёртку вокруг NFC, которая будет выглядеть как обычный EventEmitter.
При возможности использования NFC в приложениях технология почти не используется. Веб — это еще более узкая область применения. Примеры кода по обработке метки у Свена Хейгса выглядят неэстетично.
Как придумать, куда приложить веб NFC? Скорее всего, человеку понадобилось открыть тематический сайт с телефона. Затем нужно ввести данные, но не через форму, а через метку. Мне на ум приходит магазин, но у многих есть приложения. Всё уже изобретено. Это не та технология, которую мир ждал. Хочется клонирования, телепортацию, антигравитацию, термоядерные реакторы. А тут получается, что NFC в веб сделали, надо кому?
Обходные пути
Первое, что приходит в голову — а можно ли добавить в info.plist не AID платежного апплета, а AID Card Manager’а (Card Manager — это группа сервисов внутри операционной системы чипа, управляющих картой, которые отвечают за администрирование и безопасность), чтобы потом вручную послать ему команду SELECT с AID нужного апплета?
Здесь мы споткнулись о первый подводный камень — Core NFC не позволяет отправлять команду SELECT, содержащую AID, который не прописан в info.plist.
Хорошо, добавили A0000000041010, но и тут неудача — Core NFC не позволяет отправлять команду SELECT, содержащую платежный AID, вне зависимости от того, есть он в info.plist или нет.
Разберемся, как именно работает ограничение по идентификаторам.
В info.plist мы указали следующие AID’ы:
1. A000000001510000 - GlobalPlatform Card Manager AID
2. 325041592E5359532E444446303101 - Proximity Payment System Environment (PPSE)
3. A0000000041010 - Mastercard Credit/Debit (Global)
4. A00000000401 - Mastercard PayPass
5. A00000000410101213 - Mastercard Credit
6. A00000000410101215 - Mastercard Credit
7. A00000000410101214 - Придуманный платежный AID
8. A00000000410101216 - Придуманный платежный AID
9. A0000000041010121F - Придуманный платежный AID
10. A0000000041010BB5445535401 - Придуманный платежный Long AID
11. A0000000041010BB5445535405 - Придуманный платежный Long AID
12. A000000004101FBB5445535401 - Придуманный не платежный AID
13. A000000004101F1213 - Придуманный не платежный AID
14. A00000000F1010 - Придуманный не платежный AID
15. A0000000040F - Придуманный не платежный AID
Мы установили 14 платежных апплетов с разными AID (пп. 2-11 — платежные AID-ы), и попробовали отправить Card Manager команды SELECT с каждым из этих AID.
Ответили номера 12-15.
Получается, что ограничение накладывается именно на некий префикс AID, наличие которого и определяет, платежный это идентификатор или нет.
Жаль, но этот способ отпадает.
Второй способ персонализации, предусмотренный GlobalPlatform, это команда INSTALL [for personalization].
Она отправляется в Card Manager и содержит AID апплета, который нужно персонализировать.
После этого можно отправлять команды STORE DATA в Card Manager, а он будет пересылать их в целевое приложение.
Но есть одно ограничение. Для того, чтобы апплет поддерживал такой способ персонализации, он должен реализовывать интерфейс org.globalplatform.Application.
Card Manager, на команду INSTALL [for personalization] с Mastercard Credit/Debit (Global) AID, который был присвоен апплету M/Chip Advance от NXP, отвечал ошибкой «6985» (Conditions of use not satisfied),
а значит надо проверить, реализует ли он интерфейс Application.
Для этого мы написали простое приложение-пустышку, реализующее этот интерфейс. Как и ожидалось, на INSTALL [for personalization] оно ответило «9000».
Но когда Application был убран из интерфейсов, реализуемых приложением, оно стало отвечать на эту команду «6985», как и в случае с апплетом M/Chip Advance.
Следовательно, проблема именно в том, что приложение NXP не реализует необходимый для такого способа персонализации интерфейс. Этот способ тоже отпадает.
Персонализация апплетов
На самом деле, персонализация апплета — очень простая штука; всё, что требуется, это загрузить в него необходимые платежные данные. Для этого нужно выбрать апплет командой SELECT по его AID, установить защищенное соединение и отправить выбранному апплету команды STORE DATA с данными внутри.
Теперь вернемся к списку AID’ов в файле info.plist — зачем он нужен, и как конкретно Core NFC выбирает, с каким апплетом взаимодействовать?
Выглядит это примерно так:
- Программа идет по списку сверху вниз;
- Для каждого AID она формирует и отправляет команду SELECT;
- AID первого апплета, ответившего «9000» (статус успешного ответа, здесь список всех возможных ответов) записывается в поле initialSelectedAID объекта типа NFCISO7816Tag, который кладется в массив обнаруженных чипов
@available(iOS 13.0, *)
public protocol NFCISO7816Tag : NFCNDEFTag, __NFCTag {
/**
* @property initialSelectedAID The Hex string of the application identifier (DF name) selected by the reader when the tag is discovered.
* This will match one of the entries in the «com.apple.developer.nfc.readersession.iso7816.select-identifiers»
* in the Info.plist.
*/
@available(iOS 13.0, *)
var initialSelectedAID: String { get }
Дальше из массива можно выбрать любой такой объект, и с помощью метода
отправлять
выбранному апплету.
А теперь поговорим об этом ограничении:
Core NFC doesn't support payment-related Application IDs.
То есть
не поддерживает платежные AID’ы, а именно боевые, с которыми работают платежные терминалы.
Конечно, платежный AID в список info.plist добавить можно, вот только Core NFC его проигнорирует и не будет отправлять для него SELECT (кстати, здесь список всех использующихся AID’ов). Apple таким образом защищают свою технологию Apple Pay, закрывая сторонним разработчикам доступ к любым платежным функциям iPhone (и всему, что с этим связано).
Пишем свой класс для smart poster
Ниже я расскажу как создать свой тип
NDEF
записи на примере создания типа для Smart Poster записи.
Сразу оговорюсь, что мой тип упрощен. Он не поддерживает ни Action ни Size ни даже иконки, но он позволяет одновременно хранить текст и ссылку.
Так выглядит объявление для класса нашего Smart Poster’а:
class NdefNfcSmartPosterRecord : public QNdefRecord
{
public:
Q_DECLARE_NDEF_RECORD(NdefNfcSmartPosterRecord, QNdefRecord::NfcRtd, "Sp", QByteArray())
void setTitle(const QString &title, const QString &locale = "en");
void setUri(const QUrl &uri);
QString title(const QString &locale = "en") const;
QUrl uri() const;
//TODO: Add icon, action and size fields support
private:
RecordPart readPart(int &offset) const;
};
Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(NdefNfcSmartPosterRecord, QNdefRecord::NfcRtd, "Sp")
Итак, разработчики Qt Mobility уже позаботились о том, чтобы нам было проще жить, и создали два специальных макроса, которые выполняют всю самую черновую работу.
Параметрами для макросов служат: имя класса, тип записи (для Smart Poster’а это QNdefRecord::NfcRtd) и «Имя типа» — аббревиатура для распознавания в теге. А также последний параметр в Q_DECLARE_NDEF_RECORD являются данные для первоначальной инициализации данных, в нашем случае это пустой массив байт.
Теперь посмотрим на реализацию методов чтения и записи.
Простая структура для хранения разобранной части записи:
struct RecordPart {
enum Type {
Uri,
Text,
Action,
Icon,
Size,
Unknown
};
Type type;
QString text;
QString locale; // For text type
quint8 prefix; // For Uri type
RecordPart()
: type(Unknown), text(QString()), locale(QString()), prefix(0)
{
}
};
Для начала рассмотрим методы для чтения:
Пример 1. разработка nfc приложения для чтения/записи меток.
Следующий пример показывает функции чтения/записи NFC метки. Для того, чтобы получить доступ к аппаратной части NFC и корректно обрабатывать NFC информацию, объявите эти позиции в файле AndroidManifest.xml.
Минимальную версию SDK, которую должно поддерживать ваше приложение — 10, объявите об этом в файле AndroidManifest.xml
Следующий целевой вызов демонстрирует функцию чтения. Если широковещательное сообщение системы равняется NfcAdapter.ACTION_TAG_DISCOVERED, тогда вы можете считать информацию и показать ее.
@Override
protected void onNewIntent(Intent intent){
if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
mytag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // get the detected tag
Parcelable[] msgs =
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefRecord firstRecord = ((NdefMessage)msgs[0]).getRecords()[0];
byte[] payload = firstRecord.getPayload();
int payloadLength = payload.length;
int langLength = payload[0];
int textLength = payloadLength - langLength - 1;
byte[] text = new byte[textLength];
System.arraycopy(payload, 1 langLength, text, 0, textLength);
Toast.makeText(this, this.getString(R.string.ok_detection) new String(text), Toast.LENGTH_LONG).show();
}
}
Следующий код демонстрирует функцию записи. Перед тем, как определить значение mytag, вы должны убедиться, что метка определена и только потом вписать в нее свои данные.
If (mytag==Null){
……
}
else{
……
write(message.getText().toString(),mytag);
……
}
private void write(String text, Tag tag) throws IOException, FormatException {
NdefRecord[] records = { createRecord(text) };
NdefMessage message = new NdefMessage(records);
// Get an instance of Ndef for the tag.
Ndef ndef = Ndef.get(tag); // Enable I/O
ndef.connect(); // Write the message
ndef.writeNdefMessage(message); // Close the connection
ndef.close();
}
В зависимости от прочитанной информации вы можете выполнить дополнительные действия, такие как запуск какого-либо задания, переход по ссылке и т.д.
Установка апплетов
Для установки апплетов на чип необходимо защищенное соединение (Secure Channel Protocol или SCP); мы сделали это за кадром с помощью обычного
считывателя и платформы
TSM.
Однако, даже если у вас ничего из этого нет, вы все равно можете попробовать установить свой собственный апплет на чип — только на виртуальный.
Понадобится любая IDE с поддержкой JCOP Shell и эмулятором JavaCard, например, вот эта.
Создаем пустой проект, указываем желаемый AID (например 0000000000) и запускаем.
Дальше разбираемся по шагам:
- /card
Получаем ATR, отправляем SELECT без идентификатора, чтобы был выбран Card Manager; - auth
Создаем защищенное соединение с эмулятором, иначе ничего установить не получится; - ls (опционально)
С помощью этой команды можно увидеть, какие приложения установлены на вашем девайсе/эмуляторе; - install [packageAID] [appletAID] [instanceAID]
Устанавливаем апплет:packageAID — идентификатор пакета (Module), например, «0000000000»
appletAID — идентификатор апплета (Load File), например, «000000000000»
instanceAID — идентификатор, который будет присвоен вашему апплету после установки, например, «A0000000041010»; - ls
Проверяем, появился ли ваш апплет в списке установленных приложений:
Установление соединения
Именно здесь речь пойдет о фичах фреймворка
, добавленных в iOS 13.
Кстати, в iOS 14 никаких существенных изменений относительно предмета статьи не случилось, поэтому все описанное актуально и для нее.
Итак, в тринадцатой версии яблочной ОС стало возможным не только считывать данные с NFC меток, как это было в iOS 12 (но не раньше iOS 11, до нее взаимодействие по NFC было возможно только в рамках Apple Pay), но и записывать их, а также общаться на языке APDU-команд с любым чипом, который соответствует одному из следующих стандартов:
Для этого в
были добавлены два новых класса:
Первый используется для взаимодействия с NDEF метками, а второй — для всего остального, соответственно.
В нашем случае это чип, поддерживающий спецификацию GlobalPlatform Card Specification 2.2.1 и стандарт ISO/IEC 7816, значит, будем использовать второй класс.
В документации написано, что нужно сделать (помимо написания кода, конечно), чтобы начать общение с чипом по ISO 7816:
Но ниже есть вот такое интересное ограничение:
ImportantCore NFC doesn’t support payment-related Application IDs.Как раз его мы и хотим «пощупать», узнав, что конкретно оно означает.
Добавляем строку, например «Allow NFC connection» для ключа NFCReaderUsageDescription в файле info.plist. С любым другим значением этого ключа тоже работает.
[Здесь в колонке слева не сам ключ, а его описание, XCode прячет формальные названия]
Дальше, если мы хотим взаимодействовать с чипом, как с устройством стандарта ISO/IEC 7816, то в значении ключа com.apple.developer.nfc.readersession.iso7816.select-identifiers укажем список ID всех апплетов (Application Identifier или AID), с которым будет взаимодействовать приложение.
Здесь стоит пояснить, что эти идентификаторы — не просто случайный набор символов.
Это шестнадцатеричные (hex) строки, содержащие информацию о приложении, которому они присвоены.
AID’ы могут быть длиной от 5 до 16 байт (два символа в строке = один байт). Они состоят из двух частей, первая определяет провайдера приложения (для Mastercard это «A000000004»), вторая говорит, какой именно это продукт данного провайдера (для продукта с именем «Mastercard» это «1010», а, например, для Maestro это «3060»).
Кроме того, иногда в AID требуется поместить дополнительную информацию, например, если на чипе находятся два одинаковых приложения от одного провайдера, но для разных банков. Для этого существует поддержка Long AID (или Extended AID). До тех пор, пока длина AID не превышает 16 байт, в него можно записывать все, что угодно. Например, мы взяли Mastercard AID и в конце дописали к нему «TEST», итог: «A0000000041010BB5445535401».
Единственный AID, который выбивается из списка — «325041592E5359532E444446303101». На самом деле это обычная (только в hex-формате), что называется, plain-text строка «2PAY.SYS.DDF01». Это AID PPSE, который платежным апплетом, как таковым, не является. Он лишь содержит данные окружения, необходимые платежным приложениям.
Чтение
Теперь рассмотрим методы чтения тега:
void NfcManager::readTarget(QNearFieldTarget *target)
{
connect(target, SIGNAL(error(QNearFieldTarget::Error,QNearFieldTarget::RequestId)), this, SLOT(errorHandler(QNearFieldTarget::Error,QNearFieldTarget::RequestId)));
connect(target, SIGNAL(ndefMessageRead(QNdefMessage)), this, SLOT(readRecords(QNdefMessage)));
target->readNdefMessages();
}
Чтение происходит в асинхронном режиме, поэтому в данном методе мы просто подключаем сигнал обработки ошибок и сигнал завершения чтения, который вызовется только в случае, если чтение произошло без ошибок.
После этого мы просто вызываем метод для чтения:
void NfcManager::readRecords(const QNdefMessage &message)
{
if (message.isEmpty())
return;
QNdefRecord record = message.at(0); // Read only first
readRecord(record);
}
Если чтение прошло успешно, то мы попадем в данный слот, где получим первую запись из списка присутсвующих на теге записей.
Да-да, по спецификации на теге может быть несколько записей, но как говорит документация, для
SymbianHarmattan
доступно чтение и запись только одной записи.
void NfcManager::readRecord(const QtMobility::QNdefRecord &record)
{
DataContainer *result = 0;
if (record.isRecordType<QNdefNfcUriRecord>()) {
QNdefNfcUriRecord uriRecord(record);
result = new UriDataContainer(uriRecord.payload(), uriRecord.uri().toString());
}
else if (record.isRecordType<QNdefNfcTextRecord>()) {
QNdefNfcTextRecord textRecord(record);
result = new TextDataContainer(textRecord.payload(), textRecord.text());
}
else if (record.isRecordType<NdefNfcSmartPosterRecord>()) {
NdefNfcSmartPosterRecord smartPosterRecord(record);
result = new SmartPosterDataContainer(smartPosterRecord.payload(), smartPosterRecord.uri().toString(), smartPosterRecord.title());
}
else {
result = new DataContainer(record.payload());
}
emit tagReadFinished(result);
}
И вот, после нескольких переходов по вспомогательным методам мы добрались до самого главного метода, который превращает информацию закодированную в теги в привычные нам буквы.
На данный момент
Qt Mobility
из коробки поддерживает только два вида записей это ссылки (
Uri
) и текст (
Text
), к третьему типу —
Smart Poster
мы еще вернемся ниже.
Как можно заметить данные из записи сразу помещаются в некий новый объект, это простые объекты, которые я специально создал для облегчения передачи данных в
QML
В конце вызывается сигнал, содержащий объект с данными. В дальнейшем мы будем ловить этот сигнал в QML.