1 /*
2  * Copyright 2018 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "math.h"
7 #include "bs_types.h"
8 #include "bs_tracing.h"
9 #include "bs_oswrap.h"
10 #include "bs_utils.h"
11 #include "bs_pc_2G4.h"
12 #include "bs_pc_2G4_utils.h"
13 #include "modem_if.h"
14 #include "modem_magic_args.h"
15 #include "p2G4_pending_tx_rx_list.h"
16 
17 /**
18  * Initialize the modem internal status
19  *
20  * The input parameters are:
21  *   dev_nbr      : the device number this modem library corresponds to
22  *                  (note that this library may be reused in between several devices)
23  *   nbr_devices  : the total number of devices in the simulation (gives the length of vectors later)
24  *   char *argv[] : a set of arguments passed to the modem library (same convention as POSIX main() command line arguments)
25  *   int argc     : the number of arguments passed to the modem library
26  *
27  * See modem_magic_argparse() for more info about this parameters
28  *
29  * This function returns a pointer to this modem's status structure
30  * This same pointer will be passed back to consecutive function calls of the library (void *this)
31  */
modem_init(int argc,char * argv[],uint dev_nbr,uint nbr_devices)32 void* modem_init(int argc, char *argv[], uint dev_nbr, uint nbr_devices) {
33   mo_magic_args_t *args;
34 
35   args = (mo_magic_args_t *)bs_calloc(1,sizeof(mo_magic_args_t));
36   args->nbr_devices = nbr_devices;
37 
38   modem_magic_argparse(argc, argv, dev_nbr, args);
39 
40   return (void*)args;
41 }
42 
43 /**
44  * Calculate the SNR of the desired input signal at the digital modem input/analog output
45  * including all modem analog impairments
46  *
47  * inputs:
48  *  this             : Pointer to this modem object
49  *  rx_radio_params  : Radio parameters/configuration of this receiver for this Rx/RSSI measurement
50  *  rx_powers        : For each possible transmitter ([0..n_devices]) what is their power level at this device antenna connector
51  *  txl_c            : For each possible transmitter what are their Tx parameters
52  *  tx_nbr           : which of the transmitters is the one we are trying to receive
53  *
54  * outputs:
55  *  OutputSNR               : SNR in the analog output / digital input of this modem (dB)
56  *  Output_RSSI_power_level : RSSI level (analog, dBm) sent to the modem digital
57  */
modem_analog_rx(void * this,p2G4_radioparams_t * rx_radio_params,double * OutputSNR,double * Output_RSSI_power_level,double * rx_powers,tx_l_c_t * txl_c,uint tx_nbr)58 void modem_analog_rx(void *this, p2G4_radioparams_t *rx_radio_params, double *OutputSNR,double *Output_RSSI_power_level,
59                      double *rx_powers, tx_l_c_t *txl_c, uint tx_nbr) {
60 
61   mo_magic_args_t *mo_st = (mo_magic_args_t *)this;
62 
63   //Trivial RSSI model: If a transmitted has the same center frequency as where the receiver is open,
64   //we assume all its power is measured. Otherwise none.
65   //Meaning, we ignore receiver filter and modulation shapes
66   p2G4_freq_t  rx_freq = rx_radio_params->center_freq;
67   double acc_power = 4e-12; //-114dBm : Thermal noise floor for 1MHz @300K
68   for (int i = 0; i < mo_st->nbr_devices ; i++ ) {
69     if ( txl_c->used[i] ){ //For each active transmitter (including the desired one
70       if (rx_freq == txl_c->tx_list[i].tx_s.radio_params.center_freq) {
71         acc_power += pow(10.0, rx_powers[i]/10.0);
72       }
73     }
74   }
75 
76   *Output_RSSI_power_level = 10*log10(acc_power);
77   *OutputSNR = 100;
78 
79 }
80 
81 /**
82  * Return the bit error probability ([0.. RAND_PROB_1]) for a given SNR
83  *
84  * inputs:
85  *  this          : Pointer to this modem object
86  *  rx_modem_params: Radio parameters/configuration of this receiver for this Rx/RSSI measurement
87  *  SNR           : SNR level at the analog output as calculated by modem_analog_rx()
88  */
modem_digital_perf_ber(void * this,p2G4_modemdigparams_t * rx_modem_params,double SNR)89 uint32_t modem_digital_perf_ber(void *this, p2G4_modemdigparams_t *rx_modem_params, double SNR) {
90   return ((mo_magic_args_t*)this)->BER;
91 }
92 
93 /**
94  * Return the probability of the packet sync'ing ([0.. RAND_PROB_1]) for a given SNR and
95  * transmission parameters
96  *
97  * (note that this should ONLY include excess packet error probability,
98  * as over the sync word and address normal bit errors will also be calculated)
99  *
100  * inputs:
101  *  this            : Pointer to this modem object
102  *  rx_modem_params : Radio parameters/configuration of this receiver for this Rx/RSSI measurement
103  *  SNR             : SNR level at the analog output as calculated by modem_analog_rx()
104  *  tx_s            : Parameters of the transmission we are receiving (in case the sync. probability depends on any of them)
105  */
modem_digital_perf_sync(void * this,p2G4_modemdigparams_t * rx_modem_params,double SNR,p2G4_txv2_t * tx_s)106 uint32_t modem_digital_perf_sync(void *this, p2G4_modemdigparams_t *rx_modem_params, double SNR, p2G4_txv2_t* tx_s) {
107   return  ((mo_magic_args_t*)this)->sync_prob;
108 }
109 
110 /**
111  * Return the digital RSSI value the modem would have produced for this given
112  * RSSI_power_level in the digital input
113  *
114  * inputs:
115  *  this             : Pointer to this modem object
116  *  rx_radio_params  : Radio parameters/configuration of this receiver for this Rx/RSSI measurement
117  *  RSSI_power_level : Analog power level as measured by modem_analog_rx()
118  *
119  * outputs:
120  *  RSSI  : RSSI "digital" value returned by this modem, following the c2G4_rssi_power_t format (16.16 signed value)
121  */
modem_digital_RSSI(void * this,p2G4_radioparams_t * rx_radio_params,double RSSI_power_level,p2G4_rssi_power_t * RSSI)122 void modem_digital_RSSI(void *this, p2G4_radioparams_t *rx_radio_params, double RSSI_power_level,
123                         p2G4_rssi_power_t *RSSI) {
124 
125   *RSSI = p2G4_RSSI_value_from_dBm(RSSI_power_level);
126 }
127 
128 /**
129  * Clean up: Free the memory the modem may have allocated
130  * close any file descriptors etc.
131  * (the simulation has ended)
132  */
modem_delete(void * this)133 void modem_delete(void *this){
134   if (this != NULL){
135     free(this);
136   }
137 }
138 
139