Pre-ci test passed git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
352 lines
11 KiB
C
Executable File
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--
|