Commit 0799a07f authored by Ben Wojtowicz's avatar Ben Wojtowicz

Version 0.19.3: Added support for PUCCH decode in liblte, added support for...

Version 0.19.3: Added support for PUCCH decode in liblte, added support for H-ARQ and PUCCH in LTE_fdd_enodeb, and fixed a bug related to improper cleanup of the inactivity timer in LTE_fdd_enodeb.
parent d232409f
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
######################################################################## ########################################################################
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
project(openLTE CXX C) project(openLTE CXX C)
set(openLTE_version 0.19.1) set(openLTE_version 0.19.3)
enable_testing() enable_testing()
#select the release build type by default to get optimization flags #select the release build type by default to get optimization flags
......
...@@ -222,3 +222,6 @@ v00.19.02 Pulled in unit tests for the turbo decoder from Ziming He, optimiz ...@@ -222,3 +222,6 @@ v00.19.02 Pulled in unit tests for the turbo decoder from Ziming He, optimiz
EPS bearer context (thanks to Pedro Batista), moved the message queue EPS bearer context (thanks to Pedro Batista), moved the message queue
empty error to a warning, and properly updating the user list iterator empty error to a warning, and properly updating the user list iterator
after erasing a user (thanks to Damian Jarek). after erasing a user (thanks to Damian Jarek).
v00.19.03 Added support for PUCCH decode in liblte, added support for H-ARQ and
PUCCH in LTE_fdd_enodeb, and fixed a bug related to improper cleanup
of the inactivity timer in LTE_fdd_enodeb
/******************************************************************************* /*******************************************************************************
Copyright 2015 Ben Wojtowicz Copyright 2015-2016 Ben Wojtowicz
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by it under the terms of the GNU Affero General Public License as published by
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
Revision History Revision History
---------- ------------- -------------------------------------------- ---------- ------------- --------------------------------------------
02/15/2015 Ben Wojtowicz Created file 02/15/2015 Ben Wojtowicz Created file
03/12/2016 Ben Wojtowicz Added error for H-ARQ info not found.
*******************************************************************************/ *******************************************************************************/
...@@ -73,6 +74,7 @@ typedef enum{ ...@@ -73,6 +74,7 @@ typedef enum{
LTE_FDD_ENB_ERROR_CANT_REASSEMBLE_SDU, LTE_FDD_ENB_ERROR_CANT_REASSEMBLE_SDU,
LTE_FDD_ENB_ERROR_DUPLICATE_ENTRY, LTE_FDD_ENB_ERROR_DUPLICATE_ENTRY,
LTE_FDD_ENB_ERROR_READ_ONLY, LTE_FDD_ENB_ERROR_READ_ONLY,
LTE_FDD_ENB_ERROR_HARQ_INFO_NOT_FOUND,
LTE_FDD_ENB_ERROR_N_ITEMS, LTE_FDD_ENB_ERROR_N_ITEMS,
}LTE_FDD_ENB_ERROR_ENUM; }LTE_FDD_ENB_ERROR_ENUM;
static const char LTE_fdd_enb_error_text[LTE_FDD_ENB_ERROR_N_ITEMS][100] = {"none", static const char LTE_fdd_enb_error_text[LTE_FDD_ENB_ERROR_N_ITEMS][100] = {"none",
...@@ -97,7 +99,8 @@ static const char LTE_fdd_enb_error_text[LTE_FDD_ENB_ERROR_N_ITEMS][100] = {"non ...@@ -97,7 +99,8 @@ static const char LTE_fdd_enb_error_text[LTE_FDD_ENB_ERROR_N_ITEMS][100] = {"non
"timer not found", "timer not found",
"cant reassemble SDU", "cant reassemble SDU",
"duplicate entry", "duplicate entry",
"read only"}; "read only",
"HARQ info not found"};
/******************************************************************************* /*******************************************************************************
CLASS DECLARATIONS CLASS DECLARATIONS
......
/******************************************************************************* /*******************************************************************************
Copyright 2013-2015 Ben Wojtowicz Copyright 2013-2016 Ben Wojtowicz
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by it under the terms of the GNU Affero General Public License as published by
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
12/06/2015 Ben Wojtowicz Changed boost::mutex and 12/06/2015 Ben Wojtowicz Changed boost::mutex and
boost::interprocess::interprocess_semaphore boost::interprocess::interprocess_semaphore
to sem_t. to sem_t.
03/12/2016 Ben Wojtowicz Added PUCCH support.
*******************************************************************************/ *******************************************************************************/
...@@ -177,11 +178,16 @@ typedef struct{ ...@@ -177,11 +178,16 @@ typedef struct{
uint32 current_tti; uint32 current_tti;
}LTE_FDD_ENB_DL_SCHEDULE_MSG_STRUCT; }LTE_FDD_ENB_DL_SCHEDULE_MSG_STRUCT;
typedef struct{ typedef struct{
LIBLTE_PHY_PDCCH_STRUCT decodes; uint16 rnti;
uint32 N_avail_prbs; bool decode;
uint32 N_sched_prbs; }LTE_FDD_ENB_PUCCH_STRUCT;
uint32 current_tti; typedef struct{
uint8 next_prb; LIBLTE_PHY_PDCCH_STRUCT decodes;
LTE_FDD_ENB_PUCCH_STRUCT pucch;
uint32 N_avail_prbs;
uint32 N_sched_prbs;
uint32 current_tti;
uint8 next_prb;
}LTE_FDD_ENB_UL_SCHEDULE_MSG_STRUCT; }LTE_FDD_ENB_UL_SCHEDULE_MSG_STRUCT;
typedef struct{ typedef struct{
LTE_FDD_ENB_DL_SCHEDULE_MSG_STRUCT dl_sched; LTE_FDD_ENB_DL_SCHEDULE_MSG_STRUCT dl_sched;
...@@ -202,6 +208,8 @@ typedef struct{ ...@@ -202,6 +208,8 @@ typedef struct{
}LTE_FDD_ENB_PRACH_DECODE_MSG_STRUCT; }LTE_FDD_ENB_PRACH_DECODE_MSG_STRUCT;
typedef struct{ typedef struct{
uint32 current_tti; uint32 current_tti;
uint16 rnti;
bool ack;
}LTE_FDD_ENB_PUCCH_DECODE_MSG_STRUCT; }LTE_FDD_ENB_PUCCH_DECODE_MSG_STRUCT;
typedef struct{ typedef struct{
LIBLTE_BIT_MSG_STRUCT msg; LIBLTE_BIT_MSG_STRUCT msg;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
12/06/2015 Ben Wojtowicz Changed the deletion and C-RNTI release 12/06/2015 Ben Wojtowicz Changed the deletion and C-RNTI release
procedures. procedures.
02/13/2016 Ben Wojtowicz Added an inactivity timer. 02/13/2016 Ben Wojtowicz Added an inactivity timer.
03/12/2016 Ben Wojtowicz Added H-ARQ support.
*******************************************************************************/ *******************************************************************************/
...@@ -52,6 +53,7 @@ ...@@ -52,6 +53,7 @@
*******************************************************************************/ *******************************************************************************/
#include "LTE_fdd_enb_rb.h" #include "LTE_fdd_enb_rb.h"
#include "liblte_phy.h"
#include "liblte_mac.h" #include "liblte_mac.h"
#include "liblte_mme.h" #include "liblte_mme.h"
#include "typedefs.h" #include "typedefs.h"
...@@ -109,6 +111,11 @@ typedef struct{ ...@@ -109,6 +111,11 @@ typedef struct{
uint32 dl_bytes_per_subfn; uint32 dl_bytes_per_subfn;
}LTE_FDD_ENB_QOS_STRUCT; }LTE_FDD_ENB_QOS_STRUCT;
typedef struct{
LIBLTE_MAC_PDU_STRUCT mac_pdu;
LIBLTE_PHY_ALLOCATION_STRUCT alloc;
}LTE_FDD_ENB_HARQ_INFO_STRUCT;
/******************************************************************************* /*******************************************************************************
CLASS DECLARATIONS CLASS DECLARATIONS
*******************************************************************************/ *******************************************************************************/
...@@ -203,6 +210,9 @@ public: ...@@ -203,6 +210,9 @@ public:
void flip_ul_ndi(void); void flip_ul_ndi(void);
void start_ul_sched_timer(uint32 m_seconds); void start_ul_sched_timer(uint32 m_seconds);
void stop_ul_sched_timer(void); void stop_ul_sched_timer(void);
void store_harq_info(uint32 pucch_tti, LIBLTE_MAC_PDU_STRUCT *mac_pdu, LIBLTE_PHY_ALLOCATION_STRUCT *alloc);
void clear_harq_info(uint32 pucch_tti);
LTE_FDD_ENB_ERROR_ENUM get_harq_info(uint32 pucch_tti, LIBLTE_MAC_PDU_STRUCT *mac_pdu, LIBLTE_PHY_ALLOCATION_STRUCT *alloc);
// Generic // Generic
void set_N_del_ticks(uint32 N_ticks); void set_N_del_ticks(uint32 N_ticks);
...@@ -259,10 +269,12 @@ private: ...@@ -259,10 +269,12 @@ private:
bool eit_flag; bool eit_flag;
// MAC // MAC
uint32 ul_sched_timer_m_seconds; sem_t harq_buffer_sem;
uint32 ul_sched_timer_id; std::map<uint32, LTE_FDD_ENB_HARQ_INFO_STRUCT*> harq_buffer;
bool dl_ndi; uint32 ul_sched_timer_m_seconds;
bool ul_ndi; uint32 ul_sched_timer_id;
bool dl_ndi;
bool ul_ndi;
// Generic // Generic
void handle_timer_expiry(uint32 timer_id); void handle_timer_expiry(uint32 timer_id);
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
structure (thanks to Markus Grab for finding structure (thanks to Markus Grab for finding
this). this).
02/13/2016 Ben Wojtowicz Added a user inactivity timer. 02/13/2016 Ben Wojtowicz Added a user inactivity timer.
03/12/2016 Ben Wojtowicz Added PUCCH and H-ARQ support.
*******************************************************************************/ *******************************************************************************/
...@@ -184,6 +185,8 @@ void LTE_fdd_enb_mac::start(LTE_fdd_enb_msgq *from_phy, ...@@ -184,6 +185,8 @@ void LTE_fdd_enb_mac::start(LTE_fdd_enb_msgq *from_phy,
sched_ul_subfr[i].N_sched_prbs = 0; sched_ul_subfr[i].N_sched_prbs = 0;
sched_ul_subfr[i].current_tti = i; sched_ul_subfr[i].current_tti = i;
sched_ul_subfr[i].next_prb = 0; sched_ul_subfr[i].next_prb = 0;
sched_ul_subfr[i].pucch.decode = false;
sched_ul_subfr[i].pucch.rnti = LIBLTE_MAC_INVALID_RNTI;
} }
sched_dl_subfr[0].current_tti = 10; sched_dl_subfr[0].current_tti = 10;
sched_dl_subfr[1].current_tti = 11; sched_dl_subfr[1].current_tti = 11;
...@@ -363,6 +366,8 @@ void LTE_fdd_enb_mac::handle_ready_to_send(LTE_FDD_ENB_READY_TO_SEND_MSG_STRUCT ...@@ -363,6 +366,8 @@ void LTE_fdd_enb_mac::handle_ready_to_send(LTE_FDD_ENB_READY_TO_SEND_MSG_STRUCT
sched_ul_subfr[sched_cur_ul_subfn].decodes.N_alloc = 0; sched_ul_subfr[sched_cur_ul_subfn].decodes.N_alloc = 0;
sched_ul_subfr[sched_cur_ul_subfn].N_sched_prbs = 0; sched_ul_subfr[sched_cur_ul_subfn].N_sched_prbs = 0;
sched_ul_subfr[sched_cur_ul_subfn].next_prb = 0; sched_ul_subfr[sched_cur_ul_subfn].next_prb = 0;
sched_ul_subfr[sched_cur_ul_subfn].pucch.decode = false;
sched_ul_subfr[sched_cur_ul_subfn].pucch.rnti = LIBLTE_MAC_INVALID_RNTI;
sem_post(&sys_info_sem); sem_post(&sys_info_sem);
// Advance the subframe numbers // Advance the subframe numbers
...@@ -388,6 +393,8 @@ void LTE_fdd_enb_mac::handle_ready_to_send(LTE_FDD_ENB_READY_TO_SEND_MSG_STRUCT ...@@ -388,6 +393,8 @@ void LTE_fdd_enb_mac::handle_ready_to_send(LTE_FDD_ENB_READY_TO_SEND_MSG_STRUCT
sched_ul_subfr[sched_cur_ul_subfn].decodes.N_alloc = 0; sched_ul_subfr[sched_cur_ul_subfn].decodes.N_alloc = 0;
sched_ul_subfr[sched_cur_ul_subfn].N_sched_prbs = 0; sched_ul_subfr[sched_cur_ul_subfn].N_sched_prbs = 0;
sched_ul_subfr[sched_cur_ul_subfn].next_prb = 0; sched_ul_subfr[sched_cur_ul_subfn].next_prb = 0;
sched_ul_subfr[sched_cur_ul_subfn].pucch.decode = false;
sched_ul_subfr[sched_cur_ul_subfn].pucch.rnti = LIBLTE_MAC_INVALID_RNTI;
sem_post(&sys_info_sem); sem_post(&sys_info_sem);
// Advance the subframe numbers // Advance the subframe numbers
...@@ -411,11 +418,77 @@ void LTE_fdd_enb_mac::handle_prach_decode(LTE_FDD_ENB_PRACH_DECODE_MSG_STRUCT *p ...@@ -411,11 +418,77 @@ void LTE_fdd_enb_mac::handle_prach_decode(LTE_FDD_ENB_PRACH_DECODE_MSG_STRUCT *p
} }
void LTE_fdd_enb_mac::handle_pucch_decode(LTE_FDD_ENB_PUCCH_DECODE_MSG_STRUCT *pucch_decode) void LTE_fdd_enb_mac::handle_pucch_decode(LTE_FDD_ENB_PUCCH_DECODE_MSG_STRUCT *pucch_decode)
{ {
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_ERROR, LTE_fdd_enb_user_mgr *user_mgr = LTE_fdd_enb_user_mgr::get_instance();
LTE_fdd_enb_user *user;
LIBLTE_MAC_PDU_STRUCT mac_pdu;
LIBLTE_PHY_ALLOCATION_STRUCT alloc;
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
LTE_FDD_ENB_DEBUG_LEVEL_MAC, LTE_FDD_ENB_DEBUG_LEVEL_MAC,
__FILE__, __FILE__,
__LINE__, __LINE__,
"Not handling PUCCH_DECODE"); "PUCCH decode received %u for %u",
pucch_decode->ack,
pucch_decode->current_tti);
if(LTE_FDD_ENB_ERROR_NONE == user_mgr->find_user(pucch_decode->rnti, &user))
{
if(pucch_decode->ack)
{
user->clear_harq_info(pucch_decode->current_tti);
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
LTE_FDD_ENB_DEBUG_LEVEL_MAC,
__FILE__,
__LINE__,
"Clearing HARQ info RNTI=%u TTI=%u",
pucch_decode->rnti,
pucch_decode->current_tti);
}else{
if(LTE_FDD_ENB_ERROR_NONE == user->get_harq_info(pucch_decode->current_tti,
&mac_pdu,
&alloc))
{
alloc.ndi = user->get_dl_ndi();
if(LTE_FDD_ENB_ERROR_NONE == add_to_dl_sched_queue(add_to_tti(sched_dl_subfr[sched_cur_dl_subfn].current_tti,
4),
&mac_pdu,
&alloc))
{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
LTE_FDD_ENB_DEBUG_LEVEL_MAC,
__FILE__,
__LINE__,
"Resending HARQ info RNTI=%u TTI=%u",
pucch_decode->rnti,
pucch_decode->current_tti);
}else{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_ERROR,
LTE_FDD_ENB_DEBUG_LEVEL_MAC,
__FILE__,
__LINE__,
"Failed to resend HARQ info RNTI=%u TTI=%u",
pucch_decode->rnti,
pucch_decode->current_tti);
}
}else{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_ERROR,
LTE_FDD_ENB_DEBUG_LEVEL_MAC,
__FILE__,
__LINE__,
"Failed to find HARQ info RNTI=%u TTI=%u",
pucch_decode->rnti,
pucch_decode->current_tti);
}
}
}else{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_ERROR,
LTE_FDD_ENB_DEBUG_LEVEL_MAC,
__FILE__,
__LINE__,
"Failed to find PUCCH user RNTI=%u TTI=%u",
pucch_decode->rnti,
pucch_decode->current_tti);
}
} }
void LTE_fdd_enb_mac::handle_pusch_decode(LTE_FDD_ENB_PUSCH_DECODE_MSG_STRUCT *pusch_decode) void LTE_fdd_enb_mac::handle_pusch_decode(LTE_FDD_ENB_PUSCH_DECODE_MSG_STRUCT *pusch_decode)
{ {
...@@ -881,7 +954,9 @@ void LTE_fdd_enb_mac::construct_random_access_response(uint8 preamble, ...@@ -881,7 +954,9 @@ void LTE_fdd_enb_mac::construct_random_access_response(uint8 preamble,
void LTE_fdd_enb_mac::scheduler(void) void LTE_fdd_enb_mac::scheduler(void)
{ {
libtools_scoped_lock lock(sys_info_sem); libtools_scoped_lock lock(sys_info_sem);
LTE_fdd_enb_phy *phy = LTE_fdd_enb_phy::get_instance(); LTE_fdd_enb_phy *phy = LTE_fdd_enb_phy::get_instance();
LTE_fdd_enb_user_mgr *user_mgr = LTE_fdd_enb_user_mgr::get_instance();
LTE_fdd_enb_user *user;
LTE_FDD_ENB_RAR_SCHED_QUEUE_STRUCT *rar_sched; LTE_FDD_ENB_RAR_SCHED_QUEUE_STRUCT *rar_sched;
LTE_FDD_ENB_DL_SCHED_QUEUE_STRUCT *dl_sched; LTE_FDD_ENB_DL_SCHED_QUEUE_STRUCT *dl_sched;
LTE_FDD_ENB_UL_SCHED_QUEUE_STRUCT *ul_sched; LTE_FDD_ENB_UL_SCHED_QUEUE_STRUCT *ul_sched;
...@@ -1123,6 +1198,14 @@ void LTE_fdd_enb_mac::scheduler(void) ...@@ -1123,6 +1198,14 @@ void LTE_fdd_enb_mac::scheduler(void)
sizeof(LIBLTE_PHY_ALLOCATION_STRUCT)); sizeof(LIBLTE_PHY_ALLOCATION_STRUCT));
sched_dl_subfr[sched_cur_dl_subfn].dl_allocations.N_alloc++; sched_dl_subfr[sched_cur_dl_subfn].dl_allocations.N_alloc++;
// Schedule PUCCH 4 subframes from now and store the DL allocation for potential H-ARQ retransmission
sched_ul_subfr[(sched_cur_dl_subfn+4)%10].pucch.decode = true;
sched_ul_subfr[(sched_cur_dl_subfn+4)%10].pucch.rnti = dl_sched->alloc.rnti;
if(LTE_FDD_ENB_ERROR_NONE == user_mgr->find_user(dl_sched->alloc.rnti, &user))
{
user->store_harq_info(sched_ul_subfr[(sched_cur_dl_subfn+4)%10].current_tti, &dl_sched->mac_pdu, &dl_sched->alloc);
}
// Remove DL schedule from queue // Remove DL schedule from queue
dl_sched_queue.pop_front(); dl_sched_queue.pop_front();
delete dl_sched; delete dl_sched;
......
#line 2 "LTE_fdd_enb_phy.cc" // Make __FILE__ omit the path #line 2 "LTE_fdd_enb_phy.cc" // Make __FILE__ omit the path
/******************************************************************************* /*******************************************************************************
Copyright 2013-2015 Ben Wojtowicz Copyright 2013-2016 Ben Wojtowicz
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by it under the terms of the GNU Affero General Public License as published by
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
new radio interface. new radio interface.
12/06/2015 Ben Wojtowicz Changed boost::mutex to pthread_mutex_t and 12/06/2015 Ben Wojtowicz Changed boost::mutex to pthread_mutex_t and
sem_t. sem_t.
03/12/2016 Ben Wojtowicz Added PUCCH support.
*******************************************************************************/ *******************************************************************************/
...@@ -182,7 +183,9 @@ void LTE_fdd_enb_phy::start(LTE_fdd_enb_msgq *from_mac, ...@@ -182,7 +183,9 @@ void LTE_fdd_enb_phy::start(LTE_fdd_enb_msgq *from_mac,
sys_info.sib2.rr_config_common_sib.pusch_cnfg.ul_rs.group_hopping_enabled, sys_info.sib2.rr_config_common_sib.pusch_cnfg.ul_rs.group_hopping_enabled,
sys_info.sib2.rr_config_common_sib.pusch_cnfg.ul_rs.sequence_hopping_enabled, sys_info.sib2.rr_config_common_sib.pusch_cnfg.ul_rs.sequence_hopping_enabled,
sys_info.sib2.rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift, sys_info.sib2.rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift,
0); 0,
sys_info.sib2.rr_config_common_sib.pucch_cnfg.n_cs_an,
sys_info.sib2.rr_config_common_sib.pucch_cnfg.delta_pucch_shift);
// Downlink // Downlink
for(i=0; i<10; i++) for(i=0; i<10; i++)
...@@ -736,12 +739,13 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf) ...@@ -736,12 +739,13 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf)
/****************/ /****************/
void LTE_fdd_enb_phy::process_ul(LTE_FDD_ENB_RADIO_RX_BUF_STRUCT *rx_buf) void LTE_fdd_enb_phy::process_ul(LTE_FDD_ENB_RADIO_RX_BUF_STRUCT *rx_buf)
{ {
uint32 N_skipped_subfrs = 0; LIBLTE_ERROR_ENUM subfr_err;
uint32 sfn; uint32 N_skipped_subfrs = 0;
uint32 i; uint32 sfn;
uint32 I_prb_ra; uint32 i;
uint32 n_group_phich; uint32 I_prb_ra;
uint32 n_seq_phich; uint32 n_group_phich;
uint32 n_seq_phich;
// Check the received current_tti // Check the received current_tti
if(rx_buf->current_tti != ul_current_tti) if(rx_buf->current_tti != ul_current_tti)
...@@ -785,50 +789,75 @@ void LTE_fdd_enb_phy::process_ul(LTE_FDD_ENB_RADIO_RX_BUF_STRUCT *rx_buf) ...@@ -785,50 +789,75 @@ void LTE_fdd_enb_phy::process_ul(LTE_FDD_ENB_RADIO_RX_BUF_STRUCT *rx_buf)
} }
} }
sem_wait(&ul_sched_sem);
if(ul_schedule[ul_subframe.num].pucch.decode ||
0 != ul_schedule[ul_subframe.num].decodes.N_alloc)
{
subfr_err = liblte_phy_get_ul_subframe(phy_struct,
rx_buf->i_buf,
rx_buf->q_buf,
&ul_subframe);
}
// Handle PUCCH // Handle PUCCH
// FIXME if(LIBLTE_SUCCESS == subfr_err &&
ul_schedule[ul_subframe.num].pucch.decode)
{
pucch_decode.current_tti = ul_current_tti;
pucch_decode.rnti = ul_schedule[ul_subframe.num].pucch.rnti;
if(LIBLTE_SUCCESS == liblte_phy_pucch_channel_decode(phy_struct,
&ul_subframe,
sys_info.N_id_cell,
sys_info.N_ant,
0)) // FIXME: N_1_p_pucch
{
pucch_decode.ack = true;
}else{
pucch_decode.ack = false;
}
msgq_to_mac->send(LTE_FDD_ENB_MESSAGE_TYPE_PUCCH_DECODE,
LTE_FDD_ENB_DEST_LAYER_MAC,
(LTE_FDD_ENB_MESSAGE_UNION *)&pucch_decode,
sizeof(LTE_FDD_ENB_PUCCH_DECODE_MSG_STRUCT));
}
ul_schedule[ul_subframe.num].pucch.decode = false;
ul_schedule[ul_subframe.num].pucch.rnti = LIBLTE_MAC_INVALID_RNTI;
// Handle PUSCH // Handle PUSCH
sem_wait(&ul_sched_sem); if(LIBLTE_SUCCESS == subfr_err &&
if(0 != ul_schedule[ul_subframe.num].decodes.N_alloc) 0 != ul_schedule[ul_subframe.num].decodes.N_alloc)
{ {
if(LIBLTE_SUCCESS == liblte_phy_get_ul_subframe(phy_struct, for(i=0; i<ul_schedule[ul_subframe.num].decodes.N_alloc; i++)
rx_buf->i_buf,
rx_buf->q_buf,
&ul_subframe))
{ {
for(i=0; i<ul_schedule[ul_subframe.num].decodes.N_alloc; i++) // Determine PHICH indecies
I_prb_ra = ul_schedule[ul_subframe.num].decodes.alloc[i].prb[0][0];
n_group_phich = I_prb_ra % phy_struct->N_group_phich;
n_seq_phich = (I_prb_ra/phy_struct->N_group_phich) % (2*phy_struct->N_sf_phich);
// Attempt decode
if(LIBLTE_SUCCESS == liblte_phy_pusch_channel_decode(phy_struct,
&ul_subframe,
&ul_schedule[ul_subframe.num].decodes.alloc[i],
sys_info.N_id_cell,
1,
pusch_decode.msg.msg,
&pusch_decode.msg.N_bits))
{ {
// Determine PHICH indecies pusch_decode.current_tti = ul_current_tti;
I_prb_ra = ul_schedule[ul_subframe.num].decodes.alloc[i].prb[0][0]; pusch_decode.rnti = ul_schedule[ul_subframe.num].decodes.alloc[i].rnti;
n_group_phich = I_prb_ra % phy_struct->N_group_phich;
n_seq_phich = (I_prb_ra/phy_struct->N_group_phich) % (2*phy_struct->N_sf_phich); msgq_to_mac->send(LTE_FDD_ENB_MESSAGE_TYPE_PUSCH_DECODE,
LTE_FDD_ENB_DEST_LAYER_MAC,
// Attempt decode (LTE_FDD_ENB_MESSAGE_UNION *)&pusch_decode,
if(LIBLTE_SUCCESS == liblte_phy_pusch_channel_decode(phy_struct, sizeof(LTE_FDD_ENB_PUSCH_DECODE_MSG_STRUCT));
&ul_subframe,
&ul_schedule[ul_subframe.num].decodes.alloc[i], // Add ACK to PHICH
sys_info.N_id_cell, phich[(ul_subframe.num + 4) % 10].present[n_group_phich][n_seq_phich] = true;
1, phich[(ul_subframe.num + 4) % 10].b[n_group_phich][n_seq_phich] = 1;
pusch_decode.msg.msg, }else{
&pusch_decode.msg.N_bits)) // Add NACK to PHICH
{ phich[(ul_subframe.num + 4) % 10].present[n_group_phich][n_seq_phich] = true;
pusch_decode.current_tti = ul_current_tti; phich[(ul_subframe.num + 4) % 10].b[n_group_phich][n_seq_phich] = 0;
pusch_decode.rnti = ul_schedule[ul_subframe.num].decodes.alloc[i].rnti;
msgq_to_mac->send(LTE_FDD_ENB_MESSAGE_TYPE_PUSCH_DECODE,
LTE_FDD_ENB_DEST_LAYER_MAC,
(LTE_FDD_ENB_MESSAGE_UNION *)&pusch_decode,
sizeof(LTE_FDD_ENB_PUSCH_DECODE_MSG_STRUCT));
// Add ACK to PHICH
phich[(ul_subframe.num + 4) % 10].present[n_group_phich][n_seq_phich] = true;
phich[(ul_subframe.num + 4) % 10].b[n_group_phich][n_seq_phich] = 1;
}else{
// Add NACK to PHICH
phich[(ul_subframe.num + 4) % 10].present[n_group_phich][n_seq_phich] = true;
phich[(ul_subframe.num + 4) % 10].b[n_group_phich][n_seq_phich] = 0;
}
} }
} }
} }
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
procedures and changed the QoS parameters procedures and changed the QoS parameters
for default data. for default data.
02/13/2016 Ben Wojtowicz Added an inactivity timer. 02/13/2016 Ben Wojtowicz Added an inactivity timer.
03/12/2016 Ben Wojtowicz Added H-ARQ support and properly cleaning
up inactivity timer.
*******************************************************************************/ *******************************************************************************/
...@@ -55,6 +57,7 @@ ...@@ -55,6 +57,7 @@
#include "LTE_fdd_enb_mac.h" #include "LTE_fdd_enb_mac.h"
#include "LTE_fdd_enb_rrc.h" #include "LTE_fdd_enb_rrc.h"
#include "liblte_mme.h" #include "liblte_mme.h"
#include "libtools_scoped_lock.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
/******************************************************************************* /*******************************************************************************
...@@ -125,6 +128,8 @@ LTE_fdd_enb_user::LTE_fdd_enb_user() ...@@ -125,6 +128,8 @@ LTE_fdd_enb_user::LTE_fdd_enb_user()
protocol_cnfg_opts.N_opts = 0; protocol_cnfg_opts.N_opts = 0;
// MAC // MAC
sem_init(&harq_buffer_sem, 0, 1);
harq_buffer.clear();
ul_sched_timer_id = LTE_FDD_ENB_INVALID_TIMER_ID; ul_sched_timer_id = LTE_FDD_ENB_INVALID_TIMER_ID;
dl_ndi = false; dl_ndi = false;
ul_ndi = false; ul_ndi = false;
...@@ -139,8 +144,17 @@ LTE_fdd_enb_user::LTE_fdd_enb_user() ...@@ -139,8 +144,17 @@ LTE_fdd_enb_user::LTE_fdd_enb_user()
} }
LTE_fdd_enb_user::~LTE_fdd_enb_user() LTE_fdd_enb_user::~LTE_fdd_enb_user()
{ {
LTE_fdd_enb_timer_mgr *timer_mgr = LTE_fdd_enb_timer_mgr::get_instance(); LTE_fdd_enb_timer_mgr *timer_mgr = LTE_fdd_enb_timer_mgr::get_instance();
uint32 i; std::map<uint32, LTE_FDD_ENB_HARQ_INFO_STRUCT*>::iterator iter;
uint32 i;
// MAC
sem_wait(&harq_buffer_sem);
for(iter=harq_buffer.begin(); iter!=harq_buffer.end(); iter++)
{
delete (*iter).second;
}
sem_destroy(&harq_buffer_sem);
// Radio Bearers // Radio Bearers
for(i=0; i<8; i++) for(i=0; i<8; i++)
...@@ -155,6 +169,10 @@ LTE_fdd_enb_user::~LTE_fdd_enb_user() ...@@ -155,6 +169,10 @@ LTE_fdd_enb_user::~LTE_fdd_enb_user()
{ {
timer_mgr->stop_timer(ul_sched_timer_id); timer_mgr->stop_timer(ul_sched_timer_id);
} }
if(LTE_FDD_ENB_INVALID_TIMER_ID != inactivity_timer_id)
{
timer_mgr->stop_timer(inactivity_timer_id);
}
} }
/********************/ /********************/
...@@ -644,6 +662,55 @@ void LTE_fdd_enb_user::stop_ul_sched_timer(void) ...@@ -644,6 +662,55 @@ void LTE_fdd_enb_user::stop_ul_sched_timer(void)
timer_mgr->stop_timer(ul_sched_timer_id); timer_mgr->stop_timer(ul_sched_timer_id);
ul_sched_timer_id = LTE_FDD_ENB_INVALID_TIMER_ID; ul_sched_timer_id = LTE_FDD_ENB_INVALID_TIMER_ID;
} }
void LTE_fdd_enb_user::store_harq_info(uint32 pucch_tti,
LIBLTE_MAC_PDU_STRUCT *mac_pdu,
LIBLTE_PHY_ALLOCATION_STRUCT *alloc)
{
LTE_FDD_ENB_HARQ_INFO_STRUCT *harq_info = NULL;
harq_info = new LTE_FDD_ENB_HARQ_INFO_STRUCT;
if(NULL != harq_info)
{
memcpy(&harq_info->mac_pdu, mac_pdu, sizeof(LIBLTE_MAC_PDU_STRUCT));
memcpy(&harq_info->alloc, alloc, sizeof(LIBLTE_PHY_ALLOCATION_STRUCT));
sem_wait(&harq_buffer_sem);
harq_buffer[pucch_tti] = harq_info;
sem_post(&harq_buffer_sem);
}
}
void LTE_fdd_enb_user::clear_harq_info(uint32 pucch_tti)
{
libtools_scoped_lock lock(harq_buffer_sem);
std::map<uint32, LTE_FDD_ENB_HARQ_INFO_STRUCT*>::iterator iter;
iter = harq_buffer.find(pucch_tti);
if(harq_buffer.end() != iter)
{
delete (*iter).second;
harq_buffer.erase(iter);
}
}
LTE_FDD_ENB_ERROR_ENUM LTE_fdd_enb_user::get_harq_info(uint32 pucch_tti,
LIBLTE_MAC_PDU_STRUCT *mac_pdu,
LIBLTE_PHY_ALLOCATION_STRUCT *alloc)
{
libtools_scoped_lock lock(harq_buffer_sem);
std::map<uint32, LTE_FDD_ENB_HARQ_INFO_STRUCT*>::iterator iter;
LTE_FDD_ENB_ERROR_ENUM err = LTE_FDD_ENB_ERROR_HARQ_INFO_NOT_FOUND;
iter = harq_buffer.find(pucch_tti);
if(harq_buffer.end() != iter)
{
memcpy(mac_pdu, &(*iter).second->mac_pdu, sizeof(LIBLTE_MAC_PDU_STRUCT));
memcpy(alloc, &(*iter).second->alloc, sizeof(LIBLTE_PHY_ALLOCATION_STRUCT));
delete (*iter).second;
harq_buffer.erase(iter);
err = LTE_FDD_ENB_ERROR_NONE;
}
return(err);
}
/*****************/ /*****************/
/* Generic */ /* Generic */
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
code block segmentation/desegmentation to code block segmentation/desegmentation to
globally available routines to support unit globally available routines to support unit
tests. tests.
03/12/2016 Ben Wojtowicz Added PUCCH channel decode support.
*******************************************************************************/ *******************************************************************************/
...@@ -119,6 +120,10 @@ ...@@ -119,6 +120,10 @@
#define LIBLTE_PHY_N_SC_RB_DL_NORMAL_CP 12 #define LIBLTE_PHY_N_SC_RB_DL_NORMAL_CP 12
// FIXME: Add Extended CP // FIXME: Add Extended CP