Example #1
0
/* ************************************************** */
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;
}