/* Find all the neighbors (i.e. nodes in range) of the current node */ int find_neighbors(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *neighbor = NULL; nodeid_t i; double dist = 0; int nb_neigh = 0; /* Parse all the nodes in the simulation: and find the ones * that are in range of that node */ for(i = 0; i < get_node_count(); i++) { /* Do not include myself */ if (i == c->node) { continue; } dist = distance(get_node_position(c->node), get_node_position(i)); if (dist <= nodedata->range) { /* Add the node in the list of neighbors */ neighbor = (struct neighbor *) malloc(sizeof(struct neighbor)); neighbor->id = i; neighbor->position.x = get_node_position(i)->x; neighbor->position.y = get_node_position(i)->y; neighbor->position.z = get_node_position(i)->z; neighbor->time = get_time(); //PRINT_ROUTING("Node %d is added to neighbor list of node %d\n", // neighbor->id, c->node); das_insert(nodedata->neighbors, (void *) neighbor); nb_neigh++; } } return nb_neigh; }
/* ************************************************** */ void rx_xy_hello(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct xy_hello_p *hello = (struct xy_hello_p *) (packet->data + nodedata->overhead); struct xy_neighbor *neighbor; /* check for existing neighbors */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct xy_neighbor *) das_traverse(nodedata->neighbors)) != NULL) { if (neighbor->id == hello->src) { neighbor->position.x = hello->position.x; neighbor->position.y = hello->position.y; neighbor->position.z = hello->position.z; neighbor->time = get_time(); packet_dealloc(packet); return; } } /* new neighbor */ neighbor = (struct xy_neighbor *) malloc(sizeof(struct xy_neighbor)); neighbor->id = hello->src; neighbor->position.x = hello->position.x; neighbor->position.y = hello->position.y; neighbor->position.z = hello->position.z; neighbor->time = get_time(); das_insert(nodedata->neighbors, (void *) neighbor); packet_dealloc(packet); return; }
void add_neighbor(call_t *c, struct routing_header *header) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *neighbor = NULL; /* check wether neighbor already exists */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct neighbor *) das_traverse(nodedata->neighbors)) != NULL) { if (neighbor->id == header->src) { neighbor->position.x = header->src_pos.x; neighbor->position.y = header->src_pos.y; neighbor->position.z = header->src_pos.z; neighbor->time = get_time(); return; } } neighbor = (struct neighbor *) malloc(sizeof(struct neighbor)); neighbor->id = header->src; neighbor->position.x = header->src_pos.x; neighbor->position.y = header->src_pos.y; neighbor->position.z = header->src_pos.z; neighbor->time = get_time(); das_insert(nodedata->neighbors, (void *) neighbor); return; }
/* ************************************************** */ void tx(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); das_insert(nodedata->packets, (void *) packet); if (nodedata->state == STATE_IDLE) { nodedata->clock = get_time(); state_machine(c,NULL); } }
/* ************************************************** */ void register_callback(call_t *c, callback_t callback, void *arg) { struct entitydata *entitydata = get_entity_private_data(c); struct monitor_callback *call = malloc(sizeof(struct monitor_callback)); call->callback = callback; call->c.entity = c->from; call->c.node = c->node; call->c.from = -1; call->arg = arg; das_insert(entitydata->callbacks, (void *) call); return; }
/* ************************************************** */ void *spadas_rangesearch(void *s, void *key, position_t *position, double range) { spadas_t *spadas = (spadas_t *) s; void *das; int i, j, k; if ((das = das_create()) == NULL) { return NULL; } if (spadas->cell_width != -1) { int x = (int) position->x / spadas->cell_width; int y = (int) position->y / spadas->cell_width; int z = (int) position->z / spadas->cell_width; int adj = range / spadas->cell_width; int m_x = MAX(0, x - adj); int M_x = MIN(spadas->cell_nbr_x - 1, x + adj); int m_y = MAX(0, y - adj); int M_y = MIN(spadas->cell_nbr_y - 1, y + adj); int m_z = MAX(0, z - adj); int M_z = MIN(spadas->cell_nbr_z - 1, z + adj); for (i = m_x; i <= M_x; i++) { for (j = m_y; j <= M_y; j++) { for (k = m_z; k <= M_z; k++) { spadas_elt_t *elt = spadas->elts[i][j][k]; while (elt != NULL) { if (elt->key == key) { elt = elt->next; continue; } if (distance(&(elt->position), position) <= range) { das_insert(das, elt->key); } elt = elt->next; } } } } } return das; }
/* 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; }