• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 байт в сек.
 
Сверху Снизу