/*---------------------------------------------------------------------------*/ int mesh_send(struct mesh_conn *c, const rimeaddr_t *to) { int could_send; PRINTF("%d.%d: mesh_send to %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], to->u8[0], to->u8[1]); could_send = multihop_send(&c->multihop, to); if(!could_send) { if(c->queued_data != NULL) { queuebuf_free(c->queued_data); } PRINTF("mesh_send: queueing data, sending rreq\n"); c->queued_data = queuebuf_new_from_packetbuf(); rimeaddr_copy(&c->queued_data_dest, to); route_discovery_discover(&c->route_discovery_conn, to, PACKET_TIMEOUT); return 0; } c->cb->sent(c); return 1; }
PROCESS_THREAD(rimeroute_process, ev, data) { static struct route_discovery_conn route_discovery_conn; rimeaddr_t *dest; PROCESS_BEGIN(); rimeroute_event = process_alloc_event(); route_discovery_open(&route_discovery_conn, CLOCK_SECOND * 10, ROUTE_DISCOVERY_CHANNEL, &route_discovery_callbacks); while(1) { PROCESS_WAIT_EVENT_UNTIL(ev == rimeroute_event); dest = data; PRINTF("discovering route to %d.%d\n", dest->u8[0], dest->u8[1]); route_discovery_discover(&route_discovery_conn, dest, PACKET_TIMEOUT); } route_discovery_close(&route_discovery_conn); PROCESS_END(); }
/*---------------------------------------------------------------------------*/ static rimeaddr_t * data_packet_forward(struct multihop_conn *multihop, const rimeaddr_t *originator, const rimeaddr_t *dest, const rimeaddr_t *prevhop, uint8_t hops) { struct route_entry *rt; struct mesh_conn *c = (struct mesh_conn *) ((char *)multihop - offsetof(struct mesh_conn, multihop)); rt = route_lookup(dest); if(rt == NULL) { if(c->queued_data != NULL) { queuebuf_free(c->queued_data); } PRINTF("data_packet_forward: queueing data, sending rreq\n"); c->queued_data = queuebuf_new_from_packetbuf(); rimeaddr_copy(&c->queued_data_dest, dest); route_discovery_discover(&c->route_discovery_conn, dest, PACKET_TIMEOUT); return NULL; } else { route_refresh(rt); } return &rt->R_next_addr; }
/*---------------------------------------------------------------------------*/ static rimeaddr_t * data_packet_forward(struct multihop_conn *multihop, const rimeaddr_t *originator, const rimeaddr_t *dest, const rimeaddr_t *prevhop, uint8_t hops) { struct route_entry *rt; struct mesh_conn *c = (struct mesh_conn *) ((char *)multihop - offsetof(struct mesh_conn, multihop)); rt = route_lookup(dest); if(rt == NULL) { route_discovery_discover(&c->route_discovery_conn, dest, PACKET_TIMEOUT); return NULL; } else { route_refresh(rt); } return &rt->nexthop; }
/*---------------------------------------------------------------------------*/ uint8_t uip_over_mesh_send(void) { linkaddr_t receiver; struct route_entry *rt; /* This function is called by the uip-fw module to send out an IP packet. We try to send the IP packet to the next hop route, or we queue the packet and send out a route request for the final receiver of the packet. */ /* Packets destined to this network is sent using mesh, whereas packets destined to a network outside this network is sent towards the gateway node. */ if(uip_ipaddr_maskcmp(&BUF->destipaddr, &netaddr, &netmask)) { receiver.u8[0] = BUF->destipaddr.u8[2]; receiver.u8[1] = BUF->destipaddr.u8[3]; } else { if(linkaddr_cmp(&gateway, &linkaddr_node_addr)) { PRINTF("uip_over_mesh_send: I am gateway, packet to %d.%d.%d.%d to local interface\n", uip_ipaddr_to_quad(&BUF->destipaddr)); if(gw_netif != NULL) { return gw_netif->output(); } return UIP_FW_DROPPED; } else if(linkaddr_cmp(&gateway, &linkaddr_null)) { PRINTF("uip_over_mesh_send: No gateway setup, dropping packet\n"); return UIP_FW_OK; } else { PRINTF("uip_over_mesh_send: forwarding packet to %d.%d.%d.%d towards gateway %d.%d\n", uip_ipaddr_to_quad(&BUF->destipaddr), gateway.u8[0], gateway.u8[1]); linkaddr_copy(&receiver, &gateway); } } PRINTF("uIP over mesh send to %d.%d with len %d\n", receiver.u8[0], receiver.u8[1], uip_len); packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len); /* Send TCP data with the PACKETBUF_ATTR_ERELIABLE set so that an underlying power-saving MAC layer knows that it should be waiting for an ACK. */ if(BUF->proto == UIP_PROTO_TCP) { packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 1); packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1); /* packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM);*/ } rt = route_lookup(&receiver); if(rt == NULL) { PRINTF("uIP over mesh no route to %d.%d\n", receiver.u8[0], receiver.u8[1]); if(queued_packet == NULL) { queued_packet = queuebuf_new_from_packetbuf(); linkaddr_copy(&queued_receiver, &receiver); route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT); } else if(!linkaddr_cmp(&queued_receiver, &receiver)) { route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT); } } else { route_decay(rt); send_data(&rt->nexthop); } return UIP_FW_OK; }