/* ************************************************** */ void xy_stats(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); position_t *position = get_node_position(c->node); if (nodedata->type == INLINE_NODE) { printf("INLINE node %d (%lf,%lf,%lf) Group_id=%d Neighbors=%d\n", c->node, position->x, position->y, position->z, nodedata->group_id, das_getsize(nodedata->neighbors)); } else { printf("SENSOR node %d (%lf,%lf,%lf) Neighbors=%d\n", c->node, position->x, position->y, position->z, das_getsize(nodedata->neighbors)); } }
/* Get the best next hop for a specific destination */ struct neighbor* get_nexthop(call_t *c, nodeid_t dst) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *neighbor = NULL, *n_hop = NULL; double dist = distance(get_node_position(c->node), get_node_position(dst)); double d = dist; if (nodedata->curr_dst != dst || (nodedata->curr_nexthop != NULL && !is_node_alive(nodedata->curr_nexthop->id))) { /* If the destination is different from the last one, * or if the current next hop is dead, reinit the * random counters (to force the selection of a * new next_hop) */ nodedata->random_counter = nodedata->random_nexthop; } if (nodedata->random_nexthop == 0) { /* We keep the current next hop if * - next hop is not randomized * - the next hop is is still alive * - the destination is the same */ if (nodedata->curr_nexthop != NULL && nodedata->curr_dst == dst && is_node_alive(nodedata->curr_nexthop->id)) { return nodedata->curr_nexthop; } /* Parse neighbors */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct neighbor *) das_traverse(nodedata->neighbors)) != NULL) { /* Choose next hop (the one the nearest from the final dst) * and verify if it is still alive */ if ((d = distance(&(neighbor->position), get_node_position(dst))) < dist && is_node_alive(neighbor->id)) { dist = d; n_hop = neighbor; } } } else if (nodedata->random_counter == nodedata->random_nexthop) { void *next_hops = das_create(); int nh = 0; double nexthop_dst = 0; /* Random geographic routing : we choose randomly among * the neighbors that are nearer from the destination * than the current node. */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct neighbor *) das_traverse(nodedata->neighbors)) != NULL) { /* If the neighbor happens to be the final destination, * then we just choose it as the next hop */ if (neighbor->id == dst) { n_hop = neighbor; goto out; } /* Store the neighbors that are nearer from the destination * and that are still alive */ nexthop_dst = distance(&(neighbor->position), get_node_position(dst)); if (nexthop_dst < dist && is_node_alive(neighbor->id)) { das_insert(next_hops, (void *) neighbor); } } /* Choose next hop randomly among the list */ nh = das_getsize(next_hops); if (nh > 0) { int rnd = get_random_integer_range(1, nh); while (rnd--) { neighbor = das_pop(next_hops); } n_hop = neighbor; } das_destroy(next_hops); } else /* nodedata->random_counter != nodedata->random_nexthop */ { /* Keep the current next hop */ n_hop = nodedata->curr_nexthop; } out: nodedata->random_counter--; if (nodedata->random_counter <= 0) { nodedata->random_counter = nodedata->random_nexthop; } /* Save the current next hop and destination */ nodedata->curr_nexthop = n_hop; nodedata->curr_dst = dst; return n_hop; }