Pre-ci test passed git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
460 lines
14 KiB
C
460 lines
14 KiB
C
/*!
|
|
*******************************************************************************
|
|
|
|
\file neighbor_db.c
|
|
|
|
\brief Fonctions permettant la gestion de la base de donnée sur le voisinage
|
|
directe (1 saut) du cluster head et indirecte a 2 sauts.
|
|
|
|
\author BURLOT Pascal
|
|
|
|
\date 29/08/08
|
|
|
|
|
|
\par Historique:
|
|
$Author$ $Date$ $Revision$
|
|
$Id$
|
|
$Log$
|
|
|
|
*******************************************************************************
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include "debug.h"
|
|
#include "L3_rrc_defs.h"
|
|
#include "rrm_sock.h"
|
|
#include "rrc_rrm_msg.h"
|
|
#include "rrm_util.h"
|
|
#include "neighbor_db.h"
|
|
|
|
//! Selection locale du mode de debug
|
|
#define DBG_NEIGHBOR_DB 0
|
|
|
|
#if DBG_NEIGHBOR_DB==0
|
|
//! Macro inactive
|
|
#define PRINT_NEIGHBOR_DB(...)
|
|
#else
|
|
//! Macro affichant la liste du voisnage d'un cluster
|
|
#define PRINT_NEIGHBOR_DB(...) print_neighbor_db( __VA_ARGS__ )
|
|
#endif
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief Comparaison de deux ID de niveau 2
|
|
|
|
\return si 0 alors les IDs sont identiques
|
|
*/
|
|
static int L2_ID_cmp(
|
|
L2_ID *L2_id1, ///< ID de niveau 2
|
|
L2_ID *L2_id2 ///< ID de niveau 2
|
|
)
|
|
{
|
|
return memcmp( L2_id1, L2_id2, sizeof(L2_ID) ) ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction affiche a l'ecran la liste (pour DEBUG )
|
|
|
|
\return aucune valeur retournee
|
|
*/
|
|
static void print_neighbor_db(
|
|
neighbor_desc_t *pEntry ///< pointeur sur le debut de liste
|
|
)
|
|
{
|
|
unsigned int i , j ;
|
|
neighbor_desc_t *pCurrentItem = pEntry;
|
|
|
|
fprintf(stderr,"neighbor list=[\n");
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
fprintf(stderr," @%p(.L2_id=", pCurrentItem );
|
|
|
|
for ( i=0;i<8;i++)
|
|
fprintf(stderr,"%02X", pCurrentItem->L2_id.L2_id[i]);
|
|
|
|
fprintf(stderr,", .NB_neighbor=%u, .Sensing_meas=%p, .next=%p)\n",
|
|
pCurrentItem->NB_neighbor, pCurrentItem->Sensing_meas,pCurrentItem->next );
|
|
|
|
if ( pCurrentItem->Sensing_meas != NULL )
|
|
for ( j=0;j<pCurrentItem->NB_neighbor;j++)
|
|
{
|
|
fprintf(stderr,"\tNeighbor(%d):.L2_id=",j);
|
|
for ( i=0;i<8;i++)
|
|
fprintf(stderr,"%02X", pCurrentItem->Sensing_meas[j].L2_id.L2_id[i]);
|
|
|
|
fprintf(stderr," .RSSI=%02X\n", pCurrentItem->Sensing_meas[j].Rssi);
|
|
}
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
fprintf(stderr," ]\n");
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction ajoute un voisin dans la liste des voisins du Cluster head.
|
|
|
|
\return retourne la valeur du nouvel element
|
|
*/
|
|
neighbor_desc_t *add_neighbor(
|
|
neighbor_desc_t **neighbor_entry, ///< pointeur sur l'entree de la liste de voisinage
|
|
L2_ID *L2_id ///< ID du nouveau noeud
|
|
)
|
|
{
|
|
neighbor_desc_t *pNewItem = get_neighbor( *neighbor_entry, L2_id );
|
|
|
|
if ( pNewItem == NULL )
|
|
{ // If not Exist then create a new item
|
|
neighbor_desc_t *pOldEntry = *neighbor_entry;
|
|
|
|
pNewItem = RRM_MALLOC(neighbor_desc_t , 1 ) ;
|
|
|
|
PNULL(pNewItem) ;
|
|
if ( pNewItem == NULL )
|
|
return NULL ;
|
|
|
|
memcpy( pNewItem->L2_id.L2_id , L2_id->L2_id, sizeof(L2_ID) ) ;
|
|
//pNewItem->RSSI = 0 ;
|
|
pNewItem->NB_neighbor = 0 ;
|
|
pNewItem->Sensing_meas= NULL;
|
|
|
|
*neighbor_entry = pNewItem ;
|
|
pNewItem->next = pOldEntry;
|
|
}
|
|
|
|
PRINT_NEIGHBOR_DB( *neighbor_entry );
|
|
return pNewItem ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction retire un element de la liste des voisins
|
|
|
|
\return aucune valeur.
|
|
*/
|
|
void del_neighbor(
|
|
neighbor_desc_t **neighbor_entry, ///< pointeur sur l'entree de la liste de voisinage
|
|
L2_ID *L2_id ///< ID niveau 2 du voisin a detruire
|
|
)
|
|
{
|
|
neighbor_desc_t *pCurrentItem = *neighbor_entry;
|
|
neighbor_desc_t *pNextItem ;
|
|
neighbor_desc_t **ppPrevItem = neighbor_entry ;
|
|
|
|
if ( (pCurrentItem == NULL) || (neighbor_entry==NULL))
|
|
return ;
|
|
|
|
while ( pCurrentItem != NULL )
|
|
{
|
|
pNextItem = pCurrentItem->next ;
|
|
if ( L2_ID_cmp( &(pCurrentItem->L2_id),L2_id) == 0 )
|
|
{
|
|
*ppPrevItem = pNextItem;
|
|
|
|
RRM_FREE( pCurrentItem->Sensing_meas) ;
|
|
RRM_FREE( pCurrentItem ) ;
|
|
break ;
|
|
}
|
|
ppPrevItem = &(pCurrentItem->next) ;
|
|
pCurrentItem = pNextItem ;
|
|
}
|
|
|
|
PRINT_NEIGHBOR_DB( *neighbor_entry );
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction detruit entierement la liste des voisins
|
|
|
|
\return aucune valeur.
|
|
*/
|
|
void del_all_neighbor(
|
|
neighbor_desc_t **neighbor_entry ///< pointeur sur l'entree de la liste de voisinage
|
|
)
|
|
{
|
|
neighbor_desc_t *pCurrentItem = *neighbor_entry;
|
|
neighbor_desc_t *pNextItem ;
|
|
|
|
if ( (pCurrentItem == NULL) || (neighbor_entry==NULL))
|
|
return ;
|
|
|
|
while ( pCurrentItem != NULL )
|
|
{
|
|
pNextItem = pCurrentItem->next ;
|
|
|
|
RRM_FREE( pCurrentItem->Sensing_meas ) ;
|
|
RRM_FREE( pCurrentItem ) ;
|
|
|
|
pCurrentItem = pNextItem ;
|
|
}
|
|
*neighbor_entry = NULL ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction recherche les informations de voisinage d'un noeud
|
|
|
|
\return descripteur sur les infos de voisinage du noeud ou NULL
|
|
*/
|
|
neighbor_desc_t *get_neighbor(
|
|
neighbor_desc_t *neighbor_entry, ///< pointeur sur l'entree de la liste de voisinage
|
|
L2_ID *L2_id ///< ID du noeud
|
|
)
|
|
{
|
|
neighbor_desc_t *pCurrentItem = neighbor_entry;
|
|
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
if ( L2_ID_cmp( &(pCurrentItem->L2_id),L2_id) == 0 )
|
|
break ;
|
|
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
|
|
return pCurrentItem ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction met a jour les informations de mesure de voisinage d'un noeud
|
|
|
|
\return aucune valeur
|
|
*/
|
|
void set_Sensing_meas_neighbor(
|
|
neighbor_desc_t *neighbor_entry, ///< pointeur sur l'entree de la liste de voisinage
|
|
L2_ID *L2_id , ///< ID du noeud
|
|
unsigned int nb_meas , ///< Nombre de mesure associe au noeud
|
|
SENSING_MEAS_T *sensing_meas ///< Mesures de voisinage
|
|
)
|
|
{
|
|
neighbor_desc_t *pCurrentItem = neighbor_entry;
|
|
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
if ( L2_ID_cmp( &(pCurrentItem->L2_id),L2_id) == 0 )
|
|
{
|
|
pCurrentItem->NB_neighbor = 0 ;
|
|
|
|
RRM_FREE(pCurrentItem->Sensing_meas );
|
|
|
|
if ( nb_meas > 0 )
|
|
{
|
|
SENSING_MEAS_T *p = RRM_MALLOC(SENSING_MEAS_T, nb_meas ) ;
|
|
|
|
if ( p != NULL )
|
|
{
|
|
int size = nb_meas * sizeof(SENSING_MEAS_T) ;
|
|
memcpy( p,sensing_meas , size );
|
|
pCurrentItem->NB_neighbor = nb_meas ;
|
|
pCurrentItem->Sensing_meas = p ;
|
|
}
|
|
}
|
|
break ;
|
|
}
|
|
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
|
|
if (pCurrentItem==NULL)
|
|
{
|
|
fprintf(stderr,"ERROR: Unknown MR L2_id :");
|
|
print_L2_id(L2_id) ;
|
|
fprintf(stderr,"\n");
|
|
}
|
|
|
|
PRINT_NEIGHBOR_DB( neighbor_entry );
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction lit l'information de RSSI entre un noeud et un noeud voisin
|
|
|
|
\return la valeur de RSSI
|
|
*/
|
|
unsigned char get_RSSI_neighbor(
|
|
neighbor_desc_t *neighbor_entry , ///< pointeur sur l'entree de la liste de voisinage
|
|
L2_ID *L2_id , ///< ID du noeud
|
|
L2_ID *neighbor_id ///< ID du noeud voisin
|
|
)
|
|
{
|
|
neighbor_desc_t *pCurrentItem = neighbor_entry;
|
|
unsigned char rssi = 0xFF ;
|
|
int i ;
|
|
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
if ( L2_ID_cmp( &(pCurrentItem->L2_id),L2_id) == 0 )
|
|
{
|
|
for ( i = 0 ; i < pCurrentItem->NB_neighbor ; i++ )
|
|
{
|
|
if ( L2_ID_cmp( &(pCurrentItem->Sensing_meas[i].L2_id),neighbor_id) == 0 )
|
|
{
|
|
rssi = pCurrentItem->Sensing_meas[i].Rssi ;
|
|
return (rssi) ;
|
|
}
|
|
}
|
|
}
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
|
|
return rssi ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction ajoute un couple de voisin a la liste de type neighbor_list_t
|
|
|
|
\return le nouvel element de liste
|
|
*/
|
|
static neighbor_list_t *add_item_neighbor_list(
|
|
neighbor_list_t **neighbor_list_entry , ///< pointeur sur l'entree de la liste des couples de voisins
|
|
L2_ID *L2_id1 , ///< ID du noeud 1
|
|
L2_ID *L2_id2 ///< ID du noeud 2
|
|
)
|
|
{
|
|
neighbor_list_t *pOldEntry = *neighbor_list_entry;
|
|
|
|
neighbor_list_t *pNewItem = RRM_MALLOC(neighbor_list_t, 1 ) ;
|
|
|
|
PNULL(pNewItem) ;
|
|
if ( pNewItem == NULL )
|
|
return NULL ;
|
|
|
|
memcpy( &(pNewItem->L2_id[0]) , L2_id1, sizeof(L2_ID) ) ;
|
|
memcpy( &(pNewItem->L2_id[1]) , L2_id2, sizeof(L2_ID) ) ;
|
|
pNewItem->Rssi[0] = 0xFF ;
|
|
pNewItem->Rssi[1] = 0xFF ;
|
|
pNewItem->nb_opened_rb = 0 ;
|
|
pNewItem->rb_meas = NULL;
|
|
|
|
*neighbor_list_entry = pNewItem ;
|
|
pNewItem->next = pOldEntry;
|
|
|
|
return pNewItem ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction touve un couple de voisin dans la liste de type neighbor_list_t
|
|
|
|
\return l'element trouve
|
|
*/
|
|
static neighbor_list_t *get_item_neighbor_list(
|
|
neighbor_list_t *neighbor_list_entry, ///< pointeur sur l'entree de la liste des couples de voisins
|
|
L2_ID *L2_id1 , ///< ID du noeud 1
|
|
L2_ID *L2_id2 ///< ID du noeud 2
|
|
)
|
|
{
|
|
neighbor_list_t *pCurrentItem = neighbor_list_entry;
|
|
L2_ID L2_id[2] ;
|
|
|
|
memcpy( &(L2_id[0]), L2_id1, sizeof(L2_ID) ) ;
|
|
memcpy( &(L2_id[1]), L2_id2, sizeof(L2_ID) ) ;
|
|
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
if ( memcmp( &(pCurrentItem->L2_id),L2_id,2*sizeof(L2_ID)) == 0 )
|
|
break ;
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
|
|
return pCurrentItem ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction cree la liste de type neighbor_list_t a partie d'une liste
|
|
de type neighbor_desc_t:
|
|
- Elle construit la liste des MR en vue directe du CH (voisinage directe)
|
|
- Elle construit la liste des MR voyant d'autre MR (voisinage a 2 sauts)
|
|
|
|
\return retourne la liste de type neighbor_list_t.
|
|
*/
|
|
neighbor_list_t *create_neighbor_list(
|
|
neighbor_desc_t *neighbor_entry , ///< pointeur sur l'entree de la liste de voisinage
|
|
L2_ID *L2_id_CH ///< ID du Cluster Head
|
|
)
|
|
{
|
|
neighbor_desc_t *pCurrentItem = neighbor_entry;
|
|
neighbor_list_t *pList=NULL ;
|
|
|
|
// construit la liste des MR voyant le CH en directe (voisinage directe)
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
add_item_neighbor_list( &pList, L2_id_CH, &(pCurrentItem->L2_id) ) ;
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
|
|
// construit la liste des MR voyant d'autre MR (voisinage a 2 sauts)
|
|
pCurrentItem = neighbor_entry;
|
|
while ( pCurrentItem != NULL)
|
|
{
|
|
int i ;
|
|
for ( i = 0 ; i<pCurrentItem->NB_neighbor; i++ )
|
|
{
|
|
neighbor_list_t *pItemFound ;
|
|
// Recherche du couple de voisin dans la liste
|
|
pItemFound = get_item_neighbor_list(pList ,
|
|
&(pCurrentItem->L2_id) ,
|
|
&(pCurrentItem->Sensing_meas[i].L2_id)
|
|
);
|
|
|
|
if ( pItemFound == NULL )
|
|
{ // si le couple n'est pas trouve alors on inverse les adresses MAC
|
|
pItemFound = get_item_neighbor_list(pList ,
|
|
&(pCurrentItem->Sensing_meas[i].L2_id) ,
|
|
&(pCurrentItem->L2_id)
|
|
);
|
|
if ( pItemFound == NULL )
|
|
{ // si ce couple n'est pas dans la liste alors on l'y ajoute
|
|
pItemFound = add_item_neighbor_list( &pList, &(pCurrentItem->L2_id), &(pCurrentItem->Sensing_meas[i].L2_id)) ;
|
|
pItemFound->Rssi[1] = pCurrentItem->Sensing_meas[i].Rssi ;
|
|
}
|
|
}
|
|
else
|
|
{ // Met a jour le champs Rssi
|
|
pItemFound->Rssi[0] = pCurrentItem->Sensing_meas[i].Rssi ;
|
|
}
|
|
}
|
|
pCurrentItem = pCurrentItem->next ;
|
|
}
|
|
return pList ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief La fonction detruit la liste de type neighbor_list_t .
|
|
|
|
\return Aucune valeur
|
|
*/
|
|
void del_neighbor_list(
|
|
neighbor_list_t **neighbor_list_entry ///< pointeur sur l'entree de la liste de voisinage
|
|
)
|
|
{
|
|
neighbor_list_t *pCurrentItem = *neighbor_list_entry;
|
|
neighbor_list_t *pNextItem ;
|
|
|
|
if ( (pCurrentItem == NULL) || (neighbor_list_entry==NULL))
|
|
return ;
|
|
|
|
while ( pCurrentItem != NULL )
|
|
{
|
|
pNextItem = pCurrentItem->next ;
|
|
|
|
RRM_FREE( pCurrentItem->rb_meas ) ;
|
|
RRM_FREE( pCurrentItem ) ;
|
|
|
|
pCurrentItem = pNextItem ;
|
|
}
|
|
*neighbor_list_entry = NULL ;
|
|
}
|