- Fix: avoid infinite loop on mulitcast read thread if no data to read
Pre-ci test passed git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -0,0 +1,383 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Eurecom OpenAirInterface
|
||||
Copyright(c) 1999 - 2011 Eurecom
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information
|
||||
Openair Admin: openair_admin@eurecom.fr
|
||||
Openair Tech : openair_tech@eurecom.fr
|
||||
Forums : http://forums.eurecom.fsr/openairinterface
|
||||
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*! \file OMG.c
|
||||
* \brief Main function containing the OMG interface
|
||||
* \author M. Mahersi, J. Harri, N. Nikaein,
|
||||
* \date 2011
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "omg.h"
|
||||
|
||||
#define frand() ((double) rand() / (RAND_MAX+1))
|
||||
//#ifndef STANDALONE
|
||||
mapping nodes_type[] =
|
||||
{
|
||||
{"eNB", eNB},
|
||||
{"UE", UE},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
mapping nodes_status[] =
|
||||
{
|
||||
{"sleeping", 0},
|
||||
{"moving", 1},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
mapping mob_type[] =
|
||||
{
|
||||
{"STATIC", STATIC},
|
||||
{"RWP", RWP},
|
||||
{"RWALK", RWALK},
|
||||
{"TRACE", TRACE},
|
||||
{"SUMO", SUMO},
|
||||
{NULL, -1}
|
||||
};
|
||||
//#endif
|
||||
NodePtr create_node(void) {
|
||||
NodePtr ptr;
|
||||
ptr = malloc(sizeof(node_struct));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void delete_node(NodePtr node) {
|
||||
free(node->mob);
|
||||
node->mob = NULL;
|
||||
free(node);
|
||||
}
|
||||
|
||||
double randomGen(double a, double b){
|
||||
|
||||
return ( rand()/(double)RAND_MAX ) * (b-a) + a;
|
||||
}
|
||||
|
||||
|
||||
MobilityPtr create_mobility(void) {
|
||||
MobilityPtr ptr;
|
||||
ptr = malloc(sizeof(mobility_struct));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
Node_list add_entry(NodePtr node, Node_list Node_Vector){
|
||||
Node_list entry = malloc(sizeof(node_list_struct));
|
||||
entry->node = node;
|
||||
entry->next = NULL;
|
||||
if (Node_Vector == NULL) {
|
||||
// LOG_D(OMG, "\nempty Node_list");
|
||||
//LOG_D(OMG, "\nadded elmt ID %d\n", entry->node->ID);
|
||||
return entry;
|
||||
}
|
||||
else {
|
||||
Node_list tmp = Node_Vector;
|
||||
while (tmp->next != NULL){
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp->next = entry;
|
||||
//LOG_D(OMG, "\nnon empty Node_list");
|
||||
//LOG_D(OMG, "added elmt ID %d\n", entry->node->ID);
|
||||
|
||||
return Node_Vector;
|
||||
}
|
||||
}
|
||||
|
||||
Node_list remove_node_entry(NodePtr node, Node_list Node_Vector){
|
||||
Node_list list = Node_Vector;
|
||||
Node_list tmp, toRemove;
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(list->node->ID == node->ID) {
|
||||
// TODO delete the entry
|
||||
toRemove = list;
|
||||
LOG_D(OMG,"removed entry for node %d \n",list->node->ID);
|
||||
if(list->next ==NULL) {
|
||||
Node_Vector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Node_Vector = list->next;
|
||||
}
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
if(list->next->node->ID == node->ID) {
|
||||
toRemove = tmp; // TODO delete the entry
|
||||
tmp = list->next->next;
|
||||
if(tmp !=NULL) {
|
||||
list->next = tmp;
|
||||
}
|
||||
else{
|
||||
list->next = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Node_Vector;
|
||||
}
|
||||
|
||||
|
||||
// display list of nodes
|
||||
void display_node_list(Node_list Node_Vector){
|
||||
Node_list tmp = Node_Vector;
|
||||
if (tmp == NULL){
|
||||
#ifdef STANDALONE
|
||||
printf("Empty Node_list\n");
|
||||
#else
|
||||
LOG_I(OMG, "Empty Node_list\n");
|
||||
#endif
|
||||
}
|
||||
while (tmp != NULL){
|
||||
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n",
|
||||
map_int_to_str(mob_type, tmp->node->generator),
|
||||
map_int_to_str(nodes_type, tmp->node->type),
|
||||
tmp->node->ID,
|
||||
map_int_to_str(nodes_status, tmp->node->mobile),
|
||||
tmp->node->X_pos,
|
||||
tmp->node->Y_pos );
|
||||
|
||||
//LOG_I(OMG, "node number %d\tstatus(fix/mobile) %d\tX_pos %.2f\tY_pos %.2f\tnode_type(eNB, UE)%d\t", tmp->node->ID,tmp->node->mobile, tmp->node->X_pos,tmp->node->Y_pos, tmp->node->type);
|
||||
//LOG_D(OMG, "mob->X_from %.3f\tmob->Y_from %.3f\tmob->X_to %.3f\tmob->Y_to %.3f\t", tmp->node->mob->X_from,tmp->node->mob->Y_from, tmp->node->mob->X_to, tmp->node->mob->Y_to );
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void display_node_position(int ID, int generator, int type, int mobile, double X, double Y){
|
||||
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
|
||||
map_int_to_str(mob_type, generator),
|
||||
map_int_to_str(nodes_type, type),
|
||||
ID,
|
||||
map_int_to_str(nodes_status, mobile),
|
||||
X,
|
||||
Y
|
||||
);
|
||||
}
|
||||
|
||||
Node_list filter(Node_list Vector, int node_type){
|
||||
Node_list tmp1, tmp2;
|
||||
tmp1 = Vector;
|
||||
tmp2 = NULL;
|
||||
while (tmp1 != NULL){
|
||||
if (tmp1->node->type == node_type){
|
||||
tmp2 = add_entry(tmp1->node, tmp2);
|
||||
}
|
||||
tmp1 = tmp1->next;
|
||||
}
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
void delete_node_entry(Node_list entry) {
|
||||
NodePtr node = entry->node;
|
||||
delete_node(node);
|
||||
entry->node = NULL;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
Node_list remove_node(Node_list list, int nID, int node_type){
|
||||
|
||||
int found;
|
||||
Node_list current, previous;
|
||||
//int cond=0;
|
||||
//int i=0;
|
||||
if (list == NULL){
|
||||
found = 1; //false
|
||||
return NULL;
|
||||
}
|
||||
else{ //start search
|
||||
current = list;
|
||||
while ((current != NULL) && ((current->node->ID != nID) || (current->node->type != node_type ))){
|
||||
previous = current; // previous hobbles after
|
||||
current = current->next;
|
||||
}
|
||||
//holds: current = NULL or type != node_type or.., but not both
|
||||
if (current ==NULL) {
|
||||
found= 1 ;
|
||||
LOG_E(OMG," Element to remove is not found\n ");
|
||||
return NULL;
|
||||
} //value not found
|
||||
else{
|
||||
found = 0; // true value found
|
||||
if (current == list) {
|
||||
list = current->next;
|
||||
LOG_D(OMG,"Element to remove is found at beginning\n");
|
||||
}
|
||||
|
||||
else {
|
||||
previous->next = current->next;
|
||||
|
||||
}
|
||||
delete_node_entry(current); // freeing memory
|
||||
current = NULL;
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
int length(char* s){
|
||||
int count = 0;
|
||||
while(s[count] != '\0'){
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
NodePtr find_node(Node_list list, int nID, int node_type){
|
||||
|
||||
int found;
|
||||
Node_list current;
|
||||
|
||||
if (list == NULL){
|
||||
printf(" Node_LIST for nodeID %d is NULL \n ",nID);
|
||||
return NULL;
|
||||
}
|
||||
else{ //start search
|
||||
current = list;
|
||||
while ((current != NULL) && ((current->node->ID != nID) || (current->node->type != node_type ))){
|
||||
current = current->next;
|
||||
}
|
||||
//holds: current = NULL or type != node_type or.., but not both
|
||||
if (current ==NULL) {
|
||||
found= 1 ;
|
||||
LOG_D(OMG," Element to find in Node_Vector with ID: %d could not be found\n ",nID);
|
||||
return NULL;
|
||||
} //value not found
|
||||
else{
|
||||
//printf(" found a node for nodeID %d \n ",nID);
|
||||
return current->node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Node_list clear_node_list(Node_list list) {
|
||||
Node_list tmp;
|
||||
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
delete_node_entry(tmp);
|
||||
}
|
||||
delete_node_entry(list); // clearing the last one
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO rewrite this part...not working correctly
|
||||
Node_list reset_node_list(Node_list list) {
|
||||
Node_list tmp;
|
||||
Node_list last = list;
|
||||
if (list == NULL){
|
||||
//printf("Node_list is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
tmp->node = NULL;
|
||||
//free(tmp);
|
||||
}
|
||||
list->node = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
|
||||
//free(last);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// TODO rewrite this part...not working correctly
|
||||
String_list clear_String_list(String_list list) {
|
||||
String_list tmp;
|
||||
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
free(tmp->string);
|
||||
tmp->string = NULL;
|
||||
free(tmp);
|
||||
}
|
||||
list->string = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
/*
|
||||
* for the two functions below, the passed array must have a final entry
|
||||
* with string value NULL
|
||||
*/
|
||||
/* map a string to an int. Takes a mapping array and a string as arg */
|
||||
int map_str_to_int(mapping *map, const char *str){
|
||||
while (1) {
|
||||
if (map->name == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
if (!strcmp(map->name, str)) {
|
||||
return(map->value);
|
||||
}
|
||||
map++;
|
||||
}
|
||||
}
|
||||
|
||||
/* map an int to a string. Takes a mapping array and a value */
|
||||
char *map_int_to_str(mapping *map, int val) {
|
||||
while (1) {
|
||||
if (map->name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (map->value == val) {
|
||||
return map->name;
|
||||
}
|
||||
map++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user