Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FreeRTOS + LwIP + PPP Как правильно переинициализировать соединение
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
=F8=
Есть девайс с LPC2148 + GSM модуль. На девайсе используется связка FreeRTOS + IwIP + PPP(который входит в IwIP).
Столкнулся с проблемой при переинициализации PPP соединения, для простоты опишу порядок действий:

tcpip_init();

while(1){
Включаю и инициализирую gsm модуль.

pppInit(); Инициализирую соединение
pppSetAuth(); Устанавливаю параметры авторизации
pppOverSerialOpen(); Поднимаю соединение pppOverSerialOpen

Затем создаю и затем открываю серверное соединение;
netconn_new();
netconn_bind();
netconn_listen();

Жду входящего соединения;
if(netconn_accept() == ERR_OK)
{
Принимаю входящее соединение, начинаю передавать данные от мк компу,
и в этот момент откручиваю антенну от модуля, через 5-10 сек мк понимает что регистрация в сети потеряна.
После чего закрываю дочернее соединение.
netconn_delete(conn);
}
И затем серверное
netconn_delete(srv_conn);
И затем ppp
pppClose()

}

Так, вот на следующем цикле при выполнении netconn_bind получаю ответ ERR_USE. Если подождать около 90 сек то на следующий вызов netconn_bind получаю ответ ERR_OK. Т.е. такое впечатление, что lwip пытается передать непереданные пакеты из буфера, хотя соединение уже закрыто.
Есть ли какой-то способ полностью переинициализировать стек? Просто ждать крайне нежелательно...
Golikov A.
Он не пакеты передает.

после того как вы вызывали netconn_delete, pppClose() оно не закрывается, а помечается на закрытие. В ЛвИП есть медленный таймер, вот именно он проверяет все открытые сессии и закрывает те что помечены как закрывающиеся. До этого момента все параметры соединения в общей таблице лежат, и при попытке сделать новое соединение получите сообщение что оно уже есть.

=F8=
Цитата(Golikov A. @ Jul 19 2013, 19:09) *
В ЛвИП есть медленный таймер, вот именно он проверяет все открытые сессии и закрывает те что помечены как закрывающиеся.

Не думаю, что дело в этом. Во-первых эта ситуация возникает только при обрыве связи в момент передачи от мк к компу т.е. явно связана с наличием данных в буфере, во-вторых перезапуск gsm модуля дело не быстрое то-есть между попытками создать соединение проходит около 20-30 сек - вполне достаточно для отработки внутренних механизмов закрытия соединения.
Golikov A.
если вы их вызывали... хотя может и мак чего то там думает себе...

у меня было 2 порта, один контрольный другой для данных так вот сервер на прослушку для данных я открывал только после того как было соединение по контрольному. А при закрытии контрольного закрывал сервер. И если быстро открыть закрыть, то получал ошибку что типа порт уже используется. А если погодя то все проходило. При этом через порт данных ничего не слалось.

Вроде бы в медленном таймере я глядел есть код который шерстит все соединения и находит те что открыты. Да там есть кусок который пытается дослать все что осталось, а также дослать сигнал разрыва соединения, но вроде бы все должно сработать в течении каких то секунд, а не десятков...
MALLOY2
Цитата
Во-первых эта ситуация возникает только при обрыве связи в момент передачи от мк к компу т.е. явно связана с наличием данных в буфере

Это ситуация связана с протоколом TCP он расчитан на то что связь может пропадать на короткое время, вот и Вас связь оборвалась а TCP коректно не закрылось, (для того что бы TCP коретно закрылось должен пройти обмен пакетами), вот и висит он в состояни CLOSE_WAIT.

Попробуйте установить опцию
#define SO_REUSE 1

P.S. Надеюсь вы не закрываете netconn переданный в listen, его не надо удалять без особой надобности при потере коннекта.А удаляете только созданные listen коннекты.
=F8=
Цитата
но вроде бы все должно сработать в течении каких то секунд, а не десятков...

Возможно дело в том, что у меня GPRS. После разрыва как правило меняется IP, так-что досылать некуда, вот и ждет (время ожидания ACK) * (кол-во попыток).
Цитата
Попробуйте установить опцию
#define SO_REUSE 1

Не помогло sad.gif
Цитата
Надеюсь вы не закрываете netconn переданный в listen, его не надо удалять без особой надобности при потере коннекта.

Закрываю, дело в том, что при презагрузке модуля может произойти смена сим-карты и соотв режима работы - может понадобиться открыть другой порт, или вместо серверного поднять клиентское соединение итд.

Kolyag87
У протокола TCP есть состояние TIME-WAIT. Об этом можно вкратце почитать http://xn--80ae9aggj.xn--p1ai/2009/01/19/tcp-time-wait/.

Чтобы вызвать процесс закрытия соединения, т.е. отправку пакета FIN (как сказано по указанной ссылке), необходимо вызвать netconn_close() для TCP-соединения (или netconn_disconnect() для UDP-соединения) перед вызовом netconn_delete(). После вызова netconn_close() необходимо сделать небольшую задержку, чтобы полностью произошел обмен пакетами FIN -> ACK. (примерно 2-3 сек). Параметр MSL (maximum segment lifetime) задается в файле tcp_impl.h (lwip-1.4.1) TCP_MSL (по умолчанию 60 сек). Поэтому пока период TIME-WAIT не закончится, вызов netconn_bind() будет выдавать ошибку.



У меня похожая проблема. МК выступает TCP-клиентом. После первого соединения с сервером, последующие не проходят. Повторный вызов функций netconn_new() возвращает NULL. И аналогично повторный вызов pppOverSerialOpen() возвращает ошибку. При этом пробовал делал задержки до 5 мин. Как будто вызов функций pppClose(), netconn_delete() не очищают память. Может не вызывать повторно функции pppOverSerialOpen() и netconn_new() и тогда все будет ОК.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.