Files
openairinterface5g/openair3/MESH/RRM/channels_db.c
T
2013-06-25 09:05:02 +00:00

352 lines
11 KiB
C
Executable File

/*!
*******************************************************************************
\file channels_db.c
\brief Fonctions permettant la gestion de la base de donnée sur les canaux
\author IACOBELLI Lorenzo
\date 16/10/09
\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_util.h"
#include "sens_db.h"
#include "channels_db.h"
//! Selection locale du mode de debug
#define DBG_CHANNELS_DB 1
#if DBG_CHANNELS_DB==0
//! Macro inactive
#define PRINT_CHANNELS_DB(...)
#else
//! Macro affichant la liste des radio bearers
#define PRINT_CHANNELS_DB(...) print_channels_db( __VA_ARGS__ )
#endif
/*!
*******************************************************************************
\brief La fonction affiche a l'ecran la liste (pour du debug)
\return aucune valeur retournee
*/
void print_channels_db(
CHANNELS_DB_T *pEntry ///< pointeur sur le debut de liste
)
{
//unsigned int i; //dbg
CHANNELS_DB_T *pCurrentItem = pEntry;
int i;
//fprintf(stderr,"channels entry @%p \n", pEntry);//dbg
//fprintf(stderr,"sens list=[\n");
while ( pCurrentItem != NULL)
{
//fprintf(stderr,"curr channel %d is free? %d \n", pCurrentItem->channel.Ch_id,pCurrentItem->is_free);//dbg
pCurrentItem = pCurrentItem->next ;
}
fprintf(stderr," ]\n");
}
/*!
*******************************************************************************
\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 ajoute un nouveau canal.
\return retourne la valeur du nouvel element
*/
CHANNELS_DB_T *add_chann_db(
CHANNELS_DB_T **ch_entry , ///< pointeur sur l'entree de la liste de noeuds
CHANNEL_T channel , ///< channel to insert in the list
unsigned int is_free , ///< Information about the availability of the channel //mod_lor_10_05_28 ->char instead of int
double info_time ///< Date of information update
)
{
//fprintf(stderr,"starting ch pointer @%p \n", *ch_entry);//dbg
//fprintf(stderr,"\n NB_info=%d \n", NB_info); //dbg
CHANNELS_DB_T *pOldEntry = *ch_entry;
CHANNELS_DB_T *pNewItem = RRM_CALLOC( CHANNELS_DB_T , 1 ) ;
PNULL(pNewItem) ;
if ( pNewItem == NULL )
return NULL ;
memcpy( &(pNewItem->channel) ,&channel, sizeof(CHANNEL_T) ) ;
pNewItem->info_time = info_time ;
pNewItem->is_free = is_free;
pNewItem->priority = 0;
pNewItem->is_ass = 0;
//fprintf(stderr,"starting ch pointer @%p \n", pNewItem->info_hd);//dbg
*ch_entry = pNewItem ;
pNewItem->next = pOldEntry;
/*fprintf(stderr,"add_node\n\n");//dbg
fprintf(stderr,"node entry @%p \n", (*node_entry)->info_hd);//dbg
fprintf(stderr,"node entry @%p \n", pNewItem->info_hd);//dbg
fprintf(stderr,"passed par @%p \n", ch_info_hd);//dbg*/
return pNewItem ;
}
/*!
*******************************************************************************
\brief La fonction detruit entierement les info sur les canaux memorizées à l'adresse indiqué
\return aucune valeur.
*/
void del_all_channels(
CHANNELS_DB_T **ch_entry ///< pointeur sur l'entree de la liste
)
{
CHANNELS_DB_T *pCurrentItem = *ch_entry;
CHANNELS_DB_T *pNextItem ;
if ( (pCurrentItem == NULL) || (ch_entry==NULL))
return ;
while ( pCurrentItem != NULL )
{
pNextItem = pCurrentItem->next ;
RRM_FREE( pCurrentItem ) ;
pCurrentItem = pNextItem ;
}
*ch_entry = NULL ;
}
/*!
*******************************************************************************
\brief La fonction retire l'element identifie par le Ch_id de la liste des canaux
\return aucune valeur.
*/
void del_channel(
CHANNELS_DB_T **ch_entry , ///< pointeur sur l'entree de la liste de noeuds
unsigned int Ch_id ///< channel ID
)
{
CHANNELS_DB_T *pCurrentItem = *ch_entry;
CHANNELS_DB_T *pNextItem ;
CHANNELS_DB_T **ppPrevItem = ch_entry ;
if ( (pCurrentItem == NULL) || (ch_entry==NULL))
return ;
while ( pCurrentItem != NULL )
{
pNextItem = pCurrentItem->next ;
if ( pCurrentItem->channel.Ch_id == Ch_id )
{
*ppPrevItem = pNextItem;
RRM_FREE( pCurrentItem ) ;
fprintf( stdout,"channel %d deleted from database\n", Ch_id);
return ;
}
ppPrevItem = &(pCurrentItem->next) ;
pCurrentItem = pNextItem ;
}
if ( pCurrentItem == NULL )
fprintf(stderr, "ERROR: channel_id unknown\n") ;
}
/*!
*******************************************************************************
\brief La fonction recherche le descripteur du canal identifie par le Ch_id
dans la liste des canaux
\return pointeur sur le descripteur de canal trouve sinon NULL .
*/
CHANNELS_DB_T *get_chann_db_info(
CHANNELS_DB_T *ch_entry , ///< pointeur sur l'entree de la liste de noeuds
unsigned int Ch_id ///< channel ID
)
{
CHANNELS_DB_T *pCurrentItem = ch_entry;
while ( pCurrentItem != NULL)
{
if ( pCurrentItem->channel.Ch_id == Ch_id)
break ;
pCurrentItem = pCurrentItem->next ;
}
return pCurrentItem ;
}
/*!
*******************************************************************************
\brief La fonction ajoute ou update un canal.
\return retourne la valeur du nouvel element
*/
CHANNELS_DB_T *up_chann_db(
CHANNELS_DB_T **ch_entry , ///< pointeur sur l'entree de la liste de noeuds
CHANNEL_T channel , ///< channel to insert in the list
unsigned int is_free , ///< Information about the availability of the channel //mod_lor_10_05_28 ->char instead of int
double info_time ///< Date of information update
)
{
if (ch_entry == NULL){
fprintf(stderr,"ERROR! invalid database pointer \n");
return(NULL);
}
CHANNELS_DB_T *pNewItem = get_chann_db_info( *ch_entry, channel.Ch_id );
if ( pNewItem == NULL ){
pNewItem = add_chann_db( ch_entry, channel, is_free, info_time);
return pNewItem;
}
pNewItem->info_time = info_time ;
//mod_lor_10_05_17++
pNewItem->is_free=is_free;
/*if (is_free == pNewItem->is_free)
return pNewItem;
if (!(pNewItem->is_ass)){
pNewItem->is_free=is_free;
return pNewItem;
}*/
return pNewItem;
//else
// fprintf(stderr,"Primary User detected on channel %d in use by secondary network\n", channel.Ch_id);//mod_lor_10_05_12
//mod_lor_10_05_17--
//PRINT_CHANNELS_DB(*ch_entry); //dbg
return NULL;
}
/*!
*******************************************************************************
\brief La fonction mis à jour les canaux assignés.
\return retourne la valeur du nouvel element
*/
CHANNELS_DB_T *up_chann_ass(
CHANNELS_DB_T *ch_entry , ///< pointeur sur l'entree de la liste de noeuds
unsigned int Ch_id , ///< ID of the channel to update
unsigned int is_ass , ///< Information about the use of the channel by the secondary network
L2_ID source_id , ///< In case of channel assigned: address of the source node that is using it
L2_ID dest_id ///< In case of channel assigned: address of the destination node that is using it
)
{
//fprintf(stderr,"up_channels 1 inizio\n");//dbg
CHANNELS_DB_T *pChannels = get_chann_db_info( ch_entry , Ch_id );
if (pChannels == NULL){
fprintf(stderr,"ERROR! Channel %d not in database!\n", Ch_id);
return (NULL);
}
//fprintf(stderr,"up_channels 2 trovato\n");//dbg
//fprintf(stderr,"up_channels 2b is_free: %d is_ass: %d\n",pChannels->is_free,pChannels->is_ass);//dbg
if (!(pChannels->is_free)){
fprintf(stderr,"The channel %d is not free!\n", Ch_id);
return (NULL); //mod_lor_10_05_17
}else if (pChannels->is_ass == is_ass){
//fprintf(stderr,"up_channels 3 is_ass\n");//dbg
if (is_ass && L2_ID_cmp (&(source_id), &(pChannels->source_id))!=0)
fprintf(stderr,"The channel %d is already assigned \n", Ch_id);
//fprintf(stderr,"No updating performed for channel %d \n", Ch_id);//dbg
}else {
pChannels->is_ass = is_ass;
//fprintf(stderr,"up_channels 4 is_ass\n");//dbg
if (is_ass){
//fprintf(stderr,"up_channels 5 is_ass\n");//dbg
memcpy( pChannels->source_id.L2_id, source_id.L2_id, sizeof(L2_ID) ) ;
memcpy( pChannels->dest_id.L2_id, dest_id.L2_id, sizeof(L2_ID) ) ;
}
//fprintf(stdout,"Channel %d assignement updated in %d\n", Ch_id, is_ass);//dbg
}
//fprintf(stderr,"up_channels 6 END\n");//dbg
return (pChannels);
}
//mod_lor_10_05_17++
/*!
*******************************************************************************
\brief The function select a new channel among the free ones. It selects the
first channel marked as free and not assigned in the channels database
and assigns it to the nodes whose L2_ids are passed as imput
\return the pointer to selected channel entry; NULL if not available channels are found
*/
CHANNELS_DB_T *select_new_channel(
CHANNELS_DB_T *ch_entry , ///< pointeur sur l'entree de la liste de noeuds
L2_ID source_id , ///< In case of channel assigned: address of the source node that is using it
L2_ID dest_id ///< In case of channel assigned: address of the destination node that is using it
)
{
CHANNELS_DB_T *pChannels = ch_entry;
while ( pChannels != NULL)
{
if ( pChannels->is_free && !(pChannels->is_ass) )
break ;
pChannels = pChannels->next ;
}
if (pChannels == NULL){
fprintf(stderr,"*SELECT NEW CHANNEL* -> No free channels available!\n");
return (NULL);
}
else{
pChannels->is_ass = 1;
memcpy( pChannels->source_id.L2_id, source_id.L2_id, sizeof(L2_ID) ) ;
memcpy( pChannels->dest_id.L2_id, dest_id.L2_id, sizeof(L2_ID) ) ;
}
return (pChannels);
}
//mod_lor_10_05_17--