📄 random.c
字号:
/*************************************************************************** * random.c - Software Radio random generator module * ------------------- * begin : Oct 17th, 2002 * authors : D.Tuninetti * emails : daniela.tuninetti@epfl.ch ***************************************************************************//*************************************************************************** * Changes * ------- * date - name - description * Oct.17th, 2002 - Creation of class - * 03/05/07 - ineiti - renamed to random * 03/05/12 - ineiti - added config->mode * 04/03/05 - ineiti - adjusted description * **************************************************************************//*************************************************************************** * * * 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. * * * ***************************************************************************//** * Produces uniform random-numbers in the range 0-255. The random-number * generator is based on a simple polynomial, so it's not really high-class. * The seed may be set to a positive number, so that subsequent tests yield * the same random numbers. This is useful in testing environments. */#include "spc.h"#define DBG_LVL 0/* Random generators */#define MODULO 2147483647#define FACTOR 16807#define LASTXN 127773#define UPTOMOD -2836typedef struct { // If seed < 0, the actual timer is taken for it's initialisation, // else the random-generator is initialised using seed. // The second case is useful for testing purposes int seed; // 0 // 0 -> normal operation // 1 -> on every call the seed is reset. This is useful if one wants // to do measurements and needs the same data on sending and receiving // side int mode; // 0}config_t;typedef struct { // ADD HERE;}stats_t;typedef struct { int seed;}private_t;/* * The initialisation function, or constructor, * is called the first time this module is instantiated. */int spc_init( swr_sdb_t *context ) { // Definition of variables - don't touch if you're not an expert config_t *config; stats_t *stats; MOD_INC_USE_COUNT; context->private_data = swr_malloc( sizeof( private_t ) ); swr_sdb_get_config_struct( context->id, (void**)&config ); swr_sdb_get_stats_struct( context->id, (void**)&stats ); config->seed = 0; config->mode = 0; // Definition - don't touch swr_sdb_free_config_struct( context->id, (void**)&config ); swr_sdb_free_stats_struct( context->id, (void**)&stats ); return 0;}/* * Every time modules from the outside change the value of a configuration parameter, * this function is called. */int spc_reconfig( swr_sdb_t *context ) { // Definition of variables - don't touch config_t *config; swr_sdb_get_config_struct( context->id, (void**)&config ); // Put you code here // ADD HERE if ( config->seed<=0 ) { private->seed = (int)get_time_usec()%100000000; } else { private->seed = config->seed; } // Definition - don't touch swr_sdb_free_config_struct( context->id, (void**)&config ); return(0);}/* * This is function that impements the `main method' of the class * Every class has got just ONE method/working-mode. */int spc_pdata( swr_sdb_t *context ) { // Definition of variables - don't touch int times, rest, prod1, prod2, n; config_t *config; U8 *out; out = buffer_out(0); swr_sdb_get_config_struct( context->id, (void**)&config ); // Re-set the seed if mode is 1 and a non-timer seed is set if ( ( config->mode == 1 ) && ( config->seed > 0 ) ) { private->seed = config->seed; } swr_sdb_free_config_struct( context->id, (void**)&config ); // This for-loop generates integers between 0 ... 2^8-1 // i.i.d. and equiprobable. PR_DBG( 4, "Generating %i bytes of output\n", size_out(0) ); for (n=0;n<port_out(0).size;n++) { times = private->seed / LASTXN; rest = private->seed - times * LASTXN; prod1 = times * UPTOMOD; prod2 = rest * FACTOR; private->seed = prod1 + prod2; if (private->seed < 0) private->seed = private->seed + MODULO; out[n]=(U8)(256.*private->seed / MODULO); } return(0);}int spc_custom_msg( swr_sdb_t *context, swr_usr_msg_t* msg_data, swr_msgq ret ) { spc_pdata( context ); return 0;}/* * This is the `destructor'. */int spc_finalize( swr_sdb_t *context ) { swr_free( private ); MOD_DEC_USE_COUNT; return(0);}/* * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */swr_spc_id_t cdb_id;int spc_module_init(void) { swr_spc_desc_t *desc; // Get a description-part from SPM // Give the following parameters: // Input-ports, output-ports, config-params, stat-params desc = swr_spc_get_new_desc( 0, 1, 2, 0 ); if ( !desc ) { PR_DBG( 0, "Can't initialise the module. This is BAD!\n" ); return -1; } // Define the different parts of config and stats UM_CONFIG_INT( "seed" ); UM_CONFIG_INT( "mode" ); UM_OUTPUT( SIG_U8, 0 ); // Initialise the callback-functions. NULL for not-used functions desc->fn_init = spc_init; desc->fn_reconfigure = spc_reconfig; desc->fn_process_data = spc_pdata; desc->fn_finalize = spc_finalize; desc->fn_custom_msg = spc_custom_msg; // And register the module in the SPM cdb_id = swr_cdb_register_spc( &desc, "random" ); if ( cdb_id == SWR_SPM_INVALID_ID ) { swr_spc_free_desc( desc ); PR_DBG( 0, "Couldn't register the module!\n" ); return 1; } PR_DBG( 4, "Ready to generate random iid equiprobable u8\n"); return 0;}/* * This is called upon rmmod */void spc_module_exit( void ) { PR_DBG( 2, "Freeing id: %i\n", cdb_id ); if ( swr_cdb_unregister_spc( cdb_id ) < 0 ) { PR_DBG( 0, "Still in use somewhere\n" ); }}// Do not touch!module_init( spc_module_init );module_exit( spc_module_exit );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -