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

Сервер и обмен данными с помощью "lwip_open_demo_app"

Valdior

New member
Добрый день!
Задача стоит в управлении микропроцессорными устройствами через телефон с андроидом, с помощью esp8266.
Пытаюсь настроить сервер (esp за главного) с помощью примера "lwip_open_demo_app" в данной UDK на Eclipse.
Сервер поднимается, связь с телефоном настраивается, также получилось посылать data с телефона на esp8266, а вот в обратную сторону никак - не могу найти необходимой функции. Вернее, она вроде есть (tcpsrv_sent_data), но в примере она не применяется, и как ее использовать я так и не понял. постоянно ошибки в попытке назвать адресата. Так же, возможно необходимо не с помощью TCP, а с помощью UDP обмениваться пакетами?
Можете что-то подсказать?
Код:
/******************************************************************************
* FunctionName : tcpsrv_sent_data
* Description : sent data for server
* Parameters : void *arg -- client or server to send
* uint8* psent -- Data to send
* uint16 length -- Length of data to send
* Returns : none
*******************************************************************************/
err_t ICACHE_FLASH_ATTR tcpsrv_sent_data(TCP_SERV_CONN * ts_conn, uint8 *psent, uint16 length)
{
if (ts_conn == NULL || psent == NULL || length == 0) {
return ERR_ARG;
}
//if(ts_conn->state == ESPCONN_WAIT) return;
struct tcp_pcb *pcb = ts_conn->pcb;
err_t err;
u16_t len = length;

if (tcp_sndbuf(pcb) < length) len = tcp_sndbuf(pcb);
if(len) {
u16_t mss2 = (tcp_mss(pcb)<< 1); // <<2 ???!!!
if(len > mss2) len = mss2;
do {
err = tcp_write(pcb, psent, len, 0);
if (err == ERR_MEM) len /= 2;
} while (err == ERR_MEM && len > 1);
if (err == ERR_OK) {
ts_conn->ptrbuf = psent + len;
ts_conn->cntr = length - len;
err = tcp_output(pcb);
}
else ts_conn->state = ESPCONN_CLOSE;
}
else return tcp_output(pcb);
return err;
 

pvvx

Активный участник сообщества
Вам надо назначить функцию
err_t ICACHE_FLASH_ATTR tcpsrv_received_data(TCP_SERV_CONN *ts_conn, uint8 *data_ptr, uint16 data_cntr) которая будет принимать данные и
в ней, после приема надо вызывать отправку функцией tcpsrv_sent_data(), если у вас алгоритм прием-ответ.
При отсылке длинного ответа надо ждать передачи первого куска с помощью назначенной err_t ICACHE_FLASH_ATTR tcpsrv_sent_callback(TCP_SERV_CONN *ts_conn)
А так, как при отдаче используется память, то может потребоваться освобождать её в назначенной void ICACHE_FLASH_ATTR tcpsrv_disconnect_calback(TCP_SERV_CONN *ts_conn)
Так-же при установке соединения может потребоваться что-то изменить в назначенной err_t ICACHE_FLASH_ATTR tcpsrv_listen(TCP_SERV_CONN *ts_conn)
Включаются ваши функции так:
p->func_discon_cb = tcpsrv_disconnect_calback;
p->func_listen = tcpsrv_listen;
p->func_sent_cb = tcpsrv_sent_callback;
p->func_recv = tcpsrv_received_data;
 

Valdior

New member
Спасибо! Все заработало)
Как я сам не додумался, что надо в функции, где уже есть TCP_SERV_CONN *ts_conn тут же и отправку делать.
 

Valdior

New member
Вам надо назначить функцию
err_t ICACHE_FLASH_ATTR tcpsrv_received_data(TCP_SERV_CONN *ts_conn, uint8 *data_ptr, uint16 data_cntr) которая будет принимать данные и
в ней, после приема надо вызывать отправку функцией tcpsrv_sent_data(), если у вас алгоритм прием-ответ.
При отсылке длинного ответа надо ждать передачи первого куска с помощью назначенной err_t ICACHE_FLASH_ATTR tcpsrv_sent_callback(TCP_SERV_CONN *ts_conn)
А так, как при отдаче используется память, то может потребоваться освобождать её в назначенной void ICACHE_FLASH_ATTR tcpsrv_disconnect_calback(TCP_SERV_CONN *ts_conn)
Так-же при установке соединения может потребоваться что-то изменить в назначенной err_t ICACHE_FLASH_ATTR tcpsrv_listen(TCP_SERV_CONN *ts_conn)
Включаются ваши функции так:
p->func_discon_cb = tcpsrv_disconnect_calback;
p->func_listen = tcpsrv_listen;
p->func_sent_cb = tcpsrv_sent_callback;
p->func_recv = tcpsrv_received_data;
Такой еще вопрос:
если писать ответ в функции tcpsrv_received_data(), то получается, что мы затягиваем выполнение функции прерывания по приему данных, и если в этот момент придут данные, а мы все еще выполняем старое прерывание, будет ли нормально работать прога?
 

pvvx

Активный участник сообщества
Такой еще вопрос:
если писать ответ в функции tcpsrv_received_data(), то получается, что мы затягиваем выполнение функции прерывания по приему данных, и если в этот момент придут данные, а мы все еще выполняем старое прерывание, будет ли нормально работать прога?
Будет.
Для ограничения приема управляют "размером приемного окна TCP", там это выставляется битом throttle_data_reception и когда надо "окно" восстанавливают вызовом tcpsrv_unrecved_win(ts_conn).
Так-же данный код взят из старой версии Web-свалки и там нет управления отключением алгоритма Nagle и устаревший алгоритм передачи данных, не позволяющий достигнуть с Микрософт TCP стеком (Google Chrome) трансфера за 1 Мегабайт в секунду, а получится всего до 1460*5 байт в сек.
 
Сверху Снизу