Outgoing IGMP is functional

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2797 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2010-07-14 01:57:00 +00:00
parent 2926fe8f32
commit bb4a701c33
11 changed files with 145 additions and 31 deletions

View File

@ -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

View File

@ -41,6 +41,7 @@
#include <sys/types.h>
#include <stdint.h>
#include <errno.h>
#include <arch/board/board.h>
#include <nuttx/arch.h>

View File

@ -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
/****************************************************************************

View File

@ -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)

View File

@ -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");
* }
*

View File

@ -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 <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without

View File

@ -43,9 +43,11 @@
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <stdlib.h>
#include <string.h>
#include <wdog.h>
#include <queue.h>
#include <debug.h>
@ -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);
}
}

View File

@ -44,7 +44,6 @@
#include <nuttx/config.h>
#include <wdog.h>
#include <assert.h>
#include <debug.h>
@ -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);

View File

@ -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);
}

View File

@ -45,6 +45,7 @@
#include <net/uip/uipopt.h>
#include <net/uip/uip.h>
#include <net/uip/uip-arch.h>
#include <net/uip/uip-ipopt.h>
#include <net/uip/uip-igmp.h>
#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 */

View File

@ -42,6 +42,7 @@
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <wdog.h>
#include <assert.h>
@ -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 */