реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> IP/UDP/TFTP uIP v1.0, uIP-шники отзовитесь.
Цырен
сообщение Aug 20 2007, 12:51
Сообщение #16


Частый гость
**

Группа: Validating
Сообщений: 184
Регистрация: 26-06-07
Из: Санкт-Петербург
Пользователь №: 28 714



Кажется я ответил себе как отследить состояние каждого соединения для того, чтобы реализовать множественное подключение к моему серверу.
Ответ был как всегда под руками и никаких дополнительных глобальных переменных, отслеживающих состояние сервера не надо. Ответ вот где:

struct uip_udp_conn {
uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */
u16_t lport; /**< The local port number in network byte order. */
u16_t rport; /**< The remote port number in network byte order. */
u8_t ttl; /**< Default time-to-live. */

/** The application state. */
uip_udp_appstate_t appstate;
};

typedef struct tftp_state uip_udp_appstate_t;

struct tftp_state {
u16_t opcode; /* Êîä îïåðàöèè */
u16_t block_id; /* Íîìåð áëîêà */
u8_t *data; /* Óêàçàòåëü íà äàííûå */
};

Делая так:
struct uip_udp_conn *tftp_conn; // некое UDP-соединение
tftp_conn = (struct uip_udp_conn*)uip_udp_conn;
имеем доступ к состоянию текущего UDP-соединения (из таблицы UDP-соединений):

tftp_conn->appstate.opcode -код операции, которую данное соед. совершает (дает читать или записывать)
tftp_conn->appstate.block_id -какой блок данных он дает читать/записывать
tftp_conn->appstate.data -указатель на данные с которыми сервер должен сделать что-либо(записать/прочитать блок в/из файл).

Кому интересно:

Причем текущее соединение устанавливается только если:
1. в таблице UDP-соединений есть хоть одна запись с локальным номером порта TFTP(69 или иной не равный 0)
2. UDP-датаграмма предназначена именно порту текущего соединения
3. Текущее соединение "узнает" номер порта удаленного хоста или видит его впервые, но готов пообщаться, т.к. rport=0(типа сервер свободен и готов к новой связи)
4. Текущее соединение "узнает" IP-адрес удаленного хоста или видит его впервые, но готов пообщаться, т.к. tipaddr=0.0.0.0.
(IP-адрес проверяет IP)

При входе в наш обработчик APP_CALL() (у меня это void tftp_appcall(void)) надо:
1. определить состояние флага uip_flags( либо UIP_POLL либо UIP_NEWDATA)
1.1. Если UIP_POLL, то проверить условие истечения таймаута
1.2. Если UIP_NEWDATA, то проверить для какого порта именно предназначен пакет:
1.2.1 Если для порта 69, то создать новое соединение tftp_conn = uip_udp_new(&ripaddr, rport) и
обработать запрос (ничего другого быть и не может).
1.2.2 Если для нашего(а это проверялось еше в uip_process()), тогда обработать данные или
подтверждение.

З.Ы. При закрытии соединения (удаления ее из таблицы UDP-соединений) обязательно обнулять поля ripaddr и rport.
З.Ы. При инициализации надо создавать UDP-соединение в таблице под номером порта 69.
void tftp_init(void)
{
uip_ipaddr_t addr;
struct uip_udp_conn *c;

uip_ipaddr(&addr, 0,0,0,0);
c = uip_udp_new(&addr, HTONS(0)); // Адрес и номер порта удаленного хоста нулевые.
if(c != NULL) {
uip_udp_bind(c, HTONS(69)); // Стандартный порт TFTP
}
}
Go to the top of the page
 
+Quote Post
Usatyj
сообщение May 22 2008, 07:21
Сообщение #17


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 1-02-07
Пользователь №: 24 931



уважаемый Цырен!
поможите исходничком, а? не понимаю, как обрабатывать tftp_appcall (сущность его какая должна быть).
заранее благодарен.
Go to the top of the page
 
+Quote Post
Aprox
сообщение May 23 2008, 19:39
Сообщение #18


Местный
***

Группа: Участник
Сообщений: 374
Регистрация: 7-11-07
Из: Moscow
Пользователь №: 32 131



Цитата(Цырен @ Aug 20 2007, 16:51) *
Кажется я ответил себе как отследить состояние каждого соединения для того, чтобы реализовать множественное подключение к моему серверу.


Как я понял, вам нужен UDP сервер? Только что закончил такую разработку и прекрасно обошелся без готовых uIP, в которых сам черт ногу сломит. Суть проста. -Принимаем пакет, адресованный серверу по МАС, по IP, и по номеру порта. Выделяем запрос, обрабатываем его и выдаем пакет ответа в хидере которого, стоят МАС клиента, IP-клиента, и порт запроса клиента. Все эти данные выделяются из хидера запроса. Таким образом, UDP-сервер откликается всякому клиенту, кто грамотно к нему обратился. И никаких таблиц соединений и прочей лабуды не требуется.

Кстати, скорость передачи потока данных в пакетах UDP размером 1.5К у меня на STR912FAW44 получилась 96 Мbit/s Получилась только потому, что никакого готового софта uIP не использовал.
Go to the top of the page
 
+Quote Post
PoReX
сообщение Feb 5 2013, 12:17
Сообщение #19


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518



Подскажите с UDP на uIP v1.0. Никак не получается отправить пакет, хотя принимать получается.
Код
void uip_udp_appcall(void)
{
    if(uip_udp_conn->lport == HTONS(BOOTETH_LISTENUDPPORT))
    {
    //-----------------
        if(uip_newdata()) {udp_newdata(uip_udp_conn);}
    //-----------------
    }
}

обработчик принятых данных
Код
void udp_newdata(struct uip_udp_conn *udp_conn)
{
    struct uip_udp_state *s = &(udp_conn->appstate);
    struct uip_udp_conn *udp_connection;
    uint8_t *pBuffer,i;
    uint32_t posnum=0;
    uint32_t BytesLeft=bMIN(UIP_CONF_BUFFER_SIZE,uip_datalen());
    udp_connection=uip_udp_new(&udp_conn->ripaddr, udp_conn->rport);
        if(udp_connection==NULL)
            return;
        //-------------------
        //тут обработка полученных байт
        //-------------------
    uip_udp_remove(udp_connection);

}

отправка буфера по UDP
Код
void ETH_EthUDPFindResponse(void)
{
    //----------------------------------
    //формирование буфера
    //----------------------------------
    //memcpy(uip_appdata,ETH_TransmitBuffer,Len);
    //uip_udp_send(Len);    
    //uip_send(ETH_TransmitBuffer,(uint32_t)pBuffer-(uint32_t)ETH_TransmitBuffer);    
    uip_slen = Len;
    memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], ETH_TransmitBuffer, Len > UIP_BUFSIZE? UIP_BUFSIZE: Len);
  uip_process(UIP_UDP_SEND_CONN);
    uip_slen = 0;
}


Может есть у кого рабочий пример с UDP?


--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
Go to the top of the page
 
+Quote Post
podelkin
сообщение Feb 5 2013, 12:17
Сообщение #20





Группа: Участник
Сообщений: 14
Регистрация: 24-10-11
Пользователь №: 67 911



а lwip слишком тяжел? По мне так продвинутее на порядок
Go to the top of the page
 
+Quote Post
PoReX
сообщение Feb 5 2013, 12:18
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518



Цитата(podelkin @ Feb 5 2013, 16:17) *
а lwip слишком тяжел? По мне так продвинутее на порядок

Да, это проект bootloader'a, чем меньше размер тем лучше. lwIP используется в основной прошивке.


--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 5 2013, 15:08
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(PoReX @ Feb 5 2013, 16:17) *
Может есть у кого рабочий пример с UDP?

Есть рабочий пример. Как раз загрузчик.
Прикрепленные файлы
Прикрепленный файл  bootloader.zip ( 162.64 килобайт ) Кол-во скачиваний: 84
 
Go to the top of the page
 
+Quote Post
PoReX
сообщение Feb 6 2013, 19:08
Сообщение #23


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518



Цитата(scifi @ Feb 5 2013, 19:08) *
Есть рабочий пример. Как раз загрузчик.

Спасибо за пример, но что-то не получается. Вроде все так же делаю, а в чем причина не пойму. Может какую-нибудь мелочь упустил?
Во вложении проект в Keil и приложение для отправки UDP пакетов.

Только увидел, что у меня более старая версия uIP. Попробую завтра с вашей версией.
Прикрепленные файлы
Прикрепленный файл  STM32F107_UIP_UDP.zip ( 447.19 килобайт ) Кол-во скачиваний: 45
Прикрепленный файл  STM32F107_UIP_UDP_PC.zip ( 3.59 мегабайт ) Кол-во скачиваний: 39
 


--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
Go to the top of the page
 
+Quote Post
PoReX
сообщение Feb 7 2013, 09:27
Сообщение #24


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518



Одна проблема решилась. Оказывается uip шлет udp сообщения, но адрес получателя и порт нулевые, поэтому ближайший роутер отбрасывает это сообщение и я в Wireshark'е на компе его не вижу. После подключения STM к компу на прямую, сообщения стали видны, но проблема с неправильным адресом получателя и портом осталась. Насколько я понял, происходит это из-за того что при отправке сообщения uip использует первую структуру(соединение)
Код
struct uip_udp_conn
, в которой как раз и есть все нули в поле адреса и порта. Пробовал присвоить указателю
Код
uip_udp_conn
адрес структуры, полученной при создании нового соединения, но тогда сообщения вообще не отправляются.
CODE
void udp_newdata(struct uip_udp_state *s)
{

struct uip_udp_conn *udp_connection;
struct uip_udpip_hdr *hdr;
uint8_t *pBuffer;
uint32_t BytesLeft=bMIN(UIP_CONF_BUFFER_SIZE,uip_datalen());

hdr = (struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN];
udp_connection= uip_udp_new(&hdr->srcipaddr, hdr->srcport);
if(udp_connection==NULL)
return;
memcpy(s->inputbuffer,uip_appdata,BytesLeft);
pBuffer=(uint8_t*)&s->inputbuffer;
if(memcmp(pBuffer,tcp_startnewmessage,sizeof(tcp_startnewmessage))==0)
{
uip_udp_conn = udp_connection; //<<<<<<< присваиваем новый указатель
ETH_SendUDPResponse();
}

uip_udp_remove(udp_connection);

}


P.S. uIP из моего проекта.


--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
Go to the top of the page
 
+Quote Post
PoReX
сообщение Feb 7 2013, 10:55
Сообщение #25


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518



Наконец я победил uip:) Как и думал проблема заключалось в одном маленьком недочете:
При начальной инициализации udp вместо нулевого указателя на адрес удаленного хоста
Код
udp_conn = uip_udp_new(0, 0);
я передавал указатель на структуру
Код
uip_ipaddr_t
с забитыми нулями
Код
uip_ipaddr(ipaddr, 0,0,0,0);
udp_conn = uip_udp_new(&ipaddr, 0);


--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
Go to the top of the page
 
+Quote Post
ElectronicsLab
сообщение Aug 20 2013, 10:31
Сообщение #26





Группа: Новичок
Сообщений: 3
Регистрация: 6-11-10
Пользователь №: 60 693



Добрый день. Что-то не получается у меня отправить данных с МК на комп. Отвечать на сообщения с компа я умею, колбэки вызываются, там обрабатываю пакеты, отправляю ответы в виде uip_send().
Но вся беда в том, что uip_send() нужно вызывать только в качестве ОТВЕТА на запрос с компа.

А как сделать так, чтобы независимо слать данные с МК на комп? Чтобы через WireShark видеть что что-то шлется..?
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Aug 21 2013, 09:57
Сообщение #27


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(ElectronicsLab @ Aug 20 2013, 14:31) *
...независимо слать данные с МК на комп? Чтобы через WireShark видеть что что-то шлется..?


Вы бы посмотрели тем же ваирШарком как это делает обычная рабочая станция. в теории - зная IP шлётся бродкаст ARP запрос. По ответу(если отозвался) формируется пакет, со всеми уже известными полями.
Как реализовано в конкретной библиотеке - надо вкуривать.
Go to the top of the page
 
+Quote Post
kramener
сообщение Sep 20 2013, 11:45
Сообщение #28





Группа: Новичок
Сообщений: 2
Регистрация: 12-09-13
Пользователь №: 78 288



Цитата(PoReX @ Feb 7 2013, 14:55) *
Наконец я победил uip:) Как и думал проблема заключалось в одном маленьком недочете:
При начальной инициализации udp вместо нулевого указателя на адрес удаленного хоста
Код
udp_conn = uip_udp_new(0, 0);
я передавал указатель на структуру
Код
uip_ipaddr_t
с забитыми нулями
Код
uip_ipaddr(ipaddr, 0,0,0,0);
udp_conn = uip_udp_new(&ipaddr, 0);


Столкнулся с такой же проблемой: адрес и порт получателя нулевые, хотя нулевой указатель передаю и адрес структуры при получении сообщения.
Вы не могли бы выложить свою программу для контроллера, отвечающую за отправку UDP?

Сообщение отредактировал kramener - Sep 20 2013, 11:48
Go to the top of the page
 
+Quote Post
kramener
сообщение Sep 20 2013, 13:46
Сообщение #29





Группа: Новичок
Сообщений: 2
Регистрация: 12-09-13
Пользователь №: 78 288



Только что сам разобрался с uIP sm.gif) Выложу код на всякий случай. Вдруг кому пригодится.
Разрабатываю на Stellaris DK-LM3S9D96. uIP 1.0

Инициализация:
Код
void udp_init()
{
  struct uip_udp_conn *udp_conn;
  udp_conn = uip_udp_new(0, 0);
  
  if (udp_conn == 0)
    return;

  udp_conn->appstate = 0;
  uip_udp_bind(udp_conn, HTONS(DEFAULT_UDP_PORT));
}


Callback. process_msg записывает в структуру outputMsg содержимое и выходной размер outputLen
Код
void udp_appcall(void)
{
  if (uip_newdata())
  {
    if (uip_udp_conn->lport == HTONS(DEFAULT_UDP_PORT))
    {
        static struct uip_udpip_hdr *hdr;
        hdr = (struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN];
        uip_ipaddr_copy(&uip_udp_conn->ripaddr, hdr->srcipaddr);
        uip_udp_conn->rport = hdr->srcport;
  
        inputLen = bMIN(uip_datalen(), sizeof(tRawUdpMessage));
        memcpy((char *)&inMsg, (char *)uip_appdata, inputLen);
        
        process_msg(&inMsg, &inputLen, &outMsg, &outputLen);
        
        memcpy((char *)uip_appdata(), (char *)&outMsg, outputLen);
        uip_slen = outputLen;
  
        uip_process(UIP_UDP_SEND_CONN);
    }
  }
}


P.S: Просьба модераторам объединить 2 сообщения.

Цитата(ElectronicsLab @ Aug 20 2013, 14:31) *
А как сделать так, чтобы независимо слать данные с МК на комп? Чтобы через WireShark видеть что что-то шлется..?

Юзайте uip_poll(). Вот что по этому поводу говорит мануал: http://www.gaisler.com/doc/net/uip-0.9/doc/html/main.html
Цитата
The polling event has two purposes. The first is to let the application periodically know that a connection is idle, which allows the application to close connections that have been idle for too long. The other purpose is to let the application send new data that has been produced. The application can only send data when invoked by uIP, and therefore the poll event is the only way to send data on an otherwise idle connection.


Сообщение отредактировал kramener - Sep 20 2013, 13:49
Go to the top of the page
 
+Quote Post
Myrik
сообщение Apr 7 2014, 05:47
Сообщение #30





Группа: Новичок
Сообщений: 6
Регистрация: 14-12-13
Пользователь №: 79 623



Мне бы вернутся к теме о двух серваках на uIP. Делаю всё как в посте Цырена. Но в результате получаю ошибку "Error[Pe070]: incomplete type is not allowed" в строке struct httpd_state uip_tcp_http;.
При этом typedef struct httpd_state uip_tcp_appstate_t; компилируется без проблем.
Что я сделал не так?
Код
#ifndef __MULTIAPPLICATION_H__
#define __MULTIAPPLICATION_H__

#include "webserver.h"
#include "telnetd.h"

extern void application(void);


typedef union{
  struct telnetd_state uip_tcp_telnet;
  struct httpd_state uip_tcp_http;
} uip_tcp_appstate_t;

//typedef struct httpd_state uip_tcp_appstate_t;

#ifndef UIP_APPCALL
#define UIP_APPCALL application
#endif

#endif
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 21:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.01456 секунд с 7
ELECTRONIX ©2004-2016