]> git.llucax.com Git - z.facultad/66.09/etherled.git/commitdiff
Implementado el checksum de UDP, tanto para paquetes recibidos como para
authorLeandro Lucarella <llucax@gmail.com>
Fri, 9 Dec 2005 07:16:39 +0000 (07:16 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 9 Dec 2005 07:16:39 +0000 (07:16 +0000)
paquetes enviados.

src/dp8390.c
src/dp8390.h
src/main.c
src/netdev.h
src/udp.c
src/udp.h

index c56bb843a2a81658ee69d32ad963944a680c2730..5c472a5cb87311ccad342b9eb7b40c175979265d 100644 (file)
@@ -247,6 +247,10 @@ bool netdev_init()
 /** Comienza el envío de un nuevo frame */
 void netdev_send_start()
 {
+    // Wait until pending transmit operation completes.
+    while (read_reg(CR) & TXP) continue;
+    write_reg(ISR, PTX); // Limpio bit de interrupción
+
     // Set remote DMA start address registers to indicate where to load packet.
     write_reg(RSAR0, 0u);
     write_reg(RSAR1, TX_PAGE_START);
@@ -272,15 +276,26 @@ void netdev_send_end(byte len)
 
     // Issue command for RTL8019AS to transmit packet from it's local buffer.
     write_reg(CR, START | TXP);
-
-    // Wait until pending transmit operation completes.
-    while(read_reg(CR) & TXP) continue;
 }
 
 void netdev_write_start(byte len)
 {
     // Set remote DMA byte count registers to indicate length of packet load.
-    write_reg(RBCR0, len); // Tamaño máximo en principio
+    write_reg(RBCR0, len);
+    write_reg(RBCR1, 0u);
+
+    // Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
+    write_reg(CR, WRITE);
+}
+
+void netdev_write_start_at(byte offset, byte len)
+{
+    // Set remote DMA start address registers to packet data.
+    write_reg(RSAR0, offset);
+    write_reg(RSAR1, TX_PAGE_START);
+
+    // Set remote DMA byte count registers to indicate length of packet load.
+    write_reg(RBCR0, len);
     write_reg(RBCR1, 0u);
 
     // Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
@@ -333,7 +348,7 @@ byte netdev_recv_start()
             printb(read_reg(ISR), 0x01);
             printb(read_reg(BNRY), 0x02);
             printb(current, 0x04);
-            ledsb(0x00, 0x00);
+            printb(0x00, 0x00);
             reset();
         }
         return 0;
index 7587ec3743e1b0328074c7dda826dbc677af8532..dfd19d689f7390d5daa3a0908419d32759b5df5d 100644 (file)
@@ -30,7 +30,7 @@ sbit NICE = CTRL_PORT^2;    // A7, usado para activar placa de red
 
 // Configuración de paǵinas de buffers
 #define TX_PAGE_START  0x40 // 0x4000 Tx buffer: 256 bytes (usamos 128)
-#define RX_PAGE_START  0x46 // 0x4600 Rx buffer: 31 * 256 = 7936 bytes
+#define RX_PAGE_START  0x41 // 0x4600 Rx buffer: 31 * 256 = 7936 bytes
 #define RX_PAGE_STOP   0x60 // 0x6000
 
 // Register base address
index 18df51295b9c65c96089325ecd27930d43a5250c..60ed5db0cec78cba5e4b71922ef001982b569842 100644 (file)
@@ -32,8 +32,10 @@ void main(void)
     {
         byte buf[64]; //XXX
         byte i; //XXX
+        byte len;
 
-        if (!netdev_recv_start()) // no recibimos nada (válido)
+        len = netdev_recv_start();
+        if (!len) // no recibimos nada (válido)
             continue; // Probamos de nuevo
 
         // Tenemos algo!
@@ -72,21 +74,27 @@ void main(void)
                         //printb(udp_dgram_len, 0x40);
                         // TODO
                         // Nuestro protocolo, por ahora un simple echo!
-                        netdev_read_start(udp_dgram_len-UDP_HEADER_SIZE);
-                        for (i = 0; i < udp_dgram_len-UDP_HEADER_SIZE; ++i)
-                            buf[i] = netdev_read_byte();
+                        len = udp_dgram_len - UDP_HEADER_SIZE;
+                        netdev_read_start(len);
+                        for (i = 0; i < len; ++i)
+                            buf[i] = udp_read_byte();
                         netdev_read_end();
+                        if (!udp_checksum_ok())
+                            goto drop;
                         netdev_recv_end();
 
                         // Respuesta
                         netdev_send_start();
                         eth_write_frame_header();
+                        //udp_dgram_len = UDP_HEADER_SIZE+len;
+                        //ip_packet_len = IP_HEADER_SIZE+udp_dgram_len;
                         ip_write_packet_header();
                         udp_write_dgram_header();
-                        netdev_write_start(udp_dgram_len-UDP_HEADER_SIZE);
-                        for (i = 0; i < udp_dgram_len-UDP_HEADER_SIZE; ++i)
-                            netdev_write_byte(buf[i]);
+                        netdev_write_start(len);
+                        for (i = 0; i < len; ++i)
+                            udp_write_byte(buf[i]);
                         netdev_write_end();
+                        udp_write_checksum(ETH_HEADER_SIZE+IP_HEADER_SIZE);
                         netdev_send_end(ETH_HEADER_SIZE+IP_HEADER_SIZE+udp_dgram_len);
                 }
         }
index 175313c5b111be865ca07c4c97fb0eb8abe8312d..27bbb3bb86be1ce3d51dc5f982d5f00e2ce56f6b 100644 (file)
@@ -23,11 +23,18 @@ void netdev_send_start();
  */
 void netdev_send_end(byte len);
 
-/** Comienza una transferencia al dispositivo de red
+/** Comienza una escritura a los buffers del dispositivo de red
  * @param len Cantidad de bytes a escribir
  */
 void netdev_write_start(byte len);
 
+/** Comienza una escritura a los buffers del dispositivo de red a partir de un
+ * offset dado. 
+ * @param offset Offset en donde comenzar a escribir
+ * @param len Cantidad de bytes a escribir
+ */
+void netdev_write_start_at(byte offset, byte len);
+
 /** Escribe un byte al buffer de la placa de red para ser enviado
  * @precond netdev_write_start() debe haber sido ejecutada
  * @param b Byte a enviar
index f8264b12d5b18badf8d4fdad9266f9b7c1f40282..09b9bfc24fe89c053dce5407cdf8336557e67ef9 100644 (file)
--- a/src/udp.c
+++ b/src/udp.c
@@ -1,5 +1,6 @@
 // vim: set et sw=4 sts=4 :    
 
+#include "debug.h"
 #include "netdev.h"
 #include "ip.h"
 #include "udp.h"
@@ -12,6 +13,8 @@ byte udp_dgram_len;
 
 /* para calcular checksum */
 static uint16 checksum;
+static byte byte_count;
+static byte last_byte;
 
 /* agrega un word al checksum calculado */
 static void sum(uint16 w)
@@ -28,6 +31,7 @@ bool udp_read_dgram_header()
     netdev_read_start(UDP_HEADER_SIZE);
     /* reseteamos checksum */
     checksum = 0;
+    byte_count = 0;
     /* el UDP tiene un checksum que incluye parte de la cabecera IP */
     /* ip de origen */
     sum(WORD(ip_addr_remote[0], ip_addr_remote[1]));
@@ -66,16 +70,29 @@ bool udp_read_dgram_header()
     return true;
 }
 
-uint16 udp_read_word()
+byte udp_read_byte()
 {
-    uint16 w = netdev_read_word();
-    sum(w);
-    return w;
+    byte b;
+    if (byte_count % 2) // impar, tengo 2, sumo
+    {
+        b = netdev_read_byte();
+        sum(WORD(last_byte, b));
+    }
+    else // par, guardo para sumar cuando tenga 2
+    {
+        b = netdev_read_byte();
+        last_byte = b;
+    }
+    ++byte_count;
+    return b;
 }
 
 bool udp_checksum_ok()
 {
-    return (uint16)~checksum;
+    // Verifico si falta sumar algo (UDP debe sumar de a un word)
+    if (byte_count == (udp_dgram_len - UDP_HEADER_SIZE))
+        sum(WORD(last_byte, 0x00)); // Relleno el byte que falta con 0x00
+    return !(uint16)~checksum;
 }
 
 void udp_write_dgram_header()
@@ -83,6 +100,7 @@ void udp_write_dgram_header()
     netdev_write_start(UDP_HEADER_SIZE);
     /* reseteamos checksum */
     checksum = 0;
+    byte_count = 0;
     /* el UDP tiene un checksum que incluye parte de la cabecera IP */
     /* ip de origen */
     sum(WORD(ip_addr_remote[0], ip_addr_remote[1]));
@@ -110,15 +128,30 @@ void udp_write_dgram_header()
     netdev_write_end();
 }
 
-void udp_write_word(uint16 w)
+void udp_write_byte(byte b)
 {
-    sum(w);
-    netdev_write_word(w);
+    if (byte_count % 2) // impar, tengo 2, sumo
+    {
+        netdev_write_byte(b);
+        sum(WORD(last_byte, b));
+    }
+    else // par, guardo para sumar cuando tenga 2
+    {
+        netdev_write_byte(b);
+        last_byte = b;
+    }
+    ++byte_count;
 }
 
-void udp_write_checksum()
+void udp_write_checksum(byte offset)
 {
-    // XXX TODO FIXME
+    // Verifico si falta sumar algo (UDP debe sumar de a un word)
+    if (byte_count == (udp_dgram_len - UDP_HEADER_SIZE))
+        sum(WORD(last_byte, 0x00)); // Relleno el byte que falta con 0x00
+    // Escribo checksum en el buffer de la placa de red
+    netdev_write_start_at(offset + 6, 2); // 6 bytes de offset hasta el checksum
+    netdev_write_word((uint16)~checksum); // Guardo checksum
+    netdev_write_end();
     return;
 }
 
index d6367767f15af9dfc40db3a044298d0657aacfdf..d08d03faf15aa94e52eb7251ad87320a86b68224 100644 (file)
--- a/src/udp.h
+++ b/src/udp.h
@@ -61,7 +61,7 @@ extern uint16 udp_port_local;
 /** Puerto UDP de destino */
 extern uint16 udp_port_remote;
 
-/** Tamaño del datagrama UDP */
+/** Tamaño del datagrama UDP (no soportamos más de 255) */
 extern byte udp_dgram_len;
 
 /** Lee la cabecera del datagrama UDP.
@@ -72,8 +72,10 @@ extern byte udp_dgram_len;
  */
 bool udp_read_dgram_header();
 
-/** Recibe un word del payload UDP chequeando el checksum. */
-uint16 udp_read_word();
+/** Recibe un word del payload UDP chequeando el checksum.
+ * @precond Hay que llamar antes a netdev_read_start()
+ */
+byte udp_read_byte();
 
 /* Indica si el checksum calculado está ok */
 bool udp_checksum_ok();
@@ -85,10 +87,14 @@ bool udp_checksum_ok();
  */
 void udp_write_dgram_header();
 
-/** Escribe un word al payload UDP chequeando el checksum. */
-void udp_write_word(uint16 w);
+/** Escribe un word al payload UDP chequeando el checksum.
+ * @precond Hay que llamar antes a netdev_write_start()
+ */
+void udp_write_byte(byte b);
 
-/* Escribe el checksum calculado al frame a enviar */
-void udp_write_checksum();
+/* Escribe el checksum calculado al frame a enviar
+ * @param offset Offset a partir de donde están las cabeceras UDP.
+ */
+void udp_write_checksum(byte offset);
 
 #endif /* _UDP_H_ */