Universal Mobile Electronic Key
Статья автора Дмитрия Сенашенко, в рамках конкурса «Device Lab от Google».
На рынке сейчас присутствует множество маячков и их производителей. И в большинстве своем они предназначены для определения геолокации внутри зданий. Есть интересные идеи из разряда встраивания маячков в чемоданы, чтобы по их сигналу искать их в аэропорту. Но, учитывая мощности, это выглядит как игрушка. Хотелось придумать и реализовать нечто оригинальное и полезное одновременно. Итак, немного формальностей на сайте и в офисе Хабра, и маячок iBKS у меня в руках:
О маячках написано много. Например: «Google’s beacon platform. Часть 1» или «Google’s beacon platform. Часть 2». Повторяться не буду, однако скажу, что предполагалось использовать маячок с Google«s beacon platform и работать с ней по API. Реальность расставила свои точки над «i», о чем я расскажу немного позже.
По жизни я работаю с телефонией и интеллектуальными IVR с поддержкой email, html, sms и т.д. Поэтому имеются готовые стенды, легко достать необходимое оборудование и т.д. И именно к этой тематике мне и хотелось приспособить маячки.
Идея
Итак, мне пришла в голову идея использовать маячки как ключ авторизации к дверям в офисе. Как всем известно, в каждом офисе есть двери с электронными замками и считывателем при входе. У каждого сотрудника есть ключ в виде карточки, и для входа в дверь ему необходимо приложить данную карточку к считывателю, после чего дверь откроется. В мире количество таких дверей исчисляется многими миллиардами, а количество карточек, наверное, триллионами. Хотя на самом деле пользоваться ими не очень удобно. Если ты спешишь на важное совещание, то терять время на то, чтобы извлечь карточку (или извлечь предмет, в котором лежит эта карточка — кошелек, папку с документами) весьма утомительно.
Однако у каждого человека в кармане теперь есть телефон. И у некоторых — даже носимая на руке электроника. Проще встретить человека, забывшего карточку, чем забывшего свой телефон. Поэтому удобнее и экономически целесообразнее заменить карточку на телефон, а считыватель — на маячок. Конечно, существуют неплохие идеи в этом направлении.
Например, дверная ручка со считывателем отпечатков пальцев, NFC в телефоне и т.д. Но технология NFC так и не появилась в каждом смартфоне, а вот Bluetooth как раз в каждом смартфоне есть. Поэтому технологически данная идея уже фактически готова к реализации.
К тому же, такое решение повышает степень комфорта сотрудников. Подходя к двери, достаточно нажать на иконку приложения, и после прохождения авторизации дверь откроется. Т.е. ее можно открыть еще из лифта или на подходе к двери. Кроме того, можно открыть дверь с часов или сказав об этом в наушники с микрофоном персональному ассистенту. Важным фактором является авторизация. Давайте взглянем на это подробнее. См. рисунок 1.
Принципиальная схема работы
Телефон входит в зону видимости маячка, находит его, используя Beacon Discover и через Nearby messages API получает из Google Beacons Registry его attachment. Далее через Wifi или мобильный интернет в шифрованной сессии телефон отсылает этот аттачмент и свой IMEI или другой уникальный код, заданный при установке приложения, на сервер авторизации. Сервер авторизации идентифицирует права на доступ и в случае положительного решения дает команду на сервер управления электронными замками открыть соответствующий замок, основываясь на данных из attachment, которые уникальным образом характеризуют дверь. Сервер управления электронными замками дает команду исполнительному устройству открыть дверь.
Рисунок 1. Схема организации взаимодействия
Вот такое решение пришло мне в голову, и теперь давайте попробуем его реализовать.
Воплощаем идею в железе
В моем распоряжении была АТС компании Avaya со шлюзом G250. Это старый шлюз, давно снятый с производства. Но его новая замена — шлюз G450/G430 — имеет также необходимые нам компоненты, а именно привод управления электронным замком двери. В данный шлюз для потребностей малых офисов встроено сухое реле — так называемый Contact Closure Adjunct (см. рисунок 2).
Рисунок 2. Шлюз G430 производства Avaya
Этим разъемом можно управлять набором произвольного преднастроенного телефонного номера. При наборе этого номера шлюз замыкает реле и дает сигнал на открытие электронного замка.
Далее, у меня был в наличии рабочий стенд с IVR (Interactive Voice Response) производства также компании Avaya. Это полностью программный сервис, обладающий возможностями обработки не только голосовых запросов, но и email, смс и, что в данном решении и понадобится, html-запросов. Также этот IVR умеет инициировать не только email и смс, но и голосовые звонки. Т.е. по отношению к данному проекту этот IVR может получить запрос по html с передачей переменных и по результатам обработки этих переменных инициировать исходящий голосовой вызов на некий номер. Обработка запроса в IVR может быть проведена как встроенными средствами, так и с использованием языка программирования Java. В связи с этим в роли сервера авторизации был применен как раз этот IVR. В роли сервера управления электронным замком использовалась АТС Avaya Aura Communication Manager со шлюзом G250. Электронный замок также имелся в наличии.
Таким образом, приложению на мобильном телефоне требовалось получить идентификатор маячка, связаться с Google Beacons Registry и получить его аттачмент, после чего в html запросе отослать эту информацию и свой IMEI на IVR, который, проверив ее, сделает набор на АТС, дав таким образом сигнал для замыкания на шлюзе G250 сухого реле Contact Closure и открыв таким образом дверь.
Ну и последним шагом подготовки к реализации стало получение мобильного телефона под управлением операционной системы Android. Это был HTC Desire c Android Lollipop 5.1.1. Ну и, конечно, необходима была также установка Android Studio на свой ноутбук.
Все было готово, и я приступил. Как обычно, реальность расставила точки на «i».
Подводные камни
Для начала маячок требуется зарегистрировать в Google Beacon Registry. Проще всего это сделать через мобильное приложение Google Beacon Tools, доступное как в Google Play Market, так и в Apple App Store.
Я включил маячок, удалив пластиковый разъединитель между микросхемой и батарейкой, установил Google Beacon Tools и стал искать маячок. Он не появлялся. Тогда я скачал приложение производителя iBKS Config Tool. Это приложении тоже доступно как для Android, так и для IOS устройств. И — о чудо! Маячок появился.
Рисунок 3. iBKS Config Tool
Однако, в Google Beacon Tools он упорно появляться не хотел. Проштудировав интернет, я вычитал, что требуется войти в режим редактирования на iBKS Config Tool и изменить тип трансляции маячка. В режим редактирования приложение упорно входить отказывалось, как на Android, так и на iOS. Войти в этот режим удалось только после выключения и повторного включения маячка путем удаления батарейки. На всё про всё было около 30 секунд, далее маячок опять блокировался. Понять, это фича или бага, мне не удалось. Это нигде не описывалось. См. рисунок 4.
Рисунок 4. Режим редактирования iBKS Config Tool
Поменяв Advertising Mode c 1 на 7 (см. рисунок 5), я наконец-то увидел маячок в Google Beacon Tools (см. рисунок 6). Но регистрироваться он упорно отказывался.
Рисунок 5. Выбор Advertising Mode
Рисунок 6. Google Beacon Tools
Google Beacon Tools для регистрации требовал, чтобы маячок находился в режиме iBeacon или Eddystone UUID., но в этом режиме он его упорно не видел. В режиме же Eddystone URL он его видел, но регистрировать отказывался. Поведение этого приложения на Android и IOS было одинаковое, хотя на Android приложение сначала выбирало проект, и только потом отказывалось регистрировать маячок.
Что явилось причиной такого поведения маячка, выяснить в ходе проекта не удалось. Такое впечатление, что сам маячок был проблемный. Стоило его, конечно, заменить, но реализация проекта была ограниченна временным рамками, и на новую поездку в офис Хабра времени не было. Из опытов с iBKS Config Tool и Google Beacon Tools было понятно, что маячок излучает, причем передавая свой уникальный идентификатор. Поэтому было принято решение проводить идентификацию маячка для демонстрационного стенда не по attachment, полученного от Google Beacons Registry, а по его идентификатору. В целом для прототипа решения такая замена вполне адекватна.
Итак, осталось только найти Java библиотеку, которая позволяла бы в Android Studio организовать обнаружение идентификатора маячка. На помощь, конечно, пришелся GitHub и библиотека Radiusnetwork.com.eddystonedemo. Эта библиотека позволяет видеть транслируемый маячком его идентификатор, который также виден через iBKS Config Tool. Описание дано тут.
Был организован Activity (см. рисунок 7), который имел большую серую кнопку. Эта кнопка после нахождения маячка меняла цвет, имя и свойство Clickable. Т.е., пока маячок не найден, при нажатии на кнопку ничего не происходит. Как только маячок найден, то кнопка становится красной и позволяет на себя нажать. При нажатии на кнопку вызывается URL, ведущий на приложение IVR с передачей IMEI, которое его проверяет, и в случае успешности формирует вызов по протоколу SIP на сервер управления электронным замком. В случае потери сигнала маячка (увеличения расстояния до него или его выключения) кнопка меняет цвет и свойство Clickable обратно.
Рисунок 7. Скриншоты приложения
Код и конечная реализация
Целиком проект можно найти Github здесь. Остановимся на деталях. Ниже приведена функция, вызываемая при нахождении маячка:
public void didRangeBeaconsInRegion(Collection beacons, Region region) {
for (Beacon beacon: beacons) {
if (beacon.getServiceUuid() == 0xfeaa && beacon.getBeaconTypeCode() == 0x00) {
// This is a Eddystone-UID frame
Identifier namespaceId = beacon.getId1();
Identifier instanceId = beacon.getId2();
foundBeacon = namespaceId.toString();
//проверка идентификатора маячка для упрощения проекта проводится здесь. Ниже проверяется именно идентификатор моего конкретного маячка.
if (foundBeacon.equals("0xba1c51bab3147efee8e5")) {
Log.d("Found beacon", foundBeacon);
//Это необходимо чтобы менять свойство обратно при потере маячка
found = true;
runOnUiThread(new Runnable() {
public void run() {
//Здесь проводится смена надписи, цвета и свойства Clickable при нахождении маячка.
mainButton.setText("You can open the door now");
mainButton.setBackgroundColor(0xffef0606);
mainButton.setClickable(true);
}
});
}
Log.d("RangingActivity", "I see a beacon transmitting namespace id: " + namespaceId +
" and instance id: " + instanceId +
" approximately " + beacon.getDistance() + " meters away.");
runOnUiThread(new Runnable() {
public void run() {
((TextView) RangingActivity.this.findViewById(R.id.foundbeacon)).setText("Found beacon - " + foundBeacon);
}
});
}
}
}
Ниже приведена функция вызова URL на IVR:
public void buttonClick(View view) {
//Вызов этой функции возвращает IMEI телефона
String ret = telephonyManager.getDeviceId();
Log.d("IMEI", ret);
//URL ниже ведет на IP адрес IVR и вызывает приложение обработки HTML запросов под названием OpenTheDoor и передает туда идентификатор маячка и IMEI
webview.loadUrl("http://192.168.0.204:7080/Redirector/?AVAYAEP__LaunchId=OpenTheDoor&beacon=" +
foundBeacon + "&imei=" + ret.toString());
}
Таймер в данном приложении нужен, чтобы гасить кнопку при потере доступности телефона через 5 секунд после потери.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ranging);
mainButton = (Button) findViewById(R.id.mainbutton);
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
webview = (WebView)findViewById(R.id.webView);
//таймер деактивации кнопки
mTimer = new Timer();
mMyTimerTask = new MyTimerTask();
mTimer.schedule(mMyTimerTask, 1000, 5000);
}
class MyTimerTask extends TimerTask {
@Override
public void run() {
if (found) {
found = false;
}
else {
runOnUiThread(new Runnable() {
public void run() {
//Смена свойств кнопки по потере доступности маячка
mainButton.setText("Open the door");
mainButton.setBackgroundColor(0xffcfc3c3);
mainButton.setClickable(false);
((TextView) RangingActivity.this.findViewById(R.id.foundbeacon)).setText("");
}
});
}
}
}
}
Разработка приложений для IVR проводится в специализированной среде Avaya Aura Orchestration Designer и базируется на среде разработки Eclipse. По сути под каждым элементом скрывается Java код. Сборка приложения для упрощения разработки проводится в стиле Drag<&>Drop. На рисунке 8 приведен скриншот экрана среды разработки приложений для IVR.
Рисунок 8. Среда разработки Avaya Aura Orchestration Designer
Это приложение имеет два главных модуля: Data1 и Outcalling. Скриншоты этих модулей приведены на рисунках 9 и 10.
Рисунок 9. Модуль Data1
Рисунок 10. Модуль Outcalling
В модуле Data1 проводится фактически авторизация идентификатора маячка и IMEI: если оба правильны, то проводится перевод на модуль Outcalling, в котором формируется исходящий вызов на преднастроенный номер, хранящийся в переменной CalledNumber. В данной переменной устанавливается номер, настроенный в ATС для срабатывания сухого реле ContactClosure, подключенного к электронному замку двери.
Полный проект можно найти здесь.
Ну и в заключение по вот этому адресу выложено видео, в котором дано описание проекта и проведена демонстрация уже готового проекта. Спасибо за внимание!