struct ccnl_face_s * ccnl_face_remove(struct ccnl_relay_s *ccnl, struct ccnl_face_s *f) { struct ccnl_face_s *f2; struct ccnl_interest_s *pit; struct ccnl_forward_s **ppfwd; DEBUGMSG(1, "ccnl_face_remove relay=%p face=%p\n", (void *) ccnl, (void *) f); ccnl_sched_destroy(f->sched); ccnl_frag_destroy(f->frag); for (pit = ccnl->pit; pit;) { struct ccnl_pendint_s **ppend, *pend; if (pit->from == f) { pit->from = NULL; } for (ppend = &pit->pending; *ppend;) { if ((*ppend)->face == f) { pend = *ppend; *ppend = pend->next; ccnl_free(pend); } else { ppend = &(*ppend)->next; } } if (pit->pending) { pit = pit->next; } else { pit = ccnl_interest_remove(ccnl, pit); } } for (ppfwd = &ccnl->fib; *ppfwd;) { if ((*ppfwd)->face == f) { struct ccnl_forward_s *pfwd = *ppfwd; *ppfwd = pfwd->next; ccnl_forward_remove(ccnl, pfwd); } else { ppfwd = &(*ppfwd)->next; } } while (f->outq) { struct ccnl_buf_s *tmp = f->outq->next; ccnl_free(f->outq); f->outq = tmp; } #if ENABLE_DEBUG ccnl_face_print_stat(f); #endif f2 = f->next; DBL_LINKED_LIST_REMOVE(ccnl->faces, f); ccnl_free(f); return f2; }
int ccnl_io_loop(struct ccnl_relay_s *ccnl) { if (ccnl->ifcount == 0) { DEBUGMSG(1, "no socket to work with, not good, quitting\n"); return -1; } DEBUGMSG(1, "starting main event and IO loop\n"); if (msg_init_queue(msg_buffer_relay, RELAY_MSG_BUFFER_SIZE) != 0) { DEBUGMSG(1, "msg init queue failed...abording\n"); return -1; } msg_t in; radio_packet_t *p; riot_ccnl_msg_t *m; while (!ccnl->halt_flag) { msg_receive(&in); mutex_lock(&ccnl->global_lock); switch (in.type) { case PKT_PENDING: /* msg from transceiver */ p = (radio_packet_t *) in.content.ptr; DEBUGMSG(1, "\tLength:\t%u\n", p->length); DEBUGMSG(1, "\tSrc:\t%u\n", p->src); DEBUGMSG(1, "\tDst:\t%u\n", p->dst); // p->src must be > 0 if (!p->src) { p->src = RIOT_BROADCAST; } ccnl_core_RX(ccnl, RIOT_TRANS_IDX, (unsigned char *) p->data, (int) p->length, p->src); p->processing--; break; case (CCNL_RIOT_MSG): /* msg from device local client */ m = (riot_ccnl_msg_t *) in.content.ptr; DEBUGMSG(1, "\tLength:\t%u\n", m->size); DEBUGMSG(1, "\tSrc:\t%u\n", in.sender_pid); ccnl_core_RX(ccnl, RIOT_MSG_IDX, (unsigned char *) m->payload, m->size, in.sender_pid); break; case (CCNL_RIOT_HALT): /* cmd to stop the relay */ DEBUGMSG(1, "\tSrc:\t%" PRIkernel_pid "\n", in.sender_pid); DEBUGMSG(1, "\tNumb:\t%" PRIu32 "\n", in.content.value); ccnl->halt_flag = 1; break; #if RIOT_CCNL_POPULATE case (CCNL_RIOT_POPULATE): /* cmd to polulate the cache */ DEBUGMSG(1, "\tSrc:\t%" PRIkernel_pid "\n", in.sender_pid); DEBUGMSG(1, "\tNumb:\t%" PRIu32 "\n", in.content.value); handle_populate_cache(ccnl); break; #endif #if ENABLE_DEBUG case (CCNL_RIOT_PRINT_STAT): /* cmd to print face statistics */ for (struct ccnl_face_s *f = ccnl->faces; f; f = f->next) { ccnl_face_print_stat(f); } break; #endif case (CCNL_RIOT_CONFIG_CACHE): /* cmd to configure the size of the cache at runtime */ ccnl->max_cache_entries = in.content.value; DEBUGMSG(1, "max_cache_entries set to %d\n", ccnl->max_cache_entries); break; case (ENOBUFFER): /* transceiver has not enough buffer to store incoming packets, one packet is dropped */ DEBUGMSG(1, "transceiver: one packet is dropped because buffers are full\n"); break; default: DEBUGMSG(1, "%s Packet waiting\n", riot_ccnl_event_to_string(in.type)); DEBUGMSG(1, "\tSrc:\t%" PRIkernel_pid "\n", in.sender_pid); DEBUGMSG(1, "\tdropping it...\n"); break; } mutex_unlock(&ccnl->global_lock); } return 0; }