• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Разработка ‘библиотеки’ малого webсервера на esp8266.

Vitaly

Member
адрес локального sntp сервера?

[HASHTAG]#define[/HASHTAG] DHCP_OPTION_NTP_SERVER 42 /* RFC 2132 8.3 */


PS
10 лет назад даже патч такой предлагали в lwip https://lists.gnu.org/archive/html/lwip-users/2005-09/msg00012.html
до сих пор опцию адреса ntp сервера с dhcp даже не запрашивают
похоже это просто никому не нужно

для чего тогда нужны куски кода работа с серверами из dhcp в sdklib\lwip\core\sntp.c для меня загадка
 
Последнее редактирование:

pvvx

Активный участник сообщества
адрес локального sntp сервера?
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_NTP_SERVER 42 /* RFC 2132 8.3 */
В текущем на ESP8266 DHCP это не обслуживается :(.
Вот полез сегодня в wifi_station_set_hostname() = Очередные $2000 - вызывает перезагруз.
Но опять китайцы нечего не дадут.
 

Vitaly

Member
В текущем на ESP8266 DHCP это не обслуживается
я заметил, в ps того сообщения дописывал

кстати не только в esp8266, я в родной git lwip сходил, нет там ничего про эту опцию
если в каких-то форках только кто сделал

ps
кстати да, в форках кое-где встречаю
 

pvvx

Активный участник сообщества
я заметил, в ps того сообщения дописывал

кстати не только в esp8266, я в родной git lwip сходил, нет там ничего про эту опцию
если в каких-то форках только кто сделал
Но это не сложно вставить, а вот починить события WiFi и другие ошибки китайцы не могут :) И обойти их почти никак, т.к. либы составлены большими объектниками, а все переписывать влом.
Счас пытаюсь добавить:
newopt.gif
А быстро не выходит. Т.к. приходится обходить баги китай-SDK. Скоро скину работающую версию...
Уже запутался в:
#if DEF_SDK_VERSION > 1302
[HASHTAG]#warning[/HASHTAG] Сделали патч?
wifi_station_set_hostname(pvar);
[HASHTAG]#else[/HASHTAG] ....
:)

PS: https://lists.gnu.org/archive/html/lwip-users/2005-09/msg00012.html
 
Последнее редактирование:

pvvx

Активный участник сообщества
да, было в моем PS ранее
Это вроде что типа у нас на устройстве есть NTP сервер :)
---
Обошел багу wifi_station_set_hostname(). Пусть живет в SDK - wifi_station_set_hostname() не пользуется в моей прошивке. :)
Кто видит багу реверсе СИ? :)
len = кол-ву буковок, а после выделения памяти на кол-во буковок туда пишется кол-во буковок + терминатор строки и каюк разметке памяти
 
Последнее редактирование:

pvvx

Активный участник сообщества
почему сервер? это мы в dhcp клиенте запрашиваем у dhcp сервера адреса ntp серверов

если спрашивать - отвечает)
остается потом полученные адреса использовать
Впишите, киньтесь - вставлю :)
-------
Пока, из-за массы накопившихся глюков в SDK, первый старт после прошивки с обнуленными настройками не пашет. После следующего рестарта всё работает. Ждем уже несколько патчей от китайцев ... SDK ver 100500 :)
Скоро уже официально ГОД, как они варят свой SDK... :( А он ещё имеет более нескольких сотен ошибок, а повышать плату за них по баунти не хотят. По тому только явные ошибки им отправляются, в надежде получить бабло на поддержку форума... На последние они отнекиваются типа им не починить и не платят!
Как повысят сумму за ошибку за $5000 то сразу можно будет выкупить на их-же бабло их контору :)
 
Последнее редактирование:

Vitaly

Member
вот в таком виде оно уже получает опцию ntp сервера с dhcp и в этом случае с него же и получает время
мне неясно нужна ли поддержка множественных серверов времени с dhcp и как в случае неработы такого сервера вернуться к обычной процедуре
откат на pool.ntp.org обязателен думаю, но все остальное типа множественных серверов скорее лишнее
app/include/sntp.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/app/include/sntp.h b/app/include/sntp.h
index 32a855a..ce3c668 100644
--- a/app/include/sntp.h
+++ b/app/include/sntp.h
@@ -8,6 +8,8 @@ bool sntp_inits(void);
void sntp_close(void);
time_t get_sntp_time(void);
+extern ip_addr_t dhcp_sntp_server_address;
+
void sntp_send_request(ip_addr_t *server_addr) ICACHE_FLASH_ATTR;
[HASHTAG]#endif[/HASHTAG] /* __SNTP_H__ */
include/lwipopts.h | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/include/lwipopts.h b/include/lwipopts.h
index f447108..92438da 100644
--- a/include/lwipopts.h
+++ b/include/lwipopts.h
@@ -794,6 +794,18 @@
[HASHTAG]#endif[/HASHTAG]
/*
----------------------------------
+ ------- DHCP NTP options ---------
+ ----------------------------------
+*/
+#ifndef LWIP_DHCP_NTP
+#define LWIP_DHCP_NTP 1
+#endif
+/** The maximum of NTP servers */
+#ifndef NTP_MAX_SERVERS
+#define NTP_MAX_SERVERS 1
+#endif
+/*
+ ----------------------------------
---------- DNS options -----------
----------------------------------
*/
include/lwip/dhcp.h | 1 +
1 file changed, 1 insertion(+)

diff --git a/include/lwip/dhcp.h b/include/lwip/dhcp.h
index 9e8fd0e..8f6925d 100644
--- a/include/lwip/dhcp.h
+++ b/include/lwip/dhcp.h
@@ -211,6 +211,7 @@ void dhcp_fine_tmr(void);
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_DOMAIN_NAME 15
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_PRD 31
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_STATIC_ROUTER 33
+#define DHCP_OPTION_NTP_SERVER 42 /* RFC 2132 8.3 */
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_VSN 43
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_NB_TINS 44
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_NB_TINT 46
app/web/sntp.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/app/web/sntp.c b/app/web/sntp.c
index 863eab0..b7dc329 100644
--- a/app/web/sntp.c
+++ b/app/web/sntp.c
@@ -578,19 +578,40 @@ void ICACHE_FLASH_ATTR sntp_request(void *arg)
[HASHTAG]#endif[/HASHTAG]
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("Sending request to %s.\n", buf_sntp_server_addresses));
+
/* initialize SNTP server address */
+
+ ip_addr_t *dhcpntp;
+ dhcpntp = &dhcp_sntp_server_address;
+
+
#if SNTP_SERVER_DNS
- err = dns_gethostbyname(buf_sntp_server_addresses,
+ if (!ip_addr_isany(dhcpntp))
+ {
+ sntp_server_address=*dhcpntp;
+ err = ERR_OK;
+ }
+ else
+ {
+ err = dns_gethostbyname(buf_sntp_server_addresses,
&sntp_server_address, sntp_dns_found, NULL);
if (err == ERR_INPROGRESS) {
/* DNS request sent, wait for sntp_dns_found being called */
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
return;
}
+ }
[HASHTAG]#else[/HASHTAG] /* SNTP_SERVER_DNS */
+ if (!ip_addr_isany(dhcpntp))
+ {
+ sntp_server_address=*dhcpntp;
+ err = ERR_OK;
+ }
+ else
+ {
err = ipaddr_aton(buf_sntp_server_addresses, &sntp_server_address)
? ERR_OK : ERR_ARG;
-
+ }
[HASHTAG]#endif[/HASHTAG] /* SNTP_SERVER_DNS */
if (err == ERR_OK) {
app/sdklib/lwip/core/dhcp.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/app/sdklib/lwip/core/dhcp.c b/app/sdklib/lwip/core/dhcp.c
index f806f4b..7da88ad 100644
--- a/app/sdklib/lwip/core/dhcp.c
+++ b/app/sdklib/lwip/core/dhcp.c
@@ -116,7 +116,8 @@
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_IDX_SUBNET_MASK 6
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_IDX_ROUTER 7
[HASHTAG]#define[/HASHTAG] DHCP_OPTION_IDX_DNS_SERVER 8
-#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS)
+#define DHCP_OPTION_IDX_NTP_SERVER (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS)
+#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_NTP_SERVER + NTP_MAX_SERVERS)
/** Holds the decoded option values, only valid while in dhcp_recv.
@todo: move this into struct dhcp? */
@@ -126,6 +127,9 @@ u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
@todo: move this into struct dhcp? */
u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
+ip_addr_t dhcp_sntp_server_address;
+
+
[HASHTAG]#define[/HASHTAG] dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
[HASHTAG]#define[/HASHTAG] dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
[HASHTAG]#define[/HASHTAG] dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
@@ -288,12 +292,13 @@ dhcp_select(struct netif *netif)
dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr)));
- dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 12/*num options*/);
+ dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 13/*num options*/);
dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
dhcp_option_byte(dhcp, DHCP_OPTION_DOMAIN_NAME);
+ dhcp_option_byte(dhcp, DHCP_OPTION_NTP_SERVER);
dhcp_option_byte(dhcp, DHCP_OPTION_NB_TINS);
dhcp_option_byte(dhcp, DHCP_OPTION_NB_TINT);
dhcp_option_byte(dhcp, DHCP_OPTION_NB_TIS);
@@ -579,6 +584,19 @@ dhcp_handle_ack(struct netif *netif)
n++;
}
[HASHTAG]#endif[/HASHTAG] /* LWIP_DNS */
+
+#if LWIP_DHCP_NTP
+ /* NTP servers */
+ n = 0;
+ while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n) && (n < NTP_MAX_SERVERS)) {
+ //ip_addr_t ntp_addr;
+ //ip4_addr_set_u32(&ntp_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n)));
+ //dhcp_ntp_setserver(n, &ntp_addr);
+ ip4_addr_set_u32(&dhcp_sntp_server_address, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n)));
+ n++;
+ }
+#endif /* LWIP_DHCP_NTP */
+
}
/** Set a statically allocated struct dhcp to work with.
@@ -901,11 +919,12 @@ dhcp_discover(struct netif *netif)
}
}
[HASHTAG]#endif[/HASHTAG] /* LWIP_NETIF_HOSTNAME */
- dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 12/*num options*/);
+ dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 13/*num options*/);
dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
+ dhcp_option_byte(dhcp, DHCP_OPTION_NTP_SERVER);
dhcp_option_byte(dhcp, DHCP_OPTION_DOMAIN_NAME);
dhcp_option_byte(dhcp, DHCP_OPTION_NB_TINS);
dhcp_option_byte(dhcp, DHCP_OPTION_NB_TINT);
@@ -1451,6 +1470,14 @@ again:
LWIP_ASSERT("len >= decode_len", len >= decode_len);
decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
break;
+ case(DHCP_OPTION_NTP_SERVER):
+ /* special case: there might be more than one server */
+ LWIP_ASSERT("len % 4 == 0", len % 4 == 0);
+ /* limit number of NTP servers */
+ decode_len = LWIP_MIN(len, 4 * NTP_MAX_SERVERS);
+ LWIP_ASSERT("len >= decode_len", len >= decode_len);
+ decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
+ break;
case(DHCP_OPTION_LEASE_TIME):
LWIP_ASSERT("len == 4", len == 4);
decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
кажется ничего не забыл
 
Последнее редактирование:

pvvx

Активный участник сообщества
мне неясно нужна ли поддержка множественных серверов времени с dhcp и как в случае неработы такого сервера вернуться к обычной процедуре
откат на pool.ntp.org обязателен думаю, но все остальное типа множественных серверов скорее лишнее
Ну ESP8266 ещё не обладает интеллектом и я бы ему не доверил копаться в кучах серверов NTP... Пусть подрастет... :)
Представьте себе откат, когда введу поддержку перебора штук 6 соединений ST->AP и т.д... o_O
Та и счас - от 4 соединений к AP. По какому пользовать NTP?
 
Последнее редактирование:

PostLast

Member
починить события WiFi
Как обрабатывается потеря связи модуля с точкой доступа? Наблюдаю неприятную проблему с тем, что если точка доступа пропадает на время до примерно до 5 секунд то модуль не восстанавливает с ней связь и соединение рвется. Легко имитируется если связать порты модулей, а потом остановить модуль с поднятой точкой доступа на секунду.
 

pvvx

Активный участник сообщества
Как обрабатывается потеря связи модуля с точкой доступа? Наблюдаю неприятную проблему с тем, что если точка доступа пропадает на время до примерно до 5 секунд то модуль не восстанавливает с ней связь и соединение рвется. Легко имитируется если связать порты модулей, а потом остановить модуль с поднятой точкой доступа на секунду.
Про то и писалось. Нет возможности изменить время реконнекта и его алгоритма. Китайцам данный баг уже послан давно. Пока применен типа патч, обходящий несколько ошибок китай-SDK и всё-же соединяющийся через несколько итераций пауз указанных на Web странице Конфига WiFi в ReConnect. Это работает при работе AP+ST. Если поставить ReConnect в 1, то будет вечный реконнект (не будет исполняться никакого вмешательства в сандартный китай-алго), при котором доступа к AP вообще не будет.
Беда в том, что если модулю указано соединяться с внешней AP, то нет доступа к его AP и на модуле вечно исполняется процедура сканирования станций для поиска точки подключения. Каждые пару секунд вызывается событие EVENT_STAMODE_DISCONNECTED. Но в нем нельзя ничего переключить.
Исполнение wifi_station_disconnect() чтобы больше не соединялся вызывает отваливание вообще всего - и ST и AP модуля (наверно потерян канал и разные таймеры у китайцев).
Исполнение wifi_set_opmode(AP и т.д.) - вызывает вообще Fatal exception (28).
Ждем патч от китайцев... Но они не чинят, т.к. должны оплатить обещанное по своей программе. Ищут варианты как обойти и не платить, а не занимаются исправлением :)
На указанные ошибки, приводящие в их SDK в событиях WiFi к Fatal exception (28) они прислали новые либы SDK 1.3.0 версии 2, части которых и стоят в моем проекте. Но в них этого и многое другое не исправлено...
Так-же повторю и здесь: Кто возьмется трясти бабло с Espressif ?
Все, что они пришлют пока направляется на поддержку данного сайта и разговором с ними по багам занимается @Victor.
 
Последнее редактирование:

PostLast

Member
Обновил сборку. WiFi в ReConnect решает проблему доступности АP когда модуль не может подключиться. Это гадость но не фатальная. Все равно спасибо
Я же говорю о проблеме, когда модуль не пытается переподключиться, если точка доступа пропала на короткий промежуток времени. Эту проблему можно вероятно решать на уровне протокола и переконнекта, но это уже частный случай.
 

pvvx

Активный участник сообщества
Обновил сборку. WiFi в ReConnect решает проблему доступности АP когда модуль не может подключиться.
Слепил новый алго :) Перезалил.
Если за 3 раза не соединилось, то вступает пауза в ReConnect. Если не соединяется, а кто подключился к AP, то следующие попытки подключения ST будут отложены когда отключатся клиенты от AP.
При выборе новой конфиги для ST в Web и наличии клиентов в AP, попытка подключиться ST к новой AP производится 3 раза. Если подключиться ST не удалось, то попытки будут отложены когда отключатся клиенты от AP.

Я же говорю о проблеме, когда модуль не пытается переподключиться, если точка доступа пропала на короткий промежуток времени. Эту проблему можно вероятно решать на уровне протокола и переконнекта, но это уже частный случай.
Не очень понятно. Прошу описать подробнее, при каких вариантах и почему это вдруг "модуль не пытается переподключиться".
 
Последнее редактирование:

PostLast

Member
Собираем стенд из двух модулей
1. "модуль клиент" подключается к точке доступа "модуль точка"
2. делаем мост по 12345 порту в котором "модуль клиент" подключается к серверу на "модуль точка" ( можно наоборот результат идентичен)
шлем данные в UART обеих модулей и радостно видим как они выходят на другом модуле. Теряются данные или проходят не важно.
3.Останавливаем работу "модуля точка" сигналом Reser поданным на соответствующий вывод секунд на 10. Видим как после снятия этого сигнала система передачи восстановится через несколько секунд.
4. А теперь повторяем эксперимент но reset зажимаем на секунду. Передачи нет. Восстанавливается или рестартом "модуля клиент" или reset "модуль точка".
По сути мы имитируем работу на границе дальности связи модулей.
Вроде повторяется и на AT прошивке но надо проверять.
P/s для тестов создал простой скрипт на Node читающий данные со страницы. Если модуль Node коннектится к "модуль точка" то все о.к., но я там и сам каждый запрос создаю подключение и проверяю перед запросом данных наличие подключения. Если создать точку доступа на Node то ситуация полностью повторяется.
 
Последнее редактирование:

pvvx

Активный участник сообщества
@PostLast
Если тайминги соединения "TCP recved timeout" и "TCP close timeout" установлены нуль и не используется RTS/CTS тогда ничего работать не будет никогда.
 

pvvx

Активный участник сообщества
вот в таком виде оно уже получает опцию ntp сервера с dhcp
Вставил всё. Но у меня никогда не вызывается dhcp_handle_ack(), по тому пока не понимаю, как это должно работать в стандартной конфигурации.
Кто должен запросить и ответить, чтобы отработала ip4_addr_set_u32(&dhcp_sntp_server_address, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n))) ?
 
Сверху Снизу