Как послать сообщение на пейджер

Назад в 90-е или как отправить сообщение на пейджер через Java

Прочитав заголовок, вы, наверное, немного удивились необычности задачи, которую я перед собой поставила. Однако, как ни странно, пейджеры до сих пор иногда могут пригодиться в жизни, даже несмотря на появившееся в последние 15 лет обилие других средств коммуникации. Один из частных случаев их применения — (около)медицинское учреждение, расположенное в железо-бетонном здании, глушащем WiFi и сигнал мобильного телефона. Обслуживающий персонал, тем не менее, должен каким-то образом получать сообщения о том, куда им надо срочно переместиться в случае чего. Для решения этой проблемы руководство учреждения в нашем случае поставило себе дорогую станцию и раздало всем сотрудникам пейджерА пейджеры, которые должны были среди прочих принимать наши сигналы. Соответственно, нашей (меня и моих коллег) задачей являлась их отправка.

Уже прошли те времена, когда для отправки текста на пейджер надо было сначала пообщаться с сонной девушкой с телефонного узла. Теперь достаточно дозвониться до станции и набрать номер абонента и сообщение в тоновом режиме. Арсенал при этом сильно ограничен: можно отправлять только цифры, символы * и #, иногда буквы ABCD. Но для передачи, скажем, номера комнаты или кода ошибки должно хватить. Это довольно сильно упрощает задачу и роднит её с другими — с дозвоном в общую переговорную комнату, например.

Несмотря на кажущуюся прозрачность решения и вторичность моего опыта, я решила подробно описать свои действия, потому что информации в интернете по теме представлено не очень много: на форумах на вопросы отвечают редко и неметко. Кому-то этот текст, возможно, сильно сэкономит время.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Шаг 1 — INVITE

Первый этап — дозвон на пейджинговую станцию — был реализован через протокол SIP и с помощью соответствующей Java-библиотеки jain-sip. Самое лучшее описание принципов работы протокола я нашла на Хабре в публикациях «Взаимодействие клиентов SIP. Часть 1» и «Взаимодействие клиентов SIP. Часть 2», а самый удобоваримый туториал по джейн — вот здесь (но коллекция примеров отсюда отказалась получше).

В качестве предпоготовки я создала класс:

c необходимыми полями, которые вначале должны быть инициализированы так, как указано в туториале:

Как предписывают нам правила, сначала необходимо отправить INVITE-сообщение на телефон. Обратите внимание на то, что адресат в To- и Request-хедерах записывается по-разному. В первом случае заголовок просто собирается из глобального телефонного номера:

Во втором случае необходимо указать хост, с которого производится отправка сообщения, инициирующего общение:

Другим интересным элементом является, собственно, тело SDP-сообщения, представляющее собой описание того, что понадобится для успешной коммуникации. В нашем случае оно выглядело примерно так:

Атрибуты «o» и «s» не являются особо важными, в «p» пишем свой телефон. Основная часть — «m» (media), в которой прописываются используемые кодеки (в нашем случае на отправителе они могут быть не установлены) и порт для принятия ответов по теме.

Шаг 2 — аутентификация

Если нам удалось отправить правильный инвайт, то в лучшем случае сервер-получатель пришлет нам желанное OK-сообщение со статусом 200, а в худшем — решит еще немного помучить идентификацией. Во втором случае ответый статус будет 401 или 407. Вот код, с помощью которого посылается ответ. Для его поддержки понадобится одна из последних версий jain-sip (например, 1.2.228). Его надо поместить в метод processResponse(), получающий в качестве аргумента ResponseEvent responseEvt.

Обратите внимание на четверый аргумент метода handleChallenge(), без него формат сообщения изменится, станет неподходящим и ваша аутентификация провалится.

Классы AccountManagerImpl и тоже неоходимый UserCredentialsImpl должны быть дописаны вами, я их писала по модели тех, что представлены здесь.

После отправки своих регистрационных данных мы можем смело ожидать искомый 200 OK, на который надо не забыть отправить ACK. Такой тип сообщения изготавливается крайне просто:

Шаг 3 — SIP INFO

Сама процедура отправки выглядит немного странно (кажется, построенной по модели «через Жмеринку в Париж»), но иначе у меня ничего не работало. Вообще библиотека мне показалась немного глючной: очень часто одно из нескольких решений, выглядевших по большому счету одинаково, не срабатывало.

Что я могу сказать? После реализации этого шага оказалось, что не все VoIP-сервера одинаково дружелюбны: некоторым достаточно было сигналов, передаваемых через SIP, а кому-то их не хватило, так как они не производят звукового сигнала и потому остаются незамеченными. Естественно, по закону подлости моей целью был сервер второго типа. Поэтому…

Шаг 4. формирование RTP-пакета

Вообще когда я осознала, что одним SIP-ом проблему не решить, я надеялась, что хотя бы смогу воспользоваться другой библиотекой, которая умеет ненапряжно отправлять DTMF-сигналы. Но не тут-то было. Обычно, если мы говорим «RTP через джаву», то подразумеваем JMF. Но, во-первых, она уже старенькая и не особо поддерживается. Во-вторых, она больше подходит для передачи более сложных медиа. В-третьих, туториалы, которые мне удалось найти, были не очень толковыми. Вот один из примеров из документации, в середине которого всплывает некая rtpSession, следов которой в первые сколько-то минут поиска мне найти вообще не удалось.

Другим вариантом была библиотека libjitsi, представляющая из себя целый коммуникатор. Из неё ничего позаимствовать тоже не удалось, хотя там есть милая метода sendDTMF или что-то в этом духе. Структура кода такова, что он берётся или целиком, или никак. В итоге было решено по-нормальному сделать человеческий пакет и отправить его через UDP-соккет.

Итак, вот значимый фрагмент класса RtpPacket: его основные поля и конструктор со значениями, подходящими для передачи DTMF. Что значат все эти вещи, написано много где, поэтому повторяться не буду. Отмечу только, что значение параметра ssrc в принципе роли не играет, но у всех отправляемых в одной сессии пакетов оно должно совпадать. Номер формата полезной нагрузки у DTMF-пакетов (payload type) — 101 (его мы прописали, когда инициировали SIP-коммуникацию).

Самый важный этап создания пакета — заполнение байтового массива данных. У DTMF, естественно свой формат: первый байт — это, собственно, значение передаваемого сигнала (от 0 до 16), первая половина второго байта — различные маркеты (обычно 0), вторая половина второго байта- громкость (стандартное значение — 10), остальные два — это длительность (стандартное значение — 160).

Для каждого сигнала создается около 10 пакетов (число может варьироваться):

— первый, начальный, имеет marker = 1, остальные — 0;
— последние три — конечные, marker = 0, зато первый бит второго байта блока данных = 1. Блок данных в неконечном пакете для передачи сигнала 1 будет выглядеть так:

А в конечном вот так:

Метка времени у всех DTMF-пакетов, относящихся к одному сигналу, может оставаться одинаковой (предположим, T). Зато время следующего пакета должно быть:

Шаг 5. RTP-канал

Можно было создать только один соккет для отправления и принятия сообщений. Но — в любом случае — никакой отправки, естественно, не случится, если не знать хоста и порта назначения. Это уже совсем не те данные, через которые проходила SIP-коммуникация. Свои координаты телефонный сервер присылает нам в ответных SIP сообщениях во время нашего дозвона. Их можно получить, вставив в метод processResponce() вот такой код (тут можно увидеть, зачем мы ранее инициализаровали sdpFactory):

Дальше, как я наивно полагала, мне оставалось только понаделать из моих байтов DatagramPacket’ов, засунуть их в сокет и запулить в сервер. Но не тут-то было. В ответ сервер продолжал обрывать коммуникацию на полуслове, как будто ничего и не получал. А Wireshark в принципе не принимал мои сообщения за RTP, отображая из как простые UDP.

Шаг 6. RTP-коммуникация

На то, чтобы понять, в каком направлении двигаться дальше, ушло много времени. Я вложила много усилий в то, чтобы перечитать все имеющиеся в наличии спецификации и сто раз проверить свои пакеты на правильность. На седьмой же день Зоркий Глаз в моем лице заметил, что стандартная RTP-коммуникация не начинается сразу же с отправки DTMF-данных, а что ей предшествует непродолжительный обмен пакетами с сервером, которые выглядят несколько иначе.
Формат полезной нагрузки, объявленный в заголовке, равен 0, данных нет, зато есть собственно сама полезная нагрузка (payload), которая занимает 160 байт. Этот набор байтов различается во всех приходящих и уходящих сообщениях и выглядит составленным довольно случайно. Так или иначе, я не смогла найти информации о том, как именно он должен формироваться, поэтому каждый раз забивала его рандомами.

После того, как я стала отправлять эти вспомогательные пакеты перед каждым DTMF-сигналом, Wireshark наконец-то признал RTP-формат. Всё выглядело лучше, но коммуникация по-прежнему прерывалась, хотя сервер теперь от радости тоже стал меня забрасывать «пейлодными» пакетами.

Я уже и не знала, что еще бы могла сделать, но тут вспомнила, что RTP есть брат-неразлучник — RTCP. Проблема, по всей видимости, действительно была в нем: сервер пытался мне что-то отправить, но ему от меня постоянно приходили сообщения о том, что соответствующий порт закрыт. Поскольку я не хотела заморачиваться отправкой еще и RTCP-пакетов, я начала просто с открытия чакры порта:

Это оказало решающее воздействие: абонент получил моё сообщение «305*1*66» на пейджер!

Заключение

В последних строках моей телеги хотелось бы подчеркнуть, что это мой первый пост на Хабре, так что не судите меня строго. Я совершенно не считаю себя гуру телематики или чего-либо ещё. Просто при написании исходного кода очень много времени ушло на поиск информации. Что-то я находила в спецификациях, которые от начала до конца в один присест осилить было сложновато, что-то было описано нормальным языком, но как-то неярко мелким шрифтом на полях, что-то я делала наугад. Так что в какой-то момент просто решила, что если у меня всё получится, я опишу все свои действия в одном месте и оставлю это индексироваться где-нибудь в интернете.

Так что очень надеюсь, что хоть кому-то моя статья пригодится или хотя бы покажется интересной.

Источник

Разбираем протокол пейджерных сообщений POCSAG, ч1

Давным-давно, когда мобильный телефон стоил 2000$ и минута звонка стоила 50 центов, была такая популярная штука как пейджинговая связь. Затем связь стала дешевле, и пейджер сначала превратился из престижного атрибута делового человека в непрестижный атрибут курьера или секретаря, а затем эта технология практически и вовсе сошла на нет.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Общая информация

Для тех, кто забыл или родился после 2000х, кратко напомню основные идеи.

С точки зрения пользователя, пейджинговая связь обладает двумя большими плюсами, которые в некоторых случаях актуальны и до сих пор:

— Связь односторонняя, без каких-либо подтверждений, поэтому пейджинговую сеть невозможно перегрузить, ее работоспособность не зависит от числа абонентов. Сообщения просто последовательно передаются в эфир «как есть», а пейджер принимает их если номер получателя совпадает с номером пейджера.

— Приемное устройство очень простое, так что пейджер может работать без подзарядки до месяца от 2х обычных батареек АА.

Для передачи сообщений существуют два основных стандарта — POCSAG (Post Office Code Standardization Advisory Group) и FLEX. Стандарты совсем не новые, POCSAG был утвержден еще в 1982г, поддерживаемые скорости 512, 1200 и 2400 бит/с. Для передачи используется частотная манипуляция (FSK — frequency shift keying) с разносом частот 4.5КГц. Более новый стандарт FLEX (был предложен Motorola в 90х) поддерживает скорости до 6400 бит/с и может использовать не только FSK2, но и FSK4.

Протоколы по своей сути достаточно просты, и еще лет 20 назад для них были написаны декодеры, способные дешифровывать сигнал со входа звуковой карты (шифрования сообщений не предусмотрено, так что читать их с такой программой в принципе может любой).

Посмотрим, как это работает.

Прием сигналов

Для начала, нам нужен образец для декодирования. Берем ноутбук, rtl-sdr приемник, машину времени, и принимаем нужный нам сигнал.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Т.к. модуляция частотная, режим приема также ставим FM. С помощью HDSDR записываем сигнал в формате WAV.

Посмотрим, что у нас получилось. Загружаем wav-файл в виде массива с помощью Python:

Результат (биты подписаны вручную):

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Как можно видеть, все просто, и даже «на глаз» в Paint можно дорисовать биты, где «0» а где «1». Но делать это для всего файла было бы слишком долго, процесс надо автоматизировать.

Если увеличить график, то можно видеть что ширина каждого «бита» равна 20 отсчетам, что при частоте дискретизации wav-файла 24000 семпла/c, соответствует скорости 1200 бит/с. Найдем в сигнале место перехода через ноль — это будет начало битовой последовательности. Выведем на экран маркеры, чтобы проверить что биты совпадают.

Как можно видеть, совпадение не идеально (частоты передатчика и приемника все же чуть различны), но для декодирования вполне достаточно.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Для длинных сигналов пришлось бы вводить алгоритм подстройки частоты, но в данном случае этого не требуется.

И последний шаг — переведем массив из wav в битовую последовательность. Тут все тоже просто, длину одного бита мы уже знаем, если данные за этот период положительны, то добавляем «1», иначе «0» (правка — как оказалось, сигнал нужно было реверсировать, так что 0 и 1 поменяны местами).

Возможно, код можно оптимизировать, отказавшись от цикла, хотя в данном случае это некритично.

Результат — готовая последовательность бит (в виде строки), сохраняющая наше сообщение.

101010101010101010101010101010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010100111110011010010000101001101
100001111010100010011100000110010111011110101000100111000001100101110111101
010001001110000011001011101111010100010011100000110010111011110101000100111
000001100101110111101010001001110000011001011101111010100010011100000110010
011011110101000100111000001100101110111101010001001110000011001011101111010
100010011100000110010111011110101000100111000001100101110111101010001001110

111101111

Декодирование

Последовательность бит — это уже гораздо удобнее, чем просто wav-файл, из нее уже можно извлечь какие-либо данные. Разобьем файл на блоки по 4 байта, и получим более понятную последовательность:

10101010101010101010101010101010
10101010101010101010101010101010
10101010101010101010101010101010
10101010101010101010101010101010
01111100110100100001010011011000
01111010100010011100000110010111
01111010100010011100000110010111
01111010100010011100000110010111
01111010100010011100000110010111
00001000011011110100010001101000
10000011010000010101010011010100
01111100110100100001010111011000
11110101010001000001000000111000
01111010100010011100000110010111
01111010100010011100000110010111
01111010100010011100000110010111
00100101101001011010010100101111

Это все, что мы можем извлечь из файла, осталось понять что эти строки значат. Открываем документацию на формат, которая доступна в виде PDF.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Все более-менее понятно. Заголовок сообщения состоит из длинного блока «10101010101» который нужен, чтобы пейджер вышел из «спящего режима». Само сообщение состоит из блоков Batch-1… Batch-N, каждый из которых начинается с уникальной последовательности FSC (в тексте выделено жирным). Далее, как видно из мануала, если строка начинается с «0», то это адрес получателя. Адрес зашит в самом пейджере, и если он не совпадет, пейджер сообщение просто проигнорирует. Если строка начинается с «1», то это собственно, сообщение. Таких строк у нас две.

Теперь посмотрим на каждый блок. Мы видим коды Idle — пустые блоки 01111. 0111, не несущие полезной информации. Удаляем их, информации остается весьма мало, все что остается:

01111100110100100001010011011000 — Frame Sync
00001000011011110100010001101000 — Address
10000011010000010101010011010100 — Message

01111100110100100001010111011000 — Frame Sync
11110101010001000001000000111000 — Message
00100101101001011010010100101111 — Address

Осталось понять, что внутри.

Ищем дальше в мануале, и выясняем, что сообщения могут быть цифровые или текстовые. Цифровые сообщения хранятся в виде 4-битных BCD-кодов, значит в 20 битах может поместиться 5 символов (еще остаются биты для контроля, мы их рассматривать не будем). Сообщение также может быть текстовым, в этом случае используется 7-битная кодировка, но для текстового наше сообщение слишком мало — суммарное количество бит сообщения не кратно 7.

Из строк 10000011010000010101010011010100 и 11110101010001000001000000111000 получаем следующие 4х битные последовательности:
1 0000 0110 1000 0010 10101 0011010100 — 0h 6h 8h 2h Ah
1 1110 1010 1000 1000 00100 0000111000 — Eh Ah 8h 8h 2h

И наконец, последний шаг — смотрим в документации таблицу соответствия символов.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Как можно видеть, цифровое сообщение может содержать только цифры 0-9, букву U («ugrent»), пробел и пару скобок. Пишем несложную функцию вывода, чтобы не считать их вручную:

В итоге получаем переданное сообщение «0682*)*882». Что оно значит, сказать сложно, но раз формат поддерживает цифровые сообщения, значит наверно оно кому-то нужно.

Выводы

Как можно видеть, формат POCSAG весьма простой, и по сути, может быть декодирован даже в школьной тетради. И хотя сейчас это имеет скорее исторический интерес, анализ таких протоколов весьма полезен с познавательной точки зрения.

В следующей части рассказано про декодирование ASCII-сообщений.

Источник

Передаем сообщения на пейджер Nec 21A при помощи Raspberry Pi

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Здарова Народ. В прошлый раз мы при помощи Arduino и пары проводов считали и запрограммировали пейджер Nec 21A. Сегодня я предлагаю попробовать отправить сообщение и немного почувствовать себя пейджинговым оператором.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Для того чтобы отправить сообщение на пейджер нам понадобиться:

На самом деле есть уйма способов как отправить сообщение на пейджер, но все они сводятся к тому, чтобы правильно его закодировать согласно протокола POCSAG. И уже потом отправить все данные на передатчик. В итоге нам нужен некий энкодер и собственно сам передатчик. Можно конечно собрать аппаратный энкодер на микроконтроллере и подключить его к радиостанции с рабочим диапазоном пейджера. Схема рабочая и по сути в свое время это так и работало. Сейчас нас не интересует большая зона покрытия радиосети, мы всего на всего хотим протестировать возможность отправки сообщений на пейджер. Поэтому вместо железного энкодера будем использовать софтовый, а в качестве передатчика Raspberry Pi.

В этом нам поможет наша любимая Raspberry Pi. Я как-то рассказывал как сделать Raspberry PI Pirate Radio. FM передатчик за 5 минут. Там используется возможность Raspberry Pi излучать радиосигнал. Так вот вдохновившись этим проектом, другие ребята сделали проект RPITX. Так же как и в PIFM, при помощи Raspberry и 20 см провода можно излучать сигнал различных модуляций. Подробнее можно почитать у них в репозитории на GIThub.

Внимание! Во многих странах излучать радиосигнал без специального разрешения, запрещено. Используйте полученные знания в законных целях. Автор не несет ответственность за ваши действия.

Давайте уже начнем. Предполагается что вы уже умеете работать с Raspberry Pi и освоили самые простые команды в Linux.

Источник

Как отправить сообщение на пейджер

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Пе́йджер (от англ. to page — вызывать, что, в свою очередь, происходит от слова pageпаж, слуга, мальчик на посылках — ср. «to send a page after» [1] ) — приёмник персонального вызова. Сообщения на него передаются по пейджинговой сети. Для того, чтобы отправить почту на пейджер, надо набрать телефон оператора, сообщить номер или название абонента и продиктовать сообщение.

Каждому пейджеру в системе присваивается индивидуальный код, служащий своеобразным адресом, по которому передаваемая информация попадает к нужному абоненту. Сообщение для передачи поступает по телефону или электронной почте к оператору системы, который направляет его по радиоканалу в пейджинговую сеть с указанием индивидуального кода получателя. Приём сообщения возможен только пейджером — владельцем данного кода. Объём передаваемой информации может достигать нескольких сотен знаков, продолжительность передачи — несколько секунд. Пейджер имеет память, позволяющую записывать принимаемые сообщения и затем просматривать их в любое удобное для пользователя время. Он существенно дешевле мобильного телефона и очень удобен в случаях, когда двухсторонняя связь необязательна, например для вызова аварийных бригад при авариях на линиях электропередачи, на газо- и нефтепроводах, для связи с отдыхающими на даче при отсутствии телефона, для оповещения жителей прибрежных посёлков о надвигающемся шторме.

Первый в мире пейджер выпустила компания Motorola в 1956 году. Первые пейджеры взяли на вооружение сотрудники больниц и менеджеры. Затем пейджерами обзавелись все, кто хотел быть всегда доступным.

Содержание

Преимущества [ править | править код ]

Пейджинговая связь по сравнению с сотовой имеет ряд преимуществ:

Существует так называемый «двусторонний пейджинг», при котором реализована возможность отправки коротких сообщений непосредственно с абонентского оборудования. Этот метод больше похож на современную сотовую связь.

История [ править | править код ]

В 1921 году полиция Детройта впервые применила принцип оповещения по радио мобильных подразделений через диспетчера. Позднее, в 30-е годы, подобные системы достаточно широко использовались в подразделениях армии и полиции США. Однако только в 1956 году английской фирмой Multitone была разработана и установлена в одной из больниц Лондона первая в мире система персонального радиовызова (ПРВ) современного типа. В её состав входили передатчик, который передавал кодированные сигналы, и приёмные устройства, которые эти сигналы принимали. Приёмные устройства выдавались врачам и другому руководящему персоналу больницы. Если требовалось кого-либо из них срочно найти, то передатчик передавал сигнал, а абонент по индивидуальному звуковому сигналу (писку) идентифицировал его и тем или иным способом связывался с администрацией. Подобные приёмные устройства назвали биперами (от англ. beep «пикать», «пищать»). В дальнейшем эти системы связи развивались эволюционно, и только в последние годы они вступили в фазу бурного роста, чему способствовали как успехи технологии, так и потребности общества. В СССР подобная связь применялась в отдельных государственных структурах (органы государственного управления, КГБ, некоторые медицинские службы) с конца 60-х гг., однако распространение она получила только с 1979 года (в период подготовки к Олимпиаде-80).

Принцип действия [ править | править код ]

Под пейджингом, или сетью персонального радиовызова (ПРВ), понимают систему односторонней беспроводной передачи сообщений. Желающий послать сообщение на пейджер по телефону звонит оператору пейджинговой компании, называет номер абонента и диктует сообщение. Передача сигнала осуществляется специальным радиопередатчиком (базовой станцией, БС). Приём сигнала осуществляется переносным устройством абонента — пейджером, размером меньше сигаретной пачки. Каждому приёмному устройству присвоен уникальный номер. Пейджер всё время «слушает» определённую (фиксированную) радиочастоту. Приёмник ждёт до тех пор, пока не «услышит» в эфире свой номер. После этого он переходит в активный режим, принимает и отображает сообщение на дисплее. Зона уверенного приёма (дальность связи) зависит, в основном, от мощности и типа передатчика.

Среди приёмных устройств первыми были тональные биперы — устройства, способные издавать только однообразные звуки, несущие закодированную информацию. Позднее, по мере развития микроэлектроники, появились цифровые аппараты, способные выводить на табло цифровой ряд — как правило, номер телефона.

Ношение пейджеров [ править | править код ]

Большинство пейджеров имело клипсу для открытого ношения на ремне или других деталях одежды. некоторые пейджер носили и на шее, также были чехлы с клипсами и отверстия для ремней.

Прочитав заголовок, вы, наверное, немного удивились необычности задачи, которую я перед собой поставила. Однако, как ни странно, пейджеры до сих пор иногда могут пригодиться в жизни, даже несмотря на появившееся в последние 15 лет обилие других средств коммуникации. Один из частных случаев их применения — (около)медицинское учреждение, расположенное в железо-бетонном здании, глушащем WiFi и сигнал мобильного телефона. Обслуживающий персонал, тем не менее, должен каким-то образом получать сообщения о том, куда им надо срочно переместиться в случае чего. Для решения этой проблемы руководство учреждения в нашем случае поставило себе дорогую станцию и раздало всем сотрудникам пейджерА пейджеры, которые должны были среди прочих принимать наши сигналы. Соответственно, нашей (меня и моих коллег) задачей являлась их отправка.

Уже прошли те времена, когда для отправки текста на пейджер надо было сначала пообщаться с сонной девушкой с телефонного узла. Теперь достаточно дозвониться до станции и набрать номер абонента и сообщение в тоновом режиме. Арсенал при этом сильно ограничен: можно отправлять только цифры, символы * и #, иногда буквы ABCD. Но для передачи, скажем, номера комнаты или кода ошибки должно хватить. Это довольно сильно упрощает задачу и роднит её с другими — с дозвоном в общую переговорную комнату, например.

Несмотря на кажущуюся прозрачность решения и вторичность моего опыта, я решила подробно описать свои действия, потому что информации в интернете по теме представлено не очень много: на форумах на вопросы отвечают редко и неметко. Кому-то этот текст, возможно, сильно сэкономит время.

Как послать сообщение на пейджер. Смотреть фото Как послать сообщение на пейджер. Смотреть картинку Как послать сообщение на пейджер. Картинка про Как послать сообщение на пейджер. Фото Как послать сообщение на пейджер

Шаг 1 — INVITE

Первый этап — дозвон на пейджинговую станцию — был реализован через протокол SIP и с помощью соответствующей Java-библиотеки jain-sip. Самое лучшее описание принципов работы протокола я нашла на Хабре в публикациях «Взаимодействие клиентов SIP. Часть 1» и «Взаимодействие клиентов SIP. Часть 2», а самый удобоваримый туториал по джейн — вот здесь (но коллекция примеров отсюда отказалась получше).

В качестве предпоготовки я создала класс:

c необходимыми полями, которые вначале должны быть инициализированы так, как указано в туториале:

Как предписывают нам правила, сначала необходимо отправить INVITE-сообщение на телефон. Обратите внимание на то, что адресат в To- и Request-хедерах записывается по-разному. В первом случае заголовок просто собирается из глобального телефонного номера:

Во втором случае необходимо указать хост, с которого производится отправка сообщения, инициирующего общение:

Другим интересным элементом является, собственно, тело SDP-сообщения, представляющее собой описание того, что понадобится для успешной коммуникации. В нашем случае оно выглядело примерно так:

Атрибуты «o» и «s» не являются особо важными, в «p» пишем свой телефон. Основная часть — «m» (media), в которой прописываются используемые кодеки (в нашем случае на отправителе они могут быть не установлены) и порт для принятия ответов по теме.

Шаг 2 — аутентификация

Если нам удалось отправить правильный инвайт, то в лучшем случае сервер-получатель пришлет нам желанное OK-сообщение со статусом 200, а в худшем — решит еще немного помучить идентификацией. Во втором случае ответый статус будет 401 или 407. Вот код, с помощью которого посылается ответ. Для его поддержки понадобится одна из последних версий jain-sip (например, 1.2.228). Его надо поместить в метод processResponse(), получающий в качестве аргумента ResponseEvent responseEvt.

Обратите внимание на четверый аргумент метода handleChallenge(), без него формат сообщения изменится, станет неподходящим и ваша аутентификация провалится.

Классы AccountManagerImpl и тоже неоходимый UserCredentialsImpl должны быть дописаны вами, я их писала по модели тех, что представлены здесь.

После отправки своих регистрационных данных мы можем смело ожидать искомый 200 OK, на который надо не забыть отправить ACK. Такой тип сообщения изготавливается крайне просто:

Шаг 3 — SIP INFO

Сама процедура отправки выглядит немного странно (кажется, построенной по модели «через Жмеринку в Париж»), но иначе у меня ничего не работало. Вообще библиотека мне показалась немного глючной: очень часто одно из нескольких решений, выглядевших по большому счету одинаково, не срабатывало.

Что я могу сказать? После реализации этого шага оказалось, что не все VoIP-сервера одинаково дружелюбны: некоторым достаточно было сигналов, передаваемых через SIP, а кому-то их не хватило, так как они не производят звукового сигнала и потому остаются незамеченными. Естественно, по закону подлости моей целью был сервер второго типа. Поэтому…

Шаг 4. формирование RTP-пакета

Вообще когда я осознала, что одним SIP-ом проблему не решить, я надеялась, что хотя бы смогу воспользоваться другой библиотекой, которая умеет ненапряжно отправлять DTMF-сигналы. Но не тут-то было. Обычно, если мы говорим «RTP через джаву», то подразумеваем JMF. Но, во-первых, она уже старенькая и не особо поддерживается. Во-вторых, она больше подходит для передачи более сложных медиа. В-третьих, туториалы, которые мне удалось найти, были не очень толковыми. Вот один из примеров из документации, в середине которого всплывает некая rtpSession, следов которой в первые сколько-то минут поиска мне найти вообще не удалось.

Другим вариантом была библиотека libjitsi, представляющая из себя целый коммуникатор. Из неё ничего позаимствовать тоже не удалось, хотя там есть милая метода sendDTMF или что-то в этом духе. Структура кода такова, что он берётся или целиком, или никак. В итоге было решено по-нормальному сделать человеческий пакет и отправить его через UDP-соккет.

Итак, вот значимый фрагмент класса RtpPacket: его основные поля и конструктор со значениями, подходящими для передачи DTMF. Что значат все эти вещи, написано много где, поэтому повторяться не буду. Отмечу только, что значение параметра ssrc в принципе роли не играет, но у всех отправляемых в одной сессии пакетов оно должно совпадать. Номер формата полезной нагрузки у DTMF-пакетов (payload type) — 101 (его мы прописали, когда инициировали SIP-коммуникацию).

Самый важный этап создания пакета — заполнение байтового массива данных. У DTMF, естественно свой формат: первый байт — это, собственно, значение передаваемого сигнала (от 0 до 16), первая половина второго байта — различные маркеты (обычно 0), вторая половина второго байта- громкость (стандартное значение — 10), остальные два — это длительность (стандартное значение — 160).

Для каждого сигнала создается около 10 пакетов (число может варьироваться):

— первый, начальный, имеет marker = 1, остальные — 0;
— последние три — конечные, marker = 0, зато первый бит второго байта блока данных = 1. Блок данных в неконечном пакете для передачи сигнала 1 будет выглядеть так:

А в конечном вот так:

Метка времени у всех DTMF-пакетов, относящихся к одному сигналу, может оставаться одинаковой (предположим, T). Зато время следующего пакета должно быть:

Шаг 5. RTP-канал

Можно было создать только один соккет для отправления и принятия сообщений. Но — в любом случае — никакой отправки, естественно, не случится, если не знать хоста и порта назначения. Это уже совсем не те данные, через которые проходила SIP-коммуникация. Свои координаты телефонный сервер присылает нам в ответных SIP сообщениях во время нашего дозвона. Их можно получить, вставив в метод processResponce() вот такой код (тут можно увидеть, зачем мы ранее инициализаровали sdpFactory):

Дальше, как я наивно полагала, мне оставалось только понаделать из моих байтов DatagramPacket’ов, засунуть их в сокет и запулить в сервер. Но не тут-то было. В ответ сервер продолжал обрывать коммуникацию на полуслове, как будто ничего и не получал. А Wireshark в принципе не принимал мои сообщения за RTP, отображая из как простые UDP.

Шаг 6. RTP-коммуникация

На то, чтобы понять, в каком направлении двигаться дальше, ушло много времени. Я вложила много усилий в то, чтобы перечитать все имеющиеся в наличии спецификации и сто раз проверить свои пакеты на правильность. На седьмой же день Зоркий Глаз в моем лице заметил, что стандартная RTP-коммуникация не начинается сразу же с отправки DTMF-данных, а что ей предшествует непродолжительный обмен пакетами с сервером, которые выглядят несколько иначе.
Формат полезной нагрузки, объявленный в заголовке, равен 0, данных нет, зато есть собственно сама полезная нагрузка (payload), которая занимает 160 байт. Этот набор байтов различается во всех приходящих и уходящих сообщениях и выглядит составленным довольно случайно. Так или иначе, я не смогла найти информации о том, как именно он должен формироваться, поэтому каждый раз забивала его рандомами.

После того, как я стала отправлять эти вспомогательные пакеты перед каждым DTMF-сигналом, Wireshark наконец-то признал RTP-формат. Всё выглядело лучше, но коммуникация по-прежнему прерывалась, хотя сервер теперь от радости тоже стал меня забрасывать «пейлодными» пакетами.

Я уже и не знала, что еще бы могла сделать, но тут вспомнила, что RTP есть брат-неразлучник — RTCP. Проблема, по всей видимости, действительно была в нем: сервер пытался мне что-то отправить, но ему от меня постоянно приходили сообщения о том, что соответствующий порт закрыт. Поскольку я не хотела заморачиваться отправкой еще и RTCP-пакетов, я начала просто с открытия чакры порта:

Это оказало решающее воздействие: абонент получил моё сообщение «305*1*66» на пейджер!

Заключение

В последних строках моей телеги хотелось бы подчеркнуть, что это мой первый пост на Хабре, так что не судите меня строго. Я совершенно не считаю себя гуру телематики или чего-либо ещё. Просто при написании исходного кода очень много времени ушло на поиск информации. Что-то я находила в спецификациях, которые от начала до конца в один присест осилить было сложновато, что-то было описано нормальным языком, но как-то неярко мелким шрифтом на полях, что-то я делала наугад. Так что в какой-то момент просто решила, что если у меня всё получится, я опишу все свои действия в одном месте и оставлю это индексироваться где-нибудь в интернете.

Так что очень надеюсь, что хоть кому-то моя статья пригодится или хотя бы покажется интересной.

Приколы,

Стихи

Сообщения на пейджер

«Срочно узнай номер моего пейджера и скинь мне его на него.»

Сообщение на пейджеp:
«Лена, не pаскачивай так сильно бедpами, меня yкачивает. Твой ПЕЙДЖЕР. «

Абонент:
— Архив за несколько дней прочитайте, пожалуйста.
Оператор читает:
— Рома, у меня задержка. — Рома, я еду к врачу.

— Рома, ты скоро станешь папой. — Рома, у нас будет ребенок.
Абонент неожиданно разражается хохотом:
— А мне по барабану, меня Дима зовут.

Новый русский говорит другу:
— Мой пейджер 32-04. И запомнить легко: 32 зуба и 4 пальца.

«Позвони мне на пейджер. Очень хочу услышать твой голос.»

«Все ушли. Остались я и Чари. Подпись — Чари.»

— Девушка! У Вас интервал есть?
— Да.
— Дайте ему через интервал.

— Миша — это подпись?
— Hет! Зовут меня так.

— Это пункт приема сообщений?

— Девушка, Вы пейджер?

«Ты где? Я тебя заждался. Когда подойдешь, ударь по моей машине, я тебя услышу.»

— Поставьте, пожалуйста, 3 восклицательных знака вопроса.

«Мы больше не будем прелюбодействовать тебе на нервы.»

— Девушка, прочитайте ему, пожалуйста, с выражением эту информацию.

— Hазовите, пожалуйста, номер абонента.
— Вы мне эти буржуазные штучки бросьте.

«Позвони мне завтра в любое удобное для тебя время с 7 до 8 утра.»

«Приезжай ко мне непосредственно в квартиру.»

«Включи пейджер и перезвони мне.»

«Я и баранья нога едем домой. Мама.»

«Сообщи стоимость вешалки под плечики.»

«Прошу обеспокоить Вячеслава Михайловича в дому.»

«У меня все нормально. Меня пронесло.»

«Оля, ты обещала 2 инвалидов. Жду. Папа.»

— Долбаните ему пару раз, чтобы он понял.

Hетрезвый голос поздно вечером:
— Секретарша срочно вызывается в офис для выполнения своих прямых обязанностей.

«Как только проснетесь и соберетесь ехать к Шурику, срочно сейчас перезвони мне домой.»

«Hе забудь в субботу привезти постирать пеленки и малыша.»

Диктует:
«Света — тире — позвони. Постскриптум — Илья.»

«Позвони мне в автомат.»

«Дверь пришла. Жду дома. Саша.»

Сообщение в 11 часов:
«Приезжай срочно в 15 часов на Войковскую.»
— Приезжай срочно? Сейчас только 11.
— Да он успеет, он близко живет.

«Милый, я вчера забыла юбку в твоей машине. Верни ее, пожалуйста.»

— Это все сообщение?
— Hу, добавьте ему еще от себя.

«Если ты в пределах телефона, позвони. Мама.»

— Дайте ему эту информацию 2 раза через раз.
— Извините, это как?
— Как, как! 2 раза через 2 минуты.

«Сижу на фонтане. Жду дальнейших указаний.»

«Жду звонка в натуре. Меня кинули на телефон.»

В окошке примечаний указано пожелание абонента дублировать сообщения 2 раза через 10 минут:
— Девушка, дайте ему 2 раза через 5 минут.
— Hе могу! У него стоит 2 раза через 10-ть.

«Срочно вызывай сантехника. У нас нет памперсов и еды.»

«Слава, тебя ждет дома Андрей и звонок из Спектрсервиса.»

«Дублируйте им пару раз. Они люди с гор, читать умеют плохо.»

«Девушка, передайте с акцентом, пожалуйста!»

«Вася, будешь идти мимо моей комнаты, занеси мне мои штаны и галстук.»

С мучительными паузами:
— Ехай за мной как можно быстро!
— Приезжай за мной как можно быстрее?
— О! Точно!

Претензия:
— Почему у вас с 20 до 22 не работал оператор?
— Какой номер оператора?
— Откуда я знаю? Он же не работал.

— Передайте передачу.
— Девушка, передайте, пожалуйста, сообщение!
— Хорошо! Передаду.

«Твоя сестра разжирела как Монтсеррат Кабалье. Купи ей 2 упаковки пластыря для похудения, и пусть она его жрет пачками.»

Звонит абонент и жалуется, что ему не пришли сообщения. Оператор предлагает сделать повтор сообщений за данный промежуток времени и вместе дождаться прихода информации. Абонент соглашается.
Проходит минута, оператор спрашивает:
— Поступила информация или нет?
— Откуда я знаю. Я — дома, а пейджер — в машине.

«Милый, я хочу или гамбургер, или «Сникерс», или тебя. Лена.»

«Дорогая, позвони мне, пожалуйста, по поводу вечера. Хочу пригласить тебя в ресторан или в лес. Юрий.»

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

«Я еду по Москве, сам не знаю куда. Когда разберусь, сообщу, как меня искать. А вообще, я здесь до вечера воскресенья. Женя.»

«Алексей, будь готов с кирпичом подъехать к программисту, который покажет и объяснит программу. Руками понапрасну не размахивай. Hе дай бог выпадет. Сергей.»

Абонент: — Могу я продиктовать сообщение?
Оператор (флегматично): — Я для этого и живу.

«Подумай о совести, а то подумаешь о вечном. Срочно позвони.»

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *