From c7aa964347c50fccb7335362472cf2ee6f46efc6 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 14 Jul 2010 01:57:00 +0000 Subject: Outgoing IGMP is functional git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2797 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/z80/src/ez80/ez80_emac.c | 4 +- nuttx/arch/z80/src/ez80/ez80_spi.c | 1 + nuttx/include/net/uip/uip-igmp.h | 1 - nuttx/include/net/uip/uip-ipopt.h | 16 +++---- nuttx/include/net/uip/uip.h | 2 +- nuttx/net/uip/uip_icmpsend.c | 4 +- nuttx/net/uip/uip_igmpgroup.c | 85 +++++++++++++++++++++++++++++++++---- nuttx/net/uip/uip_igmpinit.c | 5 --- nuttx/net/uip/uip_igmpleave.c | 2 +- nuttx/net/uip/uip_igmpsend.c | 5 ++- nuttx/net/uip/uip_igmptimer.c | 51 +++++++++++++++++++++- 11 files changed, 145 insertions(+), 31 deletions(-) (limited to 'nuttx') diff --git a/nuttx/arch/z80/src/ez80/ez80_emac.c b/nuttx/arch/z80/src/ez80/ez80_emac.c index a8db36a67..f347521c2 100644 --- a/nuttx/arch/z80/src/ez80/ez80_emac.c +++ b/nuttx/arch/z80/src/ez80/ez80_emac.c @@ -1822,8 +1822,8 @@ static int ez80emac_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac) FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; /* Add the MAC address to the hardware multicast routing table */ + /* MISSING LOGIC!!! */ -#warning "Multicast MAC support not implemented" return OK; } #endif @@ -1852,8 +1852,8 @@ static int ez80emac_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac) FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; /* Add the MAC address to the hardware multicast routing table */ + /* MISSING LOGIC!!! */ -#warning "Multicast MAC support not implemented" return OK; } #endif diff --git a/nuttx/arch/z80/src/ez80/ez80_spi.c b/nuttx/arch/z80/src/ez80/ez80_spi.c index 22cfd789c..d701d5548 100755 --- a/nuttx/arch/z80/src/ez80/ez80_spi.c +++ b/nuttx/arch/z80/src/ez80/ez80_spi.c @@ -41,6 +41,7 @@ #include #include +#include #include #include diff --git a/nuttx/include/net/uip/uip-igmp.h b/nuttx/include/net/uip/uip-igmp.h index 58ca7565e..29a3d5334 100755 --- a/nuttx/include/net/uip/uip-igmp.h +++ b/nuttx/include/net/uip/uip-igmp.h @@ -110,7 +110,6 @@ #define IS_SCHEDMSG(f) (((f) & IGMP_SCHEDMSG) != 0) #define IS_WAITMSG(f) (((f) & IGMP_WAITMSG) != 0) -#define ROUTER_ALERT 0x94040000 #define IGMP_TTL 1 /**************************************************************************** diff --git a/nuttx/include/net/uip/uip-ipopt.h b/nuttx/include/net/uip/uip-ipopt.h index d4c3aebe3..1625fbab6 100755 --- a/nuttx/include/net/uip/uip-ipopt.h +++ b/nuttx/include/net/uip/uip-ipopt.h @@ -75,8 +75,8 @@ # define IPOPT_TYPE_OPTION_SEC (2 << IPOPT_TYPE_OPTION_SHIFT) /* Security (RFC 791, 1108) */ # define IPOPT_TYPE_OPTION_LSRR (3 << IPOPT_TYPE_OPTION_SHIFT) /* Loose source and record route (RFC 791) */ # define IPOPT_TYPE_OPTION_TIMESTAMP (4 << IPOPT_TYPE_OPTION_SHIFT) /* Timestamp (RFC 781, 791) */ -# define IPORT_TYPE_OPTION_EXTSEC (5 << IPOPT_TYPE_OPTION_SHIFT) /* Extended security (RFC 1108) */ -# define IPORT_TYPE_OPTION_COMMSEC (6 << IPOPT_TYPE_OPTION_SHIFT) /* Commercial security */ +# define IPOPT_TYPE_OPTION_EXTSEC (5 << IPOPT_TYPE_OPTION_SHIFT) /* Extended security (RFC 1108) */ +# define IPOPT_TYPE_OPTION_COMMSEC (6 << IPOPT_TYPE_OPTION_SHIFT) /* Commercial security */ # define IPOPT_TYPE_OPTION_RR (7 << IPOPT_TYPE_OPTION_SHIFT) /* Record route (RFC 791) */ # define IPOPT_TYPE_OPTION_SSID (8 << IPOPT_TYPE_OPTION_SHIFT) /* Stream ID (RFC 791, 1122) */ # define IPOPT_TYPE_OPTION_SSRR (9 << IPOPT_TYPE_OPTION_SHIFT) /* Strict source and record route (RFC 791) */ @@ -110,7 +110,7 @@ #define IPOPT_MKOPTION8(copied,class,option) \ ((uint8_t)IPOPT_MKTYPE(copied,class,option)) #define IPOPT_MKOPTION32(type,len,ptr,data) \ - ((uint32_t)(type) << 24 | (uint32_t)(len) << 16) | \ + ((uint32_t)(type) << 24 | (uint32_t)(len) << 16 | \ (uint32_t)(ptr) << 8 | (uint32_t)(data)) /* Option Copy Class Length Description References @@ -169,11 +169,11 @@ #define IPOPT_TIMESTAMP_TYPE \ IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_MEASURE, IPOPT_TYPE_OPTION_TIMESTAMP) -#define IPORT_EXTSEC_TYPE \ - IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPORT_TYPE_OPTION_EXTSEC) +#define IPOPT_EXTSEC_TYPE \ + IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_EXTSEC) -#define IPORT_COMMSEC_TYPE \ - IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPORT_TYPE_OPTION_COMMSEC) +#define IPOPT_COMMSEC_TYPE \ + IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_COMMSEC) #define IPOPT_RR_TYPE \ IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RR) @@ -222,7 +222,7 @@ #define IPOPT_RA_TYPE \ IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RA) #define IPOPT_RA \ - IPOPT_MKOPTION32(IPORT_RA_TYPE, 4, 0, 0) + IPOPT_MKOPTION32(IPOPT_RA_TYPE, 4, 0, 0) #define IPOPT_SDBM_TYPE \ IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_SDBM) diff --git a/nuttx/include/net/uip/uip.h b/nuttx/include/net/uip/uip.h index fd9373666..a828d3f90 100644 --- a/nuttx/include/net/uip/uip.h +++ b/nuttx/include/net/uip/uip.h @@ -442,7 +442,7 @@ extern void uip_send(struct uip_driver_s *dev, const void *buf, int len); * uip_ipaddr_t ipaddr1, ipaddr2; * * uip_ipaddr(&ipaddr1, 192,16,1,2); - * if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { + * if(uip_ipaddr_cmp(ipaddr2, ipaddr1)) { * printf("They are the same"); * } * diff --git a/nuttx/net/uip/uip_icmpsend.c b/nuttx/net/uip/uip_icmpsend.c index 071ffe32e..f24d78008 100644 --- a/nuttx/net/uip/uip_icmpsend.c +++ b/nuttx/net/uip/uip_icmpsend.c @@ -1,7 +1,7 @@ /**************************************************************************** - * net/uip/uip_icmsend.c + * net/uip/uip_icmpsend.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without diff --git a/nuttx/net/uip/uip_igmpgroup.c b/nuttx/net/uip/uip_igmpgroup.c index 4b169cf92..8b5398aac 100755 --- a/nuttx/net/uip/uip_igmpgroup.c +++ b/nuttx/net/uip/uip_igmpgroup.c @@ -43,9 +43,11 @@ ****************************************************************************/ #include +#include #include #include +#include #include #include @@ -64,6 +66,8 @@ * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + #ifdef CONFIG_NET_IPv6 # error "IGMP for IPv6 not supported" #endif @@ -72,6 +76,40 @@ # define CONFIG_PREALLOC_IGMPGROUPS 4 #endif +/* Debug ********************************************************************/ + +#undef IGMP_GRPDEBUG /* Define to enable detailed IGMP group debug */ + +#ifndef CONFIG_NET_IGMP +# undef IGMP_GRPDEBUG +#endif + +#ifdef CONFIG_CPP_HAVE_VARARGS +# ifdef IGMP_GRPDEBUG +# define grpdbg(format, arg...) ndbg(format, ##arg) +# define grplldbg(format, arg...) nlldbg(format, ##arg) +# define grpvdbg(format, arg...) nvdbg(format, ##arg) +# define grpllvdbg(format, arg...) nllvdbg(format, ##arg) +# else +# define grpdbg(x...) +# define grplldbg(x...) +# define grpvdbg(x...) +# define grpllvdbg(x...) +# endif +#else +# ifdef IGMP_GRPDEBUG +# define grpdbg ndbg +# define grplldbg nlldbg +# define grpvdbg nvdbg +# define grpllvdbg nllvdbg +# else +# define grpdbg (void) +# define grplldbg (void) +# define grpvdbg (void) +# define grpllvdbg (void) +# endif +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -151,6 +189,8 @@ void uip_grpinit(void) FAR struct igmp_group_s *group; int i; + grplldbg("Initializing\n"); + for (i = 0; i < CONFIG_PREALLOC_IGMPGROUPS; i++) { group = &g_preallocgrps[i]; @@ -178,12 +218,15 @@ FAR struct igmp_group_s *uip_grpalloc(FAR struct uip_driver_s *dev, nllvdbg("addr: %08x dev: %p\n", *addr, dev); if (up_interrupt_context()) { + grplldbg("Allocate from the heap\n"); group = uip_grpheapalloc(); } else { + grplldbg("Use a pre-allocated group entry\n"); group = uip_grpprealloc(); } + grplldbg("group: %p\n", group); /* Check if we succesfully allocated a group structure */ @@ -194,6 +237,11 @@ FAR struct igmp_group_s *uip_grpalloc(FAR struct uip_driver_s *dev, uip_ipaddr_copy(group->grpaddr, *addr); sem_init(&group->sem, 0, 0); + /* Initialize the group timer (but don't start it yet) */ + + group->wdog = wd_create(); + DEBUGASSERT(group->wdog); + /* Interrupts must be disabled in order to modify the group list */ flags = irqsave(); @@ -223,15 +271,21 @@ FAR struct igmp_group_s *uip_grpfind(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group; irqstate_t flags; - /* We must disable interrupts because we don't which context we were called - * from. + grplldbg("Searching for addr %08x\n", (int)*addr); + + /* We must disable interrupts because we don't which context we were + * called from. */ flags = irqsave(); - for (group = (FAR struct igmp_group_s *)dev->grplist.head; group; group = group->next) + for (group = (FAR struct igmp_group_s *)dev->grplist.head; + group; + group = group->next) { - if (uip_ipaddr_cmp(&group->grpaddr, *addr)) + grplldbg("Compare: %08x vs. %08x\n", group->grpaddr, *addr); + if (uip_ipaddr_cmp(group->grpaddr, *addr)) { + grplldbg("Match!\n"); break; } } @@ -255,10 +309,13 @@ FAR struct igmp_group_s *uip_grpallocfind(FAR struct uip_driver_s *dev, FAR const uip_ipaddr_t *addr) { FAR struct igmp_group_s *group = uip_grpfind(dev, addr); + + grplldbg("group: %p addr: %08x\n", group, (int)*addr); if (!group) { group = uip_grpalloc(dev, addr); } + grplldbg("group: %p\n", group); return group; } @@ -275,16 +332,26 @@ FAR struct igmp_group_s *uip_grpallocfind(FAR struct uip_driver_s *dev, void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group) { - /* First, remove the group structure from the group list in the device - * structure - */ + irqstate_t flags; + + grplldbg("Free: %p flags: %02x\n", group, group->flags); + + /* Cancel the wdog */ + + flags = irqsave(); + wd_cancel(group->wdog); + + /* Remove the group structure from the group list in the device structure */ - irqstate_t flags = irqsave(); sq_rem((FAR sq_entry_t*)group, &dev->grplist); /* Destroy the wait semapore */ (void)sem_destroy(&group->sem); + + /* Destroy the wdog */ + + wd_delete(group->wdog); /* Then release the group structure resources. Check first if this is one * of the pre-allocated group structures that we will retain in a free list. @@ -292,6 +359,7 @@ void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group) if (IS_PREALLOCATED(group->flags)) { + grplldbg("Put back on free list\n"); sq_addlast((FAR sq_entry_t*)group, &g_freelist); irqrestore(flags); } @@ -302,6 +370,7 @@ void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group) */ irqrestore(flags); + grplldbg("Call sched_free()\n"); sched_free(group); } } diff --git a/nuttx/net/uip/uip_igmpinit.c b/nuttx/net/uip/uip_igmpinit.c index c3c379904..8d2c05db8 100755 --- a/nuttx/net/uip/uip_igmpinit.c +++ b/nuttx/net/uip/uip_igmpinit.c @@ -44,7 +44,6 @@ #include -#include #include #include @@ -113,10 +112,6 @@ void uip_igmpdevinit(struct uip_driver_s *dev) group = uip_grpalloc(dev, &g_allsystems); - /* Initialize the group timer (but don't start it yet) */ - - group->wdog = wd_create(); - /* Allow the IGMP messages at the MAC level */ uip_addmcastmac(dev, &g_allrouters); diff --git a/nuttx/net/uip/uip_igmpleave.c b/nuttx/net/uip/uip_igmpleave.c index af546dd54..85f6d78d7 100755 --- a/nuttx/net/uip/uip_igmpleave.c +++ b/nuttx/net/uip/uip_igmpleave.c @@ -158,7 +158,7 @@ int igmp_leavegroup(struct uip_driver_s *dev, FAR const struct in_addr *grpaddr) if (IS_LASTREPORT(group->flags)) { - ndbg("Schedul Leave Group message\n"); + ndbg("Schedule Leave Group message\n"); IGMP_STATINCR(uip_stat.igmp.leave_sched); uip_igmpwaitmsg(group, IGMP_LEAVE_GROUP); } diff --git a/nuttx/net/uip/uip_igmpsend.c b/nuttx/net/uip/uip_igmpsend.c index c4d5b58c8..7ea384e29 100755 --- a/nuttx/net/uip/uip_igmpsend.c +++ b/nuttx/net/uip/uip_igmpsend.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include "uip_internal.h" @@ -134,8 +135,8 @@ void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group, /* Add the router alert option */ - IGMPBUF->ra[0] = HTONS(ROUTER_ALERT >> 16); - IGMPBUF->ra[1] = HTONS(ROUTER_ALERT & 0xffff); + IGMPBUF->ra[0] = HTONS(IPOPT_RA >> 16); + IGMPBUF->ra[1] = HTONS(IPOPT_RA & 0xffff); /* Initialize the IPv4 header */ diff --git a/nuttx/net/uip/uip_igmptimer.c b/nuttx/net/uip/uip_igmptimer.c index 216b4b4e8..044276ec3 100755 --- a/nuttx/net/uip/uip_igmptimer.c +++ b/nuttx/net/uip/uip_igmptimer.c @@ -42,6 +42,7 @@ ****************************************************************************/ #include +#include #include #include @@ -59,6 +60,40 @@ * Pre-processor Definitions ****************************************************************************/ +/* Debug ********************************************************************/ + +#undef IGMP_GTMRDEBUG /* Define to enable detailed IGMP group debug */ + +#ifndef CONFIG_NET_IGMP +# undef IGMP_GTMRDEBUG +#endif + +#ifdef CONFIG_CPP_HAVE_VARARGS +# ifdef IGMP_GTMRDEBUG +# define gtmrdbg(format, arg...) ndbg(format, ##arg) +# define gtmrlldbg(format, arg...) nlldbg(format, ##arg) +# define gtmrvdbg(format, arg...) nvdbg(format, ##arg) +# define gtmrllvdbg(format, arg...) nllvdbg(format, ##arg) +# else +# define gtmrdbg(x...) +# define gtmrlldbg(x...) +# define gtmrvdbg(x...) +# define gtmrllvdbg(x...) +# endif +#else +# ifdef IGMP_GTMRDEBUG +# define gtmrdbg ndbg +# define gtmrlldbg nlldbg +# define gtmrvdbg nvdbg +# define gtmrllvdbg nllvdbg +# else +# define gtmrdbg (void) +# define gtmrlldbg (void) +# define gtmrvdbg (void) +# define gtmrllvdbg (void) +# endif +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -100,6 +135,14 @@ static void uip_igmptimeout(int argc, uint32_t arg, ...) IGMP_STATINCR(uip_stat.igmp.report_sched); uip_igmpschedmsg(group, IGMPv2_MEMBERSHIP_REPORT); + + /* Also note: The Membership Report is sent at most two times becasue + * the timer is not reset here. Hmm.. does this mean that the group + * is stranded if both reports were lost? This is consistent with the + * RFC that states: "To cover the possibility of the initial Membership + * Report being lost or damaged, it is recommended that it be repeated + * once or twice after shortdelays [Unsolicited Report Interval]..." + */ } } @@ -142,9 +185,13 @@ int uip_decisec2tick(int decisecs) void uip_igmpstartticks(FAR struct igmp_group_s *group, int ticks) { + int ret; + /* Start the timer */ - wd_start(group->wdog, ticks, uip_igmptimeout, 1, (uint32_t)group); + gtmrlldbg("ticks: %d\n", ticks); + ret = wd_start(group->wdog, ticks, uip_igmptimeout, 1, (uint32_t)group); + DEBUGASSERT(ret == OK); } void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs) @@ -153,6 +200,7 @@ void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs) * Important!! this should be a random timer from 0 to decisecs */ + gtmrdbg("decisecs: %d\n", decisecs); uip_igmpstartticks(group, uip_decisec2tick(decisecs)); } @@ -192,6 +240,7 @@ bool uip_igmpcmptimer(FAR struct igmp_group_s *group, int maxticks) * test as well. */ + gtmrdbg("maxticks: %d remaining: %d\n", maxticks, remaining); if (maxticks > remaining) { /* Cancel the watchdog timer and return true */ -- cgit v1.2.3