Шлюз для UDP між Wi-Fi та LoRa

Робимо шлюз між Wi-Fi та LoRa для UDP

Шлюз для UDP між Wi-Fi та LoRa

У мене була дитяча мрія — видати кожному побутовому «безВайФайному» пристрою квиток у мережу, тобто IP-адресу та порт. Згодом я зрозумів, що не варто відкладати. Треба взяти та зробити.

Технічне завдання

Зробити шлюзом M5Stack із встановленим Модулем LoRa (рисунок 1). Шлюз буде підключено до Wi-Fi-мережі, в якій отримати по DHCP локальну IP-адресу. Шлюз з певною періодичністю буде вести мовлення в «LoRa-ефір» своє ім'я (аналог SSID для Wi-Fi) і діапазон допустимих портів, щоб інші пристрої знали, що є така мережа, до якої можна підключитися і в якому діапазоні можна обирати вільний порт. Оскільки це буде прототип, автентифікація не на цей раз. Нові пристрої-клієнти будуть знаходити доступну мережу LoRa і передавати їй обраний порт. Після того, як шлюз отримав від нового клієнта порт, перевіряє чи він вільний, якщо так, то реєструє нового клієнта і починає слухати даний порт на власному асинхронному UDP-сервері. Після реєстрації клієнт отримає згоду чи відмову використання заявленого порту. Порядок роботи відображено у таблиці 1.

Шлюз для UDP між Wi-Fi та LoRa
Малюнок 1

Таблиця 1

сторона
напрямок та дані
сторона
сеанс

[ клиент ]
<— сигнал-маяк —
[ шлюз ]
0xA1

[ клиент ]
— выбранный порт —>
[ шлюз ]
0xB1

[ клиент ]
<— согласие или отказ —
[ шлюз ]
0xA2

[ клиент ]
— UPD-пакет —>
[ шлюз ]
0xB2

[ клиент ]
<— UPD-пакет —
[ шлюз ]
0xA3

[ сеть ]
<— UPD-пакет —
[ шлюз ]
0xC1

Переді мною на столі лежать усілякі Модулі для M5Stack і нудьгують. Давайте візьмемо LoR'у і розважимося з нею. Сама концепція модулів чудова! Що тут скажеш? Але, модулі у мене першої ревізії, в яких найжахливіша вбудована антена, виконана на гнучкій друкованій платі та приклеєна до бічної стінки корпусу. Я проводив одного разу польові тести таких модулів (можна подивитися на російськомовному каналі на YouTube):

Відтворити відео

Природно, довелося видалити ці рудименти та впаяти стандартні спіралеподібні антени, які йдуть у комплекті з Ra-01. Після такої кастомізації дальність зв'язку помітно покращала, але з'явився побічний момент — антена має діаметр більший, ніж допустима відстань між модулями. Довелося відмовитись від Завершального модуля на час проекту.

Перші труднощі від сихронної тугості

Здавалося б, бери бібліотеку WiFiUdp.h, де все є для комфортного існування UDP-сервера, так ні. Бібліотека розрахована на підняття синхронного сервера, який, на превеликий жаль, не може обслуговувати одночасно кілька з'єднань в одному потоці. Така бібліотека не підходить для поточного завдання. Довелося випити багато чашок чаю і пошукати бібліотеку, яка дозволить підняти асинхронний UDP-сервер, здатний підтримувати багато з'єднань одночасно. Така бібліотека знайшлася. AsyncUDP.h. У чому відмінність синхронного сервера від асинхронного? Давайте розглянемо шість епізодів малюнку 2, у яких очевидно відображені варіанти роботи сокетів.

Шлюз для UDP між Wi-Fi та LoRa

Малюнок 2

У головних ролях:

Людина в ролі Сокет;

голуб в ролі З'єднання;

Лист в ролі Данних.

Епізод А. Синхронний сокет без таймууту

Людина стоятиме доти, доки Голуб не принесе йому Листа.

Епізод B. Синхронний сокет із таймаутом

Людина чекає на обговорений з Голубом час, і, якщо той не прилетить вчасно, то Людина піде.

Епізод C. Синхронний сокет із багатопоточністю

Людина байдикує і спостерігає, як Голуби самі по собі доставляє Листи.

Епізод D. Асинхронний сокет (коли ще нічого отримувати)

Людина займається своїми улюбленими справами, але не забуває про Голубів.

Епізод E. Асинхронний сокет (коли є що отримати)

Людина ненадовго відволіклася від своїх справ, щоб отримати листа від Голубя.

Епізод F. Асинхронний сокет із багатопоточністю

Людина займається своїми справами і спостерігає, як Голуби самі собою доставляють Листи.

Якщо Ви були уважні, то напевно мали помітити, що нашийники на Голубях у кожному епізоді мають певне забарвлення. І це недарма. В епізоді A та B на сервері працює лише один сокет і все. В епізоді C працюють уже два сокети. В епізодах D, E та F вже по три сокети. «Чому там два, а тут три?» - Запитайте Ви. Це умовно 2 і 3, насправді замість 2 може бути 20, а замість трьох 200. Завдання показати, що асинхронні сокети не так залізо, як синхронні.

Куди скільки вміщується?

Давайте розглянемо таблицю 1, у якій наведено структуру UDP-пакета і подумаємо, що з цим зробити.

Таблиця 1. Структура UDP-пакету

біти
0 - 15
16 - 31

0-31
Порт відправника (Source port)
Порт одержувача (Destination port)

32-63
Довжина датаграми (Length)
Контрольна сума (Checksum)

64- ...
Дані (Data)

Додамо на початок цієї таблиці ще одне поле сеанс (1 Байт). Цього для цього проекту вистачить. Виходячи з сеансу пристрій буде знати, що робити з пакетом далі. Тепер придумаємо коди для сеансів та запишемо їх у таблицю 2.

Таблиця 2. Пояснення до сеансів

Код
Назва
Пояснення

0xA1
Маяк
Шлюз мовить ім'я LoRa-мережі та діапазон допустимих портів з певною періодичністю. Це потрібно, щоб нові клієнти побачили доступну мережу, а поточні клієнти, коли немає передач могли визначати рівень сигналу.

0xB1
Заявка
Коли клієнт виявив мережу, то він висилає порт.

0xA2
Згода чи відмова
Якщо запитаний клієнтом порт вільний, сервер відповідає згодою, а інакше відмовою.

0xB2
Up-лінк
Коли клієнт передає UDP пакет шлюзу.

0xA3
Down-лінк
Коли шлюз передає UDP пакет клієнту.

0xC1
Продовження Up-лінка
Коли шлюз надсилає UDP-пакет у локальну мережу.

Добре. Тепер обговоримо склад сеансів у таблиці 3.

Таблиця 3. Сеанси

Назва сеансу
Склад

Маяк
Код сеансу (1 Байт) + Ім'я LoRa-мережі (4 Байт) + Початковий порт (2 Байт) + Кінцевий порт (2 Байт)

Заявка
Код передачі (1 Байт) + Ім'я LoRa-мережі (4 Байт) + Переважний порт (2 Байт)

Згода чи відмова
Код передачі (1 Байт) + Ім'я LoRa-мережі (4 Байт) + порт (2 Байт) + Результат (1 Байт)

Up-лінк
Код передачі (1 Байт) + Ім'я LoRa-мережі (4 Байт) + Віддалена IP-адреса (4 Байт) + Віддалений порт (2 Байт) + Локальна IP-адреса (4 Байт) + Локальний порт (2 Байт) + Розмір даних (2 Байт) + Дані

Низхідне посилання
Код передачі (1 Байт) + Ім'я LoRa-мережі (4 Байт) + Віддалена IP-адреса (4 Байт) + Віддалений порт (2 Байт) + Локальна IP-адреса (4 Байт) + Локальний порт (2 Байт) + Розмір даних (2 Байт) + Дані

Продовження Up-лінка
Віддалена IP-адреса (4 Байт) + Віддалений порт (2 Байт) + Розмір даних (2 Байт) + Дані

Написав два клієнти для Ардуїно та для M5Stack. на відео можете подивитися, як це працює. У межах квартири проблем ніяких немає, польові тести поки що не робив.

Вихідний код доступний на GitHub по за посиланням

Дізнатись більше про Базовий пристрій M5Stack та купити можна тут

Вибрати бездротові модулі LoRa для базового пристрою можна тут

Буду радий, якщо цей проект буде Вам корисним. Дуже дякую за приділений час!

Список літератури та (або) джерел:

Джерело: habr.com

Купити надійний хостинг для сайтів із захистом від DDoS, VPS VDS сервери 🔥 Купити надійний хостинг для сайтів із захистом від DDoS, VPS VDS сервери | ProHoster