// vim: set et sw=4 sts=4 :
+#include "debug.h"
+#include "leds.h"
+#include "reg51.h"
#include "netdev.h"
#include "eth.h"
#include "ip.h"
#include "udp.h"
-
-#ifdef SDCC
-static xdata at 0x0080 byte leds0;
-static xdata at 0x00c0 byte leds1;
-#else
-static byte xdata leds0 _at_ 0x0080;
-static byte xdata leds1 _at_ 0x00c0;
-#endif
-
-#define leds(word) \
- do \
- { \
- leds0 = ~LOW(word); \
- leds1 = ~HIGH(word); \
- } \
- while (0)
-
-
-void sleep(unsigned char times)
-{
- unsigned int i;
- unsigned char j;
- for (i = 0; i < 0xffff; ++i)
- for (j = 0; j < times; ++j);
-}
+#include "elp.h"
void main(void)
{
- // Apagamos todos los leds
- leds(0x0000);
+ // Inicializamos leds
+ leds_init();
+
+ // Hacemos prueba simple de los leds
+ leds_test();
// Inicializamos dispositivo de red
if (!netdev_init())
{
- leds(0xffff);
- while(1); // Si falla init nos quedamos bobos
+ // Si hubo un error, quedan prendidos todos los leds
+ leds_write(0xFFFF);
+ return;
}
+ // Comienza a 'dibujar'
+ EA = 1; // Habilita interrupciones globalmente
+ ET2 = 1; // Pone a correr el 'dibujado'
+
// Inicializo IP
ip_addr_local[0] = 10;
ip_addr_local[1] = 10;
ip_addr_local[3] = 100;
// Inicializo puerto UDP
- udp_port_local = 9000;
+ udp_port_local = ELP_PORT;
while (1) // Forever
{
- uint16 len = netdev_recv_start();
- if (!len) // no recibimos nada
- {
- netdev_recv_end();
- continue; // vamos de nuevo!
- }
+ byte len = netdev_recv_start();
+ //printb(len, 0x10);
+ if (!len) // no recibimos nada (válido)
+ continue; // Probamos de nuevo
+
+ // Tenemos algo!
// Parseamos cabecera ethernet
if (!eth_read_frame_header()) // No es un buen header
- {
- // Tenemos algo!
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
- }
+ goto drop; // Tiramos el paquete
// Vemos que protocolo transporta
switch (eth_proto)
{
- case ETH_ARP: // FIXME, implementar ARP!
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
+ case ETH_ARP: // TODO: implementar ARP!
+ goto drop; // Tiramos el paquete
case ETH_IP:
// Parseamos cabecera IP
if (!ip_read_packet_header()) // No es un buen header
- {
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
- }
+ goto drop; // Tiramos el paquete
// Vemos que protocolo transporta
switch (ip_proto)
{
- case IP_ICMP: // FIXME, implementar ICMP!
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
+ case IP_ICMP: // TODO: implementar ICMP!
+ goto drop; // Tiramos el paquete
case IP_UDP:
// Parseamos cabecera UDP
if (!udp_read_dgram_header()) // No es un buen header
- {
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
- }
-
- // TODO
- // Nuestro protocolo, por ahora un simple echo!
- for (len = 8; len < udp_dgram_len; len += 2) // 8 por la cabecera UDP
- {
- leds(netdev_recv_word());
- sleep(5);
- }
+ goto drop; // Tiramos el paquete
+
+ // Procesamos comando ELP y obtenemos tamaño de la
+ // respuesta
+ len = elp_read_process_command();
+ //printb(len, 0x02);
+
+ // Si el tamaño es 0, hubo error o no está soportado
+ if (!len)
+ goto drop;
+ //print(0x0004);
+
+ // FIXME por ahora no tenemos forma de 'abortar' el
+ // comando si el checksum es incorrecto, lo verificamos
+ // por deporte.
+ if (!udp_checksum_ok())
+ goto drop;
+ //print(0x0008);
+
+ // Terminamos recepción
+ netdev_recv_end();
+ //print(0x0010);
+
+ // Respuesta
+ netdev_send_start();
+ eth_write_frame_header();
+ ip_packet_len = UDP_HEADER_SIZE + len;
+ //printb(ip_packet_len, 0x20);
+ ip_write_packet_header();
+ udp_dgram_len = len;
+ //printb(udp_dgram_len, 0x40);
+ udp_write_dgram_header();
+ elp_write_response();
+ udp_write_checksum(ETH_HEADER_SIZE + IP_HEADER_SIZE);
+ netdev_send_end(ETH_HEADER_SIZE + IP_HEADER_SIZE
+ + UDP_HEADER_SIZE + len);
}
}
+ continue;
+drop:
+ netdev_recv_end();
}
}