From c5bc3b11b70dea91f7f4faa819b15d9736cfebbd Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 31 Aug 2017 18:07:54 +0200 Subject: [PATCH] remove spaces --- srsue/hdr/upper/nas.h | 192 +-- srsue/hdr/upper/rrc.h | 326 ++--- srsue/src/phy/phch_recv.cc | 932 ++++++------- srsue/src/upper/nas.cc | 1004 +++++++------- srsue/src/upper/rrc.cc | 2588 ++++++++++++++++++------------------ 5 files changed, 2521 insertions(+), 2521 deletions(-) diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index edf5dcf27..1640c9d8a 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -39,145 +39,145 @@ using srslte::byte_buffer_t; namespace srsue { // EMM states (3GPP 24.302 v10.0.0) - typedef enum { - EMM_STATE_NULL = 0, - EMM_STATE_DEREGISTERED, - EMM_STATE_REGISTERED_INITIATED, - EMM_STATE_REGISTERED, - EMM_STATE_SERVICE_REQUEST_INITIATED, - EMM_STATE_DEREGISTERED_INITIATED, - EMM_STATE_TAU_INITIATED, - EMM_STATE_N_ITEMS, - } emm_state_t; - static const char emm_state_text[EMM_STATE_N_ITEMS][100] = {"NULL", - "DEREGISTERED", - "REGISTERED INITIATED", - "REGISTERED", - "SERVICE REQUEST INITIATED", - "DEREGISTERED INITIATED", - "TRACKING AREA UPDATE INITIATED"}; +typedef enum { + EMM_STATE_NULL = 0, + EMM_STATE_DEREGISTERED, + EMM_STATE_REGISTERED_INITIATED, + EMM_STATE_REGISTERED, + EMM_STATE_SERVICE_REQUEST_INITIATED, + EMM_STATE_DEREGISTERED_INITIATED, + EMM_STATE_TAU_INITIATED, + EMM_STATE_N_ITEMS, +} emm_state_t; +static const char emm_state_text[EMM_STATE_N_ITEMS][100] = {"NULL", + "DEREGISTERED", + "REGISTERED INITIATED", + "REGISTERED", + "SERVICE REQUEST INITIATED", + "DEREGISTERED INITIATED", + "TRACKING AREA UPDATE INITIATED"}; - typedef enum { - PLMN_NOT_SELECTED = 0, - PLMN_SELECTED - } plmn_selection_state_t; +typedef enum { + PLMN_NOT_SELECTED = 0, + PLMN_SELECTED +} plmn_selection_state_t; - class nas - : public nas_interface_rrc, public nas_interface_ue { - public: - nas(); +class nas + : public nas_interface_rrc, public nas_interface_ue { +public: + nas(); - void init(usim_interface_nas *usim_, - rrc_interface_nas *rrc_, - gw_interface_nas *gw_, - srslte::log *nas_log_); + void init(usim_interface_nas *usim_, + rrc_interface_nas *rrc_, + gw_interface_nas *gw_, + srslte::log *nas_log_); - void stop(); + void stop(); - emm_state_t get_state(); + emm_state_t get_state(); - // RRC interface - void notify_connection_setup(); + // RRC interface + void notify_connection_setup(); - void write_pdu(uint32_t lcid, byte_buffer_t *pdu); + void write_pdu(uint32_t lcid, byte_buffer_t *pdu); - uint32_t get_ul_count(); + uint32_t get_ul_count(); - bool is_attached(); + bool is_attached(); - bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi); + bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi); - void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); + void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); - void cell_selected(); + void cell_selected(); - // UE interface - void attach_request(); + // UE interface + void attach_request(); - void deattach_request(); + void deattach_request(); - private: - srslte::byte_buffer_pool *pool; - srslte::log *nas_log; - rrc_interface_nas *rrc; - usim_interface_nas *usim; - gw_interface_nas *gw; +private: + srslte::byte_buffer_pool *pool; + srslte::log *nas_log; + rrc_interface_nas *rrc; + usim_interface_nas *usim; + gw_interface_nas *gw; - emm_state_t state; + emm_state_t state; - plmn_selection_state_t plmn_selection; - LIBLTE_RRC_PLMN_IDENTITY_STRUCT current_plmn; - LIBLTE_RRC_PLMN_IDENTITY_STRUCT home_plmn; + plmn_selection_state_t plmn_selection; + LIBLTE_RRC_PLMN_IDENTITY_STRUCT current_plmn; + LIBLTE_RRC_PLMN_IDENTITY_STRUCT home_plmn; - std::vector known_plmns; + std::vector known_plmns; - // Save short MAC + // Save short MAC - // Identifiers - LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; - bool is_guti_set; + // Identifiers + LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; + bool is_guti_set; - uint32_t ip_addr; - uint8_t eps_bearer_id; + uint32_t ip_addr; + uint8_t eps_bearer_id; - uint8_t transaction_id; + uint8_t transaction_id; - // NAS counters - incremented for each security-protected message recvd/sent - uint32_t count_ul; - uint32_t count_dl; + // NAS counters - incremented for each security-protected message recvd/sent + uint32_t count_ul; + uint32_t count_dl; - // Security - uint8_t ksi; - uint8_t k_nas_enc[32]; - uint8_t k_nas_int[32]; + // Security + uint8_t ksi; + uint8_t k_nas_enc[32]; + uint8_t k_nas_int[32]; - srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; - srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; - void integrity_generate(uint8_t *key_128, - uint32_t count, - uint8_t rb_id, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *mac); + void integrity_generate(uint8_t *key_128, + uint32_t count, + uint8_t rb_id, + uint8_t direction, + uint8_t *msg, + uint32_t msg_len, + uint8_t *mac); - void integrity_check(); + void integrity_check(); - void cipher_encrypt(); + void cipher_encrypt(); - void cipher_decrypt(); + void cipher_decrypt(); - // Parsers - void parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu); + // Parsers + void parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu); - void parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu); + void parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu); - void parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu); + void parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu); - void parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu); + void parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu); - void parse_identity_request(uint32_t lcid, byte_buffer_t *pdu); + void parse_identity_request(uint32_t lcid, byte_buffer_t *pdu); - void parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu); + void parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu); - void parse_service_reject(uint32_t lcid, byte_buffer_t *pdu); + void parse_service_reject(uint32_t lcid, byte_buffer_t *pdu); - void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu); + void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu); - void parse_emm_information(uint32_t lcid, byte_buffer_t *pdu); + void parse_emm_information(uint32_t lcid, byte_buffer_t *pdu); - // Senders - void send_attach_request(); + // Senders + void send_attach_request(); - void send_identity_response(); + void send_identity_response(); - void send_service_request(); + void send_service_request(); - void send_esm_information_response(); + void send_esm_information_response(); - void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg); - }; + void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg); +}; } // namespace srsue diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 225659d6f..793c2ee4f 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -43,230 +43,230 @@ using srslte::byte_buffer_t; namespace srsue { // RRC states (3GPP 36.331 v10.0.0) - typedef enum { - RRC_STATE_IDLE = 0, - RRC_STATE_PLMN_SELECTION, - RRC_STATE_CELL_SELECTING, - RRC_STATE_CELL_SELECTED, - RRC_STATE_CONNECTING, - RRC_STATE_CONNECTED, - RRC_STATE_N_ITEMS, - } rrc_state_t; - static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", - "PLMN SELECTION", - "CELL SELECTION", - "CONNECTING", - "CONNECTED", - "RRC CONNECTED"}; - typedef enum { - SI_ACQUIRE_IDLE = 0, - SI_ACQUIRE_SIB1, - SI_ACQUIRE_SIB2 - } si_acquire_state_t; - - - class rrc - : public rrc_interface_nas, - public rrc_interface_phy, - public rrc_interface_mac, - public rrc_interface_gw, - public rrc_interface_pdcp, - public rrc_interface_rlc, - public srslte::timer_callback, - public thread - { - public: - rrc(); - - void init(phy_interface_rrc *phy_, - mac_interface_rrc *mac_, - rlc_interface_rrc *rlc_, - pdcp_interface_rrc *pdcp_, - nas_interface_rrc *nas_, - usim_interface_rrc *usim_, - srslte::mac_interface_timers *mac_timers_, - srslte::log *rrc_log_); - - void stop(); - - rrc_state_t get_state(); - - void set_ue_category(int category); - - // Timeout callback interface - void timer_expired(uint32_t timeout_id); - - void test_con_restablishment(); +typedef enum { + RRC_STATE_IDLE = 0, + RRC_STATE_PLMN_SELECTION, + RRC_STATE_CELL_SELECTING, + RRC_STATE_CELL_SELECTED, + RRC_STATE_CONNECTING, + RRC_STATE_CONNECTED, + RRC_STATE_N_ITEMS, +} rrc_state_t; +static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", + "PLMN SELECTION", + "CELL SELECTION", + "CONNECTING", + "CONNECTED", + "RRC CONNECTED"}; +typedef enum { + SI_ACQUIRE_IDLE = 0, + SI_ACQUIRE_SIB1, + SI_ACQUIRE_SIB2 +} si_acquire_state_t; + + +class rrc + : public rrc_interface_nas, + public rrc_interface_phy, + public rrc_interface_mac, + public rrc_interface_gw, + public rrc_interface_pdcp, + public rrc_interface_rlc, + public srslte::timer_callback, + public thread +{ +public: + rrc(); + + void init(phy_interface_rrc *phy_, + mac_interface_rrc *mac_, + rlc_interface_rrc *rlc_, + pdcp_interface_rrc *pdcp_, + nas_interface_rrc *nas_, + usim_interface_rrc *usim_, + srslte::mac_interface_timers *mac_timers_, + srslte::log *rrc_log_); + + void stop(); + + rrc_state_t get_state(); + + void set_ue_category(int category); + + // Timeout callback interface + void timer_expired(uint32_t timeout_id); + + void test_con_restablishment(); - void liblte_rrc_log(char *str); + void liblte_rrc_log(char *str); - private: - srslte::byte_buffer_pool *pool; - srslte::log *rrc_log; - phy_interface_rrc *phy; - mac_interface_rrc *mac; - rlc_interface_rrc *rlc; - pdcp_interface_rrc *pdcp; - nas_interface_rrc *nas; - usim_interface_rrc *usim; +private: + srslte::byte_buffer_pool *pool; + srslte::log *rrc_log; + phy_interface_rrc *phy; + mac_interface_rrc *mac; + rlc_interface_rrc *rlc; + pdcp_interface_rrc *pdcp; + nas_interface_rrc *nas; + usim_interface_rrc *usim; - srslte::bit_buffer_t bit_buf; + srslte::bit_buffer_t bit_buf; - pthread_mutex_t mutex; + pthread_mutex_t mutex; - rrc_state_t state; - uint8_t transaction_id; - bool drb_up; + rrc_state_t state; + uint8_t transaction_id; + bool drb_up; - uint8_t k_rrc_enc[32]; - uint8_t k_rrc_int[32]; - uint8_t k_up_enc[32]; - uint8_t k_up_int[32]; // Not used: only for relay nodes (3GPP 33.401 Annex A.7) + uint8_t k_rrc_enc[32]; + uint8_t k_rrc_int[32]; + uint8_t k_up_enc[32]; + uint8_t k_up_int[32]; // Not used: only for relay nodes (3GPP 33.401 Annex A.7) - srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; - srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; - std::map srbs; - std::map drbs; + std::map srbs; + std::map drbs; - LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg; - LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; + LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg; + LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; - // RRC constants and timers - srslte::mac_interface_timers *mac_timers; - uint32_t n310_cnt, N310; - uint32_t n311_cnt, N311; - uint32_t t301, t310, t311; - uint32_t safe_reset_timer; - int ue_category; + // RRC constants and timers + srslte::mac_interface_timers *mac_timers; + uint32_t n310_cnt, N310; + uint32_t n311_cnt, N311; + uint32_t t301, t310, t311; + uint32_t safe_reset_timer; + int ue_category; - typedef struct { - uint32_t earfcn; - srslte_cell_t phy_cell; - float rsrp; - bool has_valid_sib1; - bool has_valid_sib2; - LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; - LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2; - } cell_t; + typedef struct { + uint32_t earfcn; + srslte_cell_t phy_cell; + float rsrp; + bool has_valid_sib1; + bool has_valid_sib2; + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2; + } cell_t; - std::vector known_cells; - cell_t *current_cell; + std::vector known_cells; + cell_t *current_cell; - si_acquire_state_t si_acquire_state; + si_acquire_state_t si_acquire_state; - void select_next_cell_in_plmn(); - LIBLTE_RRC_PLMN_IDENTITY_STRUCT selected_plmn_id; - int last_selected_cell; + void select_next_cell_in_plmn(); + LIBLTE_RRC_PLMN_IDENTITY_STRUCT selected_plmn_id; + int last_selected_cell; - bool thread_running; - void run_thread(); + bool thread_running; + void run_thread(); - // NAS interface - void write_sdu(uint32_t lcid, byte_buffer_t *sdu); + // NAS interface + void write_sdu(uint32_t lcid, byte_buffer_t *sdu); - uint16_t get_mcc(); + uint16_t get_mcc(); - uint16_t get_mnc(); + uint16_t get_mnc(); - void enable_capabilities(); - void plmn_search(); - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id); - void connect(); + void enable_capabilities(); + void plmn_search(); + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id); + void connect(); - // PHY interface - void in_sync(); + // PHY interface + void in_sync(); - void out_of_sync(); - void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); + void out_of_sync(); + void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); - // MAC interface - void release_pucch_srs(); + // MAC interface + void release_pucch_srs(); - void ra_problem(); + void ra_problem(); - // GW interface - bool is_connected(); + // GW interface + bool is_connected(); - bool have_drb(); + bool have_drb(); - // PDCP interface - void write_pdu(uint32_t lcid, byte_buffer_t *pdu); + // PDCP interface + void write_pdu(uint32_t lcid, byte_buffer_t *pdu); - void write_pdu_bcch_bch(byte_buffer_t *pdu); + void write_pdu_bcch_bch(byte_buffer_t *pdu); - void write_pdu_bcch_dlsch(byte_buffer_t *pdu); + void write_pdu_bcch_dlsch(byte_buffer_t *pdu); - void write_pdu_pcch(byte_buffer_t *pdu); + void write_pdu_pcch(byte_buffer_t *pdu); - // RLC interface - void max_retx_attempted(); + // RLC interface + void max_retx_attempted(); - // Senders - void send_con_request(); + // Senders + void send_con_request(); - void send_con_restablish_request(); + void send_con_restablish_request(); - void send_con_restablish_complete(); + void send_con_restablish_complete(); - void send_con_setup_complete(byte_buffer_t *nas_msg); + void send_con_setup_complete(byte_buffer_t *nas_msg); - void send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu); + void send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu); - void send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu); + void send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu); - void send_rrc_con_reconfig_complete(uint32_t lcid, byte_buffer_t *pdu); + void send_rrc_con_reconfig_complete(uint32_t lcid, byte_buffer_t *pdu); - void send_rrc_ue_cap_info(uint32_t lcid, byte_buffer_t *pdu); + void send_rrc_ue_cap_info(uint32_t lcid, byte_buffer_t *pdu); - // Parsers - void parse_dl_ccch(byte_buffer_t *pdu); + // Parsers + void parse_dl_ccch(byte_buffer_t *pdu); - void parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu); + void parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu); - void parse_dl_info_transfer(uint32_t lcid, byte_buffer_t *pdu); + void parse_dl_info_transfer(uint32_t lcid, byte_buffer_t *pdu); - // Helpers - void reset_ue(); + // Helpers + void reset_ue(); - void rrc_connection_release(); + void rrc_connection_release(); - void radio_link_failure(); + void radio_link_failure(); - uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t x); + uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t x); - void apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2); + void apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2); - void handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup); + void handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup); - void handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup); + void handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup); - void - handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, byte_buffer_t *pdu); + void + handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, byte_buffer_t *pdu); - void add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg); + void add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg); - void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg); + void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg); - void release_drb(uint8_t lcid); + void release_drb(uint8_t lcid); - void apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg); + void apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg); - void apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *phy_cnfg, bool apply_defaults); + void apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *phy_cnfg, bool apply_defaults); - void apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cfg, bool apply_defaults); + void apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cfg, bool apply_defaults); - // Helpers for setting default values - void set_phy_default_pucch_srs(); + // Helpers for setting default values + void set_phy_default_pucch_srs(); - void set_phy_default(); + void set_phy_default(); - void set_mac_default(); + void set_mac_default(); - void set_rrc_default(); + void set_rrc_default(); - }; +}; } // namespace srsue diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 3dedcb606..3662f4d24 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -40,576 +40,576 @@ namespace srsue { - phch_recv::phch_recv() { - running = false; - } +phch_recv::phch_recv() { + running = false; +} - void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_mac, rrc_interface_phy *_rrc, - prach *_prach_buffer, srslte::thread_pool *_workers_pool, - phch_common *_worker_com, srslte::log *_log_h, uint32_t nof_rx_antennas_, uint32_t prio, - int sync_cpu_affinity) { - radio_h = _radio_handler; - log_h = _log_h; - mac = _mac; - rrc = _rrc; - workers_pool = _workers_pool; - worker_com = _worker_com; - prach_buffer = _prach_buffer; - nof_rx_antennas = nof_rx_antennas_; - - tx_mutex_cnt = 0; - running = true; - phy_state = IDLE; - time_adv_sec = 0; - cell_is_set = false; - sync_sfn_cnt = 0; - srate_mode = SRATE_NONE; - cell_search_in_progress = false; +void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_mac, rrc_interface_phy *_rrc, + prach *_prach_buffer, srslte::thread_pool *_workers_pool, + phch_common *_worker_com, srslte::log *_log_h, uint32_t nof_rx_antennas_, uint32_t prio, + int sync_cpu_affinity) { + radio_h = _radio_handler; + log_h = _log_h; + mac = _mac; + rrc = _rrc; + workers_pool = _workers_pool; + worker_com = _worker_com; + prach_buffer = _prach_buffer; + nof_rx_antennas = nof_rx_antennas_; + + tx_mutex_cnt = 0; + running = true; + phy_state = IDLE; + time_adv_sec = 0; + cell_is_set = false; + sync_sfn_cnt = 0; + srate_mode = SRATE_NONE; + cell_search_in_progress = false; + + for (uint32_t i = 0; i < nof_rx_antennas; i++) { + sf_buffer[i] = (cf_t *) srslte_vec_malloc(sizeof(cf_t) * 3 * SRSLTE_SF_LEN_PRB(100)); + } - for (uint32_t i = 0; i < nof_rx_antennas; i++) { - sf_buffer[i] = (cf_t *) srslte_vec_malloc(sizeof(cf_t) * 3 * SRSLTE_SF_LEN_PRB(100)); - } + nof_tx_mutex = MUTEX_X_WORKER * workers_pool->get_nof_workers(); + worker_com->set_nof_mutex(nof_tx_mutex); + if (sync_cpu_affinity < 0) { + start(prio); + } else { + start_cpu(prio, sync_cpu_affinity); + } - nof_tx_mutex = MUTEX_X_WORKER * workers_pool->get_nof_workers(); - worker_com->set_nof_mutex(nof_tx_mutex); - if (sync_cpu_affinity < 0) { - start(prio); - } else { - start_cpu(prio, sync_cpu_affinity); - } +} +void phch_recv::stop() { + running = false; + wait_thread_finish(); + for (uint32_t i = 0; i < nof_rx_antennas; i++) { + if (sf_buffer[i]) { + free(sf_buffer[i]); + } } +} - void phch_recv::stop() { - running = false; - wait_thread_finish(); - for (uint32_t i = 0; i < nof_rx_antennas; i++) { - if (sf_buffer[i]) { - free(sf_buffer[i]); - } +void phch_recv::set_agc_enable(bool enable) { + do_agc = enable; +} + +int radio_recv_wrapper_cs(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time) { + srslte::radio_multi *radio_h = (srslte::radio_multi *) h; + if (radio_h->rx_now(data, nsamples, rx_time)) { + int offset = nsamples - radio_h->get_tti_len(); + if (abs(offset) < 10 && offset != 0) { + radio_h->tx_offset(offset); + } else if (nsamples < 10) { + radio_h->tx_offset(nsamples); } + return nsamples; + } else { + return -1; } +} - void phch_recv::set_agc_enable(bool enable) { - do_agc = enable; - } +double callback_set_rx_gain(void *h, double gain) { + srslte::radio_multi *radio_handler = (srslte::radio_multi *) h; + return radio_handler->set_rx_gain_th(gain); +} - int radio_recv_wrapper_cs(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time) { - srslte::radio_multi *radio_h = (srslte::radio_multi *) h; - if (radio_h->rx_now(data, nsamples, rx_time)) { - int offset = nsamples - radio_h->get_tti_len(); - if (abs(offset) < 10 && offset != 0) { - radio_h->tx_offset(offset); - } else if (nsamples < 10) { - radio_h->tx_offset(nsamples); - } - return nsamples; - } else { - return -1; - } +void phch_recv::set_time_adv_sec(float _time_adv_sec) { + time_adv_sec = _time_adv_sec; +} + +void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) { + if (worker_com->args->cfo_integer_enabled) { + srslte_ue_sync_cfo_i_detec_en(q, true); } - double callback_set_rx_gain(void *h, double gain) { - srslte::radio_multi *radio_handler = (srslte::radio_multi *) h; - return radio_handler->set_rx_gain_th(gain); + float cfo_tol = worker_com->args->cfo_correct_tol_hz; + srslte_cfo_set_tol(&q->strack.cfocorr, cfo_tol / (15000 * q->fft_size)); + srslte_cfo_set_tol(&q->sfind.cfocorr, cfo_tol / (15000 * q->fft_size)); + + int time_correct_period = worker_com->args->time_correct_period; + if (time_correct_period > 0) { + srslte_ue_sync_set_sample_offset_correct_period(q, time_correct_period); } - void phch_recv::set_time_adv_sec(float _time_adv_sec) { - time_adv_sec = _time_adv_sec; + sss_alg_t sss_alg = SSS_FULL; + if (!worker_com->args->sss_algorithm.compare("diff")) { + sss_alg = SSS_DIFF; + } else if (!worker_com->args->sss_algorithm.compare("partial")) { + sss_alg = SSS_PARTIAL_3; + } else if (!worker_com->args->sss_algorithm.compare("full")) { + sss_alg = SSS_FULL; + } else { + Warning("Invalid SSS algorithm %s. Using 'full'\n", worker_com->args->sss_algorithm.c_str()); } + srslte_sync_set_sss_algorithm(&q->strack, (sss_alg_t) sss_alg); + srslte_sync_set_sss_algorithm(&q->sfind, (sss_alg_t) sss_alg); +} - void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) { - if (worker_com->args->cfo_integer_enabled) { - srslte_ue_sync_cfo_i_detec_en(q, true); - } +bool phch_recv::init_cell() { + cell_is_set = false; + if (!srslte_ue_mib_init(&ue_mib, cell)) { + if (!srslte_ue_sync_init_multi(&ue_sync, cell, radio_recv_wrapper_cs, nof_rx_antennas, radio_h)) { - float cfo_tol = worker_com->args->cfo_correct_tol_hz; - srslte_cfo_set_tol(&q->strack.cfocorr, cfo_tol / (15000 * q->fft_size)); - srslte_cfo_set_tol(&q->sfind.cfocorr, cfo_tol / (15000 * q->fft_size)); + // Set options defined in expert section + set_ue_sync_opts(&ue_sync); - int time_correct_period = worker_com->args->time_correct_period; - if (time_correct_period > 0) { - srslte_ue_sync_set_sample_offset_correct_period(q, time_correct_period); - } + if (srslte_ue_dl_init_multi(&ue_dl_measure, cell, nof_rx_antennas)) { + Error("Setting cell: initiating ue_dl_measure\n"); + return false; + } - sss_alg_t sss_alg = SSS_FULL; - if (!worker_com->args->sss_algorithm.compare("diff")) { - sss_alg = SSS_DIFF; - } else if (!worker_com->args->sss_algorithm.compare("partial")) { - sss_alg = SSS_PARTIAL_3; - } else if (!worker_com->args->sss_algorithm.compare("full")) { - sss_alg = SSS_FULL; + for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) { + if (!((phch_worker *) workers_pool->get_worker(i))->init_cell(cell)) { + Error("Setting cell: initiating PHCH worker\n"); + return false; + } + } + radio_h->set_tti_len(SRSLTE_SF_LEN_PRB(cell.nof_prb)); + if (do_agc) { + srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain); + } + srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); + cell_is_set = true; } else { - Warning("Invalid SSS algorithm %s. Using 'full'\n", worker_com->args->sss_algorithm.c_str()); + Error("Error setting cell: initiating ue_sync"); } - srslte_sync_set_sss_algorithm(&q->strack, (sss_alg_t) sss_alg); - srslte_sync_set_sss_algorithm(&q->sfind, (sss_alg_t) sss_alg); + } else { + Error("Error setting cell: initiating ue_mib\n"); } + return cell_is_set; +} - bool phch_recv::init_cell() { - cell_is_set = false; - if (!srslte_ue_mib_init(&ue_mib, cell)) { - if (!srslte_ue_sync_init_multi(&ue_sync, cell, radio_recv_wrapper_cs, nof_rx_antennas, radio_h)) { +void phch_recv::free_cell() { + if (phy_state != IDLE) { + phy_state = IDLE; + usleep(2000); + } - // Set options defined in expert section - set_ue_sync_opts(&ue_sync); + srslte_ue_sync_free(&ue_sync); - if (srslte_ue_dl_init_multi(&ue_dl_measure, cell, nof_rx_antennas)) { - Error("Setting cell: initiating ue_dl_measure\n"); - return false; - } + srslte_ue_dl_free(&ue_dl_measure); - for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) { - if (!((phch_worker *) workers_pool->get_worker(i))->init_cell(cell)) { - Error("Setting cell: initiating PHCH worker\n"); - return false; - } - } - radio_h->set_tti_len(SRSLTE_SF_LEN_PRB(cell.nof_prb)); - if (do_agc) { - srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain); - } - srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); - cell_is_set = true; - } else { - Error("Error setting cell: initiating ue_sync"); - } - } else { - Error("Error setting cell: initiating ue_mib\n"); + if (cell_is_set) { + for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) { + ((phch_worker *) workers_pool->get_worker(i))->free_cell(); } - return cell_is_set; + prach_buffer->free_cell(); + cell_is_set = false; } +} - void phch_recv::free_cell() { - if (phy_state != IDLE) { - phy_state = IDLE; - usleep(2000); - } - srslte_ue_sync_free(&ue_sync); +bool phch_recv::cell_search(int force_N_id_2) { + uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; + uint8_t bch_payload_bits[SRSLTE_BCH_PAYLOAD_LEN / 8]; - srslte_ue_dl_free(&ue_dl_measure); + srslte_ue_cellsearch_result_t found_cells[3]; + srslte_ue_cellsearch_t cs; - if (cell_is_set) { - for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) { - ((phch_worker *) workers_pool->get_worker(i))->free_cell(); - } - prach_buffer->free_cell(); - cell_is_set = false; - } + bzero(found_cells, 3 * sizeof(srslte_ue_cellsearch_result_t)); + + if (srslte_ue_cellsearch_init_multi(&cs, SRSLTE_DEFAULT_MAX_FRAMES_PSS, radio_recv_wrapper_cs, nof_rx_antennas, + radio_h)) { + Error("Initiating UE cell search\n"); + return false; } + srslte_ue_cellsearch_set_nof_valid_frames(&cs, SRSLTE_DEFAULT_NOF_VALID_PSS_FRAMES); - bool phch_recv::cell_search(int force_N_id_2) { - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - uint8_t bch_payload_bits[SRSLTE_BCH_PAYLOAD_LEN / 8]; + // Set options defined in expert section + set_ue_sync_opts(&cs.ue_sync); - srslte_ue_cellsearch_result_t found_cells[3]; - srslte_ue_cellsearch_t cs; + if (do_agc) { + srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, last_gain); + } - bzero(found_cells, 3 * sizeof(srslte_ue_cellsearch_result_t)); + if (srate_mode != SRATE_FIND) { + srate_mode = SRATE_FIND; + radio_h->set_rx_srate(1.92e6); + } + radio_h->start_rx(); - if (srslte_ue_cellsearch_init_multi(&cs, SRSLTE_DEFAULT_MAX_FRAMES_PSS, radio_recv_wrapper_cs, nof_rx_antennas, - radio_h)) { - Error("Initiating UE cell search\n"); - return false; - } + /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ + uint32_t max_peak_cell = 0; + int ret = SRSLTE_ERROR; - srslte_ue_cellsearch_set_nof_valid_frames(&cs, SRSLTE_DEFAULT_NOF_VALID_PSS_FRAMES); + if (force_N_id_2 >= 0 && force_N_id_2 < 3) { + ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]); + max_peak_cell = force_N_id_2; + } else { + ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell); + } - // Set options defined in expert section - set_ue_sync_opts(&cs.ue_sync); + last_gain = srslte_agc_get_gain(&cs.ue_sync.agc); - if (do_agc) { - srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, last_gain); - } + radio_h->stop_rx(); + srslte_ue_cellsearch_free(&cs); - if (srate_mode != SRATE_FIND) { - srate_mode = SRATE_FIND; - radio_h->set_rx_srate(1.92e6); - } - radio_h->start_rx(); + if (ret < 0) { + Error("Error decoding MIB: Error searching PSS\n"); + return false; + } else if (ret == 0) { + Error("Error decoding MIB: Could not find any PSS in this frequency\n"); + return false; + } - /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ - uint32_t max_peak_cell = 0; - int ret = SRSLTE_ERROR; + // Save result + cell.id = found_cells[max_peak_cell].cell_id; + cell.cp = found_cells[max_peak_cell].cp; + cellsearch_cfo = found_cells[max_peak_cell].cfo; - if (force_N_id_2 >= 0 && force_N_id_2 < 3) { - ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]); - max_peak_cell = force_N_id_2; - } else { - ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell); - } + srslte_ue_mib_sync_t ue_mib_sync; - last_gain = srslte_agc_get_gain(&cs.ue_sync.agc); + if (srslte_ue_mib_sync_init_multi(&ue_mib_sync, cell.id, cell.cp, radio_recv_wrapper_cs, nof_rx_antennas, + radio_h)) { + Error("Initiating UE MIB synchronization\n"); + return false; + } - radio_h->stop_rx(); - srslte_ue_cellsearch_free(&cs); + // Set options defined in expert section + set_ue_sync_opts(&ue_mib_sync.ue_sync); - if (ret < 0) { - Error("Error decoding MIB: Error searching PSS\n"); - return false; - } else if (ret == 0) { - Error("Error decoding MIB: Could not find any PSS in this frequency\n"); - return false; - } + if (do_agc) { + srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, last_gain); + } - // Save result - cell.id = found_cells[max_peak_cell].cell_id; - cell.cp = found_cells[max_peak_cell].cp; - cellsearch_cfo = found_cells[max_peak_cell].cfo; + srslte_ue_sync_set_cfo(&ue_mib_sync.ue_sync, cellsearch_cfo); + + /* Find and decode MIB */ + uint32_t sfn; + int sfn_offset; + radio_h->start_rx(); + ret = srslte_ue_mib_sync_decode(&ue_mib_sync, + SRSLTE_DEFAULT_MAX_FRAMES_PBCH, + bch_payload, &cell.nof_ports, &sfn_offset); + radio_h->stop_rx(); + last_gain = srslte_agc_get_gain(&ue_mib_sync.ue_sync.agc); + cellsearch_cfo = srslte_ue_sync_get_cfo(&ue_mib_sync.ue_sync); + srslte_ue_mib_sync_free(&ue_mib_sync); + + if (ret == 1) { + srslte_pbch_mib_unpack(bch_payload, &cell, NULL); + worker_com->set_cell(cell); + return true; + } else { + Warning("Error decoding MIB: Error decoding PBCH\n"); + return false; + } +} - srslte_ue_mib_sync_t ue_mib_sync; - if (srslte_ue_mib_sync_init_multi(&ue_mib_sync, cell.id, cell.cp, radio_recv_wrapper_cs, nof_rx_antennas, - radio_h)) { - Error("Initiating UE MIB synchronization\n"); - return false; - } +void phch_recv::resync_sfn() { + sync_sfn_cnt = 0; + phy_state = CELL_SELECT; +} - // Set options defined in expert section - set_ue_sync_opts(&ue_mib_sync.ue_sync); +void phch_recv::set_earfcn(std::vector earfcn) { + this->earfcn = earfcn; +} - if (do_agc) { - srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, last_gain); +void phch_recv::cell_search_next() { + cell_search_in_progress = true; + cur_earfcn_index++; + if (cur_earfcn_index >= 0) { + if (cur_earfcn_index >= (int) earfcn.size() - 1) { + cur_earfcn_index = 0; } + // If PHY is running, stop and free resources + free_cell(); - srslte_ue_sync_set_cfo(&ue_mib_sync.ue_sync, cellsearch_cfo); - - /* Find and decode MIB */ - uint32_t sfn; - int sfn_offset; - radio_h->start_rx(); - ret = srslte_ue_mib_sync_decode(&ue_mib_sync, - SRSLTE_DEFAULT_MAX_FRAMES_PBCH, - bch_payload, &cell.nof_ports, &sfn_offset); - radio_h->stop_rx(); - last_gain = srslte_agc_get_gain(&ue_mib_sync.ue_sync.agc); - cellsearch_cfo = srslte_ue_sync_get_cfo(&ue_mib_sync.ue_sync); - srslte_ue_mib_sync_free(&ue_mib_sync); - - if (ret == 1) { - srslte_pbch_mib_unpack(bch_payload, &cell, NULL); - worker_com->set_cell(cell); - return true; + float dl_freq = 1e6*srslte_band_fd(earfcn[cur_earfcn_index]); + if (dl_freq >= 0) { + log_h->info("Cell Search: Set DL EARFCN=%d, frequency=%.1f MHz, channel_index=%d\n", earfcn[cur_earfcn_index], + dl_freq / 1e6, cur_earfcn_index); + radio_h->set_rx_freq(dl_freq); + + // Start PHY cell search (finds maximum cell in frequency) + phy_state = CELL_SEARCH; } else { - Warning("Error decoding MIB: Error decoding PBCH\n"); - return false; + log_h->error("Cell Search: Invalid EARFCN=%d, channel_index=%d\n", earfcn[cur_earfcn_index], cur_earfcn_index); } } +} - - void phch_recv::resync_sfn() { - sync_sfn_cnt = 0; - phy_state = CELL_SELECT; +void phch_recv::cell_search_start() { + if (earfcn.size() > 0) { + cur_earfcn_index = -1; + log_h->console("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); + log_h->info("Cell Search: Starting procedure...\n"); + cell_search_next(); + } else { + log_h->info("Empty EARFCN list. Stopping cell search...\n"); + log_h->console("Empty EARFCN list. Stopping cell search...\n"); } +} - void phch_recv::set_earfcn(std::vector earfcn) { - this->earfcn = earfcn; - } +bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { + free_cell(); - void phch_recv::cell_search_next() { - cell_search_in_progress = true; - cur_earfcn_index++; - if (cur_earfcn_index >= 0) { - if (cur_earfcn_index >= (int) earfcn.size() - 1) { - cur_earfcn_index = 0; - } - // If PHY is running, stop and free resources - free_cell(); - - float dl_freq = 1e6*srslte_band_fd(earfcn[cur_earfcn_index]); - if (dl_freq >= 0) { - log_h->info("Cell Search: Set DL EARFCN=%d, frequency=%.1f MHz, channel_index=%d\n", earfcn[cur_earfcn_index], - dl_freq / 1e6, cur_earfcn_index); - radio_h->set_rx_freq(dl_freq); - - // Start PHY cell search (finds maximum cell in frequency) - phy_state = CELL_SEARCH; - } else { - log_h->error("Cell Search: Invalid EARFCN=%d, channel_index=%d\n", earfcn[cur_earfcn_index], cur_earfcn_index); - } - } + int cnt=0; + while(phy_state == CELL_SEARCH && cnt<100) { + usleep(10000); + log_h->info("PHY in CELL_SEARCH. Waiting...\n"); + } + if (phy_state==CELL_SEARCH) { + log_h->warning("PHY still in CELL_SEARCH, forcing CELL_SELECT...\n"); } + float dl_freq = 1e6*srslte_band_fd(earfcn); + float ul_freq = 1e6*srslte_band_fu(srslte_band_ul_earfcn(earfcn)); + if (dl_freq >= 0 || ul_freq <= 0) { + log_h->info("Cell Select: Set EARFCN=%d, frequency=%.1f MHz, UL frequency=%.1f MHz\n", earfcn, dl_freq / 1e6, + ul_freq / 1e6); + radio_h->set_rx_freq(dl_freq); + radio_h->set_tx_freq(ul_freq); + + ul_dl_factor = ul_freq/dl_freq; - void phch_recv::cell_search_start() { - if (earfcn.size() > 0) { - cur_earfcn_index = -1; - log_h->console("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); - log_h->info("Cell Search: Starting procedure...\n"); - cell_search_next(); + cell_search_in_progress = false; + this->cell = cell; + if (init_cell()) { + phy_state = CELL_SELECT; + return true; } else { - log_h->info("Empty EARFCN list. Stopping cell search...\n"); - log_h->console("Empty EARFCN list. Stopping cell search...\n"); + log_h->error("Cell Select: Initializing cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); } + } else { + log_h->error("Cell Select: Invalid EARFCN=%d\n", earfcn); } + return false; +} - bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { - free_cell(); - int cnt=0; - while(phy_state == CELL_SEARCH && cnt<100) { - usleep(10000); - log_h->info("PHY in CELL_SEARCH. Waiting...\n"); - } - if (phy_state==CELL_SEARCH) { - log_h->warning("PHY still in CELL_SEARCH, forcing CELL_SELECT...\n"); - } - float dl_freq = 1e6*srslte_band_fd(earfcn); - float ul_freq = 1e6*srslte_band_fu(srslte_band_ul_earfcn(earfcn)); - if (dl_freq >= 0 || ul_freq <= 0) { - log_h->info("Cell Select: Set EARFCN=%d, frequency=%.1f MHz, UL frequency=%.1f MHz\n", earfcn, dl_freq / 1e6, - ul_freq / 1e6); - radio_h->set_rx_freq(dl_freq); - radio_h->set_tx_freq(ul_freq); +int phch_recv::cell_sync_sfn(void) { + + int ret = SRSLTE_ERROR; + uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; + + srslte_ue_sync_decode_sss_on_track(&ue_sync, true); + ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); + if (ret < 0) { + Error("Error calling ue_sync_get_buffer"); + return -1; + } + + if (ret == 1) { + if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { + int sfn_offset = 0; + Info("SYNC: Decoding MIB...\n"); + int n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); + if (n < 0) { + Error("SYNC: Error decoding MIB while synchronising SFN"); + return -1; + } else if (n == SRSLTE_UE_MIB_FOUND) { + uint32_t sfn; + srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); - ul_dl_factor = ul_freq/dl_freq; + sfn = (sfn+sfn_offset)%1024; + tti = sfn * 10; - cell_search_in_progress = false; - this->cell = cell; - if (init_cell()) { - phy_state = CELL_SELECT; - return true; - } else { - log_h->error("Cell Select: Initializing cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); + srslte_ue_sync_decode_sss_on_track(&ue_sync, true); + Info("SYNC: DONE, TTI=%d, sfn_offset=%d\n", tti, sfn_offset); + srslte_ue_mib_reset(&ue_mib); + return 1; } - } else { - log_h->error("Cell Select: Invalid EARFCN=%d\n", earfcn); } - return false; + } else { + Debug("SYNC: PSS/SSS not found...\n"); } + return 0; +} +int phch_recv::cell_meas_rsrp() { - int phch_recv::cell_sync_sfn(void) { + uint32_t cfi = 0; - int ret = SRSLTE_ERROR; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; + tti = (tti+1) % 10240; + log_h->step(tti); - srslte_ue_sync_decode_sss_on_track(&ue_sync, true); - ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); - if (ret < 0) { - Error("Error calling ue_sync_get_buffer"); + uint32_t sf_idx = tti%10; + + int sync_res = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); + if (sync_res == 1) { + if (srslte_ue_dl_decode_fft_estimate_multi(&ue_dl_measure, sf_buffer, sf_idx, &cfi)) { + log_h->error("SYNC: Measuring RSRP: Estimating channel\n"); return -1; } - - if (ret == 1) { - if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { - int sfn_offset = 0; - Info("SYNC: Decoding MIB...\n"); - int n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); - if (n < 0) { - Error("SYNC: Error decoding MIB while synchronising SFN"); - return -1; - } else if (n == SRSLTE_UE_MIB_FOUND) { - uint32_t sfn; - srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); - - sfn = (sfn+sfn_offset)%1024; - tti = sfn * 10; - - srslte_ue_sync_decode_sss_on_track(&ue_sync, true); - Info("SYNC: DONE, TTI=%d, sfn_offset=%d\n", tti, sfn_offset); - srslte_ue_mib_reset(&ue_mib); - return 1; - } - } - } else { - Debug("SYNC: PSS/SSS not found...\n"); + float rsrp = srslte_chest_dl_get_rsrp(&ue_dl_measure.chest); + measure_rsrp = SRSLTE_VEC_CMA(rsrp, measure_rsrp, measure_cnt); + measure_cnt++; + log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm\n", + measure_cnt, RSRP_MEASURE_NOF_FRAMES, sf_idx, 10 * log10(rsrp / 1000)); + if (measure_cnt >= RSRP_MEASURE_NOF_FRAMES) { + return 1; } - return 0; + } else { + log_h->error("SYNC: Measuring RSRP: Sync error\n"); + return -1; } - int phch_recv::cell_meas_rsrp() { + return 0; +} - uint32_t cfi = 0; +void phch_recv::run_thread() { + int sync_res; + phch_worker *worker = NULL; + cf_t *buffer[SRSLTE_MAX_PORTS]; + while (running) { + switch (phy_state) { + case CELL_SEARCH: + if (cell_search()) { + init_cell(); + float srate = (float) srslte_sampling_freq_hz(cell.nof_prb); + + if (30720 % ((int) srate / 1000) == 0) { + radio_h->set_master_clock_rate(30.72e6); + } else { + radio_h->set_master_clock_rate(23.04e6); + } - tti = (tti+1) % 10240; - log_h->step(tti); + log_h->info("Setting Sampling frequency %.2f MHz\n", (float) srate / 1000000); + srate_mode = SRATE_CAMP; + radio_h->set_rx_srate(srate); + radio_h->set_tx_srate(srate); - uint32_t sf_idx = tti%10; + Info("SYNC: Cell found. Synchronizing...\n"); + phy_state = CELL_SELECT; + sync_sfn_cnt = 0; + srslte_ue_mib_reset(&ue_mib); + } + break; + case CELL_SELECT: - int sync_res = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); - if (sync_res == 1) { - if (srslte_ue_dl_decode_fft_estimate_multi(&ue_dl_measure, sf_buffer, sf_idx, &cfi)) { - log_h->error("SYNC: Measuring RSRP: Estimating channel\n"); - return -1; - } - float rsrp = srslte_chest_dl_get_rsrp(&ue_dl_measure.chest); - measure_rsrp = SRSLTE_VEC_CMA(rsrp, measure_rsrp, measure_cnt); - measure_cnt++; - log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm\n", - measure_cnt, RSRP_MEASURE_NOF_FRAMES, sf_idx, 10 * log10(rsrp / 1000)); - if (measure_cnt >= RSRP_MEASURE_NOF_FRAMES) { - return 1; - } - } else { - log_h->error("SYNC: Measuring RSRP: Sync error\n"); - return -1; - } + srslte_ue_sync_decode_sss_on_track(&ue_sync, true); - return 0; - } + if (!radio_is_streaming) { + // Start streaming + radio_h->start_rx(); + radio_is_streaming = true; + } - void phch_recv::run_thread() { - int sync_res; - phch_worker *worker = NULL; - cf_t *buffer[SRSLTE_MAX_PORTS]; - while (running) { - switch (phy_state) { - case CELL_SEARCH: - if (cell_search()) { - init_cell(); - float srate = (float) srslte_sampling_freq_hz(cell.nof_prb); - - if (30720 % ((int) srate / 1000) == 0) { - radio_h->set_master_clock_rate(30.72e6); + switch (cell_sync_sfn()) { + default: + log_h->console("Going IDLE\n"); + phy_state = IDLE; + break; + case 1: + srslte_ue_sync_set_agc_period(&ue_sync, 20); + if (!cell_search_in_progress) { + phy_state = CELL_CAMP; + log_h->console("Sync OK. Camping on cell PCI=%d...\n", cell.id); } else { - radio_h->set_master_clock_rate(23.04e6); + measure_cnt = 0; + measure_rsrp = 0; + phy_state = CELL_MEASURE; } + break; + case 0: + break; + } + sync_sfn_cnt++; + if (sync_sfn_cnt >= SYNC_SFN_TIMEOUT) { + sync_sfn_cnt = 0; + radio_h->stop_rx(); + radio_is_streaming = false; + log_h->console("Timeout while synchronizing SFN\n"); + log_h->warning("Timeout while synchronizing SFN\n"); + } + break; + case CELL_MEASURE: + switch(cell_meas_rsrp()) { + case 1: + rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000)); + phy_state = CELL_CAMP; + case 0: + break; + default: + log_h->error("SYNC: Getting RSRP cell measurement.\n"); + cell_search_next(); + } + break; + case CELL_CAMP: + tti = (tti+1) % 10240; + worker = (phch_worker *) workers_pool->wait_worker(tti); + if (worker) { + for (uint32_t i = 0; i < nof_rx_antennas; i++) { + buffer[i] = worker->get_buffer(i); + } - log_h->info("Setting Sampling frequency %.2f MHz\n", (float) srate / 1000000); - srate_mode = SRATE_CAMP; - radio_h->set_rx_srate(srate); - radio_h->set_tx_srate(srate); + sync_res = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer); + if (sync_res == 1) { - Info("SYNC: Cell found. Synchronizing...\n"); - phy_state = CELL_SELECT; - sync_sfn_cnt = 0; - srslte_ue_mib_reset(&ue_mib); - } - break; - case CELL_SELECT: + log_h->step(tti); - srslte_ue_sync_decode_sss_on_track(&ue_sync, true); + Debug("Worker %d synchronized\n", worker->get_id()); - if (!radio_is_streaming) { - // Start streaming - radio_h->start_rx(); - radio_is_streaming = true; - } + metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); + metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); + worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); + worker_com->set_sync_metrics(metrics); - switch (cell_sync_sfn()) { - default: - log_h->console("Going IDLE\n"); - phy_state = IDLE; - break; - case 1: - srslte_ue_sync_set_agc_period(&ue_sync, 20); - if (!cell_search_in_progress) { - phy_state = CELL_CAMP; - log_h->console("Sync OK. Camping on cell PCI=%d...\n", cell.id); - } else { - measure_cnt = 0; - measure_rsrp = 0; - phy_state = CELL_MEASURE; - } - break; - case 0: - break; - } - sync_sfn_cnt++; - if (sync_sfn_cnt >= SYNC_SFN_TIMEOUT) { - sync_sfn_cnt = 0; - radio_h->stop_rx(); - radio_is_streaming = false; - log_h->console("Timeout while synchronizing SFN\n"); - log_h->warning("Timeout while synchronizing SFN\n"); - } - break; - case CELL_MEASURE: - switch(cell_meas_rsrp()) { - case 1: - rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000)); - phy_state = CELL_CAMP; - case 0: - break; - default: - log_h->error("SYNC: Getting RSRP cell measurement.\n"); - cell_search_next(); - } - break; - case CELL_CAMP: - tti = (tti+1) % 10240; - worker = (phch_worker *) workers_pool->wait_worker(tti); - if (worker) { - for (uint32_t i = 0; i < nof_rx_antennas; i++) { - buffer[i] = worker->get_buffer(i); - } + float sample_offset = (float) srslte_ue_sync_get_sfo(&ue_sync) / 1000; + worker->set_sample_offset(sample_offset); - sync_res = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer); - if (sync_res == 1) { - - log_h->step(tti); - - Debug("Worker %d synchronized\n", worker->get_id()); - - metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); - metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); - worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); - worker_com->set_sync_metrics(metrics); - - float sample_offset = (float) srslte_ue_sync_get_sfo(&ue_sync) / 1000; - worker->set_sample_offset(sample_offset); - - /* Compute TX time: Any transmission happens in TTI4 thus advance 4 ms the reception time */ - srslte_timestamp_t rx_time, tx_time, tx_time_prach; - srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time); - srslte_timestamp_copy(&tx_time, &rx_time); - srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec); - worker->set_tx_time(tx_time); - - Debug("Settting TTI=%d, tx_mutex=%d to worker %d\n", tti, tx_mutex_cnt, worker->get_id()); - worker->set_tti(tti, tx_mutex_cnt); - tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex; - - // Check if we need to TX a PRACH - if (prach_buffer->is_ready_to_send(tti)) { - srslte_timestamp_copy(&tx_time_prach, &rx_time); - srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3); - prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach); - radio_h->tx_end(); - worker_com->p0_preamble = prach_buffer->get_p0_preamble(); - worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); - } - workers_pool->start_worker(worker); - // Notify RRC in-sync every 1 frame - if ((tti % 10) == 0) { - rrc->in_sync(); - log_h->debug("Sending in-sync to RRC\n"); - } - } else { - log_h->console("Sync error.\n"); - log_h->error("Sync error. Sending out-of-sync to RRC\n"); - // Notify RRC of out-of-sync frame - rrc->out_of_sync(); - worker->release(); - worker_com->reset_ul(); - phy_state = CELL_SELECT; + /* Compute TX time: Any transmission happens in TTI4 thus advance 4 ms the reception time */ + srslte_timestamp_t rx_time, tx_time, tx_time_prach; + srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time); + srslte_timestamp_copy(&tx_time, &rx_time); + srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec); + worker->set_tx_time(tx_time); + + Debug("Settting TTI=%d, tx_mutex=%d to worker %d\n", tti, tx_mutex_cnt, worker->get_id()); + worker->set_tti(tti, tx_mutex_cnt); + tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex; + + // Check if we need to TX a PRACH + if (prach_buffer->is_ready_to_send(tti)) { + srslte_timestamp_copy(&tx_time_prach, &rx_time); + srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3); + prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach); + radio_h->tx_end(); + worker_com->p0_preamble = prach_buffer->get_p0_preamble(); + worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); + } + workers_pool->start_worker(worker); + // Notify RRC in-sync every 1 frame + if ((tti % 10) == 0) { + rrc->in_sync(); + log_h->debug("Sending in-sync to RRC\n"); } } else { - // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here - running = false; + log_h->console("Sync error.\n"); + log_h->error("Sync error. Sending out-of-sync to RRC\n"); + // Notify RRC of out-of-sync frame + rrc->out_of_sync(); + worker->release(); + worker_com->reset_ul(); + phy_state = CELL_SELECT; } - break; - case IDLE: - usleep(1000); - break; - } + } else { + // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here + running = false; + } + break; + case IDLE: + usleep(1000); + break; } } +} - uint32_t phch_recv::get_current_tti() { - return tti; - } +uint32_t phch_recv::get_current_tti() { + return tti; +} - bool phch_recv::status_is_sync() { - return phy_state == CELL_CAMP; - } +bool phch_recv::status_is_sync() { + return phy_state == CELL_CAMP; +} - void phch_recv::get_current_cell(srslte_cell_t *cell_) { - if (cell_) { - memcpy(cell_, &cell, sizeof(srslte_cell_t)); - } +void phch_recv::get_current_cell(srslte_cell_t *cell_) { + if (cell_) { + memcpy(cell_, &cell, sizeof(srslte_cell_t)); } } +} diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index f9bc88064..11372e198 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -33,280 +33,280 @@ using namespace srslte; namespace srsue { - nas::nas() - : state(EMM_STATE_DEREGISTERED), plmn_selection(PLMN_SELECTED), is_guti_set(false), ip_addr(0), eps_bearer_id(0), - count_ul(0), count_dl(0) {} - - void nas::init(usim_interface_nas *usim_, - rrc_interface_nas *rrc_, - gw_interface_nas *gw_, - srslte::log *nas_log_) { - pool = byte_buffer_pool::get_instance(); - usim = usim_; - rrc = rrc_; - gw = gw_; - nas_log = nas_log_; - state = EMM_STATE_DEREGISTERED; - plmn_selection = PLMN_NOT_SELECTED; - home_plmn.mcc = 61441; // This is 001 - home_plmn.mnc = 65281; // This is 01 - } - - void nas::stop() {} - - emm_state_t nas::get_state() { - return state; - } +nas::nas() + : state(EMM_STATE_DEREGISTERED), plmn_selection(PLMN_SELECTED), is_guti_set(false), ip_addr(0), eps_bearer_id(0), + count_ul(0), count_dl(0) {} + +void nas::init(usim_interface_nas *usim_, + rrc_interface_nas *rrc_, + gw_interface_nas *gw_, + srslte::log *nas_log_) { + pool = byte_buffer_pool::get_instance(); + usim = usim_; + rrc = rrc_; + gw = gw_; + nas_log = nas_log_; + state = EMM_STATE_DEREGISTERED; + plmn_selection = PLMN_NOT_SELECTED; + home_plmn.mcc = 61441; // This is 001 + home_plmn.mnc = 65281; // This is 01 +} + +void nas::stop() {} + +emm_state_t nas::get_state() { + return state; +} /******************************************************************************* - UE interface +UE interface *******************************************************************************/ - void nas::attach_request() { - nas_log->info("Attach Request\n"); - if (state == EMM_STATE_DEREGISTERED) { - state = EMM_STATE_REGISTERED_INITIATED; - if (plmn_selection == PLMN_NOT_SELECTED) { - nas_log->info("Starting PLMN Search...\n"); - rrc->plmn_search(); - } else if (plmn_selection == PLMN_SELECTED) { - nas_log->info("Selecting PLMN %s\n", plmn_id_to_c_str(current_plmn).c_str()); - rrc->plmn_select(current_plmn); - } - } else { - nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]); +void nas::attach_request() { + nas_log->info("Attach Request\n"); + if (state == EMM_STATE_DEREGISTERED) { + state = EMM_STATE_REGISTERED_INITIATED; + if (plmn_selection == PLMN_NOT_SELECTED) { + nas_log->info("Starting PLMN Search...\n"); + rrc->plmn_search(); + } else if (plmn_selection == PLMN_SELECTED) { + nas_log->info("Selecting PLMN %s\n", plmn_id_to_c_str(current_plmn).c_str()); + rrc->plmn_select(current_plmn); } + } else { + nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]); } +} - void nas::deattach_request() { - state = EMM_STATE_DEREGISTERED_INITIATED; - nas_log->info("Dettach request not supported\n"); - } +void nas::deattach_request() { + state = EMM_STATE_DEREGISTERED_INITIATED; + nas_log->info("Dettach request not supported\n"); +} /******************************************************************************* - RRC interface +RRC interface *******************************************************************************/ - void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { +void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { - // Store PLMN if not registered - for (uint32_t i=0;iinfo("Detected known PLMN %s\n", plmn_id_to_c_str(plmn_id).c_str()); - if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { - rrc->plmn_select(plmn_id); - } - return; + // Store PLMN if not registered + for (uint32_t i=0;iinfo("Detected known PLMN %s\n", plmn_id_to_c_str(plmn_id).c_str()); + if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { + rrc->plmn_select(plmn_id); } - } - nas_log->info("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_c_str(plmn_id).c_str(), - tracking_area_code); - nas_log->console("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_c_str(plmn_id).c_str(), - tracking_area_code); - if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { - rrc->plmn_select(plmn_id); + return; } } - - void nas::cell_selected() { - if (state == EMM_STATE_REGISTERED_INITIATED) { - rrc->connect(); - } else { - nas_log->info("Cell selected in invalid state = %s\n", emm_state_text[state]); - } - } - - bool nas::is_attached() { - return state == EMM_STATE_REGISTERED; + nas_log->info("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_c_str(plmn_id).c_str(), + tracking_area_code); + nas_log->console("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_c_str(plmn_id).c_str(), + tracking_area_code); + if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { + rrc->plmn_select(plmn_id); } +} - void nas::notify_connection_setup() { - nas_log->debug("State = %s\n", emm_state_text[state]); - if (EMM_STATE_REGISTERED_INITIATED == state) { - send_attach_request(); - } else { - send_service_request(); - } +void nas::cell_selected() { + if (state == EMM_STATE_REGISTERED_INITIATED) { + rrc->connect(); + } else { + nas_log->info("Cell selected in invalid state = %s\n", emm_state_text[state]); } - - void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - uint8 pd; - uint8 msg_type; - - nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rb_id_text[lcid]); - - // Parse the message - liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) pdu, &pd, &msg_type); - switch (msg_type) { - case LIBLTE_MME_MSG_TYPE_ATTACH_ACCEPT: - parse_attach_accept(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT: - parse_attach_reject(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: - parse_authentication_request(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT: - parse_authentication_reject(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST: - parse_identity_request(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND: - parse_security_mode_command(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: - parse_service_reject(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST: - parse_esm_information_request(lcid, pdu); - break; - case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: - parse_emm_information(lcid, pdu); - break; - default: - nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); - pool->deallocate(pdu); - break; - } +} + +bool nas::is_attached() { + return state == EMM_STATE_REGISTERED; +} + +void nas::notify_connection_setup() { + nas_log->debug("State = %s\n", emm_state_text[state]); + if (EMM_STATE_REGISTERED_INITIATED == state) { + send_attach_request(); + } else { + send_service_request(); } - - uint32_t nas::get_ul_count() { - return count_ul; +} + +void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { + uint8 pd; + uint8 msg_type; + + nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rb_id_text[lcid]); + + // Parse the message + liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) pdu, &pd, &msg_type); + switch (msg_type) { + case LIBLTE_MME_MSG_TYPE_ATTACH_ACCEPT: + parse_attach_accept(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT: + parse_attach_reject(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: + parse_authentication_request(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT: + parse_authentication_reject(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST: + parse_identity_request(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND: + parse_security_mode_command(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: + parse_service_reject(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST: + parse_esm_information_request(lcid, pdu); + break; + case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: + parse_emm_information(lcid, pdu); + break; + default: + nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); + pool->deallocate(pdu); + break; } - - bool nas::get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) { - if (is_guti_set) { - s_tmsi->mmec = guti.mme_code; - s_tmsi->m_tmsi = guti.m_tmsi; - return true; - } else { - return false; - } +} + +uint32_t nas::get_ul_count() { + return count_ul; +} + +bool nas::get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) { + if (is_guti_set) { + s_tmsi->mmec = guti.mme_code; + s_tmsi->m_tmsi = guti.m_tmsi; + return true; + } else { + return false; } +} /******************************************************************************* - Security +Security *******************************************************************************/ - void nas::integrity_generate(uint8_t *key_128, - uint32_t count, - uint8_t rb_id, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *mac) { - switch (integ_algo) { - case INTEGRITY_ALGORITHM_ID_EIA0: - break; - case INTEGRITY_ALGORITHM_ID_128_EIA1: - security_128_eia1(key_128, - count, - rb_id, - direction, - msg, - msg_len, - mac); - break; - case INTEGRITY_ALGORITHM_ID_128_EIA2: - security_128_eia2(key_128, - count, - rb_id, - direction, - msg, - msg_len, - mac); - break; - default: - break; - } +void nas::integrity_generate(uint8_t *key_128, + uint32_t count, + uint8_t rb_id, + uint8_t direction, + uint8_t *msg, + uint32_t msg_len, + uint8_t *mac) { + switch (integ_algo) { + case INTEGRITY_ALGORITHM_ID_EIA0: + break; + case INTEGRITY_ALGORITHM_ID_128_EIA1: + security_128_eia1(key_128, + count, + rb_id, + direction, + msg, + msg_len, + mac); + break; + case INTEGRITY_ALGORITHM_ID_128_EIA2: + security_128_eia2(key_128, + count, + rb_id, + direction, + msg, + msg_len, + mac); + break; + default: + break; } +} - void nas::integrity_check() { +void nas::integrity_check() { - } +} - void nas::cipher_encrypt() { +void nas::cipher_encrypt() { - } +} - void nas::cipher_decrypt() { +void nas::cipher_decrypt() { - } +} /******************************************************************************* - Parsers +Parsers *******************************************************************************/ - void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { - LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; - LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; - LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete; - LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_def_eps_bearer_context_accept; +void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { + LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; + LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; + LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete; + LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_def_eps_bearer_context_accept; - nas_log->info("Received Attach Accept\n"); - count_dl++; + nas_log->info("Received Attach Accept\n"); + count_dl++; - liblte_mme_unpack_attach_accept_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &attach_accept); + liblte_mme_unpack_attach_accept_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &attach_accept); - if (attach_accept.eps_attach_result == LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY) { - //FIXME: Handle t3412.unit - //FIXME: Handle tai_list - if (attach_accept.guti_present) { - memcpy(&guti, &attach_accept.guti.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT)); - is_guti_set = true; - // TODO: log message to console - } - if (attach_accept.lai_present) { - } - if (attach_accept.ms_id_present) {} - if (attach_accept.emm_cause_present) {} - if (attach_accept.t3402_present) {} - if (attach_accept.t3423_present) {} - if (attach_accept.equivalent_plmns_present) {} - if (attach_accept.emerg_num_list_present) {} - if (attach_accept.eps_network_feature_support_present) {} - if (attach_accept.additional_update_result_present) {} - if (attach_accept.t3412_ext_present) {} - - liblte_mme_unpack_activate_default_eps_bearer_context_request_msg(&attach_accept.esm_msg, - &act_def_eps_bearer_context_req); - - if (LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) { - ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[0] << 24; - ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[1] << 16; - ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[2] << 8; - ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[3]; - - nas_log->info("IP allocated by network %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3]); - - nas_log->console("Network attach successful. IP: %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3]); - - // Setup GW - char *err_str = NULL; - if (gw->setup_if_addr(ip_addr, err_str)) { - nas_log->error("Failed to set gateway address - %s\n", err_str); - } - } else { - nas_log->error("Not handling IPV6 or IPV4V6\n"); - pool->deallocate(pdu); - return; - } - eps_bearer_id = act_def_eps_bearer_context_req.eps_bearer_id; - if (act_def_eps_bearer_context_req.transaction_id_present) { - transaction_id = act_def_eps_bearer_context_req.proc_transaction_id; + if (attach_accept.eps_attach_result == LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY) { + //FIXME: Handle t3412.unit + //FIXME: Handle tai_list + if (attach_accept.guti_present) { + memcpy(&guti, &attach_accept.guti.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT)); + is_guti_set = true; + // TODO: log message to console + } + if (attach_accept.lai_present) { + } + if (attach_accept.ms_id_present) {} + if (attach_accept.emm_cause_present) {} + if (attach_accept.t3402_present) {} + if (attach_accept.t3423_present) {} + if (attach_accept.equivalent_plmns_present) {} + if (attach_accept.emerg_num_list_present) {} + if (attach_accept.eps_network_feature_support_present) {} + if (attach_accept.additional_update_result_present) {} + if (attach_accept.t3412_ext_present) {} + + liblte_mme_unpack_activate_default_eps_bearer_context_request_msg(&attach_accept.esm_msg, + &act_def_eps_bearer_context_req); + + if (LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) { + ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[0] << 24; + ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[1] << 16; + ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[2] << 8; + ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[3]; + + nas_log->info("IP allocated by network %u.%u.%u.%u\n", + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3]); + + nas_log->console("Network attach successful. IP: %u.%u.%u.%u\n", + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3]); + + // Setup GW + char *err_str = NULL; + if (gw->setup_if_addr(ip_addr, err_str)) { + nas_log->error("Failed to set gateway address - %s\n", err_str); } + } else { + nas_log->error("Not handling IPV6 or IPV4V6\n"); + pool->deallocate(pdu); + return; + } + eps_bearer_id = act_def_eps_bearer_context_req.eps_bearer_id; + if (act_def_eps_bearer_context_req.transaction_id_present) { + transaction_id = act_def_eps_bearer_context_req.proc_transaction_id; + } - //FIXME: Handle the following parameters + //FIXME: Handle the following parameters // act_def_eps_bearer_context_req.eps_qos.qci // act_def_eps_bearer_context_req.eps_qos.br_present // act_def_eps_bearer_context_req.eps_qos.br_ext_present @@ -319,315 +319,315 @@ namespace srsue { // act_def_eps_bearer_context_req.protocol_cnfg_opts_present // act_def_eps_bearer_context_req.connectivity_type_present - // FIXME: Setup the default EPS bearer context - - state = EMM_STATE_REGISTERED; - - // Send EPS bearer context accept and attach complete - count_ul++; - act_def_eps_bearer_context_accept.eps_bearer_id = eps_bearer_id; - act_def_eps_bearer_context_accept.proc_transaction_id = transaction_id; - act_def_eps_bearer_context_accept.protocol_cnfg_opts_present = false; - liblte_mme_pack_activate_default_eps_bearer_context_accept_msg(&act_def_eps_bearer_context_accept, - &attach_complete.esm_msg); - liblte_mme_pack_attach_complete_msg(&attach_complete, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - count_ul, - (LIBLTE_BYTE_MSG_STRUCT *) pdu); - integrity_generate(&k_nas_int[16], - count_ul, - lcid - 1, - SECURITY_DIRECTION_UPLINK, - &pdu->msg[5], - pdu->N_bytes - 5, - &pdu->msg[1]); + // FIXME: Setup the default EPS bearer context - // Instruct RRC to enable capabilities - rrc->enable_capabilities(); + state = EMM_STATE_REGISTERED; - nas_log->info("Sending Attach Complete\n"); - rrc->write_sdu(lcid, pdu); + // Send EPS bearer context accept and attach complete + count_ul++; + act_def_eps_bearer_context_accept.eps_bearer_id = eps_bearer_id; + act_def_eps_bearer_context_accept.proc_transaction_id = transaction_id; + act_def_eps_bearer_context_accept.protocol_cnfg_opts_present = false; + liblte_mme_pack_activate_default_eps_bearer_context_accept_msg(&act_def_eps_bearer_context_accept, + &attach_complete.esm_msg); + liblte_mme_pack_attach_complete_msg(&attach_complete, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, + count_ul, + (LIBLTE_BYTE_MSG_STRUCT *) pdu); + integrity_generate(&k_nas_int[16], + count_ul, + lcid - 1, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); - } else { - nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result); - state = EMM_STATE_DEREGISTERED; - pool->deallocate(pdu); - } - } + // Instruct RRC to enable capabilities + rrc->enable_capabilities(); - void nas::parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu) { - LIBLTE_MME_ATTACH_REJECT_MSG_STRUCT attach_rej; + nas_log->info("Sending Attach Complete\n"); + rrc->write_sdu(lcid, pdu); - liblte_mme_unpack_attach_reject_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &attach_rej); - nas_log->warning("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); - nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); + } else { + nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result); state = EMM_STATE_DEREGISTERED; pool->deallocate(pdu); - // FIXME: Command RRC to release? } +} - void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) { - LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req; - LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_res; +void nas::parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu) { + LIBLTE_MME_ATTACH_REJECT_MSG_STRUCT attach_rej; - nas_log->info("Received Authentication Request\n");; - liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &auth_req); + liblte_mme_unpack_attach_reject_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &attach_rej); + nas_log->warning("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); + nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); + state = EMM_STATE_DEREGISTERED; + pool->deallocate(pdu); + // FIXME: Command RRC to release? +} - // Reuse the pdu for the response message - pdu->reset(); +void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) { + LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req; + LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_res; - // Generate authentication response using RAND, AUTN & KSI-ASME - uint16 mcc, mnc; - mcc = rrc->get_mcc(); - mnc = rrc->get_mnc(); + nas_log->info("Received Authentication Request\n");; + liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &auth_req); - nas_log->info("MCC=%d, MNC=%d\n", mcc, mnc); + // Reuse the pdu for the response message + pdu->reset(); - bool net_valid; - uint8_t res[16]; - usim->generate_authentication_response(auth_req.rand, auth_req.autn, mcc, mnc, &net_valid, res); + // Generate authentication response using RAND, AUTN & KSI-ASME + uint16 mcc, mnc; + mcc = rrc->get_mcc(); + mnc = rrc->get_mnc(); - if (net_valid) { - nas_log->info("Network authentication successful\n"); - for (int i = 0; i < 8; i++) { - auth_res.res[i] = res[i]; - } - liblte_mme_pack_authentication_response_msg(&auth_res, (LIBLTE_BYTE_MSG_STRUCT *) pdu); + nas_log->info("MCC=%d, MNC=%d\n", mcc, mnc); - nas_log->info("Sending Authentication Response\n"); - rrc->write_sdu(lcid, pdu); - } else { - nas_log->warning("Network authentication failure\n"); - nas_log->console("Warning: Network authentication failure\n"); - pool->deallocate(pdu); + bool net_valid; + uint8_t res[16]; + usim->generate_authentication_response(auth_req.rand, auth_req.autn, mcc, mnc, &net_valid, res); + + if (net_valid) { + nas_log->info("Network authentication successful\n"); + for (int i = 0; i < 8; i++) { + auth_res.res[i] = res[i]; } - } + liblte_mme_pack_authentication_response_msg(&auth_res, (LIBLTE_BYTE_MSG_STRUCT *) pdu); - void nas::parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu) { - nas_log->warning("Received Authentication Reject\n"); + nas_log->info("Sending Authentication Response\n"); + rrc->write_sdu(lcid, pdu); + } else { + nas_log->warning("Network authentication failure\n"); + nas_log->console("Warning: Network authentication failure\n"); pool->deallocate(pdu); - state = EMM_STATE_DEREGISTERED; - // FIXME: Command RRC to release? - } - - void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { - nas_log->error("TODO:parse_identity_request\n"); } - - void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) { - bool success; - LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd; - LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; - LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej; - - nas_log->info("Received Security Mode Command\n"); - liblte_mme_unpack_security_mode_command_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &sec_mode_cmd); - - ksi = sec_mode_cmd.nas_ksi.nas_ksi; - cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) sec_mode_cmd.selected_nas_sec_algs.type_of_eea; - integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) sec_mode_cmd.selected_nas_sec_algs.type_of_eia; - // FIXME: Handle nonce_ue, nonce_mme - // FIXME: Currently only handling ciphering EEA0 (null) and integrity EIA1,EIA2 - // FIXME: Use selected_nas_sec_algs to choose correct algos - - nas_log->debug("Security details: ksi=%d, eea=%s, eia=%s\n", - ksi, ciphering_algorithm_id_text[cipher_algo], integrity_algorithm_id_text[integ_algo]); - - - if (CIPHERING_ALGORITHM_ID_EEA0 != cipher_algo || - (INTEGRITY_ALGORITHM_ID_128_EIA2 != integ_algo && - INTEGRITY_ALGORITHM_ID_128_EIA1 != integ_algo) || - sec_mode_cmd.nas_ksi.tsc_flag != LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE) { - sec_mode_rej.emm_cause = LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH; - nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n"); +} + +void nas::parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu) { + nas_log->warning("Received Authentication Reject\n"); + pool->deallocate(pdu); + state = EMM_STATE_DEREGISTERED; + // FIXME: Command RRC to release? +} + +void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { + nas_log->error("TODO:parse_identity_request\n"); +} + +void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) { + bool success; + LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd; + LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; + LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej; + + nas_log->info("Received Security Mode Command\n"); + liblte_mme_unpack_security_mode_command_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &sec_mode_cmd); + + ksi = sec_mode_cmd.nas_ksi.nas_ksi; + cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) sec_mode_cmd.selected_nas_sec_algs.type_of_eea; + integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) sec_mode_cmd.selected_nas_sec_algs.type_of_eia; + // FIXME: Handle nonce_ue, nonce_mme + // FIXME: Currently only handling ciphering EEA0 (null) and integrity EIA1,EIA2 + // FIXME: Use selected_nas_sec_algs to choose correct algos + + nas_log->debug("Security details: ksi=%d, eea=%s, eia=%s\n", + ksi, ciphering_algorithm_id_text[cipher_algo], integrity_algorithm_id_text[integ_algo]); + + + if (CIPHERING_ALGORITHM_ID_EEA0 != cipher_algo || + (INTEGRITY_ALGORITHM_ID_128_EIA2 != integ_algo && + INTEGRITY_ALGORITHM_ID_128_EIA1 != integ_algo) || + sec_mode_cmd.nas_ksi.tsc_flag != LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE) { + sec_mode_rej.emm_cause = LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH; + nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n"); + success = false; + } else { + // Generate NAS encryption key and integrity protection key + usim->generate_nas_keys(k_nas_enc, k_nas_int, cipher_algo, integ_algo); + nas_log->debug_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + nas_log->debug_hex(k_nas_int, 32, "NAS integrity key - k_nas_int"); + + // Check incoming MAC + uint8_t *inMAC = &pdu->msg[1]; + uint8_t genMAC[4]; + integrity_generate(&k_nas_int[16], + count_dl, + lcid - 1, + SECURITY_DIRECTION_DOWNLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + genMAC); + + nas_log->info_hex(inMAC, 4, "Incoming PDU MAC:"); + nas_log->info_hex(genMAC, 4, "Generated PDU MAC:"); + + bool match = true; + for (int i = 0; i < 4; i++) { + if (inMAC[i] != genMAC[i]) { + match = false; + } + } + if (!match) { + sec_mode_rej.emm_cause = LIBLTE_MME_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED; + nas_log->warning("Sending Security Mode Reject due to integrity check failure\n"); success = false; } else { - // Generate NAS encryption key and integrity protection key - usim->generate_nas_keys(k_nas_enc, k_nas_int, cipher_algo, integ_algo); - nas_log->debug_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - nas_log->debug_hex(k_nas_int, 32, "NAS integrity key - k_nas_int"); - - // Check incoming MAC - uint8_t *inMAC = &pdu->msg[1]; - uint8_t genMAC[4]; - integrity_generate(&k_nas_int[16], - count_dl, - lcid - 1, - SECURITY_DIRECTION_DOWNLINK, - &pdu->msg[5], - pdu->N_bytes - 5, - genMAC); - - nas_log->info_hex(inMAC, 4, "Incoming PDU MAC:"); - nas_log->info_hex(genMAC, 4, "Generated PDU MAC:"); - bool match = true; - for (int i = 0; i < 4; i++) { - if (inMAC[i] != genMAC[i]) { - match = false; - } - } - if (!match) { - sec_mode_rej.emm_cause = LIBLTE_MME_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED; - nas_log->warning("Sending Security Mode Reject due to integrity check failure\n"); - success = false; + if (sec_mode_cmd.imeisv_req_present && LIBLTE_MME_IMEISV_REQUESTED == sec_mode_cmd.imeisv_req) { + sec_mode_comp.imeisv_present = true; + sec_mode_comp.imeisv.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_IMEISV; + usim->get_imei_vec(sec_mode_comp.imeisv.imeisv, 15); + sec_mode_comp.imeisv.imeisv[14] = 5; + sec_mode_comp.imeisv.imeisv[15] = 3; } else { - - if (sec_mode_cmd.imeisv_req_present && LIBLTE_MME_IMEISV_REQUESTED == sec_mode_cmd.imeisv_req) { - sec_mode_comp.imeisv_present = true; - sec_mode_comp.imeisv.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_IMEISV; - usim->get_imei_vec(sec_mode_comp.imeisv.imeisv, 15); - sec_mode_comp.imeisv.imeisv[14] = 5; - sec_mode_comp.imeisv.imeisv[15] = 3; - } else { - sec_mode_comp.imeisv_present = false; - } - - // Reuse pdu for response - pdu->reset(); - liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - count_ul, - (LIBLTE_BYTE_MSG_STRUCT *) pdu); - integrity_generate(&k_nas_int[16], - count_ul, - lcid - 1, - SECURITY_DIRECTION_UPLINK, - &pdu->msg[5], - pdu->N_bytes - 5, - &pdu->msg[1]); - nas_log->info("Sending Security Mode Complete nas_count_ul=%d, RB=%s\n", - count_ul, - rb_id_text[lcid]); - success = true; + sec_mode_comp.imeisv_present = false; } - } - if (!success) { // Reuse pdu for response pdu->reset(); - liblte_mme_pack_security_mode_reject_msg(&sec_mode_rej, (LIBLTE_BYTE_MSG_STRUCT *) pdu); + liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, + count_ul, + (LIBLTE_BYTE_MSG_STRUCT *) pdu); + integrity_generate(&k_nas_int[16], + count_ul, + lcid - 1, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); + nas_log->info("Sending Security Mode Complete nas_count_ul=%d, RB=%s\n", + count_ul, + rb_id_text[lcid]); + success = true; } - - rrc->write_sdu(lcid, pdu); - } - - void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) { - nas_log->error("TODO:parse_service_reject\n"); } - void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) { - nas_log->error("TODO:parse_esm_information_request\n"); - } - - void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { - nas_log->error("TODO:parse_emm_information\n"); - } - -/******************************************************************************* - Senders -*******************************************************************************/ - - void nas::send_attach_request() { - LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; - byte_buffer_t *msg = pool_allocate; - u_int32_t i; - - attach_req.eps_attach_type = LIBLTE_MME_EPS_ATTACH_TYPE_EPS_ATTACH; - - for (i = 0; i < 8; i++) { - attach_req.ue_network_cap.eea[i] = false; - attach_req.ue_network_cap.eia[i] = false; - } - attach_req.ue_network_cap.eea[0] = true; // EEA0 supported - attach_req.ue_network_cap.eia[0] = true; // EIA0 supported - attach_req.ue_network_cap.eia[1] = true; // EIA1 supported - attach_req.ue_network_cap.eia[2] = true; // EIA2 supported - - attach_req.ue_network_cap.uea_present = false; // UMTS encryption algos - attach_req.ue_network_cap.uia_present = false; // UMTS integrity algos - - attach_req.ms_network_cap_present = false; // A/Gb mode (2G) or Iu mode (3G) - - attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; - usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); - - // ESM message (PDN connectivity request) for first default bearer - gen_pdn_connectivity_request(&attach_req.esm_msg); - - attach_req.old_p_tmsi_signature_present = false; - attach_req.additional_guti_present = false; - attach_req.last_visited_registered_tai_present = false; - attach_req.drx_param_present = false; - attach_req.ms_network_cap_present = false; - attach_req.old_lai_present = false; - attach_req.tmsi_status_present = false; - attach_req.ms_cm2_present = false; - attach_req.ms_cm3_present = false; - attach_req.supported_codecs_present = false; - attach_req.additional_update_type_present = false; - attach_req.voice_domain_pref_and_ue_usage_setting_present = false; - attach_req.device_properties_present = false; - attach_req.old_guti_type_present = false; - - // Pack the message - liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT *) msg); - - nas_log->info("Sending attach request\n"); - rrc->write_sdu(RB_ID_SRB1, msg); + if (!success) { + // Reuse pdu for response + pdu->reset(); + liblte_mme_pack_security_mode_reject_msg(&sec_mode_rej, (LIBLTE_BYTE_MSG_STRUCT *) pdu); } - void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { - LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; + rrc->write_sdu(lcid, pdu); +} - nas_log->info("Generating PDN Connectivity Request\n"); +void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) { + nas_log->error("TODO:parse_service_reject\n"); +} - // Set the PDN con req parameters - pdn_con_req.eps_bearer_id = 0x00; // Unassigned bearer ID - pdn_con_req.proc_transaction_id = 0x01; // First transaction ID - pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4; - pdn_con_req.request_type = LIBLTE_MME_REQUEST_TYPE_INITIAL_REQUEST; +void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) { + nas_log->error("TODO:parse_esm_information_request\n"); +} - // Set the optional flags - pdn_con_req.esm_info_transfer_flag_present = false; //FIXME: Check if this is needed - pdn_con_req.apn_present = false; - pdn_con_req.protocol_cnfg_opts_present = false; - pdn_con_req.device_properties_present = false; +void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { + nas_log->error("TODO:parse_emm_information\n"); +} - // Pack the message - liblte_mme_pack_pdn_connectivity_request_msg(&pdn_con_req, msg); - } - - void nas::send_identity_response() {} +/******************************************************************************* +Senders +*******************************************************************************/ - void nas::send_service_request() { - byte_buffer_t *msg = pool_allocate; - count_ul++; +void nas::send_attach_request() { + LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; + byte_buffer_t *msg = pool_allocate; + u_int32_t i; - // Pack the service request message directly - msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); - msg->N_bytes++; - msg->msg[1] = (ksi & 0x07) << 5; - msg->msg[1] |= count_ul & 0x1F; - msg->N_bytes++; + attach_req.eps_attach_type = LIBLTE_MME_EPS_ATTACH_TYPE_EPS_ATTACH; - uint8_t mac[4]; - integrity_generate(&k_nas_int[16], - count_ul, - RB_ID_SRB1 - 1, - SECURITY_DIRECTION_UPLINK, - &msg->msg[0], - 2, - &mac[0]); - // Set the short MAC - msg->msg[2] = mac[2]; - msg->N_bytes++; - msg->msg[3] = mac[3]; - msg->N_bytes++; - nas_log->info("Sending service request\n"); - rrc->write_sdu(RB_ID_SRB1, msg); + for (i = 0; i < 8; i++) { + attach_req.ue_network_cap.eea[i] = false; + attach_req.ue_network_cap.eia[i] = false; } - - void nas::send_esm_information_response() {} + attach_req.ue_network_cap.eea[0] = true; // EEA0 supported + attach_req.ue_network_cap.eia[0] = true; // EIA0 supported + attach_req.ue_network_cap.eia[1] = true; // EIA1 supported + attach_req.ue_network_cap.eia[2] = true; // EIA2 supported + + attach_req.ue_network_cap.uea_present = false; // UMTS encryption algos + attach_req.ue_network_cap.uia_present = false; // UMTS integrity algos + + attach_req.ms_network_cap_present = false; // A/Gb mode (2G) or Iu mode (3G) + + attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; + usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); + + // ESM message (PDN connectivity request) for first default bearer + gen_pdn_connectivity_request(&attach_req.esm_msg); + + attach_req.old_p_tmsi_signature_present = false; + attach_req.additional_guti_present = false; + attach_req.last_visited_registered_tai_present = false; + attach_req.drx_param_present = false; + attach_req.ms_network_cap_present = false; + attach_req.old_lai_present = false; + attach_req.tmsi_status_present = false; + attach_req.ms_cm2_present = false; + attach_req.ms_cm3_present = false; + attach_req.supported_codecs_present = false; + attach_req.additional_update_type_present = false; + attach_req.voice_domain_pref_and_ue_usage_setting_present = false; + attach_req.device_properties_present = false; + attach_req.old_guti_type_present = false; + + // Pack the message + liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT *) msg); + + nas_log->info("Sending attach request\n"); + rrc->write_sdu(RB_ID_SRB1, msg); +} + +void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { + LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; + + nas_log->info("Generating PDN Connectivity Request\n"); + + // Set the PDN con req parameters + pdn_con_req.eps_bearer_id = 0x00; // Unassigned bearer ID + pdn_con_req.proc_transaction_id = 0x01; // First transaction ID + pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4; + pdn_con_req.request_type = LIBLTE_MME_REQUEST_TYPE_INITIAL_REQUEST; + + // Set the optional flags + pdn_con_req.esm_info_transfer_flag_present = false; //FIXME: Check if this is needed + pdn_con_req.apn_present = false; + pdn_con_req.protocol_cnfg_opts_present = false; + pdn_con_req.device_properties_present = false; + + // Pack the message + liblte_mme_pack_pdn_connectivity_request_msg(&pdn_con_req, msg); +} + +void nas::send_identity_response() {} + +void nas::send_service_request() { + byte_buffer_t *msg = pool_allocate; + count_ul++; + + // Pack the service request message directly + msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); + msg->N_bytes++; + msg->msg[1] = (ksi & 0x07) << 5; + msg->msg[1] |= count_ul & 0x1F; + msg->N_bytes++; + + uint8_t mac[4]; + integrity_generate(&k_nas_int[16], + count_ul, + RB_ID_SRB1 - 1, + SECURITY_DIRECTION_UPLINK, + &msg->msg[0], + 2, + &mac[0]); + // Set the short MAC + msg->msg[2] = mac[2]; + msg->N_bytes++; + msg->msg[3] = mac[3]; + msg->N_bytes++; + nas_log->info("Sending service request\n"); + rrc->write_sdu(RB_ID_SRB1, msg); +} + +void nas::send_esm_information_response() {} } // namespace srsue diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 3e8bfcab8..81577cce4 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -46,388 +46,388 @@ namespace srsue { Base functions *******************************************************************************/ - rrc::rrc() - : state(RRC_STATE_IDLE), drb_up(false) {} - - static void liblte_rrc_handler(void *ctx, char *str) { - rrc *r = (rrc *) ctx; - r->liblte_rrc_log(str); - } - - void rrc::liblte_rrc_log(char *str) { - if (rrc_log) { - rrc_log->warning("[ASN]: %s\n", str); - } else { - printf("[ASN]: %s\n", str); - } - } - - void rrc::init(phy_interface_rrc *phy_, - mac_interface_rrc *mac_, - rlc_interface_rrc *rlc_, - pdcp_interface_rrc *pdcp_, - nas_interface_rrc *nas_, - usim_interface_rrc *usim_, - mac_interface_timers *mac_timers_, - srslte::log *rrc_log_) { - pool = byte_buffer_pool::get_instance(); - phy = phy_; - mac = mac_; - rlc = rlc_; - pdcp = pdcp_; - nas = nas_; - usim = usim_; - rrc_log = rrc_log_; - mac_timers = mac_timers_; - state = RRC_STATE_IDLE; - si_acquire_state = SI_ACQUIRE_IDLE; - - thread_running = true; - start(); - - pthread_mutex_init(&mutex, NULL); - - ue_category = SRSLTE_UE_CATEGORY; - - transaction_id = 0; - - // Register logging handler with liblte_rrc - liblte_rrc_log_register_handler(this, liblte_rrc_handler); - - // Set default values for all layers - set_rrc_default(); - set_phy_default(); - set_mac_default(); - } - - void rrc::stop() { - thread_running = false; - wait_thread_finish(); +rrc::rrc() + : state(RRC_STATE_IDLE), drb_up(false) {} + +static void liblte_rrc_handler(void *ctx, char *str) { + rrc *r = (rrc *) ctx; + r->liblte_rrc_log(str); +} + +void rrc::liblte_rrc_log(char *str) { + if (rrc_log) { + rrc_log->warning("[ASN]: %s\n", str); + } else { + printf("[ASN]: %s\n", str); } - - rrc_state_t rrc::get_state() { - return state; - } - - void rrc::set_ue_category(int category) { - if (category >= 1 && category <= 5) { - ue_category = category; - } else { - rrc_log->error("Unsupported UE category %d\n", category); - } +} + +void rrc::init(phy_interface_rrc *phy_, + mac_interface_rrc *mac_, + rlc_interface_rrc *rlc_, + pdcp_interface_rrc *pdcp_, + nas_interface_rrc *nas_, + usim_interface_rrc *usim_, + mac_interface_timers *mac_timers_, + srslte::log *rrc_log_) { + pool = byte_buffer_pool::get_instance(); + phy = phy_; + mac = mac_; + rlc = rlc_; + pdcp = pdcp_; + nas = nas_; + usim = usim_; + rrc_log = rrc_log_; + mac_timers = mac_timers_; + state = RRC_STATE_IDLE; + si_acquire_state = SI_ACQUIRE_IDLE; + + thread_running = true; + start(); + + pthread_mutex_init(&mutex, NULL); + + ue_category = SRSLTE_UE_CATEGORY; + + transaction_id = 0; + + // Register logging handler with liblte_rrc + liblte_rrc_log_register_handler(this, liblte_rrc_handler); + + // Set default values for all layers + set_rrc_default(); + set_phy_default(); + set_mac_default(); +} + +void rrc::stop() { + thread_running = false; + wait_thread_finish(); +} + +rrc_state_t rrc::get_state() { + return state; +} + +void rrc::set_ue_category(int category) { + if (category >= 1 && category <= 5) { + ue_category = category; + } else { + rrc_log->error("Unsupported UE category %d\n", category); } +} /******************************************************************************* - * - * - * - * PLMN selection, cell selection/reselection and acquisition of SI procedures - * - * - * +* +* +* +* PLMN selection, cell selection/reselection and acquisition of SI procedures +* +* +* *******************************************************************************/ /******************************************************************************* - NAS interface +NAS interface *******************************************************************************/ - uint16_t rrc::get_mcc() { - if (current_cell) { - if (current_cell->sib1.N_plmn_ids > 0) { - return current_cell->sib1.plmn_id[0].id.mcc; - } +uint16_t rrc::get_mcc() { + if (current_cell) { + if (current_cell->sib1.N_plmn_ids > 0) { + return current_cell->sib1.plmn_id[0].id.mcc; } - return 0; } + return 0; +} - uint16_t rrc::get_mnc() { - if (current_cell) { - if (current_cell->sib1.N_plmn_ids > 0) { - return current_cell->sib1.plmn_id[0].id.mnc; - } +uint16_t rrc::get_mnc() { + if (current_cell) { + if (current_cell->sib1.N_plmn_ids > 0) { + return current_cell->sib1.plmn_id[0].id.mnc; } - return 0; } + return 0; +} - void rrc::plmn_search() { - rrc_log->info("Starting PLMN search procedure\n"); - state = RRC_STATE_PLMN_SELECTION; - phy->cell_search_start(); - } +void rrc::plmn_search() { + rrc_log->info("Starting PLMN search procedure\n"); + state = RRC_STATE_PLMN_SELECTION; + phy->cell_search_start(); +} - void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { - rrc_log->info("PLMN %s selected\n", plmn_id_to_c_str(plmn_id).c_str()); +void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { + rrc_log->info("PLMN %s selected\n", plmn_id_to_c_str(plmn_id).c_str()); - state = RRC_STATE_CELL_SELECTING; + state = RRC_STATE_CELL_SELECTING; - // Sort cells according to RSRP + // Sort cells according to RSRP - selected_plmn_id = plmn_id; - last_selected_cell = -1; + selected_plmn_id = plmn_id; + last_selected_cell = -1; - select_next_cell_in_plmn(); - } + select_next_cell_in_plmn(); +} - void rrc::connect() { - pthread_mutex_lock(&mutex); - if (RRC_STATE_CELL_SELECTED == state) { - rrc_log->info("RRC in IDLE state - sending connection request.\n"); - state = RRC_STATE_CONNECTING; - send_con_request(); - } else { - rrc_log->warning("Received connect() but cell is not selected\n"); - } - pthread_mutex_unlock(&mutex); +void rrc::connect() { + pthread_mutex_lock(&mutex); + if (RRC_STATE_CELL_SELECTED == state) { + rrc_log->info("RRC in IDLE state - sending connection request.\n"); + state = RRC_STATE_CONNECTING; + send_con_request(); + } else { + rrc_log->warning("Received connect() but cell is not selected\n"); } - - void rrc::select_next_cell_in_plmn() { - for (uint32_t i = last_selected_cell + 1; i < known_cells.size(); i++) { - for (uint32_t j = 0; j < known_cells[i].sib1.N_plmn_ids; j++) { - if (known_cells[i].sib1.plmn_id[j].id.mcc == selected_plmn_id.mcc || - known_cells[i].sib1.plmn_id[j].id.mnc == selected_plmn_id.mnc) { - rrc_log->info("Selecting cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - known_cells[i].phy_cell.id, known_cells[i].earfcn, - known_cells[i].sib1.cell_id); - rrc_log->console("Selecting cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - known_cells[i].phy_cell.id, known_cells[i].earfcn, - known_cells[i].sib1.cell_id); - // Check that cell satisfies S criteria - if (phy->cell_select(known_cells[i].earfcn, known_cells[i].phy_cell)) { - // Give time to the PHY to sync on the new cell - int cnt=0; - while(!phy->sync_status() && cnt<100) { - usleep(1000); - cnt++; - } - if (phy->sync_status()) { - if (!known_cells[i].has_valid_sib1) { - si_acquire_state = SI_ACQUIRE_SIB1; - } else if (!known_cells[i].has_valid_sib2) { - si_acquire_state = SI_ACQUIRE_SIB2; - } else { - si_acquire_state = SI_ACQUIRE_IDLE; - } - last_selected_cell = i; + pthread_mutex_unlock(&mutex); +} + +void rrc::select_next_cell_in_plmn() { + for (uint32_t i = last_selected_cell + 1; i < known_cells.size(); i++) { + for (uint32_t j = 0; j < known_cells[i].sib1.N_plmn_ids; j++) { + if (known_cells[i].sib1.plmn_id[j].id.mcc == selected_plmn_id.mcc || + known_cells[i].sib1.plmn_id[j].id.mnc == selected_plmn_id.mnc) { + rrc_log->info("Selecting cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + known_cells[i].phy_cell.id, known_cells[i].earfcn, + known_cells[i].sib1.cell_id); + rrc_log->console("Selecting cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + known_cells[i].phy_cell.id, known_cells[i].earfcn, + known_cells[i].sib1.cell_id); + // Check that cell satisfies S criteria + if (phy->cell_select(known_cells[i].earfcn, known_cells[i].phy_cell)) { + // Give time to the PHY to sync on the new cell + int cnt=0; + while(!phy->sync_status() && cnt<100) { + usleep(1000); + cnt++; + } + if (phy->sync_status()) { + if (!known_cells[i].has_valid_sib1) { + si_acquire_state = SI_ACQUIRE_SIB1; + } else if (!known_cells[i].has_valid_sib2) { + si_acquire_state = SI_ACQUIRE_SIB2; } else { - rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x: Could not synchronize\n", - known_cells[i].earfcn, known_cells[i].sib1.cell_id); + si_acquire_state = SI_ACQUIRE_IDLE; } - return; + last_selected_cell = i; } else { - rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", + rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x: Could not synchronize\n", known_cells[i].earfcn, known_cells[i].sib1.cell_id); } + return; + } else { + rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", + known_cells[i].earfcn, known_cells[i].sib1.cell_id); } } } } +} /******************************************************************************* - PHY interface +PHY interface *******************************************************************************/ - void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { +void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { - // find if cell_id-earfcn combination already exists - for (uint32_t i = 0; i < known_cells.size(); i++) { - if (earfcn == known_cells[i].earfcn && phy_cell.id == known_cells[i].phy_cell.id) { - known_cells[i].rsrp = rsrp; - current_cell = &known_cells[i]; - rrc_log->info("Updating cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", known_cells[i].earfcn, - known_cells[i].phy_cell.id, known_cells[i].rsrp); - return; - } + // find if cell_id-earfcn combination already exists + for (uint32_t i = 0; i < known_cells.size(); i++) { + if (earfcn == known_cells[i].earfcn && phy_cell.id == known_cells[i].phy_cell.id) { + known_cells[i].rsrp = rsrp; + current_cell = &known_cells[i]; + rrc_log->info("Updating cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", known_cells[i].earfcn, + known_cells[i].phy_cell.id, known_cells[i].rsrp); + return; } - // add to list of known cells - cell_t cell; - cell.phy_cell = phy_cell; - cell.rsrp = rsrp; - cell.earfcn = earfcn; - cell.has_valid_sib1 = false; - cell.has_valid_sib2 = false; - known_cells.push_back(cell); + } + // add to list of known cells + cell_t cell; + cell.phy_cell = phy_cell; + cell.rsrp = rsrp; + cell.earfcn = earfcn; + cell.has_valid_sib1 = false; + cell.has_valid_sib2 = false; + known_cells.push_back(cell); - // save current cell - current_cell = &known_cells.back(); + // save current cell + current_cell = &known_cells.back(); - si_acquire_state = SI_ACQUIRE_SIB1; + si_acquire_state = SI_ACQUIRE_SIB1; - rrc_log->info("Found Cell: PCI=%d, PRB=%d, Ports=%d, EARFCN=%d, RSRP=%.1f dBm\n", - cell.phy_cell.id, cell.phy_cell.nof_prb, cell.phy_cell.nof_ports, - cell.earfcn, cell.rsrp); + rrc_log->info("Found Cell: PCI=%d, PRB=%d, Ports=%d, EARFCN=%d, RSRP=%.1f dBm\n", + cell.phy_cell.id, cell.phy_cell.nof_prb, cell.phy_cell.nof_ports, + cell.earfcn, cell.rsrp); - rrc_log->console("Found Cell: PCI=%d, PRB=%d, Ports=%d, EARFCN=%d, RSRP=%.1f dBm\n", - cell.phy_cell.id, cell.phy_cell.nof_prb, cell.phy_cell.nof_ports, - cell.earfcn, cell.rsrp); + rrc_log->console("Found Cell: PCI=%d, PRB=%d, Ports=%d, EARFCN=%d, RSRP=%.1f dBm\n", + cell.phy_cell.id, cell.phy_cell.nof_prb, cell.phy_cell.nof_ports, + cell.earfcn, cell.rsrp); - } +} // Detection of physical layer problems (5.3.11.1) - void rrc::out_of_sync() { - if (!mac_timers->get(t311)->is_running() && !mac_timers->get(t310)->is_running()) { - n310_cnt++; - if (n310_cnt == N310) { - mac_timers->get(t310)->reset(); - mac_timers->get(t310)->run(); - n310_cnt = 0; - rrc_log->info("Detected %d out-of-sync from PHY. Starting T310 timer\n", N310); - } +void rrc::out_of_sync() { + if (!mac_timers->get(t311)->is_running() && !mac_timers->get(t310)->is_running()) { + n310_cnt++; + if (n310_cnt == N310) { + mac_timers->get(t310)->reset(); + mac_timers->get(t310)->run(); + n310_cnt = 0; + rrc_log->info("Detected %d out-of-sync from PHY. Starting T310 timer\n", N310); } } +} // Recovery of physical layer problems (5.3.11.2) - void rrc::in_sync() { - if (mac_timers->get(t310)->is_running()) { - n311_cnt++; - if (n311_cnt == N311) { - mac_timers->get(t310)->stop(); - n311_cnt = 0; - rrc_log->info("Detected %d in-sync from PHY. Stopping T310 timer\n", N311); - } +void rrc::in_sync() { + if (mac_timers->get(t310)->is_running()) { + n311_cnt++; + if (n311_cnt == N311) { + mac_timers->get(t310)->stop(); + n311_cnt = 0; + rrc_log->info("Detected %d in-sync from PHY. Stopping T310 timer\n", N311); } } +} /******************************************************************************* - PDCP interface +PDCP interface *******************************************************************************/ - void rrc::write_pdu_bcch_bch(byte_buffer_t *pdu) { - pool->deallocate(pdu); - if (state == RRC_STATE_PLMN_SELECTION) { - // Do we need to do something with BCH? - rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); - } else { - rrc_log->warning("Received BCCH BCH in incorrect state\n"); - } +void rrc::write_pdu_bcch_bch(byte_buffer_t *pdu) { + pool->deallocate(pdu); + if (state == RRC_STATE_PLMN_SELECTION) { + // Do we need to do something with BCH? + rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); + } else { + rrc_log->warning("Received BCCH BCH in incorrect state\n"); } +} - void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { - rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH DLSCH message received."); - rrc_log->info("BCCH DLSCH message Stack latency: %ld us\n", pdu->get_latency_us()); - LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT dlsch_msg; - srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); - bit_buf.N_bits = pdu->N_bytes * 8; - pool->deallocate(pdu); - liblte_rrc_unpack_bcch_dlsch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dlsch_msg); - - if (dlsch_msg.N_sibs > 0) { - if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1 == dlsch_msg.sibs[0].sib_type && SI_ACQUIRE_SIB1 == si_acquire_state) { - mac->bcch_stop_rx(); +void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { + rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH DLSCH message received."); + rrc_log->info("BCCH DLSCH message Stack latency: %ld us\n", pdu->get_latency_us()); + LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT dlsch_msg; + srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); + bit_buf.N_bits = pdu->N_bytes * 8; + pool->deallocate(pdu); + liblte_rrc_unpack_bcch_dlsch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dlsch_msg); - // Handle SIB1 - memcpy(¤t_cell->sib1, &dlsch_msg.sibs[0].sib.sib1, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT)); + if (dlsch_msg.N_sibs > 0) { + if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1 == dlsch_msg.sibs[0].sib_type && SI_ACQUIRE_SIB1 == si_acquire_state) { + mac->bcch_stop_rx(); - rrc_log->info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d\n", - current_cell->sib1.cell_id & 0xfff, - liblte_rrc_si_window_length_num[current_cell->sib1.si_window_length], - liblte_rrc_si_periodicity_num[current_cell->sib1.sched_info[0].si_periodicity]); + // Handle SIB1 + memcpy(¤t_cell->sib1, &dlsch_msg.sibs[0].sib.sib1, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT)); + rrc_log->info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d\n", + current_cell->sib1.cell_id & 0xfff, + liblte_rrc_si_window_length_num[current_cell->sib1.si_window_length], + liblte_rrc_si_periodicity_num[current_cell->sib1.sched_info[0].si_periodicity]); - // Set TDD Config - if (current_cell->sib1.tdd) { - phy->set_config_tdd(¤t_cell->sib1.tdd_cnfg); - } - current_cell->has_valid_sib1 = true; + // Set TDD Config + if (current_cell->sib1.tdd) { + phy->set_config_tdd(¤t_cell->sib1.tdd_cnfg); + } - // Jump to next state - switch(state) { - case RRC_STATE_CELL_SELECTING: - si_acquire_state = SI_ACQUIRE_SIB2; - break; - case RRC_STATE_PLMN_SELECTION: - si_acquire_state = SI_ACQUIRE_IDLE; - rrc_log->info("SI Acquisition done. Searching next cell...\n"); - usleep(5000); - phy->cell_search_next(); - break; - default: - si_acquire_state = SI_ACQUIRE_IDLE; - } + current_cell->has_valid_sib1 = true; - // Send PLMN and TAC to NAS - std::stringstream ss; - for (uint32_t i = 0; i < current_cell->sib1.N_plmn_ids; i++) { - nas->plmn_found(current_cell->sib1.plmn_id[i].id, current_cell->sib1.tracking_area_code); - } + // Jump to next state + switch(state) { + case RRC_STATE_CELL_SELECTING: + si_acquire_state = SI_ACQUIRE_SIB2; + break; + case RRC_STATE_PLMN_SELECTION: + si_acquire_state = SI_ACQUIRE_IDLE; + rrc_log->info("SI Acquisition done. Searching next cell...\n"); + usleep(5000); + phy->cell_search_next(); + break; + default: + si_acquire_state = SI_ACQUIRE_IDLE; + } - } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2 == dlsch_msg.sibs[0].sib_type && - SI_ACQUIRE_SIB2 == si_acquire_state) { - mac->bcch_stop_rx(); + // Send PLMN and TAC to NAS + std::stringstream ss; + for (uint32_t i = 0; i < current_cell->sib1.N_plmn_ids; i++) { + nas->plmn_found(current_cell->sib1.plmn_id[i].id, current_cell->sib1.tracking_area_code); + } - // Handle SIB2 - memcpy(¤t_cell->sib2, &dlsch_msg.sibs[0].sib.sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); - rrc_log->info("SIB2 received\n"); + } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2 == dlsch_msg.sibs[0].sib_type && + SI_ACQUIRE_SIB2 == si_acquire_state) { + mac->bcch_stop_rx(); - apply_sib2_configs(¤t_cell->sib2); + // Handle SIB2 + memcpy(¤t_cell->sib2, &dlsch_msg.sibs[0].sib.sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); + rrc_log->info("SIB2 received\n"); - current_cell->has_valid_sib2 = true; + apply_sib2_configs(¤t_cell->sib2); - // Jump to next state - switch(state) { - case RRC_STATE_CELL_SELECTING: - si_acquire_state = SI_ACQUIRE_IDLE; - state = RRC_STATE_CELL_SELECTED; - nas->cell_selected(); - break; - default: - si_acquire_state = SI_ACQUIRE_IDLE; - } + current_cell->has_valid_sib2 = true; + // Jump to next state + switch(state) { + case RRC_STATE_CELL_SELECTING: + si_acquire_state = SI_ACQUIRE_IDLE; + state = RRC_STATE_CELL_SELECTED; + nas->cell_selected(); + break; + default: + si_acquire_state = SI_ACQUIRE_IDLE; } + } } +} // Right now, this thread only controls System Information acquisition procedure - void rrc::run_thread() { - uint32_t tti; - uint32_t si_win_start, si_win_len; - uint16_t period; - uint32_t nof_sib1_trials = 0; - const int SIB1_SEARCH_TIMEOUT = 30; - - while (thread_running) { - switch (si_acquire_state) { - case SI_ACQUIRE_SIB1: - // Instruct MAC to look for SIB1 - tti = mac->get_current_tti(); - si_win_start = sib_start_tti(tti, 2, 5); - mac->bcch_start_rx(si_win_start, 1); - rrc_log->debug("Instructed MAC to search for SIB1, win_start=%d, win_len=%d\n", - si_win_start, 1); - nof_sib1_trials++; - if (nof_sib1_trials >= SIB1_SEARCH_TIMEOUT) { - if (state == RRC_STATE_CELL_SELECTING) { - select_next_cell_in_plmn(); - si_acquire_state = SI_ACQUIRE_IDLE; - } else if (state == RRC_STATE_PLMN_SELECTION) { - phy->cell_search_next(); - } - nof_sib1_trials = 0; +void rrc::run_thread() { + uint32_t tti; + uint32_t si_win_start, si_win_len; + uint16_t period; + uint32_t nof_sib1_trials = 0; + const int SIB1_SEARCH_TIMEOUT = 30; + + while (thread_running) { + switch (si_acquire_state) { + case SI_ACQUIRE_SIB1: + // Instruct MAC to look for SIB1 + tti = mac->get_current_tti(); + si_win_start = sib_start_tti(tti, 2, 5); + mac->bcch_start_rx(si_win_start, 1); + rrc_log->debug("Instructed MAC to search for SIB1, win_start=%d, win_len=%d\n", + si_win_start, 1); + nof_sib1_trials++; + if (nof_sib1_trials >= SIB1_SEARCH_TIMEOUT) { + if (state == RRC_STATE_CELL_SELECTING) { + select_next_cell_in_plmn(); + si_acquire_state = SI_ACQUIRE_IDLE; + } else if (state == RRC_STATE_PLMN_SELECTION) { + phy->cell_search_next(); } - usleep(20000); - break; - case SI_ACQUIRE_SIB2: - // Instruct MAC to look for SIB2 only when selecting a cell - tti = mac->get_current_tti(); - period = liblte_rrc_si_periodicity_num[current_cell->sib1.sched_info[0].si_periodicity]; - si_win_start = sib_start_tti(tti, period, 0); - si_win_len = liblte_rrc_si_window_length_num[current_cell->sib1.si_window_length]; - - mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->debug("Instructed MAC to search for SIB2, win_start=%d, win_len=%d\n", - si_win_start, si_win_len); - usleep(current_cell->sib1.si_window_length*1000); - break; - default: - break; - } - usleep(10000); + nof_sib1_trials = 0; + } + usleep(20000); + break; + case SI_ACQUIRE_SIB2: + // Instruct MAC to look for SIB2 only when selecting a cell + tti = mac->get_current_tti(); + period = liblte_rrc_si_periodicity_num[current_cell->sib1.sched_info[0].si_periodicity]; + si_win_start = sib_start_tti(tti, period, 0); + si_win_len = liblte_rrc_si_window_length_num[current_cell->sib1.si_window_length]; + + mac->bcch_start_rx(si_win_start, si_win_len); + rrc_log->debug("Instructed MAC to search for SIB2, win_start=%d, win_len=%d\n", + si_win_start, si_win_len); + usleep(current_cell->sib1.si_window_length*1000); + break; + default: + break; } + usleep(10000); } +} @@ -448,13 +448,13 @@ namespace srsue { /******************************************************************************* - * - * - * - * Connection control and establishment/reestablishment procedures - * - * - * +* +* +* +* Connection control and establishment/reestablishment procedures +* +* +* *******************************************************************************/ @@ -463,1135 +463,1135 @@ namespace srsue { /******************************************************************************* - NAS interface +NAS interface *******************************************************************************/ - void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", rb_id_text[lcid]); - - switch (state) { - case RRC_STATE_CONNECTING: - send_con_setup_complete(sdu); - break; - case RRC_STATE_CONNECTED: - send_ul_info_transfer(lcid, sdu); - break; - default: - rrc_log->error("SDU received from NAS while RRC state = %s", rrc_state_text[state]); - break; - } +void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { + rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", rb_id_text[lcid]); + + switch (state) { + case RRC_STATE_CONNECTING: + send_con_setup_complete(sdu); + break; + case RRC_STATE_CONNECTED: + send_ul_info_transfer(lcid, sdu); + break; + default: + rrc_log->error("SDU received from NAS while RRC state = %s", rrc_state_text[state]); + break; } +} /******************************************************************************* - MAC interface +MAC interface *******************************************************************************/ /* Reception of PUCCH/SRS release procedure (Section 5.3.13) */ - void rrc::release_pucch_srs() { - // Apply default configuration for PUCCH (CQI and SR) and SRS (release) - set_phy_default_pucch_srs(); +void rrc::release_pucch_srs() { + // Apply default configuration for PUCCH (CQI and SR) and SRS (release) + set_phy_default_pucch_srs(); - // Configure RX signals without pregeneration because default option is release - phy->configure_ul_params(true); - } + // Configure RX signals without pregeneration because default option is release + phy->configure_ul_params(true); +} - void rrc::ra_problem() { - radio_link_failure(); - } +void rrc::ra_problem() { + radio_link_failure(); +} /******************************************************************************* - GW interface +GW interface *******************************************************************************/ - bool rrc::is_connected() { - return (RRC_STATE_CONNECTED == state); - } +bool rrc::is_connected() { + return (RRC_STATE_CONNECTED == state); +} - bool rrc::have_drb() { - return drb_up; - } +bool rrc::have_drb() { + return drb_up; +} /******************************************************************************* - PDCP interface +PDCP interface *******************************************************************************/ - void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", rb_id_text[lcid]); - rrc_log->info("TX PDU Stack latency: %ld us\n", pdu->get_latency_us()); - - switch (lcid) { - case RB_ID_SRB0: - parse_dl_ccch(pdu); - break; - case RB_ID_SRB1: - case RB_ID_SRB2: - parse_dl_dcch(lcid, pdu); - break; - default: - rrc_log->error("TX PDU with invalid bearer id: %s", lcid); - break; - } - +void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { + rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", rb_id_text[lcid]); + rrc_log->info("TX PDU Stack latency: %ld us\n", pdu->get_latency_us()); + + switch (lcid) { + case RB_ID_SRB0: + parse_dl_ccch(pdu); + break; + case RB_ID_SRB1: + case RB_ID_SRB2: + parse_dl_dcch(lcid, pdu); + break; + default: + rrc_log->error("TX PDU with invalid bearer id: %s", lcid); + break; } +} - void rrc::write_pdu_pcch(byte_buffer_t *pdu) { - if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) { - rrc_log->info_hex(pdu->msg, pdu->N_bytes, "PCCH message received %d bytes\n", pdu->N_bytes); - rrc_log->info("PCCH message Stack latency: %ld us\n", pdu->get_latency_us()); - rrc_log->console("PCCH message received %d bytes\n", pdu->N_bytes); - LIBLTE_RRC_PCCH_MSG_STRUCT pcch_msg; - srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); - bit_buf.N_bits = pdu->N_bytes * 8; - pool->deallocate(pdu); - liblte_rrc_unpack_pcch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &pcch_msg); +void rrc::write_pdu_pcch(byte_buffer_t *pdu) { + if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) { + rrc_log->info_hex(pdu->msg, pdu->N_bytes, "PCCH message received %d bytes\n", pdu->N_bytes); + rrc_log->info("PCCH message Stack latency: %ld us\n", pdu->get_latency_us()); + rrc_log->console("PCCH message received %d bytes\n", pdu->N_bytes); - if (pcch_msg.paging_record_list_size > LIBLTE_RRC_MAX_PAGE_REC) { - pcch_msg.paging_record_list_size = LIBLTE_RRC_MAX_PAGE_REC; - } + LIBLTE_RRC_PCCH_MSG_STRUCT pcch_msg; + srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); + bit_buf.N_bits = pdu->N_bytes * 8; + pool->deallocate(pdu); + liblte_rrc_unpack_pcch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &pcch_msg); - LIBLTE_RRC_S_TMSI_STRUCT s_tmsi; - if (!nas->get_s_tmsi(&s_tmsi)) { - rrc_log->info("No S-TMSI present in NAS\n"); - return; - } + if (pcch_msg.paging_record_list_size > LIBLTE_RRC_MAX_PAGE_REC) { + pcch_msg.paging_record_list_size = LIBLTE_RRC_MAX_PAGE_REC; + } - LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi_paged; - for (uint32_t i = 0; i < pcch_msg.paging_record_list_size; i++) { - s_tmsi_paged = &pcch_msg.paging_record_list[i].ue_identity.s_tmsi; - rrc_log->info("Received paging (%d/%d) for UE 0x%x\n", i + 1, pcch_msg.paging_record_list_size, - pcch_msg.paging_record_list[i].ue_identity.s_tmsi); - rrc_log->console("Received paging (%d/%d) for UE 0x%x\n", i + 1, pcch_msg.paging_record_list_size, - pcch_msg.paging_record_list[i].ue_identity.s_tmsi); - if (s_tmsi.mmec == s_tmsi_paged->mmec && s_tmsi.m_tmsi == s_tmsi_paged->m_tmsi) { - rrc_log->info("S-TMSI match in paging message\n"); - rrc_log->console("S-TMSI match in paging message\n"); - mac->pcch_stop_rx(); - if (RRC_STATE_IDLE == state) { - rrc_log->info("RRC in IDLE state - sending connection request.\n"); - state = RRC_STATE_CONNECTING; - send_con_request(); - } + LIBLTE_RRC_S_TMSI_STRUCT s_tmsi; + if (!nas->get_s_tmsi(&s_tmsi)) { + rrc_log->info("No S-TMSI present in NAS\n"); + return; + } + + LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi_paged; + for (uint32_t i = 0; i < pcch_msg.paging_record_list_size; i++) { + s_tmsi_paged = &pcch_msg.paging_record_list[i].ue_identity.s_tmsi; + rrc_log->info("Received paging (%d/%d) for UE 0x%x\n", i + 1, pcch_msg.paging_record_list_size, + pcch_msg.paging_record_list[i].ue_identity.s_tmsi); + rrc_log->console("Received paging (%d/%d) for UE 0x%x\n", i + 1, pcch_msg.paging_record_list_size, + pcch_msg.paging_record_list[i].ue_identity.s_tmsi); + if (s_tmsi.mmec == s_tmsi_paged->mmec && s_tmsi.m_tmsi == s_tmsi_paged->m_tmsi) { + rrc_log->info("S-TMSI match in paging message\n"); + rrc_log->console("S-TMSI match in paging message\n"); + mac->pcch_stop_rx(); + if (RRC_STATE_IDLE == state) { + rrc_log->info("RRC in IDLE state - sending connection request.\n"); + state = RRC_STATE_CONNECTING; + send_con_request(); } } } } +} /******************************************************************************* - RLC interface +RLC interface *******************************************************************************/ - void rrc::max_retx_attempted() { - //TODO: Handle the radio link failure - rrc_log->warning("Max RLC reTx attempted\n"); - //radio_link_failure(); - } +void rrc::max_retx_attempted() { + //TODO: Handle the radio link failure + rrc_log->warning("Max RLC reTx attempted\n"); + //radio_link_failure(); +} /******************************************************************************* - Senders +Senders *******************************************************************************/ - void rrc::send_con_request() { - rrc_log->debug("Preparing RRC Connection Request\n"); - LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; - LIBLTE_RRC_S_TMSI_STRUCT s_tmsi; - - // Prepare ConnectionRequest packet - ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ; - if (nas->get_s_tmsi(&s_tmsi)) { - ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_S_TMSI; - ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi = s_tmsi; - } else { - ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE; - ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000; - } - ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; - liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - byte_buffer_t *pdcp_buf = pool_allocate;; - srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); - pdcp_buf->N_bytes = bit_buf.N_bits / 8; - pdcp_buf->set_timestamp(); - - // Set UE contention resolution ID in MAC - uint64_t uecri = 0; - uint8_t *ue_cri_ptr = (uint8_t *) &uecri; - uint32_t nbytes = 6; - for (uint32_t i = 0; i < nbytes; i++) { - ue_cri_ptr[nbytes - i - 1] = pdcp_buf->msg[i]; - } - rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); - - mac->set_contention_id(uecri); - - rrc_log->info("Sending RRC Connection Request on SRB0\n"); - pdcp->write_sdu(RB_ID_SRB0, pdcp_buf); +void rrc::send_con_request() { + rrc_log->debug("Preparing RRC Connection Request\n"); + LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; + LIBLTE_RRC_S_TMSI_STRUCT s_tmsi; + + // Prepare ConnectionRequest packet + ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ; + if (nas->get_s_tmsi(&s_tmsi)) { + ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_S_TMSI; + ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi = s_tmsi; + } else { + ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE; + ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000; } - - -/* RRC connection re-establishment procedure (5.3.7) */ - void rrc::send_con_restablish_request() { - - srslte_cell_t cell; - phy->get_current_cell(&cell); - - LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; - LIBLTE_RRC_S_TMSI_STRUCT s_tmsi; - - // Compute shortMAC-I - uint8_t varShortMAC[128], varShortMAC_packed[16]; - bzero(varShortMAC, 128); - bzero(varShortMAC_packed, 16); - uint8_t *msg_ptr = varShortMAC; - liblte_rrc_pack_cell_identity_ie(0x1a2d0, &msg_ptr); - liblte_rrc_pack_phys_cell_id_ie(cell.id, &msg_ptr); - mac_interface_rrc::ue_rnti_t ue_rnti; - mac->get_rntis(&ue_rnti); - liblte_rrc_pack_c_rnti_ie(ue_rnti.crnti, &msg_ptr); - srslte_bit_pack_vector(varShortMAC, varShortMAC_packed, msg_ptr - varShortMAC); - - uint8_t mac_key[4]; - security_128_eia2(&k_rrc_int[16], - 1, - 1, - 1, - varShortMAC_packed, - 7, - mac_key); - - mac_interface_rrc::ue_rnti_t uernti; - mac->get_rntis(&uernti); - - // Prepare ConnectionRestalishmentRequest packet - ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REEST_REQ; - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti = uernti.crnti; - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.phys_cell_id = cell.id; - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i = mac_key[2] << 8 | mac_key[3]; - ul_ccch_msg.msg.rrc_con_reest_req.cause = LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE; - liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - rrc_log->info("Initiating RRC Connection Reestablishment Procedure\n"); - rrc_log->console("RRC Connection Reestablishment\n"); - mac_timers->get(t310)->stop(); - mac_timers->get(t311)->reset(); - mac_timers->get(t311)->run(); - - set_phy_default(); - mac->reset(); - - // FIXME: Cell selection should be different?? - phy->resync_sfn(); - - // Wait for cell re-synchronization - uint32_t timeout_cnt = 0; - while (!phy->sync_status() && timeout_cnt < TIMEOUT_RESYNC_REESTABLISH) { - usleep(10000); - timeout_cnt++; - } - mac_timers->get(t301)->reset(); - mac_timers->get(t301)->run(); - mac_timers->get(t311)->stop(); - rrc_log->info("Cell Selection finished. Initiating transmission of RRC Connection Reestablishment Request\n"); - - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - byte_buffer_t *pdcp_buf = pool_allocate;; - srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); - pdcp_buf->N_bytes = bit_buf.N_bits / 8; - - // Set UE contention resolution ID in MAC - uint64_t uecri = 0; - uint8_t *ue_cri_ptr = (uint8_t *) &uecri; - uint32_t nbytes = 6; - for (uint32_t i = 0; i < nbytes; i++) { - ue_cri_ptr[nbytes - i - 1] = pdcp_buf->msg[i]; - } - rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); - mac->set_contention_id(uecri); - - rrc_log->info("Sending RRC Connection Resetablishment Request on SRB0\n"); - pdcp->write_sdu(RB_ID_SRB0, pdcp_buf); + ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; + liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); + } + byte_buffer_t *pdcp_buf = pool_allocate;; + srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); + pdcp_buf->N_bytes = bit_buf.N_bits / 8; + pdcp_buf->set_timestamp(); + + // Set UE contention resolution ID in MAC + uint64_t uecri = 0; + uint8_t *ue_cri_ptr = (uint8_t *) &uecri; + uint32_t nbytes = 6; + for (uint32_t i = 0; i < nbytes; i++) { + ue_cri_ptr[nbytes - i - 1] = pdcp_buf->msg[i]; } + rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); + mac->set_contention_id(uecri); - void rrc::send_con_restablish_complete() { - rrc_log->debug("Preparing RRC Connection Reestablishment Complete\n"); - LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + rrc_log->info("Sending RRC Connection Request on SRB0\n"); + pdcp->write_sdu(RB_ID_SRB0, pdcp_buf); +} - // Prepare ConnectionSetupComplete packet - ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_REEST_COMPLETE; - ul_dcch_msg.msg.rrc_con_reest_complete.rrc_transaction_id = transaction_id; - liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - byte_buffer_t *pdcp_buf = pool_allocate;; - srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); - pdcp_buf->N_bytes = bit_buf.N_bits / 8; - - state = RRC_STATE_CONNECTED; - rrc_log->console("RRC Connected\n"); - rrc_log->info("Sending RRC Connection Reestablishment Complete\n"); - pdcp->write_sdu(RB_ID_SRB1, pdcp_buf); +/* RRC connection re-establishment procedure (5.3.7) */ +void rrc::send_con_restablish_request() { + + srslte_cell_t cell; + phy->get_current_cell(&cell); + + LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; + LIBLTE_RRC_S_TMSI_STRUCT s_tmsi; + + // Compute shortMAC-I + uint8_t varShortMAC[128], varShortMAC_packed[16]; + bzero(varShortMAC, 128); + bzero(varShortMAC_packed, 16); + uint8_t *msg_ptr = varShortMAC; + liblte_rrc_pack_cell_identity_ie(0x1a2d0, &msg_ptr); + liblte_rrc_pack_phys_cell_id_ie(cell.id, &msg_ptr); + mac_interface_rrc::ue_rnti_t ue_rnti; + mac->get_rntis(&ue_rnti); + liblte_rrc_pack_c_rnti_ie(ue_rnti.crnti, &msg_ptr); + srslte_bit_pack_vector(varShortMAC, varShortMAC_packed, msg_ptr - varShortMAC); + + uint8_t mac_key[4]; + security_128_eia2(&k_rrc_int[16], + 1, + 1, + 1, + varShortMAC_packed, + 7, + mac_key); + + mac_interface_rrc::ue_rnti_t uernti; + mac->get_rntis(&uernti); + + // Prepare ConnectionRestalishmentRequest packet + ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REEST_REQ; + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti = uernti.crnti; + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.phys_cell_id = cell.id; + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i = mac_key[2] << 8 | mac_key[3]; + ul_ccch_msg.msg.rrc_con_reest_req.cause = LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE; + liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + rrc_log->info("Initiating RRC Connection Reestablishment Procedure\n"); + rrc_log->console("RRC Connection Reestablishment\n"); + mac_timers->get(t310)->stop(); + mac_timers->get(t311)->reset(); + mac_timers->get(t311)->run(); + + set_phy_default(); + mac->reset(); + + // FIXME: Cell selection should be different?? + phy->resync_sfn(); + + // Wait for cell re-synchronization + uint32_t timeout_cnt = 0; + while (!phy->sync_status() && timeout_cnt < TIMEOUT_RESYNC_REESTABLISH) { + usleep(10000); + timeout_cnt++; } - - void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) { - rrc_log->debug("Preparing RRC Connection Setup Complete\n"); - LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; - - // Prepare ConnectionSetupComplete packet - ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_SETUP_COMPLETE; - ul_dcch_msg.msg.rrc_con_setup_complete.registered_mme_present = false; - ul_dcch_msg.msg.rrc_con_setup_complete.rrc_transaction_id = transaction_id; - ul_dcch_msg.msg.rrc_con_setup_complete.selected_plmn_id = 1; - memcpy(ul_dcch_msg.msg.rrc_con_setup_complete.dedicated_info_nas.msg, nas_msg->msg, nas_msg->N_bytes); - ul_dcch_msg.msg.rrc_con_setup_complete.dedicated_info_nas.N_bytes = nas_msg->N_bytes; - liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - byte_buffer_t *pdcp_buf = pool_allocate;; - srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); - pdcp_buf->N_bytes = bit_buf.N_bits / 8; - pdcp_buf->set_timestamp(); - - state = RRC_STATE_CONNECTED; - rrc_log->console("RRC Connected\n"); - rrc_log->info("Sending RRC Connection Setup Complete\n"); - pdcp->write_sdu(RB_ID_SRB1, pdcp_buf); + mac_timers->get(t301)->reset(); + mac_timers->get(t301)->run(); + mac_timers->get(t311)->stop(); + rrc_log->info("Cell Selection finished. Initiating transmission of RRC Connection Reestablishment Request\n"); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); } - - void rrc::send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu) { - rrc_log->debug("Preparing RX Info Transfer\n"); - LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; - - // Prepare RX INFO packet - ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UL_INFO_TRANSFER; - ul_dcch_msg.msg.ul_info_transfer.dedicated_info_type = LIBLTE_RRC_UL_INFORMATION_TRANSFER_TYPE_NAS; - memcpy(ul_dcch_msg.msg.ul_info_transfer.dedicated_info.msg, sdu->msg, sdu->N_bytes); - ul_dcch_msg.msg.ul_info_transfer.dedicated_info.N_bytes = sdu->N_bytes; - liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - // Reset and reuse sdu buffer - byte_buffer_t *pdu = sdu; - pdu->reset(); - - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); - pdu->N_bytes = bit_buf.N_bits / 8; - pdu->set_timestamp(); - pdu->set_timestamp(); - - rrc_log->info("Sending RX Info Transfer\n"); - pdcp->write_sdu(lcid, pdu); + byte_buffer_t *pdcp_buf = pool_allocate;; + srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); + pdcp_buf->N_bytes = bit_buf.N_bits / 8; + + // Set UE contention resolution ID in MAC + uint64_t uecri = 0; + uint8_t *ue_cri_ptr = (uint8_t *) &uecri; + uint32_t nbytes = 6; + for (uint32_t i = 0; i < nbytes; i++) { + ue_cri_ptr[nbytes - i - 1] = pdcp_buf->msg[i]; } + rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); + mac->set_contention_id(uecri); - void rrc::send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu) { - rrc_log->debug("Preparing Security Mode Complete\n"); - LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; - ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_SECURITY_MODE_COMPLETE; - ul_dcch_msg.msg.security_mode_complete.rrc_transaction_id = transaction_id; - liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); - pdu->N_bytes = bit_buf.N_bits / 8; - pdu->set_timestamp(); + rrc_log->info("Sending RRC Connection Resetablishment Request on SRB0\n"); + pdcp->write_sdu(RB_ID_SRB0, pdcp_buf); +} - rrc_log->info("Sending Security Mode Complete\n"); - pdcp->write_sdu(lcid, pdu); - } - void rrc::send_rrc_con_reconfig_complete(uint32_t lcid, byte_buffer_t *pdu) { - rrc_log->debug("Preparing RRC Connection Reconfig Complete\n"); - LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; +void rrc::send_con_restablish_complete() { + rrc_log->debug("Preparing RRC Connection Reestablishment Complete\n"); + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; - ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE; - ul_dcch_msg.msg.rrc_con_reconfig_complete.rrc_transaction_id = transaction_id; - liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + // Prepare ConnectionSetupComplete packet + ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_REEST_COMPLETE; + ul_dcch_msg.msg.rrc_con_reest_complete.rrc_transaction_id = transaction_id; + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); - pdu->N_bytes = bit_buf.N_bits / 8; - pdu->set_timestamp(); - - rrc_log->info("Sending RRC Connection Reconfig Complete\n"); - pdcp->write_sdu(lcid, pdu); + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); } - - void rrc::enable_capabilities() { - bool enable_ul_64 = ue_category >= 5 && current_cell->sib2.rr_config_common_sib.pusch_cnfg.enable_64_qam; - rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); - phy->set_config_64qam_en(enable_ul_64); + byte_buffer_t *pdcp_buf = pool_allocate;; + srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); + pdcp_buf->N_bytes = bit_buf.N_bits / 8; + + state = RRC_STATE_CONNECTED; + rrc_log->console("RRC Connected\n"); + rrc_log->info("Sending RRC Connection Reestablishment Complete\n"); + pdcp->write_sdu(RB_ID_SRB1, pdcp_buf); +} + +void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) { + rrc_log->debug("Preparing RRC Connection Setup Complete\n"); + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + + // Prepare ConnectionSetupComplete packet + ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_SETUP_COMPLETE; + ul_dcch_msg.msg.rrc_con_setup_complete.registered_mme_present = false; + ul_dcch_msg.msg.rrc_con_setup_complete.rrc_transaction_id = transaction_id; + ul_dcch_msg.msg.rrc_con_setup_complete.selected_plmn_id = 1; + memcpy(ul_dcch_msg.msg.rrc_con_setup_complete.dedicated_info_nas.msg, nas_msg->msg, nas_msg->N_bytes); + ul_dcch_msg.msg.rrc_con_setup_complete.dedicated_info_nas.N_bytes = nas_msg->N_bytes; + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); } - - void rrc::send_rrc_ue_cap_info(uint32_t lcid, byte_buffer_t *pdu) { - rrc_log->debug("Preparing UE Capability Info\n"); - LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; - - ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UE_CAPABILITY_INFO; - ul_dcch_msg.msg.ue_capability_info.rrc_transaction_id = transaction_id; - - LIBLTE_RRC_UE_CAPABILITY_INFORMATION_STRUCT *info = &ul_dcch_msg.msg.ue_capability_info; - info->N_ue_caps = 1; - info->ue_capability_rat[0].rat_type = LIBLTE_RRC_RAT_TYPE_EUTRA; - - LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *cap = &info->ue_capability_rat[0].eutra_capability; - cap->access_stratum_release = LIBLTE_RRC_ACCESS_STRATUM_RELEASE_REL8; - cap->ue_category = ue_category; - - cap->pdcp_params.max_rohc_ctxts_present = false; - cap->pdcp_params.supported_rohc_profiles[0] = false; - cap->pdcp_params.supported_rohc_profiles[1] = false; - cap->pdcp_params.supported_rohc_profiles[2] = false; - cap->pdcp_params.supported_rohc_profiles[3] = false; - cap->pdcp_params.supported_rohc_profiles[4] = false; - cap->pdcp_params.supported_rohc_profiles[5] = false; - cap->pdcp_params.supported_rohc_profiles[6] = false; - cap->pdcp_params.supported_rohc_profiles[7] = false; - cap->pdcp_params.supported_rohc_profiles[8] = false; - - cap->phy_params.specific_ref_sigs_supported = false; - cap->phy_params.tx_antenna_selection_supported = false; - - //TODO: Generate this from user input? - cap->rf_params.N_supported_band_eutras = 3; - cap->rf_params.supported_band_eutra[0].band_eutra = 3; - cap->rf_params.supported_band_eutra[0].half_duplex = false; - cap->rf_params.supported_band_eutra[1].band_eutra = 7; - cap->rf_params.supported_band_eutra[1].half_duplex = false; - cap->rf_params.supported_band_eutra[2].band_eutra = 20; - cap->rf_params.supported_band_eutra[2].half_duplex = false; - - cap->meas_params.N_band_list_eutra = 3; - cap->meas_params.band_list_eutra[0].N_inter_freq_need_for_gaps = 3; - cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[0] = true; - cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[1] = true; - cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[2] = true; - cap->meas_params.band_list_eutra[1].N_inter_freq_need_for_gaps = 3; - cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[0] = true; - cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[1] = true; - cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[2] = true; - cap->meas_params.band_list_eutra[2].N_inter_freq_need_for_gaps = 3; - cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[0] = true; - cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[1] = true; - cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[2] = true; - - cap->feature_group_indicator_present = true; - cap->feature_group_indicator = 0x62001000; - cap->inter_rat_params.utra_fdd_present = false; - cap->inter_rat_params.utra_tdd128_present = false; - cap->inter_rat_params.utra_tdd384_present = false; - cap->inter_rat_params.utra_tdd768_present = false; - cap->inter_rat_params.geran_present = false; - cap->inter_rat_params.cdma2000_hrpd_present = false; - cap->inter_rat_params.cdma2000_1xrtt_present = false; - - liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - // Byte align and pack the message bits for PDCP - if ((bit_buf.N_bits % 8) != 0) { - for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) - bit_buf.msg[bit_buf.N_bits + i] = 0; - bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); - } - srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); - pdu->N_bytes = bit_buf.N_bits / 8; - pdu->set_timestamp(); - - rrc_log->info("Sending UE Capability Info\n"); - pdcp->write_sdu(lcid, pdu); + byte_buffer_t *pdcp_buf = pool_allocate;; + srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); + pdcp_buf->N_bytes = bit_buf.N_bits / 8; + pdcp_buf->set_timestamp(); + + state = RRC_STATE_CONNECTED; + rrc_log->console("RRC Connected\n"); + rrc_log->info("Sending RRC Connection Setup Complete\n"); + pdcp->write_sdu(RB_ID_SRB1, pdcp_buf); +} + +void rrc::send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu) { + rrc_log->debug("Preparing RX Info Transfer\n"); + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + + // Prepare RX INFO packet + ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UL_INFO_TRANSFER; + ul_dcch_msg.msg.ul_info_transfer.dedicated_info_type = LIBLTE_RRC_UL_INFORMATION_TRANSFER_TYPE_NAS; + memcpy(ul_dcch_msg.msg.ul_info_transfer.dedicated_info.msg, sdu->msg, sdu->N_bytes); + ul_dcch_msg.msg.ul_info_transfer.dedicated_info.N_bytes = sdu->N_bytes; + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + // Reset and reuse sdu buffer + byte_buffer_t *pdu = sdu; + pdu->reset(); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); + } + srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); + pdu->N_bytes = bit_buf.N_bits / 8; + pdu->set_timestamp(); + pdu->set_timestamp(); + + rrc_log->info("Sending RX Info Transfer\n"); + pdcp->write_sdu(lcid, pdu); +} + +void rrc::send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu) { + rrc_log->debug("Preparing Security Mode Complete\n"); + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_SECURITY_MODE_COMPLETE; + ul_dcch_msg.msg.security_mode_complete.rrc_transaction_id = transaction_id; + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); } + srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); + pdu->N_bytes = bit_buf.N_bits / 8; + pdu->set_timestamp(); + + rrc_log->info("Sending Security Mode Complete\n"); + pdcp->write_sdu(lcid, pdu); +} + +void rrc::send_rrc_con_reconfig_complete(uint32_t lcid, byte_buffer_t *pdu) { + rrc_log->debug("Preparing RRC Connection Reconfig Complete\n"); + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + + ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE; + ul_dcch_msg.msg.rrc_con_reconfig_complete.rrc_transaction_id = transaction_id; + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); + } + srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); + pdu->N_bytes = bit_buf.N_bits / 8; + pdu->set_timestamp(); + + rrc_log->info("Sending RRC Connection Reconfig Complete\n"); + pdcp->write_sdu(lcid, pdu); +} + +void rrc::enable_capabilities() { + bool enable_ul_64 = ue_category >= 5 && current_cell->sib2.rr_config_common_sib.pusch_cnfg.enable_64_qam; + rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); + phy->set_config_64qam_en(enable_ul_64); +} + +void rrc::send_rrc_ue_cap_info(uint32_t lcid, byte_buffer_t *pdu) { + rrc_log->debug("Preparing UE Capability Info\n"); + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + + ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UE_CAPABILITY_INFO; + ul_dcch_msg.msg.ue_capability_info.rrc_transaction_id = transaction_id; + + LIBLTE_RRC_UE_CAPABILITY_INFORMATION_STRUCT *info = &ul_dcch_msg.msg.ue_capability_info; + info->N_ue_caps = 1; + info->ue_capability_rat[0].rat_type = LIBLTE_RRC_RAT_TYPE_EUTRA; + + LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *cap = &info->ue_capability_rat[0].eutra_capability; + cap->access_stratum_release = LIBLTE_RRC_ACCESS_STRATUM_RELEASE_REL8; + cap->ue_category = ue_category; + + cap->pdcp_params.max_rohc_ctxts_present = false; + cap->pdcp_params.supported_rohc_profiles[0] = false; + cap->pdcp_params.supported_rohc_profiles[1] = false; + cap->pdcp_params.supported_rohc_profiles[2] = false; + cap->pdcp_params.supported_rohc_profiles[3] = false; + cap->pdcp_params.supported_rohc_profiles[4] = false; + cap->pdcp_params.supported_rohc_profiles[5] = false; + cap->pdcp_params.supported_rohc_profiles[6] = false; + cap->pdcp_params.supported_rohc_profiles[7] = false; + cap->pdcp_params.supported_rohc_profiles[8] = false; + + cap->phy_params.specific_ref_sigs_supported = false; + cap->phy_params.tx_antenna_selection_supported = false; + + //TODO: Generate this from user input? + cap->rf_params.N_supported_band_eutras = 3; + cap->rf_params.supported_band_eutra[0].band_eutra = 3; + cap->rf_params.supported_band_eutra[0].half_duplex = false; + cap->rf_params.supported_band_eutra[1].band_eutra = 7; + cap->rf_params.supported_band_eutra[1].half_duplex = false; + cap->rf_params.supported_band_eutra[2].band_eutra = 20; + cap->rf_params.supported_band_eutra[2].half_duplex = false; + + cap->meas_params.N_band_list_eutra = 3; + cap->meas_params.band_list_eutra[0].N_inter_freq_need_for_gaps = 3; + cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[0] = true; + cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[1] = true; + cap->meas_params.band_list_eutra[0].inter_freq_need_for_gaps[2] = true; + cap->meas_params.band_list_eutra[1].N_inter_freq_need_for_gaps = 3; + cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[0] = true; + cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[1] = true; + cap->meas_params.band_list_eutra[1].inter_freq_need_for_gaps[2] = true; + cap->meas_params.band_list_eutra[2].N_inter_freq_need_for_gaps = 3; + cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[0] = true; + cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[1] = true; + cap->meas_params.band_list_eutra[2].inter_freq_need_for_gaps[2] = true; + + cap->feature_group_indicator_present = true; + cap->feature_group_indicator = 0x62001000; + cap->inter_rat_params.utra_fdd_present = false; + cap->inter_rat_params.utra_tdd128_present = false; + cap->inter_rat_params.utra_tdd384_present = false; + cap->inter_rat_params.utra_tdd768_present = false; + cap->inter_rat_params.geran_present = false; + cap->inter_rat_params.cdma2000_hrpd_present = false; + cap->inter_rat_params.cdma2000_1xrtt_present = false; + + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); + + // Byte align and pack the message bits for PDCP + if ((bit_buf.N_bits % 8) != 0) { + for (uint32_t i = 0; i < 8 - (bit_buf.N_bits % 8); i++) + bit_buf.msg[bit_buf.N_bits + i] = 0; + bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); + } + srslte_bit_pack_vector(bit_buf.msg, pdu->msg, bit_buf.N_bits); + pdu->N_bytes = bit_buf.N_bits / 8; + pdu->set_timestamp(); + + rrc_log->info("Sending UE Capability Info\n"); + pdcp->write_sdu(lcid, pdu); +} /******************************************************************************* - Parsers +Parsers *******************************************************************************/ - void rrc::parse_dl_ccch(byte_buffer_t *pdu) { - srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); - bit_buf.N_bits = pdu->N_bytes * 8; - pool->deallocate(pdu); - bzero(&dl_ccch_msg, sizeof(LIBLTE_RRC_DL_CCCH_MSG_STRUCT)); - liblte_rrc_unpack_dl_ccch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dl_ccch_msg); - - rrc_log->info("SRB0 - Received %s\n", - liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg.msg_type]); - - switch (dl_ccch_msg.msg_type) { - case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ: - rrc_log->info("Connection Reject received. Wait time: %d\n", - dl_ccch_msg.msg.rrc_con_rej.wait_time); - state = RRC_STATE_IDLE; - break; - case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP: - rrc_log->info("Connection Setup received\n"); - transaction_id = dl_ccch_msg.msg.rrc_con_setup.rrc_transaction_id; - handle_con_setup(&dl_ccch_msg.msg.rrc_con_setup); - rrc_log->info("Notifying NAS of connection setup\n"); - nas->notify_connection_setup(); - break; - case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REEST: - rrc_log->info("Connection Reestablishment received\n"); - rrc_log->console("Reestablishment OK\n"); - transaction_id = dl_ccch_msg.msg.rrc_con_reest.rrc_transaction_id; - handle_con_reest(&dl_ccch_msg.msg.rrc_con_reest); - break; - case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REEST_REJ: - rrc_log->info("Connection Reestablishment Reject received\n"); - rrc_log->console("Reestablishment Reject\n"); - usleep(50000); - rrc_connection_release(); - break; - default: - break; - } +void rrc::parse_dl_ccch(byte_buffer_t *pdu) { + srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); + bit_buf.N_bits = pdu->N_bytes * 8; + pool->deallocate(pdu); + bzero(&dl_ccch_msg, sizeof(LIBLTE_RRC_DL_CCCH_MSG_STRUCT)); + liblte_rrc_unpack_dl_ccch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dl_ccch_msg); + + rrc_log->info("SRB0 - Received %s\n", + liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg.msg_type]); + + switch (dl_ccch_msg.msg_type) { + case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ: + rrc_log->info("Connection Reject received. Wait time: %d\n", + dl_ccch_msg.msg.rrc_con_rej.wait_time); + state = RRC_STATE_IDLE; + break; + case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP: + rrc_log->info("Connection Setup received\n"); + transaction_id = dl_ccch_msg.msg.rrc_con_setup.rrc_transaction_id; + handle_con_setup(&dl_ccch_msg.msg.rrc_con_setup); + rrc_log->info("Notifying NAS of connection setup\n"); + nas->notify_connection_setup(); + break; + case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REEST: + rrc_log->info("Connection Reestablishment received\n"); + rrc_log->console("Reestablishment OK\n"); + transaction_id = dl_ccch_msg.msg.rrc_con_reest.rrc_transaction_id; + handle_con_reest(&dl_ccch_msg.msg.rrc_con_reest); + break; + case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REEST_REJ: + rrc_log->info("Connection Reestablishment Reject received\n"); + rrc_log->console("Reestablishment Reject\n"); + usleep(50000); + rrc_connection_release(); + break; + default: + break; } - - void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { - srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); - bit_buf.N_bits = pdu->N_bytes * 8; - liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dl_dcch_msg); - - rrc_log->info("%s - Received %s\n", - rb_id_text[lcid], - liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); - - // Reset and reuse pdu buffer if possible - pdu->reset(); - - switch (dl_dcch_msg.msg_type) { - case LIBLTE_RRC_DL_DCCH_MSG_TYPE_DL_INFO_TRANSFER: - memcpy(pdu->msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.msg, - dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes); - pdu->N_bytes = dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes; - nas->write_pdu(lcid, pdu); - break; - case LIBLTE_RRC_DL_DCCH_MSG_TYPE_SECURITY_MODE_COMMAND: - transaction_id = dl_dcch_msg.msg.security_mode_cmd.rrc_transaction_id; - - cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) dl_dcch_msg.msg.security_mode_cmd.sec_algs.cipher_alg; - integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) dl_dcch_msg.msg.security_mode_cmd.sec_algs.int_alg; - - // Configure PDCP for security - usim->generate_as_keys(nas->get_ul_count(), k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); - pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); - send_security_mode_complete(lcid, pdu); - break; - case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG: - transaction_id = dl_dcch_msg.msg.rrc_con_reconfig.rrc_transaction_id; - handle_rrc_con_reconfig(lcid, &dl_dcch_msg.msg.rrc_con_reconfig, pdu); - break; - case LIBLTE_RRC_DL_DCCH_MSG_TYPE_UE_CAPABILITY_ENQUIRY: - transaction_id = dl_dcch_msg.msg.ue_cap_enquiry.rrc_transaction_id; - for (uint32_t i = 0; i < dl_dcch_msg.msg.ue_cap_enquiry.N_ue_cap_reqs; i++) { - if (LIBLTE_RRC_RAT_TYPE_EUTRA == dl_dcch_msg.msg.ue_cap_enquiry.ue_capability_request[i]) { - send_rrc_ue_cap_info(lcid, pdu); - break; - } +} + +void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { + srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); + bit_buf.N_bits = pdu->N_bytes * 8; + liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dl_dcch_msg); + + rrc_log->info("%s - Received %s\n", + rb_id_text[lcid], + liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); + + // Reset and reuse pdu buffer if possible + pdu->reset(); + + switch (dl_dcch_msg.msg_type) { + case LIBLTE_RRC_DL_DCCH_MSG_TYPE_DL_INFO_TRANSFER: + memcpy(pdu->msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.msg, + dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes); + pdu->N_bytes = dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes; + nas->write_pdu(lcid, pdu); + break; + case LIBLTE_RRC_DL_DCCH_MSG_TYPE_SECURITY_MODE_COMMAND: + transaction_id = dl_dcch_msg.msg.security_mode_cmd.rrc_transaction_id; + + cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) dl_dcch_msg.msg.security_mode_cmd.sec_algs.cipher_alg; + integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) dl_dcch_msg.msg.security_mode_cmd.sec_algs.int_alg; + + // Configure PDCP for security + usim->generate_as_keys(nas->get_ul_count(), k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); + pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + send_security_mode_complete(lcid, pdu); + break; + case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG: + transaction_id = dl_dcch_msg.msg.rrc_con_reconfig.rrc_transaction_id; + handle_rrc_con_reconfig(lcid, &dl_dcch_msg.msg.rrc_con_reconfig, pdu); + break; + case LIBLTE_RRC_DL_DCCH_MSG_TYPE_UE_CAPABILITY_ENQUIRY: + transaction_id = dl_dcch_msg.msg.ue_cap_enquiry.rrc_transaction_id; + for (uint32_t i = 0; i < dl_dcch_msg.msg.ue_cap_enquiry.N_ue_cap_reqs; i++) { + if (LIBLTE_RRC_RAT_TYPE_EUTRA == dl_dcch_msg.msg.ue_cap_enquiry.ue_capability_request[i]) { + send_rrc_ue_cap_info(lcid, pdu); + break; } - break; - case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RELEASE: - rrc_connection_release(); - break; - default: - break; - } + } + break; + case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RELEASE: + rrc_connection_release(); + break; + default: + break; } +} /******************************************************************************* - Timer expiration callback +Timer expiration callback *******************************************************************************/ - void rrc::timer_expired(uint32_t timeout_id) { - if (timeout_id == t310) { - rrc_log->info("Timer T310 expired: Radio Link Failure\n"); - radio_link_failure(); - } else if (timeout_id == t311) { - rrc_log->info("Timer T311 expired: Going to RRC IDLE\n"); - rrc_connection_release(); - } else if (timeout_id == t301) { - rrc_log->info("Timer T301 expired: Going to RRC IDLE\n"); - rrc_connection_release(); - } else if (timeout_id == safe_reset_timer) { - reset_ue(); - } else { - rrc_log->error("Timeout from unknown timer id %d\n", timeout_id); - } +void rrc::timer_expired(uint32_t timeout_id) { + if (timeout_id == t310) { + rrc_log->info("Timer T310 expired: Radio Link Failure\n"); + radio_link_failure(); + } else if (timeout_id == t311) { + rrc_log->info("Timer T311 expired: Going to RRC IDLE\n"); + rrc_connection_release(); + } else if (timeout_id == t301) { + rrc_log->info("Timer T301 expired: Going to RRC IDLE\n"); + rrc_connection_release(); + } else if (timeout_id == safe_reset_timer) { + reset_ue(); + } else { + rrc_log->error("Timeout from unknown timer id %d\n", timeout_id); } +} /******************************************************************************* - Helpers +Helpers *******************************************************************************/ - void rrc::reset_ue() { - phy->reset(); - mac->reset(); - pdcp->reset(); - rlc->reset(); - mac->pcch_start_rx(); - mac_timers->get(safe_reset_timer)->stop(); - mac_timers->get(safe_reset_timer)->reset(); - rrc_log->console("RRC Connection released.\n"); - } - - void rrc::rrc_connection_release() { - pthread_mutex_lock(&mutex); - drb_up = false; - state = RRC_STATE_IDLE; - set_phy_default(); - set_mac_default(); - mac_timers->get(t311)->run(); - mac_timers->get(t310)->stop(); - mac_timers->get(t311)->stop(); - mac_timers->get(safe_reset_timer)->stop(); - mac_timers->get(safe_reset_timer)->reset(); - mac_timers->get(safe_reset_timer)->run(); - pthread_mutex_unlock(&mutex); - } - - void rrc::test_con_restablishment() { - printf("Testing connection Reestablishment\n"); - send_con_restablish_request(); - } +void rrc::reset_ue() { + phy->reset(); + mac->reset(); + pdcp->reset(); + rlc->reset(); + mac->pcch_start_rx(); + mac_timers->get(safe_reset_timer)->stop(); + mac_timers->get(safe_reset_timer)->reset(); + rrc_log->console("RRC Connection released.\n"); +} + +void rrc::rrc_connection_release() { + pthread_mutex_lock(&mutex); + drb_up = false; + state = RRC_STATE_IDLE; + set_phy_default(); + set_mac_default(); + mac_timers->get(t311)->run(); + mac_timers->get(t310)->stop(); + mac_timers->get(t311)->stop(); + mac_timers->get(safe_reset_timer)->stop(); + mac_timers->get(safe_reset_timer)->reset(); + mac_timers->get(safe_reset_timer)->run(); + pthread_mutex_unlock(&mutex); +} + +void rrc::test_con_restablishment() { + printf("Testing connection Reestablishment\n"); + send_con_restablish_request(); +} /* Detection of radio link failure (5.3.11.3) */ - void rrc::radio_link_failure() { - // TODO: Generate and store failure report - - rrc_log->warning("Detected Radio-Link Failure\n"); - rrc_log->console("Warning: Detected Radio-Link Failure\n"); - if (state != RRC_STATE_CONNECTED) { - rrc_connection_release(); - } else { - send_con_restablish_request(); - } +void rrc::radio_link_failure() { + // TODO: Generate and store failure report + + rrc_log->warning("Detected Radio-Link Failure\n"); + rrc_log->console("Warning: Detected Radio-Link Failure\n"); + if (state != RRC_STATE_CONNECTED) { + rrc_connection_release(); + } else { + send_con_restablish_request(); } +} // Determine SI messages scheduling as in 36.331 5.2.3 Acquisition of an SI message - uint32_t rrc::sib_start_tti(uint32_t tti, uint32_t period, uint32_t x) { - return (period * 10 * (1 + tti / (period * 10)) + x) % 10240; // the 1 means next opportunity +uint32_t rrc::sib_start_tti(uint32_t tti, uint32_t period, uint32_t x) { + return (period * 10 * (1 + tti / (period * 10)) + x) % 10240; // the 1 means next opportunity +} + +void rrc::apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) { + + // Apply RACH timeAlginmentTimer configuration + mac_interface_rrc::mac_cfg_t cfg; + mac->get_config(&cfg); + cfg.main.time_alignment_timer = sib2->time_alignment_timer; + memcpy(&cfg.rach, &sib2->rr_config_common_sib.rach_cnfg, sizeof(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT)); + cfg.prach_config_index = sib2->rr_config_common_sib.prach_cnfg.root_sequence_index; + mac->set_config(&cfg); + + rrc_log->info("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n", + liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles], + liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size], + liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]); + + // Apply PHY RR Config Common + phy_interface_rrc::phy_cfg_common_t common; + memcpy(&common.pdsch_cnfg, &sib2->rr_config_common_sib.pdsch_cnfg, sizeof(LIBLTE_RRC_PDSCH_CONFIG_COMMON_STRUCT)); + memcpy(&common.pusch_cnfg, &sib2->rr_config_common_sib.pusch_cnfg, sizeof(LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT)); + memcpy(&common.pucch_cnfg, &sib2->rr_config_common_sib.pucch_cnfg, sizeof(LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT)); + memcpy(&common.ul_pwr_ctrl, &sib2->rr_config_common_sib.ul_pwr_ctrl, + sizeof(LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT)); + memcpy(&common.prach_cnfg, &sib2->rr_config_common_sib.prach_cnfg, sizeof(LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT)); + if (sib2->rr_config_common_sib.srs_ul_cnfg.present) { + memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, + sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT)); + } else { + // default is release + common.srs_ul_cnfg.present = false; } - - void rrc::apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) { - - // Apply RACH timeAlginmentTimer configuration - mac_interface_rrc::mac_cfg_t cfg; - mac->get_config(&cfg); - cfg.main.time_alignment_timer = sib2->time_alignment_timer; - memcpy(&cfg.rach, &sib2->rr_config_common_sib.rach_cnfg, sizeof(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT)); - cfg.prach_config_index = sib2->rr_config_common_sib.prach_cnfg.root_sequence_index; - mac->set_config(&cfg); - - rrc_log->info("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n", - liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles], - liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size], - liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]); - - // Apply PHY RR Config Common - phy_interface_rrc::phy_cfg_common_t common; - memcpy(&common.pdsch_cnfg, &sib2->rr_config_common_sib.pdsch_cnfg, sizeof(LIBLTE_RRC_PDSCH_CONFIG_COMMON_STRUCT)); - memcpy(&common.pusch_cnfg, &sib2->rr_config_common_sib.pusch_cnfg, sizeof(LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT)); - memcpy(&common.pucch_cnfg, &sib2->rr_config_common_sib.pucch_cnfg, sizeof(LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT)); - memcpy(&common.ul_pwr_ctrl, &sib2->rr_config_common_sib.ul_pwr_ctrl, - sizeof(LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT)); - memcpy(&common.prach_cnfg, &sib2->rr_config_common_sib.prach_cnfg, sizeof(LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT)); - if (sib2->rr_config_common_sib.srs_ul_cnfg.present) { - memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, - sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT)); - } else { - // default is release - common.srs_ul_cnfg.present = false; - } - phy->set_config_common(&common); - - phy->configure_ul_params(); - - rrc_log->info("Set PUSCH ConfigCommon: HopOffset=%d, RSGroup=%d, RSNcs=%d, N_sb=%d\n", - sib2->rr_config_common_sib.pusch_cnfg.pusch_hopping_offset, - sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch, - sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift, - sib2->rr_config_common_sib.pusch_cnfg.n_sb); - - rrc_log->info("Set PUCCH ConfigCommon: DeltaShift=%d, CyclicShift=%d, N1=%d, NRB=%d\n", - liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift], - sib2->rr_config_common_sib.pucch_cnfg.n_cs_an, - sib2->rr_config_common_sib.pucch_cnfg.n1_pucch_an, - sib2->rr_config_common_sib.pucch_cnfg.n_rb_cqi); - - rrc_log->info("Set PRACH ConfigCommon: SeqIdx=%d, HS=%s, FreqOffset=%d, ZC=%d, ConfigIndex=%d\n", - sib2->rr_config_common_sib.prach_cnfg.root_sequence_index, - sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.high_speed_flag ? "yes" : "no", - sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset, - sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.zero_correlation_zone_config, - sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_config_index); - - rrc_log->info("Set SRS ConfigCommon: BW-Configuration=%d, SF-Configuration=%d, ACKNACK=%s\n", - liblte_rrc_srs_bw_config_num[sib2->rr_config_common_sib.srs_ul_cnfg.bw_cnfg], - liblte_rrc_srs_subfr_config_num[sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg], - sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx ? "yes" : "no"); - - mac_timers->get(t301)->set(this, liblte_rrc_t301_num[sib2->ue_timers_and_constants.t301]); - mac_timers->get(t310)->set(this, liblte_rrc_t310_num[sib2->ue_timers_and_constants.t310]); - mac_timers->get(t311)->set(this, liblte_rrc_t311_num[sib2->ue_timers_and_constants.t311]); - N310 = liblte_rrc_n310_num[sib2->ue_timers_and_constants.n310]; - N311 = liblte_rrc_n311_num[sib2->ue_timers_and_constants.n311]; - - rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t301=%d, t310=%d, t311=%d\n", - N310, N311, mac_timers->get(t301)->get_timeout(), - mac_timers->get(t310)->get_timeout(), mac_timers->get(t311)->get_timeout()); - + phy->set_config_common(&common); + + phy->configure_ul_params(); + + rrc_log->info("Set PUSCH ConfigCommon: HopOffset=%d, RSGroup=%d, RSNcs=%d, N_sb=%d\n", + sib2->rr_config_common_sib.pusch_cnfg.pusch_hopping_offset, + sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch, + sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift, + sib2->rr_config_common_sib.pusch_cnfg.n_sb); + + rrc_log->info("Set PUCCH ConfigCommon: DeltaShift=%d, CyclicShift=%d, N1=%d, NRB=%d\n", + liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift], + sib2->rr_config_common_sib.pucch_cnfg.n_cs_an, + sib2->rr_config_common_sib.pucch_cnfg.n1_pucch_an, + sib2->rr_config_common_sib.pucch_cnfg.n_rb_cqi); + + rrc_log->info("Set PRACH ConfigCommon: SeqIdx=%d, HS=%s, FreqOffset=%d, ZC=%d, ConfigIndex=%d\n", + sib2->rr_config_common_sib.prach_cnfg.root_sequence_index, + sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.high_speed_flag ? "yes" : "no", + sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset, + sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.zero_correlation_zone_config, + sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_config_index); + + rrc_log->info("Set SRS ConfigCommon: BW-Configuration=%d, SF-Configuration=%d, ACKNACK=%s\n", + liblte_rrc_srs_bw_config_num[sib2->rr_config_common_sib.srs_ul_cnfg.bw_cnfg], + liblte_rrc_srs_subfr_config_num[sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg], + sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx ? "yes" : "no"); + + mac_timers->get(t301)->set(this, liblte_rrc_t301_num[sib2->ue_timers_and_constants.t301]); + mac_timers->get(t310)->set(this, liblte_rrc_t310_num[sib2->ue_timers_and_constants.t310]); + mac_timers->get(t311)->set(this, liblte_rrc_t311_num[sib2->ue_timers_and_constants.t311]); + N310 = liblte_rrc_n310_num[sib2->ue_timers_and_constants.n310]; + N311 = liblte_rrc_n311_num[sib2->ue_timers_and_constants.n311]; + + rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t301=%d, t310=%d, t311=%d\n", + N310, N311, mac_timers->get(t301)->get_timeout(), + mac_timers->get(t310)->get_timeout(), mac_timers->get(t311)->get_timeout()); + +} + +// Go through all information elements and apply defaults (9.2.4) if not defined +void rrc::apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *phy_cnfg, bool apply_defaults) { + // Get current configuration + LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *current_cfg; + phy_interface_rrc::phy_cfg_t c; + phy->get_config(&c); + current_cfg = &c.dedicated; + + if (phy_cnfg->pucch_cnfg_ded_present) { + memcpy(¤t_cfg->pucch_cnfg_ded, &phy_cnfg->pucch_cnfg_ded, sizeof(LIBLTE_RRC_PUCCH_CONFIG_DEDICATED_STRUCT)); + } else if (apply_defaults) { + current_cfg->pucch_cnfg_ded.tdd_ack_nack_feedback_mode = LIBLTE_RRC_TDD_ACK_NACK_FEEDBACK_MODE_BUNDLING; + current_cfg->pucch_cnfg_ded.ack_nack_repetition_setup_present = false; } - - // Go through all information elements and apply defaults (9.2.4) if not defined - void rrc::apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *phy_cnfg, bool apply_defaults) { - // Get current configuration - LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *current_cfg; - phy_interface_rrc::phy_cfg_t c; - phy->get_config(&c); - current_cfg = &c.dedicated; - - if (phy_cnfg->pucch_cnfg_ded_present) { - memcpy(¤t_cfg->pucch_cnfg_ded, &phy_cnfg->pucch_cnfg_ded, sizeof(LIBLTE_RRC_PUCCH_CONFIG_DEDICATED_STRUCT)); - } else if (apply_defaults) { - current_cfg->pucch_cnfg_ded.tdd_ack_nack_feedback_mode = LIBLTE_RRC_TDD_ACK_NACK_FEEDBACK_MODE_BUNDLING; - current_cfg->pucch_cnfg_ded.ack_nack_repetition_setup_present = false; - } - if (phy_cnfg->pusch_cnfg_ded_present) { - memcpy(¤t_cfg->pusch_cnfg_ded, &phy_cnfg->pusch_cnfg_ded, sizeof(LIBLTE_RRC_PUSCH_CONFIG_DEDICATED_STRUCT)); - } else if (apply_defaults) { - current_cfg->pusch_cnfg_ded.beta_offset_ack_idx = 10; - current_cfg->pusch_cnfg_ded.beta_offset_ri_idx = 12; - current_cfg->pusch_cnfg_ded.beta_offset_cqi_idx = 15; - } - if (phy_cnfg->ul_pwr_ctrl_ded_present) { - memcpy(¤t_cfg->ul_pwr_ctrl_ded, &phy_cnfg->ul_pwr_ctrl_ded, - sizeof(LIBLTE_RRC_UL_POWER_CONTROL_DEDICATED_STRUCT)); - } else if (apply_defaults) { - current_cfg->ul_pwr_ctrl_ded.p0_ue_pusch = 0; - current_cfg->ul_pwr_ctrl_ded.delta_mcs_en = LIBLTE_RRC_DELTA_MCS_ENABLED_EN0; - current_cfg->ul_pwr_ctrl_ded.accumulation_en = true; - current_cfg->ul_pwr_ctrl_ded.p0_ue_pucch = 0; - current_cfg->ul_pwr_ctrl_ded.p_srs_offset = 7; - current_cfg->ul_pwr_ctrl_ded.filter_coeff = LIBLTE_RRC_FILTER_COEFFICIENT_FC4; - current_cfg->ul_pwr_ctrl_ded.filter_coeff_present = true; - } - if (phy_cnfg->tpc_pdcch_cnfg_pucch_present) { - memcpy(¤t_cfg->tpc_pdcch_cnfg_pucch, &phy_cnfg->tpc_pdcch_cnfg_pucch, - sizeof(LIBLTE_RRC_TPC_PDCCH_CONFIG_STRUCT)); + if (phy_cnfg->pusch_cnfg_ded_present) { + memcpy(¤t_cfg->pusch_cnfg_ded, &phy_cnfg->pusch_cnfg_ded, sizeof(LIBLTE_RRC_PUSCH_CONFIG_DEDICATED_STRUCT)); + } else if (apply_defaults) { + current_cfg->pusch_cnfg_ded.beta_offset_ack_idx = 10; + current_cfg->pusch_cnfg_ded.beta_offset_ri_idx = 12; + current_cfg->pusch_cnfg_ded.beta_offset_cqi_idx = 15; + } + if (phy_cnfg->ul_pwr_ctrl_ded_present) { + memcpy(¤t_cfg->ul_pwr_ctrl_ded, &phy_cnfg->ul_pwr_ctrl_ded, + sizeof(LIBLTE_RRC_UL_POWER_CONTROL_DEDICATED_STRUCT)); + } else if (apply_defaults) { + current_cfg->ul_pwr_ctrl_ded.p0_ue_pusch = 0; + current_cfg->ul_pwr_ctrl_ded.delta_mcs_en = LIBLTE_RRC_DELTA_MCS_ENABLED_EN0; + current_cfg->ul_pwr_ctrl_ded.accumulation_en = true; + current_cfg->ul_pwr_ctrl_ded.p0_ue_pucch = 0; + current_cfg->ul_pwr_ctrl_ded.p_srs_offset = 7; + current_cfg->ul_pwr_ctrl_ded.filter_coeff = LIBLTE_RRC_FILTER_COEFFICIENT_FC4; + current_cfg->ul_pwr_ctrl_ded.filter_coeff_present = true; + } + if (phy_cnfg->tpc_pdcch_cnfg_pucch_present) { + memcpy(¤t_cfg->tpc_pdcch_cnfg_pucch, &phy_cnfg->tpc_pdcch_cnfg_pucch, + sizeof(LIBLTE_RRC_TPC_PDCCH_CONFIG_STRUCT)); + } else if (apply_defaults) { + current_cfg->tpc_pdcch_cnfg_pucch.setup_present = false; + } + if (phy_cnfg->tpc_pdcch_cnfg_pusch_present) { + memcpy(¤t_cfg->tpc_pdcch_cnfg_pusch, &phy_cnfg->tpc_pdcch_cnfg_pusch, + sizeof(LIBLTE_RRC_TPC_PDCCH_CONFIG_STRUCT)); + } else { + current_cfg->tpc_pdcch_cnfg_pusch.setup_present = false; + } + if (phy_cnfg->cqi_report_cnfg_present) { + if (phy_cnfg->cqi_report_cnfg.report_periodic_present) { + memcpy(¤t_cfg->cqi_report_cnfg.report_periodic, &phy_cnfg->cqi_report_cnfg.report_periodic, + sizeof(LIBLTE_RRC_CQI_REPORT_PERIODIC_STRUCT)); + current_cfg->cqi_report_cnfg.report_periodic_setup_present = phy_cnfg->cqi_report_cnfg.report_periodic_setup_present; } else if (apply_defaults) { - current_cfg->tpc_pdcch_cnfg_pucch.setup_present = false; - } - if (phy_cnfg->tpc_pdcch_cnfg_pusch_present) { - memcpy(¤t_cfg->tpc_pdcch_cnfg_pusch, &phy_cnfg->tpc_pdcch_cnfg_pusch, - sizeof(LIBLTE_RRC_TPC_PDCCH_CONFIG_STRUCT)); - } else { - current_cfg->tpc_pdcch_cnfg_pusch.setup_present = false; - } - if (phy_cnfg->cqi_report_cnfg_present) { - if (phy_cnfg->cqi_report_cnfg.report_periodic_present) { - memcpy(¤t_cfg->cqi_report_cnfg.report_periodic, &phy_cnfg->cqi_report_cnfg.report_periodic, - sizeof(LIBLTE_RRC_CQI_REPORT_PERIODIC_STRUCT)); - current_cfg->cqi_report_cnfg.report_periodic_setup_present = phy_cnfg->cqi_report_cnfg.report_periodic_setup_present; - } else if (apply_defaults) { - current_cfg->cqi_report_cnfg.report_periodic_setup_present = false; - } - if (phy_cnfg->cqi_report_cnfg.report_mode_aperiodic_present) { - current_cfg->cqi_report_cnfg.report_mode_aperiodic = phy_cnfg->cqi_report_cnfg.report_mode_aperiodic; - current_cfg->cqi_report_cnfg.report_mode_aperiodic_present = phy_cnfg->cqi_report_cnfg.report_mode_aperiodic_present; - } else if (apply_defaults) { - current_cfg->cqi_report_cnfg.report_mode_aperiodic_present = false; - } - current_cfg->cqi_report_cnfg.nom_pdsch_rs_epre_offset = phy_cnfg->cqi_report_cnfg.nom_pdsch_rs_epre_offset; + current_cfg->cqi_report_cnfg.report_periodic_setup_present = false; } - if (phy_cnfg->srs_ul_cnfg_ded_present && phy_cnfg->srs_ul_cnfg_ded.setup_present) { - memcpy(¤t_cfg->srs_ul_cnfg_ded, &phy_cnfg->srs_ul_cnfg_ded, - sizeof(LIBLTE_RRC_SRS_UL_CONFIG_DEDICATED_STRUCT)); + if (phy_cnfg->cqi_report_cnfg.report_mode_aperiodic_present) { + current_cfg->cqi_report_cnfg.report_mode_aperiodic = phy_cnfg->cqi_report_cnfg.report_mode_aperiodic; + current_cfg->cqi_report_cnfg.report_mode_aperiodic_present = phy_cnfg->cqi_report_cnfg.report_mode_aperiodic_present; } else if (apply_defaults) { - current_cfg->srs_ul_cnfg_ded.setup_present = false; + current_cfg->cqi_report_cnfg.report_mode_aperiodic_present = false; } - if (phy_cnfg->antenna_info_present) { - if (!phy_cnfg->antenna_info_default_value) { - if (phy_cnfg->antenna_info_explicit_value.tx_mode != LIBLTE_RRC_TRANSMISSION_MODE_1 && - phy_cnfg->antenna_info_explicit_value.tx_mode != LIBLTE_RRC_TRANSMISSION_MODE_2) { - rrc_log->error("Transmission mode TM%s not currently supported by srsUE\n", - liblte_rrc_transmission_mode_text[phy_cnfg->antenna_info_explicit_value.tx_mode]); - } - memcpy(¤t_cfg->antenna_info_explicit_value, &phy_cnfg->antenna_info_explicit_value, - sizeof(LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT)); - } else if (apply_defaults) { - current_cfg->antenna_info_explicit_value.tx_mode = LIBLTE_RRC_TRANSMISSION_MODE_2; - current_cfg->antenna_info_explicit_value.codebook_subset_restriction_present = false; - current_cfg->antenna_info_explicit_value.ue_tx_antenna_selection_setup_present = false; + current_cfg->cqi_report_cnfg.nom_pdsch_rs_epre_offset = phy_cnfg->cqi_report_cnfg.nom_pdsch_rs_epre_offset; + } + if (phy_cnfg->srs_ul_cnfg_ded_present && phy_cnfg->srs_ul_cnfg_ded.setup_present) { + memcpy(¤t_cfg->srs_ul_cnfg_ded, &phy_cnfg->srs_ul_cnfg_ded, + sizeof(LIBLTE_RRC_SRS_UL_CONFIG_DEDICATED_STRUCT)); + } else if (apply_defaults) { + current_cfg->srs_ul_cnfg_ded.setup_present = false; + } + if (phy_cnfg->antenna_info_present) { + if (!phy_cnfg->antenna_info_default_value) { + if (phy_cnfg->antenna_info_explicit_value.tx_mode != LIBLTE_RRC_TRANSMISSION_MODE_1 && + phy_cnfg->antenna_info_explicit_value.tx_mode != LIBLTE_RRC_TRANSMISSION_MODE_2) { + rrc_log->error("Transmission mode TM%s not currently supported by srsUE\n", + liblte_rrc_transmission_mode_text[phy_cnfg->antenna_info_explicit_value.tx_mode]); } + memcpy(¤t_cfg->antenna_info_explicit_value, &phy_cnfg->antenna_info_explicit_value, + sizeof(LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT)); } else if (apply_defaults) { current_cfg->antenna_info_explicit_value.tx_mode = LIBLTE_RRC_TRANSMISSION_MODE_2; current_cfg->antenna_info_explicit_value.codebook_subset_restriction_present = false; current_cfg->antenna_info_explicit_value.ue_tx_antenna_selection_setup_present = false; } - if (phy_cnfg->sched_request_cnfg_present) { - memcpy(¤t_cfg->sched_request_cnfg, &phy_cnfg->sched_request_cnfg, - sizeof(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT)); - } else if (apply_defaults) { - current_cfg->sched_request_cnfg.setup_present = false; + } else if (apply_defaults) { + current_cfg->antenna_info_explicit_value.tx_mode = LIBLTE_RRC_TRANSMISSION_MODE_2; + current_cfg->antenna_info_explicit_value.codebook_subset_restriction_present = false; + current_cfg->antenna_info_explicit_value.ue_tx_antenna_selection_setup_present = false; + } + if (phy_cnfg->sched_request_cnfg_present) { + memcpy(¤t_cfg->sched_request_cnfg, &phy_cnfg->sched_request_cnfg, + sizeof(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT)); + } else if (apply_defaults) { + current_cfg->sched_request_cnfg.setup_present = false; + } + if (phy_cnfg->pdsch_cnfg_ded_present) { + current_cfg->pdsch_cnfg_ded = phy_cnfg->pdsch_cnfg_ded; + } else if (apply_defaults) { + current_cfg->pdsch_cnfg_ded = LIBLTE_RRC_PDSCH_CONFIG_P_A_DB_0; + } + + if (phy_cnfg->cqi_report_cnfg_present) { + if (phy_cnfg->cqi_report_cnfg.report_periodic_present) { + rrc_log->info("Set cqi-PUCCH-ResourceIndex=%d, cqi-pmi-ConfigIndex=%d, cqi-FormatIndicatorPeriodic=%s\n", + current_cfg->cqi_report_cnfg.report_periodic.pucch_resource_idx, + current_cfg->cqi_report_cnfg.report_periodic.pmi_cnfg_idx, + liblte_rrc_cqi_format_indicator_periodic_text[current_cfg->cqi_report_cnfg.report_periodic.format_ind_periodic]); } - if (phy_cnfg->pdsch_cnfg_ded_present) { - current_cfg->pdsch_cnfg_ded = phy_cnfg->pdsch_cnfg_ded; - } else if (apply_defaults) { - current_cfg->pdsch_cnfg_ded = LIBLTE_RRC_PDSCH_CONFIG_P_A_DB_0; + if (phy_cnfg->cqi_report_cnfg.report_mode_aperiodic_present) { + rrc_log->info("Set cqi-ReportModeAperiodic=%s\n", + liblte_rrc_cqi_report_mode_aperiodic_text[current_cfg->cqi_report_cnfg.report_mode_aperiodic]); } - if (phy_cnfg->cqi_report_cnfg_present) { - if (phy_cnfg->cqi_report_cnfg.report_periodic_present) { - rrc_log->info("Set cqi-PUCCH-ResourceIndex=%d, cqi-pmi-ConfigIndex=%d, cqi-FormatIndicatorPeriodic=%s\n", - current_cfg->cqi_report_cnfg.report_periodic.pucch_resource_idx, - current_cfg->cqi_report_cnfg.report_periodic.pmi_cnfg_idx, - liblte_rrc_cqi_format_indicator_periodic_text[current_cfg->cqi_report_cnfg.report_periodic.format_ind_periodic]); - } - if (phy_cnfg->cqi_report_cnfg.report_mode_aperiodic_present) { - rrc_log->info("Set cqi-ReportModeAperiodic=%s\n", - liblte_rrc_cqi_report_mode_aperiodic_text[current_cfg->cqi_report_cnfg.report_mode_aperiodic]); - } + } - } + if (phy_cnfg->sched_request_cnfg_present) { + rrc_log->info("Set PHY config ded: SR-n_pucch=%d, SR-ConfigIndex=%d, SR-TransMax=%d\n", + current_cfg->sched_request_cnfg.sr_pucch_resource_idx, + current_cfg->sched_request_cnfg.sr_cnfg_idx, + liblte_rrc_dsr_trans_max_num[current_cfg->sched_request_cnfg.dsr_trans_max]); + } - if (phy_cnfg->sched_request_cnfg_present) { - rrc_log->info("Set PHY config ded: SR-n_pucch=%d, SR-ConfigIndex=%d, SR-TransMax=%d\n", - current_cfg->sched_request_cnfg.sr_pucch_resource_idx, - current_cfg->sched_request_cnfg.sr_cnfg_idx, - liblte_rrc_dsr_trans_max_num[current_cfg->sched_request_cnfg.dsr_trans_max]); - } + if (current_cfg->srs_ul_cnfg_ded_present) { + rrc_log->info("Set PHY config ded: SRS-ConfigIndex=%d, SRS-bw=%s, SRS-Nrcc=%d, SRS-hop=%s, SRS-Ncs=%s\n", + current_cfg->srs_ul_cnfg_ded.srs_cnfg_idx, + liblte_rrc_srs_bandwidth_text[current_cfg->srs_ul_cnfg_ded.srs_bandwidth], + current_cfg->srs_ul_cnfg_ded.freq_domain_pos, + liblte_rrc_srs_hopping_bandwidth_text[current_cfg->srs_ul_cnfg_ded.srs_hopping_bandwidth], + liblte_rrc_cyclic_shift_text[current_cfg->srs_ul_cnfg_ded.cyclic_shift]); + } - if (current_cfg->srs_ul_cnfg_ded_present) { - rrc_log->info("Set PHY config ded: SRS-ConfigIndex=%d, SRS-bw=%s, SRS-Nrcc=%d, SRS-hop=%s, SRS-Ncs=%s\n", - current_cfg->srs_ul_cnfg_ded.srs_cnfg_idx, - liblte_rrc_srs_bandwidth_text[current_cfg->srs_ul_cnfg_ded.srs_bandwidth], - current_cfg->srs_ul_cnfg_ded.freq_domain_pos, - liblte_rrc_srs_hopping_bandwidth_text[current_cfg->srs_ul_cnfg_ded.srs_hopping_bandwidth], - liblte_rrc_cyclic_shift_text[current_cfg->srs_ul_cnfg_ded.cyclic_shift]); - } + phy->set_config_dedicated(current_cfg); - phy->set_config_dedicated(current_cfg); + // Apply changes to PHY + phy->configure_ul_params(); - // Apply changes to PHY - phy->configure_ul_params(); +} - } +void rrc::apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cnfg, bool apply_defaults) { + // Set Default MAC main configuration (9.2.2) + LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT default_cfg; + bzero(&default_cfg, sizeof(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT)); + default_cfg.ulsch_cnfg.max_harq_tx = LIBLTE_RRC_MAX_HARQ_TX_N5; + default_cfg.ulsch_cnfg.periodic_bsr_timer = LIBLTE_RRC_PERIODIC_BSR_TIMER_INFINITY; + default_cfg.ulsch_cnfg.retx_bsr_timer = LIBLTE_RRC_RETRANSMISSION_BSR_TIMER_SF2560; + default_cfg.ulsch_cnfg.tti_bundling = false; + default_cfg.drx_cnfg.setup_present = false; + default_cfg.phr_cnfg.setup_present = false; + default_cfg.time_alignment_timer = LIBLTE_RRC_TIME_ALIGNMENT_TIMER_INFINITY; - void rrc::apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cnfg, bool apply_defaults) { - // Set Default MAC main configuration (9.2.2) - LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT default_cfg; - bzero(&default_cfg, sizeof(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT)); - default_cfg.ulsch_cnfg.max_harq_tx = LIBLTE_RRC_MAX_HARQ_TX_N5; - default_cfg.ulsch_cnfg.periodic_bsr_timer = LIBLTE_RRC_PERIODIC_BSR_TIMER_INFINITY; - default_cfg.ulsch_cnfg.retx_bsr_timer = LIBLTE_RRC_RETRANSMISSION_BSR_TIMER_SF2560; - default_cfg.ulsch_cnfg.tti_bundling = false; - default_cfg.drx_cnfg.setup_present = false; - default_cfg.phr_cnfg.setup_present = false; - default_cfg.time_alignment_timer = LIBLTE_RRC_TIME_ALIGNMENT_TIMER_INFINITY; - - - if (!apply_defaults) { - if (mac_cnfg->ulsch_cnfg_present) { - if (mac_cnfg->ulsch_cnfg.max_harq_tx_present) { - default_cfg.ulsch_cnfg.max_harq_tx = mac_cnfg->ulsch_cnfg.max_harq_tx; - default_cfg.ulsch_cnfg.max_harq_tx_present = true; - } - if (mac_cnfg->ulsch_cnfg.periodic_bsr_timer_present) { - default_cfg.ulsch_cnfg.periodic_bsr_timer = mac_cnfg->ulsch_cnfg.periodic_bsr_timer; - default_cfg.ulsch_cnfg.periodic_bsr_timer_present = true; - } - default_cfg.ulsch_cnfg.retx_bsr_timer = mac_cnfg->ulsch_cnfg.retx_bsr_timer; - default_cfg.ulsch_cnfg.tti_bundling = mac_cnfg->ulsch_cnfg.tti_bundling; - } - if (mac_cnfg->drx_cnfg_present) { - memcpy(&default_cfg.drx_cnfg, &mac_cnfg->drx_cnfg, sizeof(LIBLTE_RRC_DRX_CONFIG_STRUCT)); - default_cfg.drx_cnfg_present = true; + + if (!apply_defaults) { + if (mac_cnfg->ulsch_cnfg_present) { + if (mac_cnfg->ulsch_cnfg.max_harq_tx_present) { + default_cfg.ulsch_cnfg.max_harq_tx = mac_cnfg->ulsch_cnfg.max_harq_tx; + default_cfg.ulsch_cnfg.max_harq_tx_present = true; } - if (mac_cnfg->phr_cnfg_present) { - memcpy(&default_cfg.phr_cnfg, &mac_cnfg->phr_cnfg, sizeof(LIBLTE_RRC_PHR_CONFIG_STRUCT)); - default_cfg.phr_cnfg_present = true; + if (mac_cnfg->ulsch_cnfg.periodic_bsr_timer_present) { + default_cfg.ulsch_cnfg.periodic_bsr_timer = mac_cnfg->ulsch_cnfg.periodic_bsr_timer; + default_cfg.ulsch_cnfg.periodic_bsr_timer_present = true; } - default_cfg.time_alignment_timer = mac_cnfg->time_alignment_timer; + default_cfg.ulsch_cnfg.retx_bsr_timer = mac_cnfg->ulsch_cnfg.retx_bsr_timer; + default_cfg.ulsch_cnfg.tti_bundling = mac_cnfg->ulsch_cnfg.tti_bundling; } - - // Setup MAC configuration - mac->set_config_main(&default_cfg); - - rrc_log->info("Set MAC main config: harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d\n", - liblte_rrc_max_harq_tx_num[default_cfg.ulsch_cnfg.max_harq_tx], - liblte_rrc_retransmission_bsr_timer_num[default_cfg.ulsch_cnfg.retx_bsr_timer], - liblte_rrc_periodic_bsr_timer_num[default_cfg.ulsch_cnfg.periodic_bsr_timer]); - if (default_cfg.phr_cnfg_present) { - rrc_log->info("Set MAC PHR config: periodicPHR-Timer=%d, prohibitPHR-Timer=%d, dl-PathlossChange=%d\n", - liblte_rrc_periodic_phr_timer_num[default_cfg.phr_cnfg.periodic_phr_timer], - liblte_rrc_prohibit_phr_timer_num[default_cfg.phr_cnfg.prohibit_phr_timer], - liblte_rrc_dl_pathloss_change_num[default_cfg.phr_cnfg.dl_pathloss_change]); + if (mac_cnfg->drx_cnfg_present) { + memcpy(&default_cfg.drx_cnfg, &mac_cnfg->drx_cnfg, sizeof(LIBLTE_RRC_DRX_CONFIG_STRUCT)); + default_cfg.drx_cnfg_present = true; } - } - - void rrc::apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg) { - if (cnfg->phy_cnfg_ded_present) { - apply_phy_config_dedicated(&cnfg->phy_cnfg_ded, false); - // Apply SR configuration to MAC - if (cnfg->phy_cnfg_ded.sched_request_cnfg_present) { - mac->set_config_sr(&cnfg->phy_cnfg_ded.sched_request_cnfg); - } + if (mac_cnfg->phr_cnfg_present) { + memcpy(&default_cfg.phr_cnfg, &mac_cnfg->phr_cnfg, sizeof(LIBLTE_RRC_PHR_CONFIG_STRUCT)); + default_cfg.phr_cnfg_present = true; } + default_cfg.time_alignment_timer = mac_cnfg->time_alignment_timer; + } - if (cnfg->mac_main_cnfg_present) { - apply_mac_config_dedicated(&cnfg->mac_main_cnfg.explicit_value, cnfg->mac_main_cnfg.default_value); + // Setup MAC configuration + mac->set_config_main(&default_cfg); + + rrc_log->info("Set MAC main config: harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d\n", + liblte_rrc_max_harq_tx_num[default_cfg.ulsch_cnfg.max_harq_tx], + liblte_rrc_retransmission_bsr_timer_num[default_cfg.ulsch_cnfg.retx_bsr_timer], + liblte_rrc_periodic_bsr_timer_num[default_cfg.ulsch_cnfg.periodic_bsr_timer]); + if (default_cfg.phr_cnfg_present) { + rrc_log->info("Set MAC PHR config: periodicPHR-Timer=%d, prohibitPHR-Timer=%d, dl-PathlossChange=%d\n", + liblte_rrc_periodic_phr_timer_num[default_cfg.phr_cnfg.periodic_phr_timer], + liblte_rrc_prohibit_phr_timer_num[default_cfg.phr_cnfg.prohibit_phr_timer], + liblte_rrc_dl_pathloss_change_num[default_cfg.phr_cnfg.dl_pathloss_change]); + } +} + +void rrc::apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg) { + if (cnfg->phy_cnfg_ded_present) { + apply_phy_config_dedicated(&cnfg->phy_cnfg_ded, false); + // Apply SR configuration to MAC + if (cnfg->phy_cnfg_ded.sched_request_cnfg_present) { + mac->set_config_sr(&cnfg->phy_cnfg_ded.sched_request_cnfg); } + } - if (cnfg->sps_cnfg_present) { - //TODO - } - if (cnfg->rlf_timers_and_constants_present) { - //TODO - } - for (uint32_t i = 0; i < cnfg->srb_to_add_mod_list_size; i++) { - // TODO: handle SRB modification - add_srb(&cnfg->srb_to_add_mod_list[i]); - } - for (uint32_t i = 0; i < cnfg->drb_to_release_list_size; i++) { - release_drb(cnfg->drb_to_release_list[i]); - } - for (uint32_t i = 0; i < cnfg->drb_to_add_mod_list_size; i++) { - // TODO: handle DRB modification - add_drb(&cnfg->drb_to_add_mod_list[i]); - } + if (cnfg->mac_main_cnfg_present) { + apply_mac_config_dedicated(&cnfg->mac_main_cnfg.explicit_value, cnfg->mac_main_cnfg.default_value); } - void rrc::handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup) { - // Apply the Radio Resource configuration - apply_rr_config_dedicated(&setup->rr_cnfg); + if (cnfg->sps_cnfg_present) { + //TODO + } + if (cnfg->rlf_timers_and_constants_present) { + //TODO } + for (uint32_t i = 0; i < cnfg->srb_to_add_mod_list_size; i++) { + // TODO: handle SRB modification + add_srb(&cnfg->srb_to_add_mod_list[i]); + } + for (uint32_t i = 0; i < cnfg->drb_to_release_list_size; i++) { + release_drb(cnfg->drb_to_release_list[i]); + } + for (uint32_t i = 0; i < cnfg->drb_to_add_mod_list_size; i++) { + // TODO: handle DRB modification + add_drb(&cnfg->drb_to_add_mod_list[i]); + } +} + +void rrc::handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup) { + // Apply the Radio Resource configuration + apply_rr_config_dedicated(&setup->rr_cnfg); +} /* Reception of RRCConnectionReestablishment by the UE 5.3.7.5 */ - void rrc::handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup) { - mac_timers->get(t301)->stop(); +void rrc::handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup) { + mac_timers->get(t301)->stop(); - // TODO: Restablish DRB1. Not done because never was suspended + // TODO: Restablish DRB1. Not done because never was suspended - // Apply the Radio Resource configuration - apply_rr_config_dedicated(&setup->rr_cnfg); + // Apply the Radio Resource configuration + apply_rr_config_dedicated(&setup->rr_cnfg); - // TODO: Some security stuff here... is it necessary? + // TODO: Some security stuff here... is it necessary? - send_con_restablish_complete(); - } + send_con_restablish_complete(); +} - void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, - byte_buffer_t *pdu) { - uint32_t i; +void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, + byte_buffer_t *pdu) { + uint32_t i; - if (reconfig->rr_cnfg_ded_present) { - apply_rr_config_dedicated(&reconfig->rr_cnfg_ded); - } else { - printf("received con reconfig no rr confg present\n"); - } - if (reconfig->meas_cnfg_present) { - //TODO: handle meas_cnfg - } - if (reconfig->mob_ctrl_info_present) { - //TODO: handle mob_ctrl_info - } + if (reconfig->rr_cnfg_ded_present) { + apply_rr_config_dedicated(&reconfig->rr_cnfg_ded); + } else { + printf("received con reconfig no rr confg present\n"); + } + if (reconfig->meas_cnfg_present) { + //TODO: handle meas_cnfg + } + if (reconfig->mob_ctrl_info_present) { + //TODO: handle mob_ctrl_info + } - send_rrc_con_reconfig_complete(lcid, pdu); + send_rrc_con_reconfig_complete(lcid, pdu); - byte_buffer_t *nas_sdu; - for (i = 0; i < reconfig->N_ded_info_nas; i++) { - nas_sdu = pool_allocate;; - memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes); - nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; - nas->write_pdu(lcid, nas_sdu); + byte_buffer_t *nas_sdu; + for (i = 0; i < reconfig->N_ded_info_nas; i++) { + nas_sdu = pool_allocate;; + memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes); + nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; + nas->write_pdu(lcid, nas_sdu); + } +} + +void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) { + // Setup PDCP + pdcp->add_bearer(srb_cnfg->srb_id); + if (RB_ID_SRB2 == srb_cnfg->srb_id) + pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + + // Setup RLC + if (srb_cnfg->rlc_cnfg_present) { + if (srb_cnfg->rlc_default_cnfg_present) { + rlc->add_bearer(srb_cnfg->srb_id); + } else { + rlc->add_bearer(srb_cnfg->srb_id, &srb_cnfg->rlc_explicit_cnfg); } } - void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) { - // Setup PDCP - pdcp->add_bearer(srb_cnfg->srb_id); - if (RB_ID_SRB2 == srb_cnfg->srb_id) - pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); - - // Setup RLC - if (srb_cnfg->rlc_cnfg_present) { - if (srb_cnfg->rlc_default_cnfg_present) { - rlc->add_bearer(srb_cnfg->srb_id); - } else { - rlc->add_bearer(srb_cnfg->srb_id, &srb_cnfg->rlc_explicit_cnfg); - } - } + // Setup MAC + uint8_t log_chan_group = 0; + uint8_t priority = 1; + int prioritized_bit_rate = -1; + int bucket_size_duration = -1; - // Setup MAC - uint8_t log_chan_group = 0; - uint8_t priority = 1; - int prioritized_bit_rate = -1; - int bucket_size_duration = -1; - - if (srb_cnfg->lc_cnfg_present) { - if (srb_cnfg->lc_default_cnfg_present) { - if (RB_ID_SRB2 == srb_cnfg->srb_id) - priority = 3; - } else { - if (srb_cnfg->lc_explicit_cnfg.log_chan_sr_mask_present) { - //TODO - } - if (srb_cnfg->lc_explicit_cnfg.ul_specific_params_present) { - if (srb_cnfg->lc_explicit_cnfg.ul_specific_params.log_chan_group_present) - log_chan_group = srb_cnfg->lc_explicit_cnfg.ul_specific_params.log_chan_group; + if (srb_cnfg->lc_cnfg_present) { + if (srb_cnfg->lc_default_cnfg_present) { + if (RB_ID_SRB2 == srb_cnfg->srb_id) + priority = 3; + } else { + if (srb_cnfg->lc_explicit_cnfg.log_chan_sr_mask_present) { + //TODO + } + if (srb_cnfg->lc_explicit_cnfg.ul_specific_params_present) { + if (srb_cnfg->lc_explicit_cnfg.ul_specific_params.log_chan_group_present) + log_chan_group = srb_cnfg->lc_explicit_cnfg.ul_specific_params.log_chan_group; - priority = srb_cnfg->lc_explicit_cnfg.ul_specific_params.priority; - prioritized_bit_rate = liblte_rrc_prioritized_bit_rate_num[srb_cnfg->lc_explicit_cnfg.ul_specific_params.prioritized_bit_rate]; - bucket_size_duration = liblte_rrc_bucket_size_duration_num[srb_cnfg->lc_explicit_cnfg.ul_specific_params.bucket_size_duration]; - } + priority = srb_cnfg->lc_explicit_cnfg.ul_specific_params.priority; + prioritized_bit_rate = liblte_rrc_prioritized_bit_rate_num[srb_cnfg->lc_explicit_cnfg.ul_specific_params.prioritized_bit_rate]; + bucket_size_duration = liblte_rrc_bucket_size_duration_num[srb_cnfg->lc_explicit_cnfg.ul_specific_params.bucket_size_duration]; } - mac->setup_lcid(srb_cnfg->srb_id, log_chan_group, priority, prioritized_bit_rate, bucket_size_duration); } - - srbs[srb_cnfg->srb_id] = *srb_cnfg; - rrc_log->info("Added radio bearer %s\n", rb_id_text[srb_cnfg->srb_id]); + mac->setup_lcid(srb_cnfg->srb_id, log_chan_group, priority, prioritized_bit_rate, bucket_size_duration); } - void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) { + srbs[srb_cnfg->srb_id] = *srb_cnfg; + rrc_log->info("Added radio bearer %s\n", rb_id_text[srb_cnfg->srb_id]); +} - if (!drb_cnfg->pdcp_cnfg_present || - !drb_cnfg->rlc_cnfg_present || - !drb_cnfg->lc_cnfg_present) { - rrc_log->error("Cannot add DRB - incomplete configuration\n"); - return; - } - uint32_t lcid = 0; - if (drb_cnfg->lc_id_present) { - lcid = drb_cnfg->lc_id; - } else { - lcid = RB_ID_SRB2 + drb_cnfg->drb_id; - rrc_log->warning("LCID not present, using %d\n", lcid); - } +void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) { - // Setup PDCP - pdcp->add_bearer(lcid, &drb_cnfg->pdcp_cnfg); - // TODO: setup PDCP security (using k_up_enc) - - // Setup RLC - rlc->add_bearer(lcid, &drb_cnfg->rlc_cnfg); - - // Setup MAC - uint8_t log_chan_group = 0; - uint8_t priority = 1; - int prioritized_bit_rate = -1; - int bucket_size_duration = -1; - if (drb_cnfg->lc_cnfg.ul_specific_params_present) { - if (drb_cnfg->lc_cnfg.ul_specific_params.log_chan_group_present) { - log_chan_group = drb_cnfg->lc_cnfg.ul_specific_params.log_chan_group; - } else { - rrc_log->warning("LCG not present, setting to 0\n"); - } - priority = drb_cnfg->lc_cnfg.ul_specific_params.priority; - prioritized_bit_rate = liblte_rrc_prioritized_bit_rate_num[drb_cnfg->lc_cnfg.ul_specific_params.prioritized_bit_rate]; + if (!drb_cnfg->pdcp_cnfg_present || + !drb_cnfg->rlc_cnfg_present || + !drb_cnfg->lc_cnfg_present) { + rrc_log->error("Cannot add DRB - incomplete configuration\n"); + return; + } + uint32_t lcid = 0; + if (drb_cnfg->lc_id_present) { + lcid = drb_cnfg->lc_id; + } else { + lcid = RB_ID_SRB2 + drb_cnfg->drb_id; + rrc_log->warning("LCID not present, using %d\n", lcid); + } - if (prioritized_bit_rate > 0) { - rrc_log->warning("PBR>0 currently not supported. Setting it to Inifinty\n"); - prioritized_bit_rate = -1; - } + // Setup PDCP + pdcp->add_bearer(lcid, &drb_cnfg->pdcp_cnfg); + // TODO: setup PDCP security (using k_up_enc) + + // Setup RLC + rlc->add_bearer(lcid, &drb_cnfg->rlc_cnfg); + + // Setup MAC + uint8_t log_chan_group = 0; + uint8_t priority = 1; + int prioritized_bit_rate = -1; + int bucket_size_duration = -1; + if (drb_cnfg->lc_cnfg.ul_specific_params_present) { + if (drb_cnfg->lc_cnfg.ul_specific_params.log_chan_group_present) { + log_chan_group = drb_cnfg->lc_cnfg.ul_specific_params.log_chan_group; + } else { + rrc_log->warning("LCG not present, setting to 0\n"); + } + priority = drb_cnfg->lc_cnfg.ul_specific_params.priority; + prioritized_bit_rate = liblte_rrc_prioritized_bit_rate_num[drb_cnfg->lc_cnfg.ul_specific_params.prioritized_bit_rate]; - bucket_size_duration = liblte_rrc_bucket_size_duration_num[drb_cnfg->lc_cnfg.ul_specific_params.bucket_size_duration]; + if (prioritized_bit_rate > 0) { + rrc_log->warning("PBR>0 currently not supported. Setting it to Inifinty\n"); + prioritized_bit_rate = -1; } - mac->setup_lcid(lcid, log_chan_group, priority, prioritized_bit_rate, bucket_size_duration); - drbs[lcid] = *drb_cnfg; - drb_up = true; - rrc_log->info("Added radio bearer %s\n", rb_id_text[lcid]); + bucket_size_duration = liblte_rrc_bucket_size_duration_num[drb_cnfg->lc_cnfg.ul_specific_params.bucket_size_duration]; } + mac->setup_lcid(lcid, log_chan_group, priority, prioritized_bit_rate, bucket_size_duration); - void rrc::release_drb(uint8_t lcid) { - // TODO - } + drbs[lcid] = *drb_cnfg; + drb_up = true; + rrc_log->info("Added radio bearer %s\n", rb_id_text[lcid]); +} + +void rrc::release_drb(uint8_t lcid) { + // TODO +} /************************** - * DEFAULT VALUES Section 9 +* DEFAULT VALUES Section 9 ****************************/ // PHY CONFIG DEDICATED Defaults (3GPP 36.331 v10 9.2.4) - void rrc::set_phy_default_pucch_srs() { - - phy_interface_rrc::phy_cfg_t current_cfg; - phy->get_config(¤t_cfg); - - // Set defaults to CQI, SRS and SR - current_cfg.dedicated.cqi_report_cnfg_present = false; - current_cfg.dedicated.srs_ul_cnfg_ded_present = false; - current_cfg.dedicated.sched_request_cnfg_present = false; - - apply_phy_config_dedicated(¤t_cfg.dedicated, true); - - // Release SR configuration from MAC - LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT cfg; - bzero(&cfg, sizeof(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT)); - mac->set_config_sr(&cfg); - } - - void rrc::set_phy_default() { - LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT defaults; - bzero(&defaults, sizeof(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT)); - apply_phy_config_dedicated(&defaults, true); - } - - void rrc::set_mac_default() { - apply_mac_config_dedicated(NULL, true); - LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr_cfg; - bzero(&sr_cfg, sizeof(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT)); - sr_cfg.setup_present = false; - mac->set_config_sr(&sr_cfg); - } - - void rrc::set_rrc_default() { - N310 = 1; - N311 = 1; - t301 = mac_timers->get_unique_id(); - t310 = mac_timers->get_unique_id(); - t311 = mac_timers->get_unique_id(); - safe_reset_timer = mac_timers->get_unique_id(); - mac_timers->get(t310)->set(this, 1000); - mac_timers->get(t311)->set(this, 1000); - mac_timers->get(safe_reset_timer)->set(this, 10); - } +void rrc::set_phy_default_pucch_srs() { + + phy_interface_rrc::phy_cfg_t current_cfg; + phy->get_config(¤t_cfg); + + // Set defaults to CQI, SRS and SR + current_cfg.dedicated.cqi_report_cnfg_present = false; + current_cfg.dedicated.srs_ul_cnfg_ded_present = false; + current_cfg.dedicated.sched_request_cnfg_present = false; + + apply_phy_config_dedicated(¤t_cfg.dedicated, true); + + // Release SR configuration from MAC + LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT cfg; + bzero(&cfg, sizeof(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT)); + mac->set_config_sr(&cfg); +} + +void rrc::set_phy_default() { + LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT defaults; + bzero(&defaults, sizeof(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT)); + apply_phy_config_dedicated(&defaults, true); +} + +void rrc::set_mac_default() { + apply_mac_config_dedicated(NULL, true); + LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr_cfg; + bzero(&sr_cfg, sizeof(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT)); + sr_cfg.setup_present = false; + mac->set_config_sr(&sr_cfg); +} + +void rrc::set_rrc_default() { + N310 = 1; + N311 = 1; + t301 = mac_timers->get_unique_id(); + t310 = mac_timers->get_unique_id(); + t311 = mac_timers->get_unique_id(); + safe_reset_timer = mac_timers->get_unique_id(); + mac_timers->get(t310)->set(this, 1000); + mac_timers->get(t311)->set(this, 1000); + mac_timers->get(safe_reset_timer)->set(this, 10); +} } // namespace srsue