⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radio_bs.c

📁 软件无线电的平台
💻 C
字号:
/***************************************************************************               radio_bs.c  -  SRadio MoreMS                            -------------------    begin                :  02/10/30    authors              :  Linus Gasser    emails               :  linus.gasser@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 02/10/30 - ineiti - begin 02/11/04 - ineiti - no msgqs... 03/01/16 - ineiti - added a real multi-user environment 04/03/02 - ineiti - adjusted the gains so that it works... 04/04/20 - ineiti - cleaned up exiting stuff  **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//** * Make a basestation where multiple mobiles may connect to * * Function: * - emit sync and Sch * - listen to RACh * - allocate MS a position via the Sch * - if MS got lost, clear it's position */#define DBG_LVL 1#include "system.h"#include "sdb.h"#include "stfa.h"#include "antenna.h"#include "std.h"#include "debugging.h"#include "chain.h"#include "../sradio.h"#include "../common.h"#define ANTENNA 0#define STR_LEN 256swr_sdb_idstfa,sch,energy,rndstr[MAX_SLOTS],midamble[MAX_SLOTS],mod[MAX_SLOTS],mafi[MAX_SLOTS],cch[MAX_SLOTS];struct chain_t *ch_sch, *ch_rach, *ch_dch,      *uplink[MAX_TR_SLOTS], *downlink[MAX_TR_SLOTS];struct rach_data rach_data;char *slot_str[MAX_SLOTS];struct ms_data mobile[ MAX_MS ];int slots_per_frame, looping, ms_count, frames;void mobile_attach( int index ) {  int d1, d2, u1;  // The mobile is new, so fill up it's config  swr_sdb_set_config_int_array( sch, "id0", index, rach_data.id );  // One uplink and two downlinks  d1 = mobile[index].downlink[0] = index * 4 + 3;  u1 = mobile[index].uplink[0] = index * 4 + 4;  d2 = mobile[index].downlink[1] = index * 4 + 5;  swr_sdb_set_config_int_array ( sch, "downlinks0", index,                                 ( 1 << d1 ) +                                 ( 1 << d2 ) );  swr_sdb_set_config_int_array( sch, "uplinks0", index,                                ( 1 << u1 ) );  downlink[ d1 ] = setup_send( d1, cch, mod, stfa, slot_str );  uplink[ u1 ] = setup_rcv( u1, stfa, mafi, cch, slot_str );  downlink[ d2 ] = setup_send( d2, cch, mod, stfa, slot_str );  swr_sdb_set_config_int_array( sch, "mafi0", index, mafi[ u1 ] );  ms_count++;}void mobile_detach( int index ) {  int i, up, down;  // Sanity-check  if ( !ms_count ) {    PR_DBG( 0, "No mobile to detach!\n" );    return;  }  swr_sdb_set_config_int_array( sch, "id0", index, -1 );  up = swr_sdb_get_config_int_array( sch, "uplinks0", index );  down = swr_sdb_get_config_int_array( sch, "downlinks0", index );  swr_sdb_set_config_int_array( sch, "mafi0", index, -1 );  // Delete all chains  for ( i=0; i<MAX_SLOTS; i++ ) {    if ( up & ( 1 << i ) ) {      swr_chain_destroy( uplink[ i ] );      swr_stfa_notice_sdb( stfa, i, -1 );      swr_free( slot_str[ i ] );    }    if ( down & ( 1 << i )  ) {      swr_chain_destroy( downlink[ i ] );      swr_stfa_notice_sdb( stfa, i, -1 );      swr_free( slot_str[ i ] );    }  }  PR_DBG( 1, "Detached 1 mobile.\n" );  ms_count--;}void check_exit( void ) {  int i, rec;  for ( i=0; i<MAX_MS; i++ ) {    if ( swr_sdb_get_config_int_array( sch, "id0", i ) >= 0 ) {      rec = swr_sdb_get_stats_int( cch[ mobile[i].uplink[ 0 ] ], "received" );      if ( rec < 1 ) {        PR_DBG( 2, "Receiving mobile %i: %i\n", i, rec );      } else {        PR_DBG( 4, "Receiving mobile %i: %i\n", i, rec );      }#ifdef USER_SPACE      if ( rec < -10 ) {        // This mobile hasn't sent anything for the last 10        // frames.        mobile_detach( i );      }#else      if ( rec < -100 ) {        // This mobile hasn't sent anything for the last 100        // frames.        mobile_detach( i );      }#endif    }  }}void check_for_mobile( void ) {  int i, index =  MAX_MS;  // Yipie, there is a new MS.  PR_DBG( 1, "MS %i asked for access\n", rach_data.id );  for ( i=0; i<MAX_MS; i++ ) {    if ( swr_sdb_get_config_int_array( sch, "id0", i ) == rach_data.id ) {      PR_DBG( 0, "MS is still asking for access... strange\n" );      return;    }    if ( swr_sdb_get_config_int_array( sch, "id0", i ) < 0 ) {      index = i;    }  }  if ( index < MAX_MS ) {    PR_DBG( 1, "MS got index %i\n", index );  } else {    PR_DBG( 0, "MS rejected, list full!\n" );    return;  }  mobile_attach( index );}/** * this is called once a frame */int dispatcher( int msg, void *data, swr_sdb_id ret_id ) {  // Check for 'old' mobiles  check_exit();  // Check for RACh  if ( swr_sdb_get_stats_int( cch[ SLOT_RACH ], "received" ) == 1 ) {    check_for_mobile();  }  return 0;}/** * Here everything is prepared */void *start_it( void *arg ) {  int i, j;  looping = 1;  frames = 0;  stfa = swr_sdb_instantiate_name( "stfa" );  for ( i=0; i<MAX_MS; i++ ) {    for ( j=0; j<MAX_SLOTS; j++ ) {      mobile[i].uplink[j] = mobile[i].downlink[j] = -1;    }  }  ms_count = 0;  rach_data.id = -2;  PR( "Setting up Sch on slot %i\n", SLOT_SCH );  ch_sch = swr_chain_create( NEW_SPC_VAR( "sch_send", sch ),                             NEW_SPC_VAR( "mapper", mod[SLOT_SCH] ),                             NEW_SPC( "spread" ),                             NEW_SPC( "midamble" ),                             NEW_SPC( "synch_send" ),                             NEW_SPC( "rrc" ),                             OLD_SPC_IN( stfa, SLOT_SCH ),			     CHAIN_END );  swr_stfa_notice_sdb( stfa, SLOT_SCH, sch );  swr_sdb_set_config_double( sch, "target_snr0", 20 );  swr_sdb_set_config_double( sch, "target_snr1", 20 );  PR( "Setting up RACh slot %i\n", SLOT_RACH );  ch_rach = swr_chain_create( OLD_SPC_OUT( stfa, SLOT_RACH ),                              NEW_SPC_VAR( "energy", energy ),                              NEW_SPC_VAR( "matched_filter", mafi[SLOT_RACH] ),                              NEW_SPC( "despread" ),                              NEW_SPC( "slicer" ),                              NEW_SPC_VAR( "cch_rcv", cch[SLOT_RACH] ),			      CHAIN_END );  swr_sdb_set_config_pointer( cch[SLOT_RACH], "data", &rach_data );  swr_sdb_set_config_int( cch[SLOT_RACH], "length", sizeof( rach_data ) );  swr_stfa_notice_func( stfa, 10, dispatcher );  swr_stfa_go( stfa );  swr_sdb_set_config_int( stfa, "attn_rx", 5 );  while( looping ) {    usleep( 1000000 );  }  swr_stfa_stop( stfa );  PR_DBG( 0, "Stopping STFA\n" );  return 0;}struct thread start;/** * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */int um_module_init(void) {  int i;  looping = 0;  ch_sch = NULL;  ch_rach = NULL;  ch_dch = NULL;  for ( i=0; i<MAX_TR_SLOTS; i++ ) {    uplink[i] = downlink[i] = NULL;  }  if ( swr_thread_init( &start, start_it, NULL ) ) {    goto rrc_no_thread;  }  return 0;rrc_no_thread:  PR_DBG( 0, "Couldn't init thread\n" );  return -1;}void um_module_exit( void ) {  int i;  looping = 0;  swr_thread_free( &start, NULL );  PR_DBG( 0, "deleting everything\n" );  swr_chain_destroy( ch_sch );  swr_chain_destroy( ch_rach );  swr_chain_destroy( ch_dch );  for ( i=0; i<MAX_TR_SLOTS; i++ ) {    swr_chain_destroy( uplink[i] );    swr_chain_destroy( downlink[i] );  }  swr_sdb_destroy( stfa );}module_init( um_module_init );module_exit( um_module_exit );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -