/*---------------------------------------------------------------------------*/ static int send(struct netflood_conn *c) { PRINTF("%d.%d: netflood send to ipolite\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); return ipolite_send(&c->c, c->queue_time, 4); }
/*---------------------------------------------------------------------------*/ static void send_adv(clock_time_t interval) { struct announcement_msg *adata; struct announcement *a; packetbuf_clear(); adata = packetbuf_dataptr(); adata->num = 0; for(a = announcement_list(); a != NULL; a = a->next) { adata->data[adata->num].id = a->id; adata->data[adata->num].value = a->value; adata->num++; } packetbuf_set_datalen(ANNOUNCEMENT_MSG_HEADERLEN + sizeof(struct announcement_data) * adata->num); PRINTF("%d.%d: sending neighbor advertisement with %d announcements\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], adata->num); if(adata->num > 0) { /* Send the packet only if it contains more than zero announcements. */ ipolite_send(&c.c, interval, packetbuf_datalen()); } }
/*---------------------------------------------------------------------------*/ static void recv_ipolite(struct ipolite_conn *ipolite, const rimeaddr_t *from) { struct rudolph1_conn *c = (struct rudolph1_conn *) ((char *)ipolite - offsetof(struct rudolph1_conn, ipolite)); struct rudolph1_datapacket *p = packetbuf_dataptr(); PRINTF("%d.%d: Got ipolite type %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], p->h.type); c->nacks++; if(p->h.type == TYPE_NACK) { PRINTF("%d.%d: Got NACK for %d:%d (%d:%d)\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], p->h.version, p->h.chunk, c->version, c->chunk); if(p->h.version == c->version) { if(p->h.chunk < c->chunk) { /* Format and send a repair packet */ PRINTF("%d.%d: sending repair for chunk %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], p->h.chunk); format_data(c, p->h.chunk); ipolite_send(&c->ipolite, REPAIR_TIMEOUT, sizeof(struct rudolph1_hdr)); } } else if(LT(p->h.version, c->version)) { format_data(c, 0); ipolite_send(&c->ipolite, c->send_interval / 2, sizeof(struct rudolph1_hdr)); } } else if(p->h.type == TYPE_DATA) { /* This is a repair packet from someone else. */ PRINTF("%d.%d: got repair for chunk %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], p->h.chunk); handle_data(c, p); } }
/*---------------------------------------------------------------------------*/ int netflood_send(struct netflood_conn *c, uint8_t seqno) { if(packetbuf_hdralloc(sizeof(struct netflood_hdr))) { struct netflood_hdr *hdr = packetbuf_hdrptr(); rimeaddr_copy(&hdr->originator, &rimeaddr_node_addr); rimeaddr_copy(&c->last_originator, &hdr->originator); c->last_originator_seqno = hdr->originator_seqno = seqno; hdr->hops = 0; PRINTF("%d.%d: netflood sending '%s'\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], (char *)packetbuf_dataptr()); return ipolite_send(&c->c, 0, 4); } return 0; }
/*---------------------------------------------------------------------------*/ static void send_nack(struct rudolph1_conn *c) { struct rudolph1_hdr *hdr; packetbuf_clear(); packetbuf_hdralloc(sizeof(struct rudolph1_hdr)); hdr = packetbuf_hdrptr(); hdr->type = TYPE_NACK; hdr->version = c->version; hdr->chunk = c->chunk; PRINTF("%d.%d: Sending nack for %d:%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], hdr->version, hdr->chunk); ipolite_send(&c->ipolite, NACK_TIMEOUT, sizeof(struct rudolph1_hdr)); }