Commit ee3d4064 authored by nikaeinn's avatar nikaeinn

* add some functions for terminal localizations

* fix few issues with the pre-ci tests



git-svn-id: http://svn.eurecom.fr/openair4G/trunk@6253 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 80eca142
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "PHY/defs.h" #include "PHY/defs.h"
#include "dci.h" #include "dci.h"
#include "uci.h" #include "uci.h"
#include "UTIL/LISTS/list.h"
#define MOD_TABLE_QPSK_OFFSET 1 #define MOD_TABLE_QPSK_OFFSET 1
#define MOD_TABLE_16QAM_OFFSET 5 #define MOD_TABLE_16QAM_OFFSET 5
...@@ -470,6 +471,14 @@ typedef struct { ...@@ -470,6 +471,14 @@ typedef struct {
uint8_t num_active_cba_groups; uint8_t num_active_cba_groups;
/// allocated CBA RNTI for this ulsch /// allocated CBA RNTI for this ulsch
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
#ifdef LOCALIZATION
/// epoch timestamp in millisecond
int32_t reference_timestamp_ms;
/// aggregate physical states every n millisecond
int32_t aggregation_period_ms;
/// a set of lists used for localization
struct list loc_rss_list, loc_rssi_list, loc_subcarrier_rss_list, loc_timing_advance_list, loc_timing_update_list;
#endif
} LTE_eNB_ULSCH_t; } LTE_eNB_ULSCH_t;
typedef struct { typedef struct {
...@@ -531,6 +540,12 @@ typedef struct { ...@@ -531,6 +540,12 @@ typedef struct {
uint8_t dl_power_off; uint8_t dl_power_off;
} LTE_DL_UE_HARQ_t; } LTE_DL_UE_HARQ_t;
typedef struct {
/// time-based localization, relying on TA and TOA
double time_based;
/// power-based localization, relying on RSS and RSSI
double power_based;
} eNB_UE_estimated_distances;
typedef struct { typedef struct {
/// UL RSSI per receive antenna /// UL RSSI per receive antenna
...@@ -555,7 +570,7 @@ typedef struct { ...@@ -555,7 +570,7 @@ typedef struct {
UE_MODE_t mode; UE_MODE_t mode;
/// Current sector where UE is attached /// Current sector where UE is attached
uint8_t sector; uint8_t sector;
/// dlsch l2 errors /// dlsch l2 errors
uint32_t dlsch_l2_errors[8]; uint32_t dlsch_l2_errors[8];
/// dlsch trials per harq and round /// dlsch trials per harq and round
...@@ -595,6 +610,10 @@ typedef struct { ...@@ -595,6 +610,10 @@ typedef struct {
/// Bitrate on the PDSCH [bps] /// Bitrate on the PDSCH [bps]
unsigned int dlsch_bitrate; unsigned int dlsch_bitrate;
// unsigned int total_transmitted_bits; // unsigned int total_transmitted_bits;
#ifdef LOCALIZATION
eNB_UE_estimated_distances distance;
int32_t *subcarrier_rssi;
#endif
} LTE_eNB_UE_stats; } LTE_eNB_UE_stats;
typedef struct { typedef struct {
......
...@@ -1326,14 +1326,20 @@ void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB, ...@@ -1326,14 +1326,20 @@ void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB,
eNB_pusch_vars->ulsch_power_0[i] = signal_energy(eNB_pusch_vars->drs_ch_estimates_0[eNB_id][i], eNB_pusch_vars->ulsch_power_0[i] = signal_energy(eNB_pusch_vars->drs_ch_estimates_0[eNB_id][i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction; ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
eNB_pusch_vars->ulsch_power_1[i] = signal_energy(eNB_pusch_vars->drs_ch_estimates_1[eNB_id][i], eNB_pusch_vars->ulsch_power_1[i] = signal_energy(eNB_pusch_vars->drs_ch_estimates_1[eNB_id][i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction; ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
} }
} }
else else
{ {
for (i=0;i<frame_parms->nb_antennas_rx;i++) for (i=0;i<frame_parms->nb_antennas_rx;i++) {
eNB_pusch_vars->ulsch_power[i] = signal_energy_nodc(eNB_pusch_vars->drs_ch_estimates[eNB_id][i], eNB_pusch_vars->ulsch_power[i] = signal_energy_nodc(eNB_pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction; ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
#ifdef LOCALIZATION
eNB_pusch_vars->subcarrier_power = (int32_t *)malloc(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*sizeof(int32_t));
eNB_pusch_vars->active_subcarrier = subcarrier_energy(eNB_pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12, eNB_pusch_vars->subcarrier_power, rx_power_correction);
#endif
}
} }
//write_output("rxdataF_ext.m","rxF_ext",eNB_pusch_vars->rxdataF_ext[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1); //write_output("rxdataF_ext.m","rxF_ext",eNB_pusch_vars->rxdataF_ext[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1);
......
...@@ -486,6 +486,13 @@ void mmxcopy(void *dest,void *src,int size); ...@@ -486,6 +486,13 @@ void mmxcopy(void *dest,void *src,int size);
*/ */
int32_t signal_energy(int32_t *,uint32_t); int32_t signal_energy(int32_t *,uint32_t);
#ifdef LOCALIZATION
/*!\fn int32_t signal_energy(int *,uint32_t);
\brief Computes the signal energy per subcarrier
*/
int32_t subcarrier_energy(int32_t *,uint32_t, int32_t* subcarrier_energy, uint16_t rx_power_correction);
#endif
/*!\fn int32_t signal_energy_nodc(int32_t *,uint32_t); /*!\fn int32_t signal_energy_nodc(int32_t *,uint32_t);
\brief Computes the signal energy per subcarrier, without DC removal \brief Computes the signal energy per subcarrier, without DC removal
*/ */
......
...@@ -41,6 +41,36 @@ ...@@ -41,6 +41,36 @@
#ifndef EXPRESSMIMO_TARGET #ifndef EXPRESSMIMO_TARGET
#ifdef LOCALIZATION
int32_t subcarrier_energy(int32_t *input,uint32_t length, int32_t *subcarrier_energy, uint16_t rx_power_correction) {
int32_t i, subcarrier_pwr;
register __m64 mm0,mm1, subcarrier;
subcarrier = _m_pxor(subcarrier,subcarrier);
__m64 *in = (__m64 *)input;
#ifdef MAIN
int16_t *printb;
#endif
mm0 = _m_pxor(mm0,mm0);
for (i=0;i<length>>1;i++) {
mm1 = in[i];
mm1 = _m_pmaddwd(mm1,mm1);
mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
subcarrier = mm1;
subcarrier = _m_psrlqi(subcarrier,32);
subcarrier = _m_paddd(subcarrier,mm1);
subcarrier_pwr = _m_to_int(subcarrier);
subcarrier_pwr<<=shift;
subcarrier_pwr = (unsigned short) dB_fixed(subcarrier_pwr);
subcarrier_energy[i] = subcarrier_pwr*rx_power_correction;
}
return i;
}
#endif
int32_t signal_energy(int32_t *input,uint32_t length) { int32_t signal_energy(int32_t *input,uint32_t length) {
int32_t i; int32_t i;
......
...@@ -336,6 +336,11 @@ typedef struct PHY_VARS_eNB_s{ ...@@ -336,6 +336,11 @@ typedef struct PHY_VARS_eNB_s{
time_stats_t ulsch_tc_intl1_stats; time_stats_t ulsch_tc_intl1_stats;
time_stats_t ulsch_tc_intl2_stats; time_stats_t ulsch_tc_intl2_stats;
#ifdef LOCALIZATION
/// time state for localization
time_stats_t localization_stats;
#endif
#if defined(ENABLE_RAL) #if defined(ENABLE_RAL)
hash_table_t *ral_thresholds_timed; hash_table_t *ral_thresholds_timed;
SLIST_HEAD(ral_thresholds_gen_poll_enb_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; SLIST_HEAD(ral_thresholds_gen_poll_enb_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
......
...@@ -602,6 +602,12 @@ typedef struct{ ...@@ -602,6 +602,12 @@ typedef struct{
int ulsch_power_1[2]; int ulsch_power_1[2];
/// llr values /// llr values
int16_t *llr; int16_t *llr;
#ifdef LOCALIZATION
/// number of active subcarrier for a specific UE
int32_t active_subcarrier;
/// subcarrier power in dBm
int32_t *subcarrier_power;
#endif
} LTE_eNB_PUSCH; } LTE_eNB_PUSCH;
typedef struct { typedef struct {
......
...@@ -519,6 +519,17 @@ void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,u ...@@ -519,6 +519,17 @@ void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,u
int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index); int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
#ifdef LOCALIZATION
/** \brief This function collects eNB_UE stats and aggregate them in lists for localization
@param phy_vars_ue PHY variables
@param UE_id Index of UE
@param frame Index of frame
@param subframe Index of subframe
@param UE_tx_power_dB estimated UE Tx power
@returns -1 if updated list, 0 if calculated median
*/
double aggregate_eNB_UE_localization_stats(PHY_VARS_eNB *phy_vars_eNB, int8_t UE_id, frame_t frameP, sub_frame_t subframeP, int32_t UE_tx_power_dB);
#endif
LTE_eNB_UE_stats* get_eNB_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti); LTE_eNB_UE_stats* get_eNB_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
LTE_DL_FRAME_PARMS *get_lte_frame_parms(module_id_t Mod_id, uint8_t CC_id); LTE_DL_FRAME_PARMS *get_lte_frame_parms(module_id_t Mod_id, uint8_t CC_id);
...@@ -527,7 +538,7 @@ MU_MIMO_mode* get_mu_mimo_mode (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti); ...@@ -527,7 +538,7 @@ MU_MIMO_mode* get_mu_mimo_mode (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t harq_pid); int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t harq_pid);
int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid); int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor);
int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid); int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid);
......
...@@ -44,6 +44,9 @@ ...@@ -44,6 +44,9 @@
#include "SCHED/defs.h" #include "SCHED/defs.h"
#include "SCHED/extern.h" #include "SCHED/extern.h"
#ifdef LOCALIZATION
#include <sys/time.h>
#endif
void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms, void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char current_subframe, unsigned char current_subframe,
...@@ -548,6 +551,148 @@ unsigned int is_phich_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub ...@@ -548,6 +551,148 @@ unsigned int is_phich_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub
} }
#ifdef LOCALIZATION
double aggregate_eNB_UE_localization_stats(PHY_VARS_eNB *phy_vars_eNB, int8_t UE_id, frame_t frame, sub_frame_t subframe, int32_t UE_tx_power_dB){
// parameters declaration
int8_t Mod_id, CC_id;
int32_t harq_pid, avg_power, avg_rssi, median_power, median_rssi, median_subcarrier_rss, median_TA, median_TA_update, ref_timestamp_ms, current_timestamp_ms;
char cqis[100], sub_powers[2048];
int len = 0, i;
struct timeval ts;
double sys_bw = 0;
uint8_t N_RB_DL;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
Mod_id = phy_vars_eNB->Mod_id;
CC_id = phy_vars_eNB->CC_id;
ref_timestamp_ms = phy_vars_eNB->ulsch_eNB[UE_id+1]->reference_timestamp_ms;
for (i=0;i<13;i++) {
len += sprintf(&cqis[len]," %d ", phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].DL_subband_cqi[0][i]);
}
len = 0;
for (i=0;i<phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->active_subcarrier;i++) {
len += sprintf(&sub_powers[len]," %d ", phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->subcarrier_power[i]);
}
gettimeofday(&ts, NULL);
current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
LOG_F(LOCALIZE, "PHY: [UE %x/%d -> eNB %d], timestamp %d, "
"frame %d, subframe %d"
"UE Tx power %d dBm, "
"RSSI ant1 %d dBm, "
"RSSI ant2 %d dBm, "
"pwr ant1 %d dBm, "
"pwr ant2 %d dBm, "
"Rx gain %d dBm, "
"TA %d, "
"TA update %d, "
"DL_CQI (%d,%d), "
"Wideband CQI (%d,%d), "
"DL Subband CQI[13] %s \n"
"timestamp %d, (%d active subcarrier) %s \n"
,phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->rnti, UE_id, Mod_id, current_timestamp_ms,
frame,subframe,
UE_tx_power_dB,
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UL_rssi[1],
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->ulsch_power[1]),
phy_vars_eNB->rx_total_gain_eNB_dB,
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset, // raw timing advance 1/sampling rate
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].timing_advance_update,
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].DL_cqi[0],phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].DL_cqi[1],
phy_vars_eNB->PHY_measurements_eNB[Mod_id].wideband_cqi_dB[(uint32_t)UE_id][0],
phy_vars_eNB->PHY_measurements_eNB[Mod_id].wideband_cqi_dB[(uint32_t)UE_id][1],
cqis,
current_timestamp_ms,
phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->active_subcarrier,
sub_powers);
N_RB_DL = frame_parms->N_RB_DL;
switch (N_RB_DL)
{
case 6:
sys_bw = 1.92;
break;
case 25:
sys_bw = 7.68;
break;
case 50:
sys_bw = 15.36;
break;
case 100:
sys_bw = 30.72;
break;
}
if ((current_timestamp_ms - ref_timestamp_ms > phy_vars_eNB->ulsch_eNB[UE_id+1]->aggregation_period_ms) &&
(phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rss_list.size != 0)) {
// check the size of one list to be sure there was a message transmitted during the defined aggregation period
median_power = calculate_median(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rss_list);
del(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rss_list);
median_rssi = calculate_median(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rssi_list);
del(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rssi_list);
median_subcarrier_rss = calculate_median(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_subcarrier_rss_list);
del(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_subcarrier_rss_list);
median_TA = calculate_median(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_advance_list);
del(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_advance_list);
median_TA_update = calculate_median(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_update_list);
del(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_update_list);
double alpha = 2, power_distance, time_distance;
power_distance = pow(10, ((UE_tx_power_dB - (median_subcarrier_rss - phy_vars_eNB->rx_total_gain_eNB_dB))/(20.0*alpha)));
time_distance = (double) 299792458*(phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset)/(sys_bw*1000000);
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].distance.time_based = time_distance;
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].distance.power_based = power_distance;
LOG_D(LOCALIZE, " PHY [UE %x/%d -> eNB %d], timestamp %d, "
"frame %d, subframe %d "
"UE Tx power %d dBm, "
"median RSSI %d dBm, "
"median Power %d dBm, "
"Rx gain %d dBm, "
"power estimated r = %0.3f, "
" TA %d, update %d "
"TA estimated r = %0.3f\n"
,phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->rnti, UE_id, Mod_id, current_timestamp_ms,
frame, subframe,
UE_tx_power_dB,
median_rssi,
median_power,
phy_vars_eNB->rx_total_gain_eNB_dB,
power_distance,
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset, median_TA_update,
time_distance);
initialize(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rss_list);
initialize(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_subcarrier_rss_list);
initialize(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rssi_list);
initialize(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_advance_list);
initialize(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_update_list);
// make the reference timestamp == current timestamp
phy_vars_eNB->ulsch_eNB[UE_id+1]->reference_timestamp_ms = current_timestamp_ms;
return 0;
}
else {
avg_power = (dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->ulsch_power[0]) + dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->ulsch_power[1]))/2;
avg_rssi = (phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UL_rssi[0] + phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UL_rssi[1])/2;
push_front(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rss_list,avg_power);
push_front(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_rssi_list,avg_rssi);
for (i=0;i<phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->active_subcarrier;i++) {
push_front(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_subcarrier_rss_list, phy_vars_eNB->lte_eNB_pusch_vars[(uint32_t)UE_id]->subcarrier_power[i]);
}
push_front(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_advance_list, phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset);
push_front(&phy_vars_eNB->ulsch_eNB[UE_id+1]->loc_timing_update_list, phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].timing_advance_update);
return -1;
}
}
#endif
LTE_eNB_UE_stats* get_eNB_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti) { LTE_eNB_UE_stats* get_eNB_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti) {
int8_t UE_id; int8_t UE_id;
if ((PHY_vars_eNB_g == NULL) || (PHY_vars_eNB_g[Mod_id] == NULL) || (PHY_vars_eNB_g[Mod_id][CC_id]==NULL)) { if ((PHY_vars_eNB_g == NULL) || (PHY_vars_eNB_g[Mod_id] == NULL) || (PHY_vars_eNB_g[Mod_id][CC_id]==NULL)) {
......
...@@ -2974,7 +2974,7 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e ...@@ -2974,7 +2974,7 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
//compute the expected ULSCH RX power (for the stats) //compute the expected ULSCH RX power (for the stats)
phy_vars_eNB->ulsch_eNB[(uint32_t)i]->harq_processes[harq_pid]->delta_TF = phy_vars_eNB->ulsch_eNB[(uint32_t)i]->harq_processes[harq_pid]->delta_TF =
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid); get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
//dump_ulsch(phy_vars_eNB, sched_subframe, i); //dump_ulsch(phy_vars_eNB, sched_subframe, i);
...@@ -3125,7 +3125,7 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e ...@@ -3125,7 +3125,7 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) - phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) -
phy_vars_eNB->rx_total_gain_eNB_dB - phy_vars_eNB->rx_total_gain_eNB_dB -
hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 - hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid)/100; get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1;
...@@ -3226,6 +3226,16 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e ...@@ -3226,6 +3226,16 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
LOG_D(PHY,"[eNB][Auto-Calibration] Frame %d, Subframe %d : ULSCH PDU (RX) %d bytes\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); LOG_D(PHY,"[eNB][Auto-Calibration] Frame %d, Subframe %d : ULSCH PDU (RX) %d bytes\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
} }
*/ */
#ifdef LOCALIZATION
start_meas(&phy_vars_eNB->localization_stats);
aggregate_eNB_UE_localization_stats(phy_vars_eNB,
i,
frame,
subframe,
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 1)/100);
stop_meas(&phy_vars_eNB->localization_stats);
#endif
#endif #endif
} }
......
...@@ -45,8 +45,9 @@ ...@@ -45,8 +45,9 @@
// This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25 // This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25
int16_t hundred_times_delta_TF[100] = {-32768,-1268,-956,-768,-631,-523,-431,-352,-282,-219,-161,-107,-57,-9,36,79,120,159,197,234,269,304,337,370,402,434,465,495,525,555,583,612,640,668,696,723,750,777,803,829,856,881,907,933,958,983,1008,1033,1058,1083,1108,1132,1157,1181,1205,1229,1254,1278,1302,1325,1349,1373,1397,1421,1444,1468,1491,1515,1538,1562,1585,1609,1632,1655,1679,1702,1725,1748,1772,1795,1818,1841,1864,1887,1910,1933,1956,1980,2003,2026,2049,2072,2095,2118,2141,2164,2186,2209,2232,2255}; int16_t hundred_times_delta_TF[100] = {-32768,-1268,-956,-768,-631,-523,-431,-352,-282,-219,-161,-107,-57,-9,36,79,120,159,197,234,269,304,337,370,402,434,465,495,525,555,583,612,640,668,696,723,750,777,803,829,856,881,907,933,958,983,1008,1033,1058,1083,1108,1132,1157,1181,1205,1229,1254,1278,1302,1325,1349,1373,1397,1421,1444,1468,1491,1515,1538,1562,1585,1609,1632,1655,1679,1702,1725,1748,1772,1795,1818,1841,1864,1887,1910,1933,1956,1980,2003,2026,2049,2072,2095,2118,2141,2164,2186,2209,2232,2255};
uint16_t hundred_times_log10_NPRB[100] = {0,301,477,602,698,778,845,903,954,1000,1041,1079,1113,1146,1176,1204,1230,1255,1278,1301,1322,1342,1361,1380,1397,1414,1431,1447,1462,1477,1491,1505,1518,1531,1544,1556,1568,1579,1591,1602,1612,1623,1633,1643,1653,1662,1672,1681,1690,1698,1707,1716,1724,1732,1740,1748,1755,1763,1770,1778,1785,1792,1799,1806,1812,1819,1826,1832,1838,1845,1851,1857,1863,1869,1875,1880,1886,1892,1897,1903,1908,1913,1919,1924,1929,1934,1939,1944,1949,1954,1959,1963,1968,1973,1977,1982,1986,1991,1995,2000};
int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid) { int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor) {
uint32_t Nre,sumKr,MPR_x100,Kr,r; uint32_t Nre,sumKr,MPR_x100,Kr,r;
uint16_t beta_offset_pusch; uint16_t beta_offset_pusch;
...@@ -75,7 +76,12 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id, ...@@ -75,7 +76,12 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,
if (phy_vars_eNB->ul_power_control_dedicated[UE_id].deltaMCS_Enabled == 1) { if (phy_vars_eNB->ul_power_control_dedicated[UE_id].deltaMCS_Enabled == 1) {
// This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch)
return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)); if (bw_factor == 1) {
uint8_t nb_rb = phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb;
return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1];
}
else
return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3));
} }
else { else {
return(0); return(0);
...@@ -83,7 +89,7 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id, ...@@ -83,7 +89,7 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,
} }
int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) { int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) {
return get_hundred_times_delta_IF_eNB(PHY_vars_eNB_g[module_idP][CC_id],find_ue(rnti,PHY_vars_eNB_g[module_idP][CC_id]),harq_pid); return get_hundred_times_delta_IF_eNB(PHY_vars_eNB_g[module_idP][CC_id],find_ue(rnti,PHY_vars_eNB_g[module_idP][CC_id]),harq_pid, 0);
} }
int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t harq_pid) { int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t harq_pid) {
...@@ -110,7 +116,6 @@ int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8 ...@@ -110,7 +116,6 @@ int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8
} }
} }
uint16_t hundred_times_log10_NPRB[100] = {0,301,477,602,698,778,845,903,954,1000,1041,1079,1113,1146,1176,1204,1230,1255,1278,1301,1322,1342,1361,1380,1397,1414,1431,1447,1462,1477,1491,1505,1518,1531,1544,1556,1568,1579,1591,1602,1612,1623,1633,1643,1653,1662,1672,1681,1690,1698,1707,1716,1724,1732,1740,1748,1755,1763,1770,1778,1785,1792,1799,1806,1812,1819,1826,1832,1838,1845,1851,1857,1863,1869,1875,1880,1886,1892,1897,1903,1908,1913,1919,1924,1929,1934,1939,1944,1949,1954,1959,1963,1968,1973,1977,1982,1986,1991,1995,2000};
uint8_t alpha_lut[8] = {0,40,50,60,70,80,90,100}; uint8_t alpha_lut[8] = {0,40,50,60,70,80,90,100};
......
...@@ -362,6 +362,7 @@ typedef struct{ //RRC_INTERFACE_FUNCTIONS ...@@ -362,6 +362,7 @@ typedef struct{ //RRC_INTERFACE_FUNCTIONS
void (*rrc_data_indP) (module_id_t , rb_id_t , sdu_size_t , char*); void (*rrc_data_indP) (module_id_t , rb_id_t , sdu_size_t , char*);
void (*fn_rrc) (void); void (*fn_rrc) (void);
uint8_t (*get_rrc_status)(uint8_t Mod_id,uint8_t eNB_flag,uint8_t eNB_index); uint8_t (*get_rrc_status)(uint8_t Mod_id,uint8_t eNB_flag,uint8_t eNB_index);
double (*rrc_get_estimated_ue_distance) (module_id_t Mod_id, uint8_t UE_id, uint8_t CC_id, uint8_t loc_type);
}RRC_XFACE; }RRC_XFACE;
......
...@@ -468,3 +468,36 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui ...@@ -468,3 +468,36 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
return(0); return(0);
} }
#ifdef LOCALIZATION
double
rrc_get_estimated_ue_distance(module_id_t Mod_id, const frame_t frameP, uint8_t UE_id, int CC_id, uint8_t loc_type){
// localization types:
// 0: power based
// 1: time based
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
int pCCid;
uint16_t rnti;
//for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]) {
pCCid = UE_PCCID(Mod_id,UE_id);
rnti = UE_list->UE_template[pCCid][UE_id].rnti;
if(rnti == 0)
return -1;
eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,pCCid,rnti);
switch (loc_type) {
case 0:
return eNB_UE_stats->distance.power_based;
break;
case 1:
return eNB_UE_stats->distance.time_based;
break;
default:
return eNB_UE_stats->distance.power_based;
}
// LOG_D(LOCALIZE, "DEBUG ME, dist = %d\n", &eNB_mac_inst[Mod_id].UE_list.UE_template[CC_id][UE_id].distance.power_based);
}
#endif
...@@ -567,6 +567,12 @@ typedef struct{ ...@@ -567,6 +567,12 @@ typedef struct{
uint32_t ul_buffer_info[MAX_NUM_LCGID]; uint32_t ul_buffer_info[MAX_NUM_LCGID];
/// UE tx power
int32_t ue_tx_power;
#ifdef LOCALIZATION
eNB_UE_estimated_distances distance;
#endif
} UE_TEMPLATE; } UE_TEMPLATE;
typedef struct{ typedef struct{
...@@ -919,91 +925,7 @@ typedef struct { ...@@ -919,91 +925,7 @@ typedef struct {
uint8_t n_adj_cells; uint8_t n_adj_cells;
} neigh_cell_id_t; } neigh_cell_id_t;
#include "proto.h"
/* \brief Generate header for DL-SCH. This function parses the desired control elements and sdus and generates the header as described
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in the DLSCH buffer.
@param mac_header Pointer to the first byte of the MAC header (DL-SCH buffer)
@param num_sdus Number of SDUs in the payload
@param sdu_lengths Pointer to array of SDU lengths
@param sdu_lcids Pointer to array of LCIDs (the order must be the same as the SDU length array)
@param drx_cmd dicontinous reception command
@param timing_advancd_cmd timing advanced command
@param ue_cont_res_id Pointer to contention resolution identifier (NULL means not present in payload)
@param short_padding Number of bytes for short padding (0,1,2)
@param post_padding number of bytes for padding at the end of MAC PDU
@returns Number of bytes used for header
*/
unsigned char generate_dlsch_header(unsigned char *mac_header,
unsigned char num_sdus,
unsigned short *sdu_lengths,
unsigned char *sdu_lcids,
unsigned char drx_cmd,
short timing_advance_cmd,
unsigned char *ue_cont_res_id,
unsigned char short_padding,
unsigned short post_padding);
/** \brief RRC Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages.
@param Mod_id Instance ID of eNB
@param eNB_flag Indicates if this is a eNB or UE configuration
@param UE_id Index of UE if this is an eNB configuration
@param eNB_id Index of eNB if this is a UE configuration
@param radioResourceConfigCommon Structure from SIB2 for common radio parameters (if NULL keep existing configuration)
@param physcialConfigDedicated Structure from RRCConnectionSetup or RRCConnectionReconfiguration for dedicated PHY parameters (if NULL keep existing configuration)
@param measObj Structure from RRCConnectionReconfiguration for UE measurement procedures
@param mac_MainConfig Structure from RRCConnectionSetup or RRCConnectionReconfiguration for dedicated MAC parameters (if NULL keep existing configuration)
@param logicalChannelIdentity Logical channel identity index of corresponding logical channel config
@param logicalChannelConfig Pointer to logical channel configuration
@param measGapConfig Measurement Gap configuration for MAC (if NULL keep existing configuration)
@param tdd_Config TDD Configuration from SIB1 (if NULL keep existing configuration)
@param mobilityControlInfo mobility control info received for Handover
@param SIwindowsize SI Windowsize from SIB1 (if NULL keep existing configuration)
@param SIperiod SI Period from SIB1 (if NULL keep existing configuration)
@param MBMS_Flag indicates MBMS transmission
@param mbsfn_SubframeConfigList pointer to mbsfn subframe configuration list from SIB2
@param mbsfn_AreaInfoList pointer to MBSFN Area Info list from SIB13
@param pmch_InfoList pointer to PMCH_InfoList from MBSFNAreaConfiguration Message (MCCH Message)
*/
int rrc_mac_config_req(module_id_t module_idP,
eNB_flag_t eNB_flag,
uint8_t UE_id,
uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
#ifdef Rel10
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig,
MeasGapConfig_t *measGapConfig,
TDD_Config_t *tdd_Config,
MobilityControlInfo_t *mobilityControlInfo,
uint8_t *SIwindowsize,
uint16_t *SIperiod,
ARFCN_ValueEUTRA_t *ul_CarrierFreq,
long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission,
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList
#ifdef Rel10
,
uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList
#endif
#ifdef CBA
,
uint8_t num_active_cba_groups,
uint16_t cba_rnti
#endif
);
/*@}*/ /*@}*/
#endif /*__LAYER2_MAC_DEFS_H__ */ #endif /*__LAYER2_MAC_DEFS_H__ */