Шлюз за UDP между Wi-Fi и LoRa

Създаваме шлюз между Wi-Fi и LoRa за UDP

Шлюз за UDP между Wi-Fi и LoRa

Имам детска мечта — да дам на всяко домашно устройство без Wi-Fi билет за мрежата, т.е. IP адрес и порт. След известно време осъзнах, че не бива да отлагам. Трябва да взема и да направя.

Техническо задание

Да направим шлюз с M5Stack с инсталиран Модул LoRa (изображение 1). Шлюзът ще бъде свързан към Wi-Fi мрежа, в която получава локален IP адрес чрез DHCP. Шлюзът периодично ще излъчва в "LoRa-ефира" името си (аналог на SSID за Wi-Fi) и диапазона на допустимите портове, за да могат другите устройства да знаят, че има такава мрежа, към която могат да се свържат, и в какъв диапазон могат да изберат свободен порт. Тъй като това ще бъде прототип, аутентификацията не е в този случай. Новите клиентски устройства ще намерят наличната LoRa мрежа и ще предадат избрания порт. След като шлюзът получи от нов клиент порт, проверява дали е свободен, ако да, тогава регистрира новия клиент и започва да слуша на определен порт на собствен сървър за асинхронен UDP. След регистрацията клиентът получава одобрение или отказ за използване на заявения порт. Процесът на работа е показан в таблица 1.

Шлюз за UDP между Wi-Fi и LoRa
Изображение 1

Таблица 1

страна
направление и данни
страна
сесия

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

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

[ клиент ]
<— одобрение или отказ —
[ шлюз ]
0xA2

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

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

[ мрежа ]
<— UPD пакет —
[ шлюз ]
0xC1

Пред мен на бюрото лежат различни Модули за M5Stack и скучаят. Нека вземем LoRa и да се забавляваме с нея. Самата концепция на модулите е прекрасна! Какво тук да се каже? Но, модулите са от първата ревизия, в които ужасната вградена антена е направена на гъвкава печатна платка и е залепена за страничната стена на корпуса. Проведох веднъж полеви тестове на такива модули (можете да ги видите на руския YouTube канал):

Възпроизведи видео

Естествено, наложи се да премахна тези рудименти и да споя стандартни спираловидни антени, които идват в комплекта с Ra-01. След такава кастомизация обхватът на връзката значително се подобри, но се появи и страничен момент — антена с диаметър по-голям от допустимото разстояние между модулите. Наложи се да се откажа от Завършващия модул за времето на проекта.

Първите трудности от синхронната стегнатост

Изглежда, просто вземи библиотеката WiFiUdp.h, където всичко е налично за комфортното функциониране на UDP сървър, така че не е. Библиотеката е предназначена за стартиране на синхронен сървър, който, за дълбоко съжаление, не може да обслужва едновременно няколко връзки в един поток. Тази библиотека не е подходяща за текущата задача. Бях принуден да изпия много чаши чай и да потърся библиотека, която позволява стартиране на асинхронен UDP сървър, способен да поддържа много връзки едновременно. Такава библиотека беше намерена — AsyncUDP.h. Каква е разликата между синхронен и асинхронен сървър? Нека разгледамеsix епизода на фигура 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 Байта) + Данни

Down-link
Код за предаване (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