FAR struct igmp_group_s *uip_grpfind(FAR struct uip_driver_s *dev, FAR const uip_ipaddr_t *addr) { FAR struct igmp_group_s *group; uip_lock_t flags; grplldbg("Searching for addr %08x\n", (int)*addr); /* We must disable interrupts because we don't which context we were * called from. */ flags = uip_lock(); for (group = (FAR struct igmp_group_s *)dev->grplist.head; group; group = group->next) { grplldbg("Compare: %08x vs. %08x\n", group->grpaddr, *addr); if (uip_ipaddr_cmp(group->grpaddr, *addr)) { grplldbg("Match!\n"); break; } } uip_unlock(flags); return group; }
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; }
FAR struct igmp_group_s *igmp_grpalloc(FAR struct net_driver_s *dev, FAR const in_addr_t *addr) { FAR struct igmp_group_s *group; net_lock_t flags; nllvdbg("addr: %08x dev: %p\n", *addr, dev); if (up_interrupt_context()) { #if CONFIG_PREALLOC_IGMPGROUPS > 0 grplldbg("Use a pre-allocated group entry\n"); group = igmp_grpprealloc(); #else grplldbg("Cannot allocate from interrupt handler\n"); group = NULL; #endif } else { grplldbg("Allocate from the heap\n"); group = igmp_grpheapalloc(); } grplldbg("group: %p\n", group); /* Check if we successfully allocated a group structure */ if (group) { /* Initialize the non-zero elements of the group structure */ net_ipv4addr_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 = net_lock(); /* Add the group structure to the list in the device structure */ sq_addfirst((FAR sq_entry_t *)group, &dev->grplist); net_unlock(flags); } return group; }
void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group) { uip_lock_t flags; grplldbg("Free: %p flags: %02x\n", group, group->flags); /* Cancel the wdog */ flags = uip_lock(); wd_cancel(group->wdog); /* Remove the group structure from the group list in the device structure */ 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. */ #if CONFIG_PREALLOC_IGMPGROUPS > 0 if (IS_PREALLOCATED(group->flags)) { grplldbg("Put back on free list\n"); sq_addlast((FAR sq_entry_t*)group, &g_freelist); uip_unlock(flags); } else #endif { /* No.. deallocate the group structure. Use sched_free() just in case * this function is executing within an interrupt handler. */ uip_unlock(flags); grplldbg("Call sched_free()\n"); sched_free(group); } }
void uip_grpinit(void) { FAR struct igmp_group_s *group; int i; grplldbg("Initializing\n"); #if CONFIG_PREALLOC_IGMPGROUPS > 0 for (i = 0; i < CONFIG_PREALLOC_IGMPGROUPS; i++) { group = &g_preallocgrps[i]; sq_addfirst((FAR sq_entry_t *)group, &g_freelist); } #endif }