From 569a7cbc949a415773454abf1ae647bcf393a784 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Tue, 25 Sep 2018 15:17:39 +0100 Subject: [PATCH 01/71] GTPU cleanup, adding support for GTPU echo response --- lib/include/srslte/upper/gtpu.h | 4 +- srsenb/hdr/upper/gtpu.h | 7 +- srsenb/src/upper/gtpu.cc | 138 ++++++++++++++++++-------------- 3 files changed, 82 insertions(+), 67 deletions(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 24b9c5c41..55c8189cc 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -52,8 +52,8 @@ namespace srslte { #define GTPU_HEADER_LEN 8 typedef struct{ - uint8_t flags; // Only support 0x30 - v1, PT1 (GTP), no other flags - uint8_t message_type; // Only support 0xFF - T-PDU type + uint8_t flags; + uint8_t message_type; uint16_t length; uint32_t teid; }gtpu_header_t; diff --git a/srsenb/hdr/upper/gtpu.h b/srsenb/hdr/upper/gtpu.h index 4dc05585d..519b831d9 100644 --- a/srsenb/hdr/upper/gtpu.h +++ b/srsenb/hdr/upper/gtpu.h @@ -124,12 +124,11 @@ private: }bearer_map; std::map rnti_bearers; - // Socket file descriptors - int snk_fd; - int src_fd; + // Socket file descriptor + int fd; - //Threading void run_thread(); + void echo_response(in_addr_t addr, in_port_t port, uint16_t seq); pthread_mutex_t mutex; diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 1d90fd388..777943125 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -52,35 +52,19 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ pool = byte_buffer_pool::get_instance(); - // Set up sink socket - snk_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (snk_fd < 0) { - gtpu_log->error("Failed to create sink socket\n"); + // Set up socket + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + gtpu_log->error("Failed to create socket\n"); return false; } int enable = 1; #if defined (SO_REUSEADDR) - if (setsockopt(snk_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) gtpu_log->error("setsockopt(SO_REUSEADDR) failed\n"); #endif #if defined (SO_REUSEPORT) - if (setsockopt(snk_fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) - gtpu_log->error("setsockopt(SO_REUSEPORT) failed\n"); -#endif - - - // Set up source socket - src_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (src_fd < 0) { - gtpu_log->error("Failed to create source socket\n"); - return false; - } -#if defined (SO_REUSEADDR) - if (setsockopt(src_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) - gtpu_log->error("setsockopt(SO_REUSEADDR) failed\n"); -#endif -#if defined (SO_REUSEPORT) - if (setsockopt(src_fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) gtpu_log->error("setsockopt(SO_REUSEPORT) failed\n"); #endif @@ -90,7 +74,7 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ bindaddr.sin_addr.s_addr = inet_addr(gtp_bind_addr.c_str()); bindaddr.sin_port = htons(GTPU_PORT); - if (bind(src_fd, (struct sockaddr *)&bindaddr, sizeof(struct sockaddr_in))) { + if (bind(fd, (struct sockaddr *)&bindaddr, sizeof(struct sockaddr_in))) { gtpu_log->error("Failed to bind on address %s, port %d\n", gtp_bind_addr.c_str(), GTPU_PORT); gtpu_log->console("Failed to bind on address %s, port %d\n", gtp_bind_addr.c_str(), GTPU_PORT); return false; @@ -128,11 +112,8 @@ void gtpu::stop() wait_thread_finish(); } - if (snk_fd) { - close(snk_fd); - } - if (src_fd) { - close(src_fd); + if (fd) { + close(fd); } } @@ -152,7 +133,7 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) servaddr.sin_port = htons(GTPU_PORT); gtpu_write_header(&header, pdu, gtpu_log); - if (sendto(snk_fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) { + if (sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) { perror("sendto"); } @@ -223,6 +204,10 @@ void gtpu::run_thread() } run_enable = true; + sockaddr_in client; + socklen_t client_len = sizeof(client); + size_t buflen = SRSENB_MAX_BUFFER_SIZE_BYTES - SRSENB_BUFFER_HEADER_OFFSET; + running=true; while(run_enable) { @@ -230,7 +215,7 @@ void gtpu::run_thread() gtpu_log->debug("Waiting for read...\n"); int n = 0; do{ - n = recv(src_fd, pdu->msg, SRSENB_MAX_BUFFER_SIZE_BYTES - SRSENB_BUFFER_HEADER_OFFSET, 0); + n = recvfrom(fd, pdu->msg, buflen, 0, (struct sockaddr *)&client, &client_len); } while (n == -1 && errno == EAGAIN); if (n < 0) { @@ -239,42 +224,73 @@ void gtpu::run_thread() pdu->N_bytes = (uint32_t) n; - gtpu_header_t header; - gtpu_read_header(pdu, &header,gtpu_log); - - uint16_t rnti = 0; - uint16_t lcid = 0; - teidin_to_rntilcid(header.teid, &rnti, &lcid); - - pthread_mutex_lock(&mutex); - bool user_exists = (rnti_bearers.count(rnti) > 0); - pthread_mutex_unlock(&mutex); - - if(!user_exists) { - gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti); - continue; - } - - if(lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { - gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); - continue; - } - - gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); - - pdcp->write_sdu(rnti, lcid, pdu); - - do { - pdu = pool_allocate; - if (!pdu) { - gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); - usleep(10000); + if(pdu->msg[1] == 0x01) { + if(n<10) { + continue; } - } while(!pdu); + // Echo request - send response + uint16_t seq = 0; + uint8_to_uint16(&pdu->msg[8], &seq); + echo_response(client.sin_addr.s_addr, client.sin_port, seq); + + }else{ + gtpu_header_t header; + gtpu_read_header(pdu, &header,gtpu_log); + + uint16_t rnti = 0; + uint16_t lcid = 0; + teidin_to_rntilcid(header.teid, &rnti, &lcid); + + pthread_mutex_lock(&mutex); + bool user_exists = (rnti_bearers.count(rnti) > 0); + pthread_mutex_unlock(&mutex); + + if(!user_exists) { + gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti); + continue; + } + + if(lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { + gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); + continue; + } + + gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); + + pdcp->write_sdu(rnti, lcid, pdu); + + do { + pdu = pool_allocate; + if (!pdu) { + gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); + usleep(10000); + } + } while(!pdu); + } } running = false; } +void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) +{ + gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq); + + uint8_t resp[12]; + bzero(resp, 12); + resp[0] = 0x32; //flags + resp[1] = 0x02; //type + uint16_to_uint8(4, &resp[2]); //length + uint32_to_uint8(0, &resp[4]); //TEID + uint16_to_uint8(seq, &resp[8]); //seq + + struct sockaddr_in servaddr; + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = addr; + servaddr.sin_port = port; + + sendto(fd, resp, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); +} + /**************************************************************************** * TEID to RNIT/LCID helper functions ***************************************************************************/ From 8697640945ee7306db5b5ee2fa65896a8b658580 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 10:10:00 +0200 Subject: [PATCH 02/71] drop all integrity protected NAS messages whose check is failing - also enables integrity check for messages that are only integrity protected but not ciphered --- srsue/src/upper/nas.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 197dd4367..b7fb0caaf 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -308,30 +308,31 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { uint8 pd = 0; uint8 msg_type = 0; uint8 sec_hdr_type = 0; - bool mac_valid = false; nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); // Parse the message security header liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)pdu, &pd, &sec_hdr_type); - switch(sec_hdr_type) + switch (sec_hdr_type) { case LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS: case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT: case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: + break; case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY: - break; case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED: - if((mac_valid = integrity_check(pdu))) { + if((integrity_check(pdu))) { + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED) { cipher_decrypt(pdu); - break; - } else { - nas_log->error("Not handling NAS message with integrity check error\n"); - pool->deallocate(pdu); - return; } - case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: break; + } else { + nas_log->error("Not handling NAS message with integrity check error\n"); + pool->deallocate(pdu); + return; + } + case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: + break; default: nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); pool->deallocate(pdu); From 4a68d0777b38d471b82990453d24d52844c143cf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 10:11:57 +0200 Subject: [PATCH 03/71] fix NAS tests - Modifications needed after only accepting NAS messages whose integrity check passes - Turns off loading a (possibly) existing NAS ctxt - Modifies some test vectors such that they have a zero MAC and counter 0 --- srsue/test/upper/nas_test.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 38a7f6ca3..101d403fc 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -51,7 +51,7 @@ uint8_t auth_request_pdu[] = { 0x07, 0x52, 0x01, 0x0c, 0x63, 0xa8, 0x54, 0x13, 0 uint8_t sec_mode_command_pdu[] = { 0x37, 0x37, 0xc7, 0x67, 0xae, 0x00, 0x07, 0x5d, 0x02, 0x01, 0x02, 0xe0, 0x60, 0xc1 }; -uint8_t attach_accept_pdu[] = { 0x27, 0x0f, 0x4f, 0xb3, 0xef, 0x01, 0x07, 0x42, 0x01, 0x3e, +uint8_t attach_accept_pdu[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0x01, 0x3e, 0x06, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x2a, 0x52, 0x01, 0xc1, 0x01, 0x04, 0x1b, 0x07, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33, 0x06, 0x6d, 0x6e, 0x63, 0x30, 0x30, 0x31, @@ -60,7 +60,7 @@ uint8_t attach_accept_pdu[] = { 0x27, 0x0f, 0x4f, 0xb3, 0xef, 0x01, 0x07, 0x42, 0x80, 0x50, 0x0b, 0xf6, 0x00, 0xf1, 0x10, 0x80, 0x01, 0x01, 0x35, 0x16, 0x6d, 0xbc, 0x64, 0x01, 0x00 }; -uint8_t esm_info_req_pdu[] = { 0x27, 0x1d, 0xbf, 0x7e, 0x05, 0x01, 0x02, 0x5a, 0xd9 }; +uint8_t esm_info_req_pdu[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5a, 0xd9 }; uint16 mcc = 61441; uint16 mnc = 65281; @@ -98,6 +98,7 @@ public: } std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } uint32_t get_last_sdu_len() { return last_sdu_len; } + void reset() { last_sdu_len = 0; } int plmn_search(srsue::rrc_interface_nas::found_plmn_t* found) { memcpy(found, &plmns, sizeof(found_plmn_t)); @@ -164,6 +165,7 @@ int security_command_test() srsue::nas nas; srslte_nas_config_t cfg; + ZERO_OBJECT(cfg); nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg); // push auth request PDU to NAS to generate security context @@ -218,6 +220,8 @@ int mme_attach_request_test() usim.init(&args, &usim_log); srslte_nas_config_t nas_cfg; + ZERO_OBJECT(nas_cfg); + nas_cfg.force_imsi_attach = true; nas_cfg.apn = "test123"; srsue::nas nas; nas.init(&usim, &rrc_dummy, &gw, &nas_log, nas_cfg); @@ -226,6 +230,9 @@ int mme_attach_request_test() // this will time out in the first place + // reset length of last received NAS PDU + rrc_dummy.reset(); + // finally push attach accept byte_buffer_t* tmp = byte_buffer_pool::get_instance()->allocate(); memcpy(tmp->msg, attach_accept_pdu, sizeof(attach_accept_pdu)); @@ -278,9 +285,11 @@ int esm_info_request_test() srsue::nas nas; srslte_nas_config_t cfg; + ZERO_OBJECT(cfg); cfg.apn = "srslte"; cfg.user = "srsuser"; cfg.pass = "srspass"; + cfg.force_imsi_attach = true; nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg); // push ESM info request PDU to NAS to generate response From 09a47b51b25aba901e7b9e4d34210436bd88e5bb Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 10:49:58 +0200 Subject: [PATCH 04/71] fix eNB config parsing issue causing eMBMS to be always disabled --- srsenb/src/enb_cfg_parser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 0e4771e9f..fb60f24b6 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -214,7 +214,7 @@ int enb::parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUC parser::section mbsfnSubframeConfigList("mbsfnSubframeConfigList"); sib2.add_subsection(&mbsfnSubframeConfigList); - bool mbsfn_present=false; + bool mbsfn_present=true; mbsfnSubframeConfigList.set_optional(&mbsfn_present); if (mbsfn_present) { From d6c0c7b03cda1cab9c97433f7add0a6863747d32 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 10:10:00 +0200 Subject: [PATCH 05/71] drop all integrity protected NAS messages whose check is failing - also enables integrity check for messages that are only integrity protected but not ciphered --- srsue/src/upper/nas.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index c0c263368..9655ffd81 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -287,30 +287,31 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { uint8 pd = 0; uint8 msg_type = 0; uint8 sec_hdr_type = 0; - bool mac_valid = false; nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); // Parse the message security header liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)pdu, &pd, &sec_hdr_type); - switch(sec_hdr_type) + switch (sec_hdr_type) { case LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS: case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT: case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: + break; case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY: - break; case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED: - if((mac_valid = integrity_check(pdu))) { + if((integrity_check(pdu))) { + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED) { cipher_decrypt(pdu); - break; - } else { - nas_log->error("Not handling NAS message with integrity check error\n"); - pool->deallocate(pdu); - return; } - case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: break; + } else { + nas_log->error("Not handling NAS message with integrity check error\n"); + pool->deallocate(pdu); + return; + } + case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: + break; default: nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); pool->deallocate(pdu); From b27c68abdde0c59e80ca961da07ffdd1f8094e11 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 10:11:57 +0200 Subject: [PATCH 06/71] fix NAS tests - Modifications needed after only accepting NAS messages whose integrity check passes - Turns off loading a (possibly) existing NAS ctxt - Modifies some test vectors such that they have a zero MAC and counter 0 --- srsue/test/upper/nas_test.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 38a7f6ca3..101d403fc 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -51,7 +51,7 @@ uint8_t auth_request_pdu[] = { 0x07, 0x52, 0x01, 0x0c, 0x63, 0xa8, 0x54, 0x13, 0 uint8_t sec_mode_command_pdu[] = { 0x37, 0x37, 0xc7, 0x67, 0xae, 0x00, 0x07, 0x5d, 0x02, 0x01, 0x02, 0xe0, 0x60, 0xc1 }; -uint8_t attach_accept_pdu[] = { 0x27, 0x0f, 0x4f, 0xb3, 0xef, 0x01, 0x07, 0x42, 0x01, 0x3e, +uint8_t attach_accept_pdu[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0x01, 0x3e, 0x06, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x2a, 0x52, 0x01, 0xc1, 0x01, 0x04, 0x1b, 0x07, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33, 0x06, 0x6d, 0x6e, 0x63, 0x30, 0x30, 0x31, @@ -60,7 +60,7 @@ uint8_t attach_accept_pdu[] = { 0x27, 0x0f, 0x4f, 0xb3, 0xef, 0x01, 0x07, 0x42, 0x80, 0x50, 0x0b, 0xf6, 0x00, 0xf1, 0x10, 0x80, 0x01, 0x01, 0x35, 0x16, 0x6d, 0xbc, 0x64, 0x01, 0x00 }; -uint8_t esm_info_req_pdu[] = { 0x27, 0x1d, 0xbf, 0x7e, 0x05, 0x01, 0x02, 0x5a, 0xd9 }; +uint8_t esm_info_req_pdu[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5a, 0xd9 }; uint16 mcc = 61441; uint16 mnc = 65281; @@ -98,6 +98,7 @@ public: } std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } uint32_t get_last_sdu_len() { return last_sdu_len; } + void reset() { last_sdu_len = 0; } int plmn_search(srsue::rrc_interface_nas::found_plmn_t* found) { memcpy(found, &plmns, sizeof(found_plmn_t)); @@ -164,6 +165,7 @@ int security_command_test() srsue::nas nas; srslte_nas_config_t cfg; + ZERO_OBJECT(cfg); nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg); // push auth request PDU to NAS to generate security context @@ -218,6 +220,8 @@ int mme_attach_request_test() usim.init(&args, &usim_log); srslte_nas_config_t nas_cfg; + ZERO_OBJECT(nas_cfg); + nas_cfg.force_imsi_attach = true; nas_cfg.apn = "test123"; srsue::nas nas; nas.init(&usim, &rrc_dummy, &gw, &nas_log, nas_cfg); @@ -226,6 +230,9 @@ int mme_attach_request_test() // this will time out in the first place + // reset length of last received NAS PDU + rrc_dummy.reset(); + // finally push attach accept byte_buffer_t* tmp = byte_buffer_pool::get_instance()->allocate(); memcpy(tmp->msg, attach_accept_pdu, sizeof(attach_accept_pdu)); @@ -278,9 +285,11 @@ int esm_info_request_test() srsue::nas nas; srslte_nas_config_t cfg; + ZERO_OBJECT(cfg); cfg.apn = "srslte"; cfg.user = "srsuser"; cfg.pass = "srspass"; + cfg.force_imsi_attach = true; nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg); // push ESM info request PDU to NAS to generate response From cfb3a43aed4168a83c0d46d79b5a121ddf312363 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 26 Sep 2018 14:30:39 +0200 Subject: [PATCH 07/71] Lower priority of workers --- lib/src/common/threads.c | 2 +- srsenb/hdr/phy/phy.h | 4 ++-- srsue/hdr/phy/phy.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/common/threads.c b/lib/src/common/threads.c index 024faa64a..1d35d91aa 100644 --- a/lib/src/common/threads.c +++ b/lib/src/common/threads.c @@ -86,7 +86,7 @@ bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void #else // All threads have normal priority except prio_offset=0,1,2,3,4 if (prio_offset >= 0 && prio_offset < 5) { - param.sched_priority = 50; + param.sched_priority = 50-prio_offset; pthread_attr_init(&attr); if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) { perror("pthread_attr_setinheritsched"); diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index d20079135..c1221b2ae 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -83,9 +83,9 @@ private: const static int MAX_WORKERS = 4; const static int DEFAULT_WORKERS = 2; - const static int PRACH_WORKER_THREAD_PRIO = 80; + const static int PRACH_WORKER_THREAD_PRIO = 3; const static int SF_RECV_THREAD_PRIO = 1; - const static int WORKERS_THREAD_PRIO = 0; + const static int WORKERS_THREAD_PRIO = 2; srslte::radio *radio_handler; srslte::log *log_h; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index fa3ed2fee..04599c11a 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -159,7 +159,7 @@ private: const static int DEFAULT_WORKERS = 2; const static int SF_RECV_THREAD_PRIO = 1; - const static int WORKERS_THREAD_PRIO = 0; + const static int WORKERS_THREAD_PRIO = 2; srslte::radio_multi *radio_handler; std::vector log_vec; From 58d5208bfc365d7110adec344d774204bdb1ccab Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 16:55:46 +0200 Subject: [PATCH 08/71] fix RLC AM test --- lib/test/upper/rlc_am_test.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 38d2e4641..0913dd264 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -1254,8 +1254,6 @@ bool resegment_test_7() rlc_am rlc1; rlc_am rlc2; - int len; - log1.set_level(srslte::LOG_LEVEL_DEBUG); log2.set_level(srslte::LOG_LEVEL_DEBUG); @@ -1300,7 +1298,14 @@ bool resegment_test_7() assert(pdu_bufs[i].N_bytes); } - assert(0 == rlc1.get_buffer_state()); + // Step timers until poll_retx timeout expires + int cnt = 5; + while (cnt--) { + timers.step_all(); + } + + // RLC should try to retx a random PDU because it needs to request a status from the receiver + assert(0 != rlc1.get_buffer_state()); // Skip PDU with SN 2 for(uint32_t i=0;i Date: Wed, 26 Sep 2018 16:57:07 +0200 Subject: [PATCH 09/71] fix various RLC AM issues, where - (a) no PDU is scheduled for retx after poll_retx timer expired - (b) we write outside of the PDU buffer when concatenating many SDUs --- lib/src/upper/rlc_am.cc | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index a30e0c264..933a1d9af 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -496,8 +496,10 @@ void rlc_am::rlc_am_tx::timer_expired(uint32_t timeout_id) pthread_mutex_lock(&mutex); if (poll_retx_timer != NULL && poll_retx_timer_id == timeout_id) { log->debug("Poll reTx timer expired for LCID=%d after %d ms\n", parent->lcid, poll_retx_timer->get_timeout()); - // Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit random PDU - if ((tx_window.size() >= RLC_AM_WINDOW_SIZE && retx_queue.empty() && tx_sdu_queue.size() == 0)) { + // Section 5.2.2.3 in TS 36.311, schedule random PDU for retransmission if + // (a) both tx and retx buffer are empty, or + // (b) no new data PDU can be transmitted (tx window is full) + if ((retx_queue.empty() && tx_sdu_queue.size() == 0) || tx_window.size() >= RLC_AM_WINDOW_SIZE) { retransmit_random_pdu(); } } else @@ -509,17 +511,18 @@ void rlc_am::rlc_am_tx::timer_expired(uint32_t timeout_id) void rlc_am::rlc_am_tx::retransmit_random_pdu() { - // randomly select PDU in tx window for retransmission - std::map::iterator it = tx_window.begin(); - std::advance(it, rand() % tx_window.size()); - - log->info("Schedule SN=%d for reTx.\n", it->first); - rlc_amd_retx_t retx = {}; - retx.is_segment = false; - retx.so_start = 0; - retx.so_end = it->second.buf->N_bytes; - retx.sn = it->first; - retx_queue.push_back(retx); + if (not tx_window.empty()) { + // randomly select PDU in tx window for retransmission + std::map::iterator it = tx_window.begin(); + std::advance(it, rand() % tx_window.size()); + log->info("Schedule SN=%d for reTx.\n", it->first); + rlc_amd_retx_t retx = {}; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = it->second.buf->N_bytes; + retx.sn = it->first; + retx_queue.push_back(retx); + } } uint32_t rlc_am::rlc_am_tx::get_num_tx_bytes() @@ -830,8 +833,7 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) { - if(tx_sdu == NULL && tx_sdu_queue.size() == 0) - { + if (tx_sdu == NULL && tx_sdu_queue.size() == 0) { log->info("No data available to be sent\n"); return 0; } @@ -875,7 +877,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint32_t head_len = rlc_am_packed_length(&header); uint32_t to_move = 0; uint32_t last_li = 0; - uint32_t pdu_space = nof_bytes; + uint32_t pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom()); uint8_t *pdu_ptr = pdu->msg; if(pdu_space <= head_len + 1) @@ -906,7 +908,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) tx_sdu = NULL; } if (pdu_space > to_move) { - pdu_space -= to_move; + pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom());; } else { pdu_space = 0; } @@ -934,8 +936,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; - if(tx_sdu->N_bytes == 0) - { + if (tx_sdu->N_bytes == 0) { log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", RB_NAME, tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); From e64de7ec6b6e496231108f97e14976367c1c983f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 16:59:11 +0200 Subject: [PATCH 10/71] increase maximum buffer size to accomodate max TBS for Cat4 UEs --- lib/include/srslte/common/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 0f53c4a40..27e8bf2a9 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -59,10 +59,10 @@ #define ASYNC_DL_SCHED (HARQ_DELAY_MS <= 4) -// Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI +// Cat 4 UE - Max number of DL-SCH transport block bits received within a TTI // 3GPP 36.306 Table 4.1.1 -#define SRSLTE_MAX_BUFFER_SIZE_BITS 102048 -#define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756 +#define SRSLTE_MAX_BUFFER_SIZE_BITS 150752 +#define SRSLTE_MAX_BUFFER_SIZE_BYTES (SRSLTE_MAX_BUFFER_SIZE_BITS/8) #define SRSLTE_BUFFER_HEADER_OFFSET 1020 #define SRSLTE_BUFFER_POOL_LOG_ENABLED From b603125dea401b5f439b552f86e8ba81bbf8a3e2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 26 Sep 2018 17:56:37 +0200 Subject: [PATCH 11/71] Revert "fix eNB config parsing issue causing eMBMS to be always disabled" This reverts commit 09a47b51b25aba901e7b9e4d34210436bd88e5bb. Causes issues when receiving PRACH from UE. --- srsenb/src/enb_cfg_parser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index fb60f24b6..0e4771e9f 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -214,7 +214,7 @@ int enb::parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUC parser::section mbsfnSubframeConfigList("mbsfnSubframeConfigList"); sib2.add_subsection(&mbsfnSubframeConfigList); - bool mbsfn_present=true; + bool mbsfn_present=false; mbsfnSubframeConfigList.set_optional(&mbsfn_present); if (mbsfn_present) { From 42e46bc5990ac21c4c1e3e7b143fffea16b6191b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 27 Sep 2018 18:10:35 +0200 Subject: [PATCH 12/71] Fix MBSFN section optional and default PRACH configuration for MBSFN example --- srsenb/hdr/enb.h | 2 +- srsenb/sib.conf.example | 11 ----------- srsenb/sib.conf.mbsfn.example | 6 ++---- srsenb/src/enb_cfg_parser.cc | 23 ++++++++++++----------- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 08f75bc1e..fe99f16de 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -213,7 +213,7 @@ private: bool check_srslte_version(); int parse_sib1(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *data); - int parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *data); + int parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *data, bool *mbsfn_section_present); int parse_sib3(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *data); int parse_sib4(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_4_STRUCT *data); int parse_sib9(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_9_STRUCT *data); diff --git a/srsenb/sib.conf.example b/srsenb/sib.conf.example index dded32c7c..80b2894f6 100644 --- a/srsenb/sib.conf.example +++ b/srsenb/sib.conf.example @@ -111,17 +111,6 @@ sib2 = additional_spectrum_emission = 1; }; - mbsfnSubframeConfigList = - { - radioframeAllocationPeriod = "1"; - subframeAllocationNumFrames = "1"; - radioframeAllocationOffset = 0; - subframeAllocation = 63; - - }; - - mbsfnSubframeConfigListLength = 0; - time_alignment_timer = "INFINITY"; // use "sf500", "sf750", etc. }; diff --git a/srsenb/sib.conf.mbsfn.example b/srsenb/sib.conf.mbsfn.example index 3fe2ddc11..f5ffcdd8c 100644 --- a/srsenb/sib.conf.mbsfn.example +++ b/srsenb/sib.conf.mbsfn.example @@ -46,8 +46,8 @@ sib2 = { high_speed_flag = false; prach_config_index = 3; - prach_freq_offset = 0; - zero_correlation_zone_config = 11; + prach_freq_offset = 2; + zero_correlation_zone_config = 5; }; }; pdsch_cnfg = @@ -122,8 +122,6 @@ sib2 = }; - mbsfnSubframeConfigListLength = 1; - time_alignment_timer = "INFINITY"; // use "sf500", "sf750", etc. }; diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 0e4771e9f..d928cb482 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -201,7 +201,7 @@ int enb::parse_sib1(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUC return parser::parse_section(filename, &sib1); } -int enb::parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *data) +int enb::parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *data, bool *mbsfn_section_present) { parser::section sib2("sib2"); @@ -214,12 +214,7 @@ int enb::parse_sib2(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUC parser::section mbsfnSubframeConfigList("mbsfnSubframeConfigList"); sib2.add_subsection(&mbsfnSubframeConfigList); - bool mbsfn_present=false; - mbsfnSubframeConfigList.set_optional(&mbsfn_present); - - if (mbsfn_present) { - data->mbsfn_subfr_cnfg_list_size = 1; - } + mbsfnSubframeConfigList.set_optional(mbsfn_section_present); mbsfnSubframeConfigList.add_field( new parser::field @@ -876,11 +871,12 @@ int enb::parse_sibs(all_args_t *args, rrc_cfg_t *rrc_cfg, phy_cfg_t *phy_config_ // Generate SIB2 bzero(sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); - if (parse_sib2(args->enb_files.sib_config, sib2)) { + bool mbsfn_section_present = false; + if (parse_sib2(args->enb_files.sib_config, sib2, &mbsfn_section_present)) { return -1; } - // SRS not yet supported + // SRS not yet supported sib2->rr_config_common_sib.srs_ul_cnfg.present = false; if (sib2->ul_bw.present) { switch(args->enb.n_prb) { @@ -907,8 +903,13 @@ int enb::parse_sibs(all_args_t *args, rrc_cfg_t *rrc_cfg, phy_cfg_t *phy_config_ if (sib2->arfcn_value_eutra.present) { sib2->arfcn_value_eutra.value = args->rf.ul_earfcn; } - - // Generate SIB3 if defined in mapping info + + // Update MBSFN list counter. Only 1 supported + if (mbsfn_section_present) { + sib2->mbsfn_subfr_cnfg_list_size = 1; + } + + // Generate SIB3 if defined in mapping info if (sib_is_present(sib1->sched_info, sib1->N_sched_info, LIBLTE_RRC_SIB_TYPE_3)) { bzero(sib3, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT)); if (parse_sib3(args->enb_files.sib_config, sib3)) { From ee04639337b2a29bd241eb555fc36990ab615395 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 28 Sep 2018 13:46:13 +0100 Subject: [PATCH 13/71] Changed gtpu header flags to use a bitfield. Fixing compilation issues. --- lib/include/srslte/upper/gtpu.h | 50 +++++++++++++++---- lib/src/upper/gtpu.cc | 65 +++++++++++++++++++------ srsenb/src/upper/gtpu.cc | 86 +++++++++++++++++++-------------- srsepc/src/mbms-gw/mbms-gw.cc | 15 +++--- srsepc/src/spgw/spgw.cc | 9 ++-- 5 files changed, 153 insertions(+), 72 deletions(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 55c8189cc..5cb0ed8ce 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -40,22 +40,54 @@ namespace srslte { * | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | * * 1 | Version |PT | * | E | S |PN | - * 2 | Message Type | - * 3 | Length (1st Octet) | - * 4 | Length (2nd Octet) | - * 5 | TEID (1st Octet) | - * 6 | TEID (2nd Octet) | - * 7 | TEID (3rd Octet) | - * 8 | TEID (4th Octet) | + * 2 | Message Type | + * 3 | Length (1st Octet) | + * 4 | Length (2nd Octet) | + * 5 | TEID (1st Octet) | + * 6 | TEID (2nd Octet) | + * 7 | TEID (3rd Octet) | + * 8 | TEID (4th Octet) | + * 9 | Seq Number (1st Octet) | + * 10 | Seq Number (2st Octet) | + * 11 | N-PDU | + * 12 | Next Extension Header Type | ***************************************************************************/ -#define GTPU_HEADER_LEN 8 +#define GTPU_BASE_HEADER_LEN 8 +#define GTPU_EXTENDED_HEADER_LEN 12 + +#define GTPU_VERSION_V1 1 + +#define GTP_PRIME_PROTO 0 +#define GTP_PROTO 1 + +#define GTPU_MSG_ECHO_REQUEST 0 +#define GTPU_MSG_ECHO_RESPONSE 1 +#define GTPU_MSG_ERROR_INDICATION 26 +#define GTPU_MSG_SUPPORTED_EXTENSION_HEADERS_NOTIFICATION 31 +#define GTPU_MSG_END_MARKER 254 +#define GTPU_MSG_DATA_PDU 255 typedef struct{ - uint8_t flags; + uint8_t version : 3; + uint8_t protocol_type : 1; + uint8_t star : 1; + uint8_t ext_header :1; + uint8_t sequence :1; + uint8_t pkt_number :1; +}gtpu_flags_t; + +typedef struct{ + union{ + gtpu_flags_t flag_bits; + uint8_t flags; + } gtpu_flags; uint8_t message_type; uint16_t length; uint32_t teid; + uint16_t seq_number; + uint8_t n_pdu; + uint8_t next_ext_hdr_type; }gtpu_header_t; diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index a8046aa4d..54ecdf6fc 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -37,21 +37,30 @@ namespace srslte { bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte::log *gtpu_log) { - if(header->flags != 0x30) { - gtpu_log->error("gtpu_write_header - Unhandled header flags: 0x%x\n", header->flags); + + if(header->flags.version != GTPU_VERSION_V1) { + gtpu_log->error("gtpu_write_header - Unhandled GTP-U Version.\n"); return false; } - if(header->message_type != 0xFF) { + if(header->flags.protocol_type != GTP_PROTO) { + gtpu_log->error("gtpu_write_header - Unhandled Protocol Type.\n"); + return false; + } + if(header->flags.ext_header) { + gtpu_log->error("gtpu_write_header - Unhandled Header Extensions.\n"); + return false; + } + if(header->message_type != GTPU_MSG_DATA_PDU) { gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); return false; } - if(pdu->get_headroom() < GTPU_HEADER_LEN) { + if(pdu->get_headroom() < GTPU_BASE_HEADER_LEN) { gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); return false; } - pdu->msg -= GTPU_HEADER_LEN; - pdu->N_bytes += GTPU_HEADER_LEN; + pdu->msg -= GTPU_BASE_HEADER_LEN; + pdu->N_bytes += GTPU_BASE_HEADER_LEN; uint8_t *ptr = pdu->msg; @@ -70,22 +79,50 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte: { uint8_t *ptr = pdu->msg; - pdu->msg += GTPU_HEADER_LEN; - pdu->N_bytes -= GTPU_HEADER_LEN; - - header->flags = *ptr; + header->flags = *ptr; ptr++; - header->message_type = *ptr; + header->message_type = *ptr; ptr++; uint8_to_uint16(ptr, &header->length); ptr += 2; uint8_to_uint32(ptr, &header->teid); - if(header->flags != 0x30) { - gtpu_log->error("gtpu_read_header - Unhandled header flags: 0x%x\n", header->flags); + if(header->gtpu_flags.flag_bits.version != GTPU_VERSION_V1) { + gtpu_log->error("gtpu_read_header - Unhandled GTP-U version. Flags: 0x%x\n", header->gtpu_flags.flags); return false; } - if(header->message_type != 0xFF) { + if(header->gtpu_flags.flag_bits.protocol_type != GTP_PROTO) { + gtpu_log->error("gtpu_read_header - Unhandled GTP Protocol. Flags: 0x%x\n", header->gtpu_flags.flags); + return false; + } + if(header->gtpu_flags.flag_bits.ext_header) { + gtpu_log->error("gtpu_read_header - Unhandled GTP-U Header Extensions. Flags: 0x%x\n", header->gtpu_flags.flags); + return false; + } + + //If E, S or PN are set, header is longer + if(header->gtpu_flags.flag_bits.sequence || header->gtpu_flags.flag_bits.ext_header || header->gtpu_flags.flag_bits.ext_header) { + pdu->msg += GTPU_EXTENDED_HEADER_LEN; + pdu->N_bytes -= GTPU_EXTENDED_HEADER_LEN; + + uint8_to_uint16(ptr, &header->seq_number); + ptr+=2; + + header->n_pdu = *ptr; + ptr++; + + header->next_ext_hdr_type = *ptr; + ptr++; + } else { + pdu->msg += GTPU_BASE_HEADER_LEN; + pdu->N_bytes -= GTPU_BASE_HEADER_LEN; + } + + if(header->gtpu_flags.flag_bits.sequence){ + ptr+=2; + } + + if(header->message_type != GTPU_MSG_DATA_PDU || header->message_type != GTPU_MSG_ECHO_REQUEST) { gtpu_log->error("gtpu_read_header - Unhandled message type: 0x%x\n", header->message_type); return false; } diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 777943125..62855ff5f 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -122,8 +122,10 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) { gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes); gtpu_header_t header; - header.flags = 0x30; - header.message_type = 0xFF; + bzero(&header,sizeof(header)); + header.flags.version = GTPU_VERSION_V1; + header.flags.protocol_type = GTP_PROTO; + header.message_type = GTPU_MSG_DATA_PDU; header.length = pdu->N_bytes; header.teid = rnti_bearers[rnti].teids_out[lcid]; @@ -224,48 +226,50 @@ void gtpu::run_thread() pdu->N_bytes = (uint32_t) n; - if(pdu->msg[1] == 0x01) { - if(n<10) { - continue; - } - // Echo request - send response - uint16_t seq = 0; - uint8_to_uint16(&pdu->msg[8], &seq); - echo_response(client.sin_addr.s_addr, client.sin_port, seq); + gtpu_header_t header; + if(!gtpu_read_header(pdu, &header,gtpu_log)){ + continue; + } - }else{ - gtpu_header_t header; - gtpu_read_header(pdu, &header,gtpu_log); + switch(header.message_type) { - uint16_t rnti = 0; - uint16_t lcid = 0; - teidin_to_rntilcid(header.teid, &rnti, &lcid); + case GTPU_MSG_ECHO_REQUEST: + // Echo request - send response + echo_response(client.sin_addr.s_addr, client.sin_port, header.seq_number); + break; - pthread_mutex_lock(&mutex); - bool user_exists = (rnti_bearers.count(rnti) > 0); - pthread_mutex_unlock(&mutex); + case GTPU_MSG_DATA_PDU: - if(!user_exists) { - gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti); - continue; - } + uint16_t rnti = 0; + uint16_t lcid = 0; + teidin_to_rntilcid(header.teid, &rnti, &lcid); - if(lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { - gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); - continue; - } + pthread_mutex_lock(&mutex); + bool user_exists = (rnti_bearers.count(rnti) > 0); + pthread_mutex_unlock(&mutex); - gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); - - pdcp->write_sdu(rnti, lcid, pdu); - - do { - pdu = pool_allocate; - if (!pdu) { - gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); - usleep(10000); + if(!user_exists) { + gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti); + continue; } - } while(!pdu); + + if(lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { + gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); + continue; + } + + gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); + + pdcp->write_sdu(rnti, lcid, pdu); + + do { + pdu = pool_allocate; + if (!pdu) { + gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); + usleep(10000); + } + } while(!pdu); + break; } } running = false; @@ -275,6 +279,14 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) { gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq); + gtpu_header_t header; + bzero(&header, sizeof(header)); + + //flags + header.flags.version = GTPU_VERSION_V1; + header.flags.protocol_type = GTP_PROTO; + header.flags.sequence = 1; + uint8_t resp[12]; bzero(resp, 12); resp[0] = 0x32; //flags diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index b373df4e7..03f08bcc6 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -285,31 +285,30 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg) { uint8_t version; srslte::gtpu_header_t header; + bzero(&header, sizeof(srslte::gtpu_header_t)); //Setup GTP-U header - header.flags = 0x30; - header.message_type = 0xFF; + header.flags.version = GTPU_VERSION_V1; + header.flags.protocol_type = GTP_PROTO; + header.message_type = GTPU_MSG_DATA_PDU; header.length = msg->N_bytes; header.teid = 0xAAAA; //FIXME Harcoded TEID for now //Sanity Check IP packet - if(msg->N_bytes < 20) - { + if (msg->N_bytes < 20) { m_mbms_gw_log->error("IPv4 min len: %d, drop msg len %d\n", 20, msg->N_bytes); return; } //IP Headers struct iphdr *iph = (struct iphdr *) msg->msg; - if(iph->version != 4) - { + if(iph->version != 4) { m_mbms_gw_log->warning("IPv6 not supported yet.\n"); return; } //Write GTP-U header into packet - if(!srslte::gtpu_write_header(&header, msg, m_mbms_gw_log)) - { + if (!srslte::gtpu_write_header(&header, msg, m_mbms_gw_log)) { m_mbms_gw_log->console("Error writing GTP-U header on PDU\n"); } diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 20311cc16..2c34e5da8 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -363,14 +363,15 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) //Setup GTP-U header srslte::gtpu_header_t header; - header.flags = 0x30; - header.message_type = 0xFF; + bzero(&header,sizeof(srslte::gtpu_header_t)); + header.flags.version = GTPU_VERSION_V1; + header.flags.protocol_type = GTP_PROTO; + header.message_type = GTPU_MSG_DATA_PDU; header.length = msg->N_bytes; header.teid = enb_fteid.teid; //Write header into packet - if(!srslte::gtpu_write_header(&header, msg, m_spgw_log)) - { + if (!srslte::gtpu_write_header(&header, msg, m_spgw_log)) { m_spgw_log->console("Error writing GTP-U header on PDU\n"); } From e320c33aefad68008b41a80c31f750b5e3ed4f9a Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 28 Sep 2018 15:42:28 +0100 Subject: [PATCH 14/71] Fixed last compilation issues. --- lib/src/upper/gtpu.cc | 10 +++++----- srsenb/src/upper/gtpu.cc | 30 ++++++++++++++++-------------- srsepc/src/mbms-gw/mbms-gw.cc | 4 ++-- srsepc/src/spgw/spgw.cc | 18 +++++++----------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 54ecdf6fc..b01f834fb 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -38,15 +38,15 @@ namespace srslte { bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte::log *gtpu_log) { - if(header->flags.version != GTPU_VERSION_V1) { + if(header->gtpu_flags.flag_bits.version != GTPU_VERSION_V1) { gtpu_log->error("gtpu_write_header - Unhandled GTP-U Version.\n"); return false; } - if(header->flags.protocol_type != GTP_PROTO) { + if(header->gtpu_flags.flag_bits.protocol_type != GTP_PROTO) { gtpu_log->error("gtpu_write_header - Unhandled Protocol Type.\n"); return false; } - if(header->flags.ext_header) { + if(header->gtpu_flags.flag_bits.ext_header) { gtpu_log->error("gtpu_write_header - Unhandled Header Extensions.\n"); return false; } @@ -64,7 +64,7 @@ bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte uint8_t *ptr = pdu->msg; - *ptr = header->flags; + *ptr = header->gtpu_flags.flags; ptr++; *ptr = header->message_type; ptr++; @@ -79,7 +79,7 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte: { uint8_t *ptr = pdu->msg; - header->flags = *ptr; + header->gtpu_flags.flags = *ptr; ptr++; header->message_type = *ptr; ptr++; diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 62855ff5f..99bcd7e25 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -123,8 +123,8 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes); gtpu_header_t header; bzero(&header,sizeof(header)); - header.flags.version = GTPU_VERSION_V1; - header.flags.protocol_type = GTP_PROTO; + header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; + header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; header.message_type = GTPU_MSG_DATA_PDU; header.length = pdu->N_bytes; header.teid = rnti_bearers[rnti].teids_out[lcid]; @@ -282,25 +282,27 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) gtpu_header_t header; bzero(&header, sizeof(header)); - //flags - header.flags.version = GTPU_VERSION_V1; - header.flags.protocol_type = GTP_PROTO; - header.flags.sequence = 1; + srslte::byte_buffer_t *pdu = pool_allocate; - uint8_t resp[12]; - bzero(resp, 12); - resp[0] = 0x32; //flags - resp[1] = 0x02; //type - uint16_to_uint8(4, &resp[2]); //length - uint32_to_uint8(0, &resp[4]); //TEID - uint16_to_uint8(seq, &resp[8]); //seq + //flags + header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; + header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; + header.gtpu_flags.flag_bits.sequence = 1; + + header.message_type = GTPU_MSG_ECHO_RESPONSE; + header.teid = 0; + header.length = 4; + header.seq_number = seq; + + gtpu_write_header(&header,pdu,gtpu_log); struct sockaddr_in servaddr; servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = addr; servaddr.sin_port = port; - sendto(fd, resp, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); + sendto(fd, pdu->msg, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); + pool->deallocate(pdu); } /**************************************************************************** diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index 03f08bcc6..e9d828451 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -288,8 +288,8 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg) bzero(&header, sizeof(srslte::gtpu_header_t)); //Setup GTP-U header - header.flags.version = GTPU_VERSION_V1; - header.flags.protocol_type = GTP_PROTO; + header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; + header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; header.message_type = GTPU_MSG_DATA_PDU; header.length = msg->N_bytes; header.teid = 0xAAAA; //FIXME Harcoded TEID for now diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 2c34e5da8..da36fdaac 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -330,28 +330,24 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) srslte::gtpc_f_teid_ie enb_fteid; struct iphdr *iph = (struct iphdr *) msg->msg; - if(iph->version != 4) - { + if (iph->version != 4) { m_spgw_log->warning("IPv6 not supported yet.\n"); return; } - if(iph->tot_len < 20) - { + if (iph->tot_len < 20) { m_spgw_log->warning("Invalid IP header length.\n"); return; } pthread_mutex_lock(&m_mutex); gtp_fteid_it = m_ip_to_teid.find(iph->daddr); - if(gtp_fteid_it != m_ip_to_teid.end()) - { + if (gtp_fteid_it != m_ip_to_teid.end()) { ip_found = true; enb_fteid = gtp_fteid_it->second; } pthread_mutex_unlock(&m_mutex); - if(ip_found == false) - { + if (ip_found == false) { //m_spgw_log->console("IP Packet is not for any UE\n"); return; } @@ -364,9 +360,9 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) //Setup GTP-U header srslte::gtpu_header_t header; bzero(&header,sizeof(srslte::gtpu_header_t)); - header.flags.version = GTPU_VERSION_V1; - header.flags.protocol_type = GTP_PROTO; - header.message_type = GTPU_MSG_DATA_PDU; + header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; + header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; + header.message_type = GTPU_MSG_DATA_PDU; header.length = msg->N_bytes; header.teid = enb_fteid.teid; From 7b4bc6f132f85e7348a4b8d466712db6b1cfd947 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 28 Sep 2018 20:04:01 +0100 Subject: [PATCH 15/71] Integrity fail after service request (#268) * Adding some debug prints to confirm the issue. * Cleanup whitespaces. * More debug prints * Adding boolean to whether it is actually necessary to send NAS message in RRC reconfiguration. * Deleting debug prints. --- srsenb/hdr/upper/rrc.h | 74 +++++++++++++++++++++-------------------- srsenb/src/upper/rrc.cc | 57 ++++++++++++++++++------------- 2 files changed, 71 insertions(+), 60 deletions(-) diff --git a/srsenb/hdr/upper/rrc.h b/srsenb/hdr/upper/rrc.h index c640df197..8a57f6e09 100644 --- a/srsenb/hdr/upper/rrc.h +++ b/srsenb/hdr/upper/rrc.h @@ -182,39 +182,39 @@ public: bool running; void run_thread(); }; - + class ue { - public: - ue(); + public: + ue(); bool is_connected(); - bool is_idle(); + bool is_idle(); bool is_timeout(); void set_activity(); uint32_t rl_failure(); rrc_state_t get_state(); - + void send_connection_setup(bool is_setup = true); - void send_connection_reest(); + void send_connection_reest(); void send_connection_release(); - void send_connection_reest_rej(); + void send_connection_reest_rej(); void send_connection_reconf(srslte::byte_buffer_t *sdu); void send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e); - void send_connection_reconf_upd(srslte::byte_buffer_t *pdu); + void send_connection_reconf_upd(srslte::byte_buffer_t *pdu); void send_security_mode_command(); void send_ue_cap_enquiry(); void parse_ul_dcch(uint32_t lcid, srslte::byte_buffer_t* pdu); void handle_rrc_con_req(LIBLTE_RRC_CONNECTION_REQUEST_STRUCT *msg); - void handle_rrc_con_reest_req(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_REQUEST_STRUCT *msg); + void handle_rrc_con_reest_req(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_REQUEST_STRUCT *msg); void handle_rrc_con_setup_complete(LIBLTE_RRC_CONNECTION_SETUP_COMPLETE_STRUCT *msg, srslte::byte_buffer_t *pdu); void handle_rrc_reconf_complete(LIBLTE_RRC_CONNECTION_RECONFIGURATION_COMPLETE_STRUCT *msg, srslte::byte_buffer_t *pdu); void handle_security_mode_complete(LIBLTE_RRC_SECURITY_MODE_COMPLETE_STRUCT *msg); void handle_security_mode_failure(LIBLTE_RRC_SECURITY_MODE_FAILURE_STRUCT *msg); void handle_ue_cap_info(LIBLTE_RRC_UE_CAPABILITY_INFORMATION_STRUCT *msg); - + void set_bitrates(LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT *rates); void set_security_capabilities(LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT *caps); void set_security_key(uint8_t* key, uint32_t length); @@ -229,26 +229,26 @@ public: void notify_s1ap_ue_ctxt_setup_complete(); void notify_s1ap_ue_erab_setup_response(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e); - int sr_allocate(uint32_t period, uint32_t *I_sr, uint32_t *N_pucch_sr); - void sr_get(uint32_t *I_sr, uint32_t *N_pucch_sr); + int sr_allocate(uint32_t period, uint32_t *I_sr, uint32_t *N_pucch_sr); + void sr_get(uint32_t *I_sr, uint32_t *N_pucch_sr); int sr_free(); - int cqi_allocate(uint32_t period, uint32_t *pmi_idx, uint32_t *n_pucch); - void cqi_get(uint32_t *pmi_idx, uint32_t *n_pucch); - int cqi_free(); - + int cqi_allocate(uint32_t period, uint32_t *pmi_idx, uint32_t *n_pucch); + void cqi_get(uint32_t *pmi_idx, uint32_t *n_pucch); + int cqi_free(); + void send_dl_ccch(LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ccch_msg); void send_dl_dcch(LIBLTE_RRC_DL_DCCH_MSG_STRUCT *dl_dcch_msg, srslte::byte_buffer_t *pdu = NULL); - - uint16_t rnti; - rrc *parent; - - bool connect_notified; - + + uint16_t rnti; + rrc *parent; + + bool connect_notified; + private: srslte::byte_buffer_pool *pool; - struct timeval t_last_activity; + struct timeval t_last_activity; LIBLTE_RRC_CON_REQ_EST_CAUSE_ENUM establishment_cause; @@ -260,10 +260,10 @@ public: uint32_t rlf_cnt; uint8_t transaction_id; rrc_state_t state; - + std::map srbs; std::map drbs; - + uint8_t k_enb[32]; // Provided by MME uint8_t k_rrc_enc[32]; uint8_t k_rrc_int[32]; @@ -290,20 +290,21 @@ public: bool sr_allocated; uint32_t sr_N_pucch; uint32_t sr_I; - uint32_t cqi_pucch; - uint32_t cqi_idx; - bool cqi_allocated; - int cqi_sched_sf_idx; + uint32_t cqi_pucch; + uint32_t cqi_idx; + bool cqi_allocated; + int cqi_sched_sf_idx; int cqi_sched_prb_idx; int get_drbid_config(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb, int drbid); + bool nas_pending; srslte::byte_buffer_t erab_info; - }; - - -private: - + }; + + +private: + std::map users; - + std::map pending_paging; activity_monitor act_monitor; @@ -362,7 +363,8 @@ private: typedef struct { uint32_t nof_users[100][80]; } sr_sched_t; - + + sr_sched_t sr_sched; sr_sched_t cqi_sched; LIBLTE_RRC_MCCH_MSG_STRUCT mcch; diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 269e5dcaf..eae78d4bd 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -885,24 +885,25 @@ void rrc::activity_monitor::run_thread() *******************************************************************************/ rrc::ue::ue() { - parent = NULL; + parent = NULL; set_activity(); - has_tmsi = false; - connect_notified = false; - transaction_id = 0; - sr_allocated = false; - sr_sched_sf_idx = 0; - sr_sched_prb_idx = 0; - sr_N_pucch = 0; - sr_I = 0; - cqi_allocated = false; - cqi_pucch = 0; - cqi_idx = 0; - cqi_sched_sf_idx = 0; + has_tmsi = false; + connect_notified = false; + transaction_id = 0; + sr_allocated = false; + sr_sched_sf_idx = 0; + sr_sched_prb_idx = 0; + sr_N_pucch = 0; + sr_I = 0; + cqi_allocated = false; + cqi_pucch = 0; + cqi_idx = 0; + cqi_sched_sf_idx = 0; cqi_sched_prb_idx = 0; - rlf_cnt = 0; - state = RRC_STATE_IDLE; - pool = srslte::byte_buffer_pool::get_instance(); + rlf_cnt = 0; + nas_pending = false; + state = RRC_STATE_IDLE; + pool = srslte::byte_buffer_pool::get_instance(); } rrc_state_t rrc::ue::get_state() @@ -1227,9 +1228,12 @@ void rrc::ue::setup_erab(uint8_t id, LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT parent->gtpu->add_bearer(rnti, lcid, addr_, erabs[id].teid_out, &(erabs[id].teid_in)); if(nas_pdu) { + nas_pending = true; memcpy(erab_info.buffer, nas_pdu->buffer, nas_pdu->n_octets); erab_info.N_bytes = nas_pdu->n_octets; parent->rrc_log->info_hex(erab_info.buffer, erab_info.N_bytes, "setup_erab nas_pdu -> erab_info rnti 0x%x", rnti); + } else { + nas_pending = false; } } @@ -1666,18 +1670,23 @@ void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu) // DRB1 has already been configured in GTPU through bearer setup - // Add NAS Attach accept - conn_reconf->N_ded_info_nas = 1; + // Add NAS Attach accept + if(nas_pending){ + parent->rrc_log->debug("Adding NAS message to connection reconfiguration\n"); + conn_reconf->N_ded_info_nas = 1; - parent->rrc_log->info_hex(erab_info.buffer, erab_info.N_bytes, "connection_reconf erab_info -> nas_info rnti 0x%x\n", rnti); - conn_reconf->ded_info_nas_list[0].N_bytes = erab_info.N_bytes; - memcpy(conn_reconf->ded_info_nas_list[0].msg, erab_info.buffer, erab_info.N_bytes); - + parent->rrc_log->info_hex(erab_info.buffer, erab_info.N_bytes, "connection_reconf erab_info -> nas_info rnti 0x%x\n", rnti); + conn_reconf->ded_info_nas_list[0].N_bytes = erab_info.N_bytes; + memcpy(conn_reconf->ded_info_nas_list[0].msg, erab_info.buffer, erab_info.N_bytes); + } else { + parent->rrc_log->debug("Not adding NAS message to connection reconfiguration\n"); + conn_reconf->N_ded_info_nas = 0; + } // Reuse same PDU pdu->reset(); - + send_dl_dcch(&dl_dcch_msg, pdu); - + state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; } From 26ed7fe2add78be5ce32b9f026c20cf10da16d12 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 28 Sep 2018 21:05:48 +0200 Subject: [PATCH 16/71] do not delete LCG config during reset of BSR procedure (#269) - this caused an issue after HO when the LCGs where gone and hence no BSR was provided for DRB until RRC reestablishment --- srsue/src/mac/proc_bsr.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/srsue/src/mac/proc_bsr.cc b/srsue/src/mac/proc_bsr.cc index bd49671df..1026bf2f1 100644 --- a/srsue/src/mac/proc_bsr.cc +++ b/srsue/src/mac/proc_bsr.cc @@ -41,8 +41,15 @@ bsr_proc::bsr_proc() initiated = false; last_print = 0; next_tx_tti = 0; - triggered_bsr_type=NONE; - + triggered_bsr_type=NONE; + + for (int i=0;i Date: Mon, 1 Oct 2018 15:17:26 +0100 Subject: [PATCH 17/71] Dropping bitfields for now. Using #defines and uint8_t for the flags. --- lib/include/srslte/upper/gtpu.h | 74 +++++++++++++++----------------- lib/src/upper/gtpu.cc | 75 +++++++++++++++------------------ srsenb/src/upper/gtpu.cc | 15 +++---- srsepc/src/mbms-gw/mbms-gw.cc | 4 +- srsepc/src/spgw/spgw.cc | 6 +-- 5 files changed, 76 insertions(+), 98 deletions(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 5cb0ed8ce..41e9dc2e9 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -56,10 +56,13 @@ namespace srslte { #define GTPU_BASE_HEADER_LEN 8 #define GTPU_EXTENDED_HEADER_LEN 12 -#define GTPU_VERSION_V1 1 - -#define GTP_PRIME_PROTO 0 -#define GTP_PROTO 1 +#define GTPU_FLAGS_VERSION_MASK 0xE0 +#define GTPU_FLAGS_VERSION_V1 0x20 +#define GTPU_FLAGS_GTP_PRIME_PROTOCOL 0x00 +#define GTPU_FLAGS_GTP_PROTOCOL 0x10 +#define GTPU_FLAGS_EXTENDED_HDR 0x04 +#define GTPU_FLAGS_SEQUENCE 0x02 +#define GTPU_FLAGS_PACKET_NUM 0x01 #define GTPU_MSG_ECHO_REQUEST 0 #define GTPU_MSG_ECHO_RESPONSE 1 @@ -69,19 +72,7 @@ namespace srslte { #define GTPU_MSG_DATA_PDU 255 typedef struct{ - uint8_t version : 3; - uint8_t protocol_type : 1; - uint8_t star : 1; - uint8_t ext_header :1; - uint8_t sequence :1; - uint8_t pkt_number :1; -}gtpu_flags_t; - -typedef struct{ - union{ - gtpu_flags_t flag_bits; - uint8_t flags; - } gtpu_flags; + uint8_t flags; uint8_t message_type; uint16_t length; uint32_t teid; @@ -94,35 +85,38 @@ typedef struct{ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte::log *gtpu_log); bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte::log *gtpu_log); -inline void uint8_to_uint32(uint8_t *buf, uint32_t *i) +inline bool gtpu_supported_flags_check(gtpu_header_t *header, srslte::log *gtpu_log) { - *i = (uint32_t)buf[0] << 24 | - (uint32_t)buf[1] << 16 | - (uint32_t)buf[2] << 8 | - (uint32_t)buf[3]; + //flags + if( (header->flags & GTPU_FLAGS_VERSION_MASK) != GTPU_FLAGS_VERSION_V1 ) { + gtpu_log->error("gtpu_write_header - Unhandled GTP-U Version.\n"); + return false; + } + if( !(header->flags & GTPU_FLAGS_GTP_PROTOCOL) ) { + gtpu_log->error("gtpu_write_header - Unhandled Protocol Type.\n"); + return false; + } + if( !(header->flags & GTPU_FLAGS_EXTENDED_HDR) ) { + gtpu_log->error("gtpu_write_header - Unhandled Header Extensions.\n"); + return false; + } + if( !(header->flags & GTPU_FLAGS_PACKET_NUM) ) { + gtpu_log->error("gtpu_write_header - Unhandled Packet Number.\n"); + return false; + } + return true; } -inline void uint32_to_uint8(uint32_t i, uint8_t *buf) +inline bool gtpu_supported_msg_type_check(gtpu_header_t *header, srslte::log *gtpu_log) { - buf[0] = (i >> 24) & 0xFF; - buf[1] = (i >> 16) & 0xFF; - buf[2] = (i >> 8) & 0xFF; - buf[3] = i & 0xFF; + //msg_tpye + if(header->message_type != GTPU_MSG_DATA_PDU || header->message_type != GTPU_MSG_ECHO_REQUEST) { + gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); + return false; + } + return true; } -inline void uint8_to_uint16(uint8_t *buf, uint16_t *i) -{ - *i = (uint32_t)buf[0] << 8 | - (uint32_t)buf[1]; -} - -inline void uint16_to_uint8(uint16_t i, uint8_t *buf) -{ - buf[0] = (i >> 8) & 0xFF; - buf[1] = i & 0xFF; -} - - }//namespace #endif diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index b01f834fb..b373cc546 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -26,7 +26,7 @@ #include "srslte/upper/gtpu.h" - +#include "srslte/common/int_helpers.h" namespace srslte { @@ -37,40 +37,45 @@ namespace srslte { bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte::log *gtpu_log) { + //flags + if(!gtpu_supported_flags_check(header,gtpu_log)){ + return false; + } - if(header->gtpu_flags.flag_bits.version != GTPU_VERSION_V1) { - gtpu_log->error("gtpu_write_header - Unhandled GTP-U Version.\n"); - return false; - } - if(header->gtpu_flags.flag_bits.protocol_type != GTP_PROTO) { - gtpu_log->error("gtpu_write_header - Unhandled Protocol Type.\n"); - return false; - } - if(header->gtpu_flags.flag_bits.ext_header) { - gtpu_log->error("gtpu_write_header - Unhandled Header Extensions.\n"); - return false; - } - if(header->message_type != GTPU_MSG_DATA_PDU) { + //msg type + if(header->message_type != GTPU_MSG_DATA_PDU || header->message_type != GTPU_MSG_ECHO_REQUEST) { gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); return false; } - if(pdu->get_headroom() < GTPU_BASE_HEADER_LEN) { - gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); - return false; + + //If E, S or PN are set, the header is longer + if (header->flags & (GTPU_FLAGS_EXTENDED_HDR | GTPU_FLAGS_SEQUENCE | GTPU_FLAGS_PACKET_NUM)) { + if(pdu->get_headroom() < GTPU_EXTENDED_HEADER_LEN) { + gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); + return false; + } + pdu->msg -= GTPU_EXTENDED_HEADER_LEN; + pdu->N_bytes += GTPU_EXTENDED_HEADER_LEN; + } else { + if(pdu->get_headroom() < GTPU_BASE_HEADER_LEN) { + gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); + return false; + } + pdu->msg -= GTPU_BASE_HEADER_LEN; + pdu->N_bytes += GTPU_BASE_HEADER_LEN; } - pdu->msg -= GTPU_BASE_HEADER_LEN; - pdu->N_bytes += GTPU_BASE_HEADER_LEN; - + //write mandatory fields uint8_t *ptr = pdu->msg; - - *ptr = header->gtpu_flags.flags; + *ptr = header->flags; ptr++; *ptr = header->message_type; ptr++; uint16_to_uint8(header->length, ptr); ptr += 2; uint32_to_uint8(header->teid, ptr); + //write optional fields + return true; } @@ -79,7 +84,7 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte: { uint8_t *ptr = pdu->msg; - header->gtpu_flags.flags = *ptr; + header->flags = *ptr; ptr++; header->message_type = *ptr; ptr++; @@ -87,21 +92,18 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte: ptr += 2; uint8_to_uint32(ptr, &header->teid); - if(header->gtpu_flags.flag_bits.version != GTPU_VERSION_V1) { - gtpu_log->error("gtpu_read_header - Unhandled GTP-U version. Flags: 0x%x\n", header->gtpu_flags.flags); + //flags + if(!gtpu_supported_flags_check(header,gtpu_log)){ return false; } - if(header->gtpu_flags.flag_bits.protocol_type != GTP_PROTO) { - gtpu_log->error("gtpu_read_header - Unhandled GTP Protocol. Flags: 0x%x\n", header->gtpu_flags.flags); - return false; - } - if(header->gtpu_flags.flag_bits.ext_header) { - gtpu_log->error("gtpu_read_header - Unhandled GTP-U Header Extensions. Flags: 0x%x\n", header->gtpu_flags.flags); + + //message_type + if(!gtpu_supported_msg_type_check(header,gtpu_log)){ return false; } //If E, S or PN are set, header is longer - if(header->gtpu_flags.flag_bits.sequence || header->gtpu_flags.flag_bits.ext_header || header->gtpu_flags.flag_bits.ext_header) { + if (header->flags & (GTPU_FLAGS_EXTENDED_HDR | GTPU_FLAGS_SEQUENCE | GTPU_FLAGS_PACKET_NUM)) { pdu->msg += GTPU_EXTENDED_HEADER_LEN; pdu->N_bytes -= GTPU_EXTENDED_HEADER_LEN; @@ -118,15 +120,6 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte: pdu->N_bytes -= GTPU_BASE_HEADER_LEN; } - if(header->gtpu_flags.flag_bits.sequence){ - ptr+=2; - } - - if(header->message_type != GTPU_MSG_DATA_PDU || header->message_type != GTPU_MSG_ECHO_REQUEST) { - gtpu_log->error("gtpu_read_header - Unhandled message type: 0x%x\n", header->message_type); - return false; - } - return true; } diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 99bcd7e25..acce49eb6 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -122,9 +122,7 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) { gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes); gtpu_header_t header; - bzero(&header,sizeof(header)); - header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; - header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; header.message_type = GTPU_MSG_DATA_PDU; header.length = pdu->N_bytes; header.teid = rnti_bearers[rnti].teids_out[lcid]; @@ -280,19 +278,16 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq); gtpu_header_t header; - bzero(&header, sizeof(header)); - srslte::byte_buffer_t *pdu = pool_allocate; - //flags - header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; - header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; - header.gtpu_flags.flag_bits.sequence = 1; - + //header + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE; header.message_type = GTPU_MSG_ECHO_RESPONSE; header.teid = 0; header.length = 4; header.seq_number = seq; + header.n_pdu = 0; + header.next_ext_hdr_type = 0; gtpu_write_header(&header,pdu,gtpu_log); diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index e9d828451..dc8199e27 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -285,11 +285,9 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg) { uint8_t version; srslte::gtpu_header_t header; - bzero(&header, sizeof(srslte::gtpu_header_t)); //Setup GTP-U header - header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; - header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; header.message_type = GTPU_MSG_DATA_PDU; header.length = msg->N_bytes; header.teid = 0xAAAA; //FIXME Harcoded TEID for now diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index da36fdaac..0a867d51c 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -359,10 +359,8 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) //Setup GTP-U header srslte::gtpu_header_t header; - bzero(&header,sizeof(srslte::gtpu_header_t)); - header.gtpu_flags.flag_bits.version = GTPU_VERSION_V1; - header.gtpu_flags.flag_bits.protocol_type = GTP_PROTO; - header.message_type = GTPU_MSG_DATA_PDU; + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; + header.message_type = GTPU_MSG_DATA_PDU; header.length = msg->N_bytes; header.teid = enb_fteid.teid; From c9cd355cdb891b1335edd3dc585b43ee8d2426a6 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 1 Oct 2018 15:46:14 +0100 Subject: [PATCH 18/71] Forgot to use supported_msg_type_check in gtpu_write_header. --- lib/src/upper/gtpu.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index b373cc546..38a8cd572 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -43,8 +43,7 @@ bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte } //msg type - if(header->message_type != GTPU_MSG_DATA_PDU || header->message_type != GTPU_MSG_ECHO_REQUEST) { - gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); + if(!gtpu_supported_msg_type_check(header,gtpu_log)){ return false; } From 2ff900d971b39201a7c75606b5b5feceadd9e3dd Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 1 Oct 2018 16:02:00 +0100 Subject: [PATCH 19/71] Making sure that GTPU optional fields get written --- lib/src/upper/gtpu.cc | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 38a8cd572..25e6fea75 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -73,9 +73,30 @@ bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte uint16_to_uint8(header->length, ptr); ptr += 2; uint32_to_uint8(header->teid, ptr); - //write optional fields - - + //write optional fields, if E, S or PN are set. + if (header->flags & (GTPU_FLAGS_EXTENDED_HDR | GTPU_FLAGS_SEQUENCE | GTPU_FLAGS_PACKET_NUM)) { + //S + if (header->flags & GTPU_FLAGS_SEQUENCE ) { + uint16_to_uint8(header->seq_number, ptr); + } else { + uint16_to_uint8(0, ptr); + } + ptr+=2; + //PN + if (header->flags & GTPU_FLAGS_PACKET_NUM ) { + *ptr = header->n_pdu; + } else { + header=>n_pdu = 0; + } + ptr++; + //E + if (header->flags & GTPU_FLAGS_EXTENDED_HDR ) { + *ptr = header->next_ext_hdr_type; + } else { + *ptr = 0; + } + ptr++; + } return true; } From efffd3dec971be54e75c611b23c9c8a261d81d28 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 1 Oct 2018 16:05:26 +0100 Subject: [PATCH 20/71] Fix compilation mistake. --- lib/src/upper/gtpu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 25e6fea75..283270f0b 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -86,7 +86,7 @@ bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte if (header->flags & GTPU_FLAGS_PACKET_NUM ) { *ptr = header->n_pdu; } else { - header=>n_pdu = 0; + header->n_pdu = 0; } ptr++; //E From e925ef0a42324c1247f0ef01765c5e509ef9ab5d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 1 Oct 2018 17:34:02 +0100 Subject: [PATCH 21/71] Added some more debug infor to error prints. Making sure that packet is not sent from the eNB if there is an error in the GTP-U header packing. Fixed error in checking msg_type. --- lib/include/srslte/upper/gtpu.h | 16 ++++++++-------- lib/src/upper/gtpu.cc | 4 ++++ srsenb/hdr/upper/gtpu.h | 18 ------------------ srsenb/src/upper/gtpu.cc | 5 ++++- 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 41e9dc2e9..df388ba02 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -89,19 +89,19 @@ inline bool gtpu_supported_flags_check(gtpu_header_t *header, srslte::log *gtpu_ { //flags if( (header->flags & GTPU_FLAGS_VERSION_MASK) != GTPU_FLAGS_VERSION_V1 ) { - gtpu_log->error("gtpu_write_header - Unhandled GTP-U Version.\n"); + gtpu_log->error("gtpu_header - Unhandled GTP-U Version. Flags: 0x%x\n", header->flags); return false; } if( !(header->flags & GTPU_FLAGS_GTP_PROTOCOL) ) { - gtpu_log->error("gtpu_write_header - Unhandled Protocol Type.\n"); + gtpu_log->error("gtpu_header - Unhandled Protocol Type. Flags: 0x%x\n\n", header->flags); return false; } - if( !(header->flags & GTPU_FLAGS_EXTENDED_HDR) ) { - gtpu_log->error("gtpu_write_header - Unhandled Header Extensions.\n"); + if( header->flags & GTPU_FLAGS_EXTENDED_HDR ) { + gtpu_log->error("gtpu_header - Unhandled Header Extensions. Flags: 0x%x\n\n", header->flags); return false; } - if( !(header->flags & GTPU_FLAGS_PACKET_NUM) ) { - gtpu_log->error("gtpu_write_header - Unhandled Packet Number.\n"); + if( header->flags & GTPU_FLAGS_PACKET_NUM ) { + gtpu_log->error("gtpu_header - Unhandled Packet Number. Flags: 0x%x\n\n", header->flags); return false; } return true; @@ -110,8 +110,8 @@ inline bool gtpu_supported_flags_check(gtpu_header_t *header, srslte::log *gtpu_ inline bool gtpu_supported_msg_type_check(gtpu_header_t *header, srslte::log *gtpu_log) { //msg_tpye - if(header->message_type != GTPU_MSG_DATA_PDU || header->message_type != GTPU_MSG_ECHO_REQUEST) { - gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); + if( header->message_type != GTPU_MSG_DATA_PDU && header->message_type != GTPU_MSG_ECHO_REQUEST ) { + gtpu_log->error("gtpu_header - Unhandled message type: 0x%x\n", header->message_type); return false; } return true; diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 283270f0b..537b1043c 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -39,11 +39,13 @@ bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu, srslte { //flags if(!gtpu_supported_flags_check(header,gtpu_log)){ + gtpu_log->error("gtpu_write_header - Unhandled GTP-U Flags. Flags: 0x%x\n", header->flags); return false; } //msg type if(!gtpu_supported_msg_type_check(header,gtpu_log)){ + gtpu_log->error("gtpu_write_header - Unhandled GTP-U Message Type. Message Type: 0x%x\n", header->message_type); return false; } @@ -114,11 +116,13 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte: //flags if(!gtpu_supported_flags_check(header,gtpu_log)){ + gtpu_log->error("gtpu_read_header - Unhandled GTP-U Flags. Flags: 0x%x\n", header->flags); return false; } //message_type if(!gtpu_supported_msg_type_check(header,gtpu_log)){ + gtpu_log->error("gtpu_read_header - Unhandled GTP-U Message Type. Flags: 0x%x\n", header->message_type); return false; } diff --git a/srsenb/hdr/upper/gtpu.h b/srsenb/hdr/upper/gtpu.h index 519b831d9..3771ec402 100644 --- a/srsenb/hdr/upper/gtpu.h +++ b/srsenb/hdr/upper/gtpu.h @@ -40,24 +40,6 @@ namespace srsenb { -/**************************************************************************** - * GTPU Header - * Ref: 3GPP TS 29.281 v10.1.0 Section 5 - * - * | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | - * - * 1 | Version |PT | * | E | S |PN | - * 2 | Message Type | - * 3 | Length (1st Octet) | - * 4 | Length (2nd Octet) | - * 5 | TEID (1st Octet) | - * 6 | TEID (2nd Octet) | - * 7 | TEID (3rd Octet) | - * 8 | TEID (4th Octet) | - ***************************************************************************/ - -#define GTPU_HEADER_LEN 8 - class gtpu :public gtpu_interface_rrc ,public gtpu_interface_pdcp diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index acce49eb6..d6cc3fc89 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -132,7 +132,10 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) servaddr.sin_addr.s_addr = htonl(rnti_bearers[rnti].spgw_addrs[lcid]); servaddr.sin_port = htons(GTPU_PORT); - gtpu_write_header(&header, pdu, gtpu_log); + if(!gtpu_write_header(&header, pdu, gtpu_log)){ + gtpu_log->error("Error writing GTP-U Header. Flags 0x%x, Message Type 0x%x\n", header.flags, header.message_type); + return; + } if (sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) { perror("sendto"); } From a2befbd949118adb35ec3908282616ccf10324aa Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 1 Oct 2018 18:07:30 +0100 Subject: [PATCH 22/71] Fix mistake in echo reply/response message type. --- lib/include/srslte/upper/gtpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index df388ba02..2756bc0ab 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -64,8 +64,8 @@ namespace srslte { #define GTPU_FLAGS_SEQUENCE 0x02 #define GTPU_FLAGS_PACKET_NUM 0x01 -#define GTPU_MSG_ECHO_REQUEST 0 -#define GTPU_MSG_ECHO_RESPONSE 1 +#define GTPU_MSG_ECHO_REQUEST 1 +#define GTPU_MSG_ECHO_RESPONSE 2 #define GTPU_MSG_ERROR_INDICATION 26 #define GTPU_MSG_SUPPORTED_EXTENSION_HEADERS_NOTIFICATION 31 #define GTPU_MSG_END_MARKER 254 From 28f377128b1e9a1ca0fc2c4b107aae709d4975b5 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 1 Oct 2018 18:23:04 +0100 Subject: [PATCH 23/71] Making sure both Echo request and echo response are supported types. Echo response/request is working again. --- lib/include/srslte/upper/gtpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 2756bc0ab..2230d76b7 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -110,7 +110,7 @@ inline bool gtpu_supported_flags_check(gtpu_header_t *header, srslte::log *gtpu_ inline bool gtpu_supported_msg_type_check(gtpu_header_t *header, srslte::log *gtpu_log) { //msg_tpye - if( header->message_type != GTPU_MSG_DATA_PDU && header->message_type != GTPU_MSG_ECHO_REQUEST ) { + if( header->message_type != GTPU_MSG_DATA_PDU && header->message_type != GTPU_MSG_ECHO_REQUEST && header->message_type != GTPU_MSG_ECHO_RESPONSE) { gtpu_log->error("gtpu_header - Unhandled message type: 0x%x\n", header->message_type); return false; } From af5a329fecfc3728a79c25af6685498ea2cc103d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 1 Oct 2018 21:43:42 +0200 Subject: [PATCH 24/71] print build-info during enb startup --- srsenb/hdr/enb.h | 6 +++++- srsenb/src/enb.cc | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index fe99f16de..831e1be96 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -222,7 +222,11 @@ private: int parse_rr(all_args_t *args, rrc_cfg_t *rrc_cfg); int parse_drb(all_args_t *args, rrc_cfg_t *rrc_cfg); bool sib_is_present(LIBLTE_RRC_SCHEDULING_INFO_STRUCT *sched_info, uint32_t nof_sched_info, LIBLTE_RRC_SIB_TYPE_ENUM sib_num); - int parse_cell_cfg(all_args_t *args, srslte_cell_t *cell); + int parse_cell_cfg(all_args_t *args, srslte_cell_t *cell); + + std::string get_build_mode(); + std::string get_build_info(); + std::string get_build_string(); }; } // namespace srsenb diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 911fb1d48..3d0e2da10 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -26,6 +26,9 @@ #include #include "srsenb/hdr/enb.h" +#include "srslte/build_info.h" +#include +#include namespace srsenb { @@ -54,6 +57,9 @@ void enb::cleanup(void) } enb::enb() : started(false) { + // print build info + std::cout << std::endl << get_build_string() << std::endl; + srslte_dft_load(); pool = srslte::byte_buffer_pool::get_instance(ENB_POOL_SIZE); @@ -342,4 +348,24 @@ srslte::LOG_LEVEL_ENUM enb::level(std::string l) } } +std::string enb::get_build_mode() +{ + return std::string(srslte_get_build_mode()); +} + +std::string enb::get_build_info() +{ + if (std::string(srslte_get_build_info()) == "") { + return std::string(srslte_get_version()); + } + return std::string(srslte_get_build_info()); +} + +std::string enb::get_build_string() +{ + std::stringstream ss; + ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; + return ss.str(); +} + } // namespace srsenb From 0deda67930a1b9f2af221ef49f0c1f047fae2b4a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 1 Oct 2018 21:44:16 +0200 Subject: [PATCH 25/71] print build-info during epc startup --- srsepc/src/main.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 95883cd44..984f81dd6 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -22,6 +22,7 @@ * */ #include +#include #include #include #include @@ -30,6 +31,7 @@ #include "srslte/common/crash_handler.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/config_file.h" +#include "srslte/build_info.h" #include "srsepc/hdr/mme/mme.h" #include "srsepc/hdr/hss/hss.h" #include "srsepc/hdr/spgw/spgw.h" @@ -280,6 +282,26 @@ level(std::string l) } } +std::string get_build_mode() +{ + return std::string(srslte_get_build_mode()); +} + +std::string get_build_info() +{ + if (std::string(srslte_get_build_info()) == "") { + return std::string(srslte_get_version()); + } + return std::string(srslte_get_build_info()); +} + +std::string get_build_string() +{ + std::stringstream ss; + ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; + return ss.str(); +} + int main (int argc,char * argv[] ) { @@ -287,6 +309,9 @@ main (int argc,char * argv[] ) signal(SIGTERM, sig_int_handler); signal(SIGKILL, sig_int_handler); + // print build info + cout << endl << get_build_string() << endl; + cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl; srslte_debug_handle_crash(argc, argv); From 0380c83175f6980e9f22e703bb1f7428d39183d1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 1 Oct 2018 21:59:07 +0200 Subject: [PATCH 26/71] remove RF device calibration settings from UE/eNB config - this remove RF calibration parameters that were an extra section in the eNB/UE config but were hardly used (only old bladeRF) - a better way to pass those parameter would be through the device args in the normal rf config section --- lib/include/srslte/phy/rf/rf.h | 12 ------------ lib/include/srslte/radio/radio.h | 13 ------------- lib/src/phy/rf/rf_blade_imp.c | 17 ----------------- lib/src/phy/rf/rf_blade_imp.h | 4 ---- lib/src/phy/rf/rf_dev.h | 16 +++------------- lib/src/phy/rf/rf_imp.c | 9 --------- lib/src/phy/rf/rf_soapy_imp.c | 11 ++--------- lib/src/phy/rf/rf_soapy_imp.h | 6 ++---- lib/src/phy/rf/rf_uhd_imp.c | 11 ----------- lib/src/phy/rf/rf_uhd_imp.h | 4 ---- lib/src/radio/radio.cc | 10 ---------- srsenb/enb.conf.example | 18 ------------------ srsenb/hdr/enb.h | 3 +-- srsenb/src/enb.cc | 2 -- srsenb/src/main.cc | 6 ------ srsue/hdr/ue_base.h | 1 - srsue/src/main.cc | 14 +------------- srsue/src/ue.cc | 3 --- srsue/ue.conf.example | 18 ------------------ 19 files changed, 9 insertions(+), 169 deletions(-) diff --git a/lib/include/srslte/phy/rf/rf.h b/lib/include/srslte/phy/rf/rf.h index f093d1d55..9adea96b8 100644 --- a/lib/include/srslte/phy/rf/rf.h +++ b/lib/include/srslte/phy/rf/rf.h @@ -48,14 +48,6 @@ typedef struct { float tx_rx_gain_offset; } srslte_rf_t; -typedef struct { - float dc_gain; - float dc_phase; - float iq_i; - float iq_q; -} srslte_rf_cal_t; - - typedef struct { double min_tx_gain; double max_tx_gain; @@ -96,10 +88,6 @@ SRSLTE_API int srslte_rf_start_gain_thread(srslte_rf_t *rf, SRSLTE_API int srslte_rf_close(srslte_rf_t *h); -SRSLTE_API void srslte_rf_set_tx_cal(srslte_rf_t *h, srslte_rf_cal_t *cal); - -SRSLTE_API void srslte_rf_set_rx_cal(srslte_rf_t *h, srslte_rf_cal_t *cal); - SRSLTE_API int srslte_rf_start_rx_stream(srslte_rf_t *h, bool now); SRSLTE_API int srslte_rf_stop_rx_stream(srslte_rf_t *h); diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 2b14b30cd..e9ff3a4a2 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -33,17 +33,6 @@ #ifndef SRSLTE_RADIO_H #define SRSLTE_RADIO_H -typedef struct { - float tx_corr_dc_gain; - float tx_corr_dc_phase; - float tx_corr_iq_i; - float tx_corr_iq_q; - float rx_corr_dc_gain; - float rx_corr_dc_phase; - float rx_corr_iq_i; - float rx_corr_iq_q; -} rf_cal_t; - namespace srslte { /* Interface to the RF frontend. @@ -85,8 +74,6 @@ class radio { void set_tx_adv(int nsamples); void set_tx_adv_neg(bool tx_adv_is_neg); - void set_manual_calibration(rf_cal_t *calibration); - bool is_continuous_tx(); void set_continuous_tx(bool enable); diff --git a/lib/src/phy/rf/rf_blade_imp.c b/lib/src/phy/rf/rf_blade_imp.c index 71e5025b5..061c5aa92 100644 --- a/lib/src/phy/rf/rf_blade_imp.c +++ b/lib/src/phy/rf/rf_blade_imp.c @@ -402,23 +402,6 @@ double rf_blade_set_tx_freq(void *h, double freq) return freq; } -void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal) { - rf_blade_handler_t *handler = (rf_blade_handler_t*) h; - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_PHASE, cal->dc_phase); - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_GAIN, cal->dc_gain); - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i); - bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q); -} - -void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal) { - rf_blade_handler_t *handler = (rf_blade_handler_t*) h; - bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_PHASE, cal->dc_phase); - bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_GAIN, cal->dc_gain); - bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i); - bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q); -} - - static void timestamp_to_secs(uint32_t rate, uint64_t timestamp, time_t *secs, double *frac_secs) { double totalsecs = (double) timestamp/rate; time_t secs_i = (time_t) totalsecs; diff --git a/lib/src/phy/rf/rf_blade_imp.h b/lib/src/phy/rf/rf_blade_imp.h index 6c8c04c43..3809a149f 100644 --- a/lib/src/phy/rf/rf_blade_imp.h +++ b/lib/src/phy/rf/rf_blade_imp.h @@ -40,10 +40,6 @@ SRSLTE_API char* rf_blade_devname(void *h); SRSLTE_API int rf_blade_close(void *h); -SRSLTE_API void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal); - -SRSLTE_API void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal); - SRSLTE_API int rf_blade_start_rx_stream(void *h, bool now); SRSLTE_API int rf_blade_start_rx_stream_nsamples(void *h, diff --git a/lib/src/phy/rf/rf_dev.h b/lib/src/phy/rf/rf_dev.h index 80b5125e4..0d2e11592 100644 --- a/lib/src/phy/rf/rf_dev.h +++ b/lib/src/phy/rf/rf_dev.h @@ -62,10 +62,6 @@ typedef struct { int (*srslte_rf_send_timed_multi)(void *h, void *data[4], int nsamples, time_t secs, double frac_secs, bool has_time_spec, bool blocking, bool is_start_of_burst, bool is_end_of_burst); - void (*srslte_rf_set_tx_cal)(void *h, srslte_rf_cal_t *cal); - - void (*srslte_rf_set_rx_cal)(void *h, srslte_rf_cal_t *cal); - } rf_dev_t; /* Define implementation for UHD */ @@ -102,9 +98,7 @@ static rf_dev_t dev_uhd = { rf_uhd_recv_with_time, rf_uhd_recv_with_time_multi, rf_uhd_send_timed, - .srslte_rf_send_timed_multi = rf_uhd_send_timed_multi, - rf_uhd_set_tx_cal, - rf_uhd_set_rx_cal + .srslte_rf_send_timed_multi = rf_uhd_send_timed_multi }; #endif @@ -142,9 +136,7 @@ static rf_dev_t dev_blade = { rf_blade_recv_with_time, rf_blade_recv_with_time_multi, rf_blade_send_timed, - .srslte_rf_send_timed_multi = rf_blade_send_timed_multi, - rf_blade_set_tx_cal, - rf_blade_set_rx_cal + .srslte_rf_send_timed_multi = rf_blade_send_timed_multi }; #endif @@ -181,9 +173,7 @@ static rf_dev_t dev_soapy = { rf_soapy_recv_with_time, rf_soapy_recv_with_time_multi, rf_soapy_send_timed, - .srslte_rf_send_timed_multi = rf_soapy_send_timed_multi, - rf_soapy_set_tx_cal, - rf_soapy_set_rx_cal + .srslte_rf_send_timed_multi = rf_soapy_send_timed_multi }; #endif diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index eec44ef30..bc7ac59d6 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -129,15 +129,6 @@ int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args, uint32_t return -1; } -void srslte_rf_set_tx_cal(srslte_rf_t *rf, srslte_rf_cal_t *cal) { - return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_cal(rf->handler, cal); -} - -void srslte_rf_set_rx_cal(srslte_rf_t *rf, srslte_rf_cal_t *cal) { - return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_cal(rf->handler, cal); -} - - const char* srslte_rf_name(srslte_rf_t *rf) { return ((rf_dev_t*) rf->dev)->srslte_rf_devname(rf->handler); } diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 26ad5bac0..5d77a0a0d 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -205,25 +205,18 @@ bool rf_soapy_rx_wait_lo_locked(void *h) return true; } - -void rf_soapy_set_tx_cal(void *h, srslte_rf_cal_t *cal) +void rf_soapy_calibrate_tx(void *h) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; double actual_bw = SoapySDRDevice_getBandwidth(handler->device, SOAPY_SDR_TX, 0); char str_buf[25]; snprintf(str_buf, sizeof(str_buf), "%f", actual_bw); + str_buf[24] = 0; if (SoapySDRDevice_writeSetting(handler->device, "CALIBRATE_TX", str_buf)) { printf("Error calibrating Rx\n"); } } - -void rf_soapy_set_rx_cal(void *h, srslte_rf_cal_t *cal) -{ - // not supported -} - - int rf_soapy_start_rx_stream(void *h, bool now) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index 5b1787304..da4143e76 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -43,14 +43,12 @@ SRSLTE_API char* rf_soapy_devname(void *h); SRSLTE_API int rf_soapy_close(void *h); -SRSLTE_API void rf_soapy_set_tx_cal(void *h, srslte_rf_cal_t *cal); - -SRSLTE_API void rf_soapy_set_rx_cal(void *h, srslte_rf_cal_t *cal); - SRSLTE_API int rf_soapy_start_rx_stream(void *h, bool now); SRSLTE_API int rf_soapy_stop_rx_stream(void *h); +SRSLTE_API void rf_soapy_calibrate_tx(void *h); + SRSLTE_API void rf_soapy_flush_buffer(void *h); SRSLTE_API bool rf_soapy_has_rssi(void *h); diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 5439db828..993118675 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -230,17 +230,6 @@ bool rf_uhd_rx_wait_lo_locked(void *h) return val; } -void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal) -{ - -} - -void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal) -{ - -} - - int rf_uhd_start_rx_stream(void *h, bool now) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; diff --git a/lib/src/phy/rf/rf_uhd_imp.h b/lib/src/phy/rf/rf_uhd_imp.h index e0ad09bba..2da9f4efb 100644 --- a/lib/src/phy/rf/rf_uhd_imp.h +++ b/lib/src/phy/rf/rf_uhd_imp.h @@ -47,10 +47,6 @@ SRSLTE_API char* rf_uhd_devname(void *h); SRSLTE_API int rf_uhd_close(void *h); -SRSLTE_API void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal); - -SRSLTE_API void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal); - SRSLTE_API int rf_uhd_start_rx_stream(void *h, bool now); diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 349048838..ffae700ee 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -97,16 +97,6 @@ void radio::reset() usleep(100000); } -void radio::set_manual_calibration(rf_cal_t* calibration) -{ - srslte_rf_cal_t tx_cal; - tx_cal.dc_gain = calibration->tx_corr_dc_gain; - tx_cal.dc_phase = calibration->tx_corr_dc_phase; - tx_cal.iq_i = calibration->tx_corr_iq_i; - tx_cal.iq_q = calibration->tx_corr_iq_q; - srslte_rf_set_tx_cal(&rf_device, &tx_cal); -} - void radio::set_tx_rx_gain_offset(float offset) { srslte_rf_set_tx_rx_gain_offset(&rf_device, offset); } diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 53e43e799..67b83afb5 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -162,21 +162,3 @@ nof_ctrl_symbols = 3 #rrc_inactivity_timer = 60000 #max_prach_offset_us = 30 #enable_mbsfn = false - -##################################################################### -# Manual RF calibration -# -# Applies DC offset and IQ imbalance to TX and RX modules. -# Currently this configuration is only used if the detected device is a bladeRF -# -# tx_corr_dc_gain: TX DC offset gain correction -# tx_corr_dc_phase: TX DC offset phase correction -# tx_corr_iq_i: TX IQ imbalance inphase correction -# tx_corr_iq_q: TX IQ imbalance quadrature correction -# same can be configured for rx_* -##################################################################### -[rf_calibration] -tx_corr_dc_gain = 20 -tx_corr_dc_phase = 184 -tx_corr_iq_i = 19 -tx_corr_iq_q = 97 diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 831e1be96..2f00f5f62 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -134,7 +134,6 @@ typedef struct { enb_args_t enb; enb_files_t enb_files; rf_args_t rf; - rf_cal_t rf_cal; pcap_args_t pcap; log_args_t log; gui_args_t gui; @@ -142,7 +141,7 @@ typedef struct { }all_args_t; /******************************************************************************* - Main UE class + Main eNB class *******************************************************************************/ class enb diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 3d0e2da10..23cd63882 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -165,8 +165,6 @@ bool enb::init(all_args_t *args_) if (args->rf.burst_preamble.compare("auto")) { radio.set_burst_preamble(atof(args->rf.burst_preamble.c_str())); } - - radio.set_manual_calibration(&args->rf_cal); radio.set_rx_gain(args->rf.rx_gain); radio.set_tx_gain(args->rf.tx_gain); diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 941a6fff9..d36cf7ef8 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -199,12 +199,6 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("expert.print_buffer_state", bpo::value(&args->expert.print_buffer_state)->default_value(false), "Prints on the console the buffer state every 10 seconds") - - ("rf_calibration.tx_corr_dc_gain", bpo::value(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0), "TX DC offset gain correction") - ("rf_calibration.tx_corr_dc_phase", bpo::value(&args->rf_cal.tx_corr_dc_phase)->default_value(0.0), "TX DC offset phase correction") - ("rf_calibration.tx_corr_iq_i", bpo::value(&args->rf_cal.tx_corr_iq_i)->default_value(0.0), "TX IQ imbalance inphase correction") - ("rf_calibration.tx_corr_iq_q", bpo::value(&args->rf_cal.tx_corr_iq_q)->default_value(0.0), "TX IQ imbalance quadrature correction") - ; // Positional options - config file location diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index 6e4853dfd..0f362160a 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -122,7 +122,6 @@ typedef struct { typedef struct { rf_args_t rf; - rf_cal_t rf_cal; pcap_args_t pcap; trace_args_t trace; log_args_t log; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 8204808b9..a79fbd710 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -90,13 +90,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { ("nas.pass", bpo::value(&args->nas.apn_pass)->default_value(""), "Password for CHAP authentication") ("nas.force_imsi_attach", bpo::value(&args->nas.force_imsi_attach)->default_value(false), "Whether to always perform an IMSI attach") - ("pcap.enable", bpo::value(&args->pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") ("pcap.filename", bpo::value(&args->pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename") ("pcap.nas_enable", bpo::value(&args->pcap.nas_enable)->default_value(false), "Enable NAS packet captures for wireshark") ("pcap.nas_filename", bpo::value(&args->pcap.nas_filename)->default_value("ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)") - ("trace.enable", bpo::value(&args->trace.enable)->default_value(false), "Enable PHY and radio timing traces") ("trace.phy_filename", bpo::value(&args->trace.phy_filename)->default_value("ue.phy_trace"), "PHY timing traces filename") @@ -123,7 +121,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { ("log.usim_level", bpo::value(&args->log.usim_level), "USIM log level") ("log.usim_hex_limit", bpo::value(&args->log.usim_hex_limit), "USIM log hex dump limit") - ("log.all_level", bpo::value(&args->log.all_level)->default_value("info"), "ALL log level") ("log.all_hex_limit", bpo::value(&args->log.all_hex_limit)->default_value(32), "ALL log hex dump limit") @@ -309,16 +306,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { ("expert.pdsch_8bit_decoder", bpo::value(&args->expert.phy.pdsch_8bit_decoder)->default_value(false), - "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental)") - - ("rf_calibration.tx_corr_dc_gain", bpo::value(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0), - "TX DC offset gain correction") - ("rf_calibration.tx_corr_dc_phase", bpo::value(&args->rf_cal.tx_corr_dc_phase)->default_value(0.0), - "TX DC offset phase correction") - ("rf_calibration.tx_corr_iq_i", bpo::value(&args->rf_cal.tx_corr_iq_i)->default_value(0.0), - "TX IQ imbalance inphase correction") - ("rf_calibration.tx_corr_iq_q", bpo::value(&args->rf_cal.tx_corr_iq_q)->default_value(0.0), - "TX IQ imbalance quadrature correction"); + "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental)"); // Positional options - config file location bpo::options_description position("Positional options"); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index daccfca8b..2a6b05425 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -193,10 +193,7 @@ bool ue::init(all_args_t *args_) { radio.set_continuous_tx(args->rf.continuous_tx.compare("yes")?false:true); } - radio.set_manual_calibration(&args->rf_cal); - // Set PHY options - if (args->rf.tx_gain > 0) { args->expert.phy.ul_pwr_ctrl_en = false; } else { diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 4073ad96f..bdcc29b6c 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -249,21 +249,3 @@ enable = false #cfo_loop_pss_tol = 400 #cfo_loop_ref_min = 0 #cfo_loop_pss_conv = 20 - -##################################################################### -# Manual RF calibration -# -# Applies DC offset and IQ imbalance to TX and RX modules. -# Currently this configuration is only used if the detected device is a bladeRF -# -# tx_corr_dc_gain: TX DC offset gain correction -# tx_corr_dc_phase: TX DC offset phase correction -# tx_corr_iq_i: TX IQ imbalance inphase correction -# tx_corr_iq_q: TX IQ imbalance quadrature correction -# same can be configured for rx_* -##################################################################### -[rf_calibration] -tx_corr_dc_gain = 20 -tx_corr_dc_phase = 184 -tx_corr_iq_i = 19 -tx_corr_iq_q = 97 From 0e4ab77fb05beb89c575b06b6a1df2d5ba8ff43b Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 1 Oct 2018 21:18:11 +0100 Subject: [PATCH 27/71] GTPU cleanup, adding support for GTPU echo response (#265) --- lib/include/srslte/upper/gtpu.h | 4 +- srsenb/hdr/upper/gtpu.h | 7 +- srsenb/src/upper/gtpu.cc | 138 ++++++++++++++++++-------------- 3 files changed, 82 insertions(+), 67 deletions(-) diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 24b9c5c41..55c8189cc 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -52,8 +52,8 @@ namespace srslte { #define GTPU_HEADER_LEN 8 typedef struct{ - uint8_t flags; // Only support 0x30 - v1, PT1 (GTP), no other flags - uint8_t message_type; // Only support 0xFF - T-PDU type + uint8_t flags; + uint8_t message_type; uint16_t length; uint32_t teid; }gtpu_header_t; diff --git a/srsenb/hdr/upper/gtpu.h b/srsenb/hdr/upper/gtpu.h index 4dc05585d..519b831d9 100644 --- a/srsenb/hdr/upper/gtpu.h +++ b/srsenb/hdr/upper/gtpu.h @@ -124,12 +124,11 @@ private: }bearer_map; std::map rnti_bearers; - // Socket file descriptors - int snk_fd; - int src_fd; + // Socket file descriptor + int fd; - //Threading void run_thread(); + void echo_response(in_addr_t addr, in_port_t port, uint16_t seq); pthread_mutex_t mutex; diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 1d90fd388..777943125 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -52,35 +52,19 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ pool = byte_buffer_pool::get_instance(); - // Set up sink socket - snk_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (snk_fd < 0) { - gtpu_log->error("Failed to create sink socket\n"); + // Set up socket + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + gtpu_log->error("Failed to create socket\n"); return false; } int enable = 1; #if defined (SO_REUSEADDR) - if (setsockopt(snk_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) gtpu_log->error("setsockopt(SO_REUSEADDR) failed\n"); #endif #if defined (SO_REUSEPORT) - if (setsockopt(snk_fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) - gtpu_log->error("setsockopt(SO_REUSEPORT) failed\n"); -#endif - - - // Set up source socket - src_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (src_fd < 0) { - gtpu_log->error("Failed to create source socket\n"); - return false; - } -#if defined (SO_REUSEADDR) - if (setsockopt(src_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) - gtpu_log->error("setsockopt(SO_REUSEADDR) failed\n"); -#endif -#if defined (SO_REUSEPORT) - if (setsockopt(src_fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) gtpu_log->error("setsockopt(SO_REUSEPORT) failed\n"); #endif @@ -90,7 +74,7 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ bindaddr.sin_addr.s_addr = inet_addr(gtp_bind_addr.c_str()); bindaddr.sin_port = htons(GTPU_PORT); - if (bind(src_fd, (struct sockaddr *)&bindaddr, sizeof(struct sockaddr_in))) { + if (bind(fd, (struct sockaddr *)&bindaddr, sizeof(struct sockaddr_in))) { gtpu_log->error("Failed to bind on address %s, port %d\n", gtp_bind_addr.c_str(), GTPU_PORT); gtpu_log->console("Failed to bind on address %s, port %d\n", gtp_bind_addr.c_str(), GTPU_PORT); return false; @@ -128,11 +112,8 @@ void gtpu::stop() wait_thread_finish(); } - if (snk_fd) { - close(snk_fd); - } - if (src_fd) { - close(src_fd); + if (fd) { + close(fd); } } @@ -152,7 +133,7 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) servaddr.sin_port = htons(GTPU_PORT); gtpu_write_header(&header, pdu, gtpu_log); - if (sendto(snk_fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) { + if (sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) { perror("sendto"); } @@ -223,6 +204,10 @@ void gtpu::run_thread() } run_enable = true; + sockaddr_in client; + socklen_t client_len = sizeof(client); + size_t buflen = SRSENB_MAX_BUFFER_SIZE_BYTES - SRSENB_BUFFER_HEADER_OFFSET; + running=true; while(run_enable) { @@ -230,7 +215,7 @@ void gtpu::run_thread() gtpu_log->debug("Waiting for read...\n"); int n = 0; do{ - n = recv(src_fd, pdu->msg, SRSENB_MAX_BUFFER_SIZE_BYTES - SRSENB_BUFFER_HEADER_OFFSET, 0); + n = recvfrom(fd, pdu->msg, buflen, 0, (struct sockaddr *)&client, &client_len); } while (n == -1 && errno == EAGAIN); if (n < 0) { @@ -239,42 +224,73 @@ void gtpu::run_thread() pdu->N_bytes = (uint32_t) n; - gtpu_header_t header; - gtpu_read_header(pdu, &header,gtpu_log); - - uint16_t rnti = 0; - uint16_t lcid = 0; - teidin_to_rntilcid(header.teid, &rnti, &lcid); - - pthread_mutex_lock(&mutex); - bool user_exists = (rnti_bearers.count(rnti) > 0); - pthread_mutex_unlock(&mutex); - - if(!user_exists) { - gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti); - continue; - } - - if(lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { - gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); - continue; - } - - gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); - - pdcp->write_sdu(rnti, lcid, pdu); - - do { - pdu = pool_allocate; - if (!pdu) { - gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); - usleep(10000); + if(pdu->msg[1] == 0x01) { + if(n<10) { + continue; } - } while(!pdu); + // Echo request - send response + uint16_t seq = 0; + uint8_to_uint16(&pdu->msg[8], &seq); + echo_response(client.sin_addr.s_addr, client.sin_port, seq); + + }else{ + gtpu_header_t header; + gtpu_read_header(pdu, &header,gtpu_log); + + uint16_t rnti = 0; + uint16_t lcid = 0; + teidin_to_rntilcid(header.teid, &rnti, &lcid); + + pthread_mutex_lock(&mutex); + bool user_exists = (rnti_bearers.count(rnti) > 0); + pthread_mutex_unlock(&mutex); + + if(!user_exists) { + gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti); + continue; + } + + if(lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { + gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); + continue; + } + + gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); + + pdcp->write_sdu(rnti, lcid, pdu); + + do { + pdu = pool_allocate; + if (!pdu) { + gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); + usleep(10000); + } + } while(!pdu); + } } running = false; } +void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) +{ + gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq); + + uint8_t resp[12]; + bzero(resp, 12); + resp[0] = 0x32; //flags + resp[1] = 0x02; //type + uint16_to_uint8(4, &resp[2]); //length + uint32_to_uint8(0, &resp[4]); //TEID + uint16_to_uint8(seq, &resp[8]); //seq + + struct sockaddr_in servaddr; + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = addr; + servaddr.sin_port = port; + + sendto(fd, resp, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); +} + /**************************************************************************** * TEID to RNIT/LCID helper functions ***************************************************************************/ From ea35cc9b5e533100c9c0c8a0d654bc844eff392d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 2 Oct 2018 10:52:25 +0200 Subject: [PATCH 28/71] fix typo in config files --- srsenb/sib.conf.mbsfn.example | 2 -- srsue/ue.conf.example | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/srsenb/sib.conf.mbsfn.example b/srsenb/sib.conf.mbsfn.example index f5ffcdd8c..588ba71d1 100644 --- a/srsenb/sib.conf.mbsfn.example +++ b/srsenb/sib.conf.mbsfn.example @@ -111,8 +111,6 @@ sib2 = additional_spectrum_emission = 1; }; - - mbsfnSubframeConfigList = { radioframeAllocationPeriod = "1"; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index bdcc29b6c..d2bc4bb12 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -16,7 +16,7 @@ # device_args: Arguments for the device driver. Options are "auto" or any string. # Default for UHD: "recv_frame_size=9232,send_frame_size=9232" # Default for bladeRF: "" -# #time_adv_nsamples: Transmission time advance (in number of samples) to compensate for RF delay +# time_adv_nsamples: Transmission time advance (in number of samples) to compensate for RF delay # from antenna to timestamp insertion. # Default "auto". B210 USRP: 100 samples, bladeRF: 27. # burst_preamble_us: Preamble length to transmit before start of burst. From c56fa3b46c7a9c061a0e7510996875b42158081f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 2 Oct 2018 10:52:43 +0200 Subject: [PATCH 29/71] only enable eMBMS if both the sib config is present and its enabled in enb config --- srsenb/src/enb_cfg_parser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index d928cb482..3ddb3d9f7 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -905,7 +905,7 @@ int enb::parse_sibs(all_args_t *args, rrc_cfg_t *rrc_cfg, phy_cfg_t *phy_config_ } // Update MBSFN list counter. Only 1 supported - if (mbsfn_section_present) { + if (mbsfn_section_present && args->expert.enable_mbsfn) { sib2->mbsfn_subfr_cnfg_list_size = 1; } From bd6bb6903f12be47eb89a9669e64084f2b4743f8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 3 Oct 2018 10:29:56 +0200 Subject: [PATCH 30/71] fix block_queue pop and clear methods - pop was bzero'ing the popped object which causes for more complex objects like std::string - clear wasn't actually emptying the queue --- lib/include/srslte/common/block_queue.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/include/srslte/common/block_queue.h b/lib/include/srslte/common/block_queue.h index 2e476dd65..1098e3db5 100644 --- a/lib/include/srslte/common/block_queue.h +++ b/lib/include/srslte/common/block_queue.h @@ -109,7 +109,6 @@ public: myobj wait_pop() { // blocking pop myobj value; - bzero(&value, sizeof(myobj)); pop_(&value, true); return value; } @@ -154,8 +153,8 @@ private: } if (value) { *value = q.front(); - q.pop(); } + q.pop(); ret = true; if (mutexed_callback) { mutexed_callback->popping(*value); From 717d767c2bdcc542588b34727932400056378ff0 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 3 Oct 2018 12:50:18 +0200 Subject: [PATCH 31/71] Removed PUSCH redundant line --- lib/src/phy/phch/pusch.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index 3f6a082f8..3525f754c 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -524,7 +524,6 @@ int srslte_pusch_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softb cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), rnti, cfg->grant.mcs.tbs, cfg->nbits.nof_re, cfg->nbits.nof_symb, cfg->nbits.nof_bits, cfg->rv); - bzero(q->q, cfg->nbits.nof_bits); if (srslte_ulsch_uci_encode(&q->ul_sch, cfg, softbuffer, data, uci_data, q->g, q->q)) { fprintf(stderr, "Error encoding TB\n"); return SRSLTE_ERROR; From 45e6473303cba5d838248384d7de585d6d614886 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 3 Oct 2018 12:53:28 +0200 Subject: [PATCH 32/71] Removed not implemented/reserved TM4 PMI Error messages --- lib/src/phy/ue/ue_dl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 558f8b5fe..8571825bf 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -450,9 +450,9 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 } } else { if (grant->pinfo == 2) { - ERROR("Not implemented codebook index (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); + /* Not implemented */ } else if (grant->pinfo > 2) { - ERROR("Reserved codebook index (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); + /* Reserved */ } pmi = grant->pinfo % 2; } From f20535657fe9bf21207a18cb85becd2dc4f167a8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 27 Sep 2018 11:23:06 +0200 Subject: [PATCH 33/71] add option to randomize MAC opportunities in RLC tester --- lib/test/upper/rlc_stress_test.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 631c2015f..230286305 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -55,7 +55,8 @@ typedef struct { uint32_t log_level; bool single_tx; bool write_pcap; - float opp_sdu_ratio; + uint32_t avg_opp_size; + bool random_opp; bool zero_seed; bool pedantic; } stress_test_args_t; @@ -75,10 +76,11 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { ("mode", bpo::value(&args->mode)->default_value("AM"), "Whether to test RLC acknowledged or unacknowledged mode (AM/UM)") ("duration", bpo::value(&args->test_duration_sec)->default_value(5), "Duration (sec)") ("sdu_size", bpo::value(&args->sdu_size)->default_value(1500), "Size of SDUs") + ("avg_opp_size", bpo::value(&args->avg_opp_size)->default_value(1505), "Size of the MAC opportunity (if not random)") + ("random_opp", bpo::value(&args->random_opp)->default_value(true), "Whether to generate random MAC opportunities") ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(0), "SDU generation delay (usec)") ("pdu_tx_delay", bpo::value(&args->pdu_tx_delay_usec)->default_value(0), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)") ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") - ("opp_sdu_ratio", bpo::value(&args->opp_sdu_ratio)->default_value(0.0), "Ratio between MAC opportunity and SDU size (0==random)") ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution") ("loglevel", bpo::value(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug)") ("singletx", bpo::value(&args->single_tx)->default_value(false), "If set to true, only one node is generating data") @@ -156,8 +158,11 @@ private: exit(-1); } - float r = args.opp_sdu_ratio ? args.opp_sdu_ratio : static_cast(rand())/RAND_MAX; - int opp_size = r*args.sdu_size; + float factor = 1.0; + if (args.random_opp) { + factor = 0.5 + static_cast(rand())/RAND_MAX; + } + int opp_size = args.avg_opp_size * factor; uint32_t buf_state = tx_rlc->get_buffer_state(lcid); if (buf_state > 0) { int read = tx_rlc->read_pdu(lcid, pdu->msg, opp_size); From 1ba9c4adc18d8f8530bf115b00e552acd70f87e5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 27 Sep 2018 16:16:04 +0200 Subject: [PATCH 34/71] fix typo --- lib/src/upper/rlc_am.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 933a1d9af..2b032ac9f 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -908,7 +908,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) tx_sdu = NULL; } if (pdu_space > to_move) { - pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom());; + pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom()); } else { pdu_space = 0; } From a6d918188158a7236725315d02d57891d6959d06 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 27 Sep 2018 16:16:10 +0200 Subject: [PATCH 35/71] fix RLC UM issue with very large MAC grants --- lib/include/srslte/upper/rlc_um.h | 4 ++ lib/src/upper/rlc_um.cc | 77 ++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index e47df8e73..92a7822d5 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -39,6 +39,8 @@ namespace srslte { +#define RLC_UM_MAX_SDU_SIZE (2048-1) // Length of LI field is 11bits + struct rlc_umd_pdu_t{ rlc_umd_pdu_header_t header; byte_buffer_t *buf; @@ -146,6 +148,7 @@ private: bool configure(srslte_rlc_config_t cfg, std::string rb_name); void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes); void reassemble_rx_sdus(); + bool pdu_belongs_to_rx_sdu(); bool inside_reordering_window(uint16_t sn); uint32_t get_num_rx_bytes(); void reset_metrics(); @@ -213,6 +216,7 @@ private: uint32_t lcid; srslte_rlc_um_config_t cfg; std::string rb_name; + byte_buffer_pool *pool; std::string get_rb_name(srsue::rrc_interface_rlc *rrc, uint32_t lcid, bool is_mrb); }; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 5a13b55f6..7145a8b66 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -37,6 +37,7 @@ namespace srslte { rlc_um::rlc_um(uint32_t queue_len) :lcid(0) ,tx(queue_len) + ,pool(byte_buffer_pool::get_instance()) ,rrc(NULL) ,log(NULL) { @@ -150,6 +151,11 @@ uint32_t rlc_um::get_bearer() ***************************************************************************/ void rlc_um::write_sdu(byte_buffer_t *sdu, bool blocking) { + if (sdu->N_bytes > RLC_UM_MAX_SDU_SIZE) { + log->warning("Dropping too long SDU of size %d B (Max. size %d B).", sdu->N_bytes, RLC_UM_MAX_SDU_SIZE); + pool->deallocate(sdu); + } + if (blocking) { tx.write_sdu(sdu); } else { @@ -399,7 +405,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint8_t *pdu_ptr = pdu->msg; int head_len = rlc_um_packed_length(&header); - int pdu_space = nof_bytes; + int pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom());; if(pdu_space <= head_len + 1) { @@ -430,7 +436,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) pool->deallocate(tx_sdu); tx_sdu = NULL; } - pdu_space -= to_move; + pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom()); header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU } @@ -474,7 +480,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) memcpy(payload, pdu->msg, pdu->N_bytes); uint32_t ret = pdu->N_bytes; - log->info("%s Transmitting PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes); + log->info("%s Tx PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes); pool->deallocate(pdu); debug_state(); @@ -595,7 +601,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.rx_sn_field_length, &header); - log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", get_rb_name(), header.sn); + log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d (%d B)", get_rb_name(), header.sn, nof_bytes); if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-cfg.rx_window_size) && RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) @@ -758,35 +764,29 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() // Now update vr_ur until we reach an SN we haven't yet received while(rx_window.end() != rx_window.find(vr_ur)) { log->debug("Reassemble loop for vr_ur=%d\n", vr_ur); - if ((vr_ur_in_rx_sdu+1)%cfg.rx_mod != vr_ur) { - log->warning("PDU SN=%d lost, dropping remainder of %d\n", vr_ur_in_rx_sdu+1, vr_ur); + + if (not pdu_belongs_to_rx_sdu()) { + log->warning("PDU SN=%d lost, stop reassambling SDU (vr_ur_in_rx_sdu=%d)\n", vr_ur_in_rx_sdu+1, vr_ur_in_rx_sdu); + pdu_lost = false; // Reset flag to not prevent reassembling of further segments rx_sdu->reset(); } // Handle any SDU segments for(uint32_t i=0; idebug("Handling SDU egment i=%d with len=%d of vr_ur=%d N_li=%d [%s]\n", i, len, vr_ur, rx_window[vr_ur].header.N_li, rlc_fi_field_text[rx_window[vr_ur].header.fi]); // Check if the first part of the PDU is a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->warning_hex(rx_window[vr_ur].buf->msg, len, "Dropping first part of SN %d due to lost start segment\n", vr_ur); + log->warning_hex(rx_window[vr_ur].buf->msg, len, "Dropping first %d B of SN %d due to lost start segment\n", len, vr_ur); // Advance data pointers and continue with next segment rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; rx_sdu->reset(); - // beginning of next SDU? - if (rx_window[vr_ur].header.fi == RLC_FI_FIELD_NOT_START_OR_END_ALIGNED) { - len = rx_window[vr_ur].buf->N_bytes; - log->info_hex(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU\n", len); - memcpy(rx_sdu->msg, rx_window[vr_ur].buf->msg, len); - rx_sdu->N_bytes = len; - rx_window[vr_ur].buf->msg += len; - rx_window[vr_ur].buf->N_bytes -= len; - log->info("Updating vr_ur_in_rx_sdu. old=%d, new=%d\n", vr_ur_in_rx_sdu, vr_ur); - vr_ur_in_rx_sdu = vr_ur; - goto clean_up_rx_window; - } + // Reset flag, it is safe to process all remaining segments of this PDU + pdu_lost = false; + continue; } // Check available space in SDU @@ -796,16 +796,22 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() goto clean_up_rx_window; } - log->info_hex(rx_window[vr_ur].buf->msg, len, "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n", - len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod); + if (not pdu_belongs_to_rx_sdu()) { + log->info_hex(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU\n", len); + log->info("Updating vr_ur_in_rx_sdu. old=%d, new=%d\n", vr_ur_in_rx_sdu, vr_ur); + vr_ur_in_rx_sdu = vr_ur; + } else { + log->info_hex(rx_window[vr_ur].buf->msg, len, "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n", + len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod); + } + memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len); rx_sdu->N_bytes += len; rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; - if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%cfg.rx_mod))) { - log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); - rx_sdu->reset(); - } else { + vr_ur_in_rx_sdu = vr_ur; + + if (not pdu_lost && pdu_belongs_to_rx_sdu()) { log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", get_rb_name(), vr_ur, i); rx_sdu->set_timestamp(); if(cfg.is_mrb){ @@ -818,6 +824,11 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); return; } + } else { + log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); + // Advance data pointers and continue with next segment + rx_window[vr_ur].buf->msg += len; + rx_window[vr_ur].buf->N_bytes -= len; } pdu_lost = false; } @@ -833,8 +844,8 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() rx_window[vr_ur].buf->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES && rx_window[vr_ur].buf->N_bytes + rx_sdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES) { - log->info_hex(rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes, "Writing last segment in SDU buffer. Updating vr_ur=%d, Buffer size=%d, segment size=%d\n", - vr_ur, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes); + log->info_hex(rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes, "Writing last segment in SDU buffer. Updating vr_ur=%d, vr_ur_in_rx_sdu=%d, Buffer size=%d, segment size=%d\n", + vr_ur, vr_ur_in_rx_sdu, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes); memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes); rx_sdu->N_bytes += rx_window[vr_ur].buf->N_bytes; } else { @@ -872,6 +883,18 @@ clean_up_rx_window: } } + +// Only called when lock is hold +bool rlc_um::rlc_um_rx::pdu_belongs_to_rx_sdu() +{ + // return true if the currently received SDU + if (((vr_ur_in_rx_sdu + 1)%cfg.rx_mod == vr_ur) || (vr_ur == vr_ur_in_rx_sdu)) { + return true; + } + return false; +} + + // Only called when lock is hold // 36.322 Section 5.1.2.2.1 bool rlc_um::rlc_um_rx::inside_reordering_window(uint16_t sn) From 57b472983e53963628b10ed7d3d75f46690b30f4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 27 Sep 2018 16:39:02 +0200 Subject: [PATCH 36/71] fix RLC TM stress test params --- lib/test/upper/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index 66982463f..7a5a49898 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -34,7 +34,7 @@ add_executable(rlc_stress_test rlc_stress_test.cc) target_link_libraries(rlc_stress_test srslte_upper srslte_phy srslte_common ${Boost_LIBRARIES}) add_test(rlc_am_stress_test rlc_stress_test --mode=AM --loglevel 1 --sdu_gen_delay 250) add_test(rlc_um_stress_test rlc_stress_test --mode=UM --loglevel 1) -add_test(rlc_tm_stress_test rlc_stress_test --mode=TM --loglevel 1 --opp_sdu_ratio=1.0) +add_test(rlc_tm_stress_test rlc_stress_test --mode=TM --loglevel 1 --random_opp=false) # Run clang-tidy if available if(CLANG_TIDY_BIN) From 96815e3a5f0ebb7e6f8be90e4c1d4addbd9e06ce Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 2 Oct 2018 17:00:34 +0200 Subject: [PATCH 37/71] fix RLC AM handling of bigger MAC grants - fix concatenation and header reconstruction --- lib/include/srslte/upper/rlc_am.h | 6 +- lib/src/upper/rlc_am.cc | 171 +++++++++++++++++++++--------- 2 files changed, 125 insertions(+), 52 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index ac04c991a..0e18a7e7f 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -225,7 +225,8 @@ private: void timer_expired(uint32_t timeout_id); // Functions needed by Tx subclass to query rx state - int get_status(rlc_status_pdu_t* status); + int get_status_pdu_length(); + int get_status_pdu(rlc_status_pdu_t* status, const uint32_t nof_bytes); bool get_do_status(); void reset_status(); // called when status PDU has been sent @@ -320,7 +321,8 @@ uint32_t rlc_am_packed_length(rlc_amd_retx_t retx); bool rlc_am_is_control_pdu(byte_buffer_t *pdu); bool rlc_am_is_control_pdu(uint8_t *payload); bool rlc_am_is_pdu_segment(uint8_t *payload); -std::string rlc_am_to_string(rlc_status_pdu_t *status); +std::string rlc_am_status_pdu_to_string(rlc_status_pdu_t *status); +std::string rlc_amd_pdu_header_to_string(const rlc_amd_pdu_header_t &header); bool rlc_am_start_aligned(const uint8_t fi); bool rlc_am_end_aligned(const uint8_t fi); bool rlc_am_is_unaligned(const uint8_t fi); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 2b032ac9f..7c2e18b0f 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -322,7 +322,7 @@ uint32_t rlc_am::rlc_am_tx::get_buffer_state() // Bytes needed for status report if (do_status() && not status_prohibited) { - n_bytes = parent->rx.get_status(&tx_status); + n_bytes = parent->rx.get_status_pdu_length(); log->debug("%s Buffer state - status report: %d bytes\n", RB_NAME, n_bytes); goto unlock_and_return; } @@ -378,7 +378,7 @@ uint32_t rlc_am::rlc_am_tx::get_total_buffer_state() // Bytes needed for status report if(do_status() && not status_prohibited) { - n_bytes += parent->rx.get_status(&tx_status); + n_bytes += parent->rx.get_status_pdu_length(); log->debug("%s Buffer state - total status report: %d bytes\n", RB_NAME, n_bytes); } @@ -582,10 +582,11 @@ bool rlc_am::rlc_am_tx::poll_required() int rlc_am::rlc_am_tx::build_status_pdu(uint8_t *payload, uint32_t nof_bytes) { - int pdu_len = parent->rx.get_status(&tx_status); + int pdu_len = parent->rx.get_status_pdu(&tx_status, nof_bytes); + log->debug("%s\n", rlc_am_status_pdu_to_string(&tx_status).c_str()); if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { log->info("%s Tx status PDU - %s\n", - RB_NAME, rlc_am_to_string(&tx_status).c_str()); + RB_NAME, rlc_am_status_pdu_to_string(&tx_status).c_str()); parent->rx.reset_status(); @@ -760,6 +761,10 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a upper += old_header.li[i]; head_len = rlc_am_packed_length(&new_header); + + // Accomodate some extra space for for LIs if old header contained segments too + head_len += old_header.N_li; + pdu_space = nof_bytes-head_len; if(pdu_space < (retx.so_end-retx.so_start)) { retx.so_end = retx.so_start + pdu_space; @@ -779,19 +784,17 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a if (upper == retx.so_end) { new_header.fi &= RLC_FI_FIELD_NOT_START_ALIGNED; // segment end is aligned with this SDU } - new_header.li[new_header.N_li++] = li; + new_header.li[new_header.N_li] = li; + + // only increment N_li if more SDU (segments) are being added + if (retx.so_end > upper) { + new_header.N_li++; + } } lower += old_header.li[i]; } - // Make sure LI is not deleted in case the SDU boundary is crossed - // FIXME: fix if N_li > 1 - if (new_header.N_li == 1 && retx.so_start + new_header.li[0] < retx.so_end && retx.so_end <= retx.so_start + pdu_space) { - // This segment crosses a SDU boundary - new_header.N_li++; - } - // Update retx_queue if(tx_window[retx.sn].buf->N_bytes == retx.so_end) { retx_queue.pop_front(); @@ -804,9 +807,6 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a } else { retx_queue.front().is_segment = true; retx_queue.front().so_start = retx.so_end; - if (new_header.N_li > 0) { - new_header.N_li--; - } } // Write header and pdu @@ -816,9 +816,6 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a uint32_t len = retx.so_end - retx.so_start; memcpy(ptr, data, len); - log->info("%s Retx PDU segment scheduled for tx. SN: %d, SO: %d\n", - RB_NAME, retx.sn, retx.so_start); - debug_state(); int pdu_len = (ptr-payload) + len; if (pdu_len > static_cast(nof_bytes)) { @@ -827,6 +824,10 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a log->debug("%s Retx PDU segment length error. Header len: %ld, Payload len: %d, N_li: %d\n", RB_NAME, (ptr-payload), len, new_header.N_li); } + + log->info_hex(payload, pdu_len, "%s Retx PDU segment of SN=%d (%d B), SO: %d, N_li: %d\n", + RB_NAME, retx.sn, pdu_len, retx.so_start, new_header.N_li); + return pdu_len; } @@ -921,7 +922,8 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Pull SDUs from queue while (pdu_space > head_len + 1 && tx_sdu_queue.size() > 0) { if (last_li > 0) { - header.li[header.N_li++] = last_li; + header.li[header.N_li] = last_li; + header.N_li++; } head_len = rlc_am_packed_length(&header); if (head_len >= pdu_space) { @@ -993,10 +995,11 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint8_t *ptr = payload; rlc_am_write_data_pdu_header(&header, &ptr); memcpy(ptr, pdu->msg, pdu->N_bytes); - log->info_hex(payload, pdu->N_bytes, "%s PDU scheduled for tx. SN: %d (%d B)\n", RB_NAME, header.sn, pdu->N_bytes); - + int total_len = (ptr-payload) + pdu->N_bytes; + log->info_hex(payload, total_len, "%s Tx PDU SN=%d (%d B)\n", RB_NAME, header.sn, total_len); + log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); debug_state(); - return (ptr-payload) + pdu->N_bytes; + return total_len; } void rlc_am::rlc_am_tx::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) @@ -1008,10 +1011,10 @@ void rlc_am::rlc_am_tx::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) rlc_status_pdu_t status; rlc_am_read_status_pdu(payload, nof_bytes, &status); - log->info("%s Rx Status PDU: %s\n", RB_NAME, rlc_am_to_string(&status).c_str()); + log->info("%s Rx Status PDU: %s\n", RB_NAME, rlc_am_status_pdu_to_string(&status).c_str()); if (poll_retx_timer != NULL) { - poll_retx_timer->reset(); + poll_retx_timer->stop(); } // flush retx queue to avoid unordered SNs, we expect the Rx to request lost PDUs again @@ -1305,11 +1308,11 @@ void rlc_am::rlc_am_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rl { std::map::iterator it; - log->info_hex(payload, nof_bytes, "%s Rx data PDU SN: %d (%d B), %s", + log->info_hex(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", RB_NAME, header.sn, - nof_bytes, - rlc_fi_field_text[header.fi]); + nof_bytes); + log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); if(!inside_rx_window(header.sn)) { if(header.p) { @@ -1376,9 +1379,7 @@ void rlc_am::rlc_am_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rl poll_received = true; // 36.322 v10 Section 5.2.3 - if(RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ms) || - RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_mr)) - { + if (RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ms) || RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_mr)) { do_status = true; } // else delay for reordering timer @@ -1391,7 +1392,7 @@ void rlc_am::rlc_am_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rl if (reordering_timer != NULL) { if (reordering_timer->is_running()) { if(vr_x == vr_r || (!inside_rx_window(vr_x) && vr_x != vr_mr)) { - reordering_timer->reset(); + reordering_timer->stop(); } } @@ -1412,8 +1413,9 @@ void rlc_am::rlc_am_rx::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_b { std::map::iterator it; - log->info_hex(payload, nof_bytes, "%s Rx data PDU segment. SN: %d, SO: %d", - RB_NAME, header.sn, header.so); + log->info_hex(payload, nof_bytes, "%s Rx data PDU segment of SN=%d (%d B), SO=%d, N_li=%d", + RB_NAME, header.sn, nof_bytes, header.so, header.N_li); + log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); // Check inside rx window if(!inside_rx_window(header.sn)) { @@ -1444,9 +1446,9 @@ void rlc_am::rlc_am_rx::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_b // Check if we already have a segment from the same PDU it = rx_segments.find(header.sn); - if(rx_segments.end() != it) { + if (rx_segments.end() != it) { - if(header.p) { + if (header.p) { log->info("%s Status packet requested through polling bit\n", RB_NAME); do_status = true; } @@ -1518,6 +1520,9 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus() for(uint32_t i=0; idebug_hex(rx_window[vr_r].buf->msg, len, "Handling segment %d/%d of length %d B of SN=%d\n", i+1, rx_window[vr_r].header.N_li, len, vr_r); + // sanity check to avoid zero-size SDUs if (len == 0) { break; @@ -1557,11 +1562,12 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus() // Handle last segment len = rx_window[vr_r].buf->N_bytes; + log->debug_hex(rx_window[vr_r].buf->msg, len, "Handling last segment of length %d B of SN=%d\n", len, vr_r); if (rx_sdu->get_tailroom() >= len) { memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_r].buf->msg, len); rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes; } else { - log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n"); + log->error("Cannot fit RLC PDU in SDU buffer, dropping both. Erasing SN=%d.\n", vr_r); pool->deallocate(rx_sdu); pool->deallocate(rx_window[vr_r].buf); rx_window.erase(vr_r); @@ -1585,6 +1591,19 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus() exit: // Move the rx_window + log->debug("Erasing SN=%d.\n", vr_r); + // also erase any segments of this SN + std::map::iterator it; + it = rx_segments.find(vr_r); + if(rx_segments.end() != it) { + log->debug("Erasing segments of SN=%d\n", vr_r); + std::list::iterator segit; + for(segit = it->second.segments.begin(); segit != it->second.segments.end(); ++segit) { + log->debug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d\n", segit->header.sn, segit->header.so, segit->buf->N_bytes, segit->header.N_li); + pool->deallocate(segit->buf); + } + it->second.segments.clear(); + } pool->deallocate(rx_window[vr_r].buf); rx_window.erase(vr_r); vr_r = (vr_r + 1)%MOD; @@ -1670,8 +1689,8 @@ void rlc_am::rlc_am_rx::timer_expired(uint32_t timeout_id) pthread_mutex_unlock(&mutex); } -// Called from Tx object (packs status PDU and returns length of it) -int rlc_am::rlc_am_rx::get_status(rlc_status_pdu_t* status) +// Called from Tx object to pack status PDU that doesn't exceed a given size +int rlc_am::rlc_am_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size) { pthread_mutex_lock(&mutex); status->N_nack = 0; @@ -1679,7 +1698,8 @@ int rlc_am::rlc_am_rx::get_status(rlc_status_pdu_t* status) // We don't use segment NACKs - just NACK the full PDU uint32_t i = vr_r; - while (RX_MOD_BASE(i) < RX_MOD_BASE(vr_ms) && status->N_nack < RLC_AM_WINDOW_SIZE) { + while (RX_MOD_BASE(i) < RX_MOD_BASE(vr_ms) && status->N_nack < RLC_AM_WINDOW_SIZE && rlc_am_packed_length(status) <= max_pdu_size-2) { + status->ack_sn = i; if(rx_window.find(i) == rx_window.end()) { status->nacks[status->N_nack].nack_sn = i; status->N_nack++; @@ -1690,6 +1710,22 @@ int rlc_am::rlc_am_rx::get_status(rlc_status_pdu_t* status) return rlc_am_packed_length(status); } +// Called from Tx object to obtain length of the full status PDU +int rlc_am::rlc_am_rx::get_status_pdu_length() +{ + pthread_mutex_lock(&mutex); + rlc_status_pdu_t status; + uint32_t i = vr_r; + while (RX_MOD_BASE(i) < RX_MOD_BASE(vr_ms) && status.N_nack < RLC_AM_WINDOW_SIZE) { + if(rx_window.find(i) == rx_window.end()) { + status.N_nack++; + } + i = (i + 1)%MOD; + } + pthread_mutex_unlock(&mutex); + return rlc_am_packed_length(&status); +} + void rlc_am::rlc_am_rx::print_rx_segments() { std::map::iterator it; @@ -1758,33 +1794,46 @@ bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rl header.fi |= (pdu->segments.front().header.fi & RLC_FI_FIELD_NOT_START_ALIGNED); header.fi |= (pdu->segments.back().header.fi & RLC_FI_FIELD_NOT_END_ALIGNED); + log->debug("Starting header reconstruction of %zd segments\n", pdu->segments.size()); + // Reconstruct li fields uint16_t count = 0; uint16_t carryover = 0; for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) { - if(it->header.N_li > 0) { - header.li[header.N_li++] = it->header.li[0] + carryover; - count += it->header.li[0]; - for(uint32_t i=1; iheader.N_li; i++) { - header.li[header.N_li++] = it->header.li[i]; - count += it->header.li[i]; + log->debug(" Handling %d PDU segments\n", it->header.N_li); + for(uint32_t i=0; iheader.N_li; i++) { + header.li[header.N_li] = it->header.li[i]; + if (i == 0) { + header.li[header.N_li] += carryover; } + log->debug(" - adding segment %d/%d (%d B, SO=%d, carryover=%d, count=%d)\n", i+1, it->header.N_li, header.li[header.N_li], header.so, carryover, count); + header.N_li++; + count += it->header.li[i]; + carryover = 0; } - // accumulate segment sizes until end aligned PDU is received - if (rlc_am_not_start_aligned(it->header.fi)) { + if (count <= it->buf->N_bytes) { carryover += it->buf->N_bytes - count; + log->debug("Incremented carryover (it->buf->N_bytes=%d, count=%d). New carryover=%d\n", it->buf->N_bytes, count, carryover); } else { - carryover = it->buf->N_bytes - count; + // Next segment would be too long, recalculate carryover + header.N_li--; + carryover = it->buf->N_bytes - (count - header.li[header.N_li]); + log->debug("Recalculated carryover=%d (it->buf->N_bytes=%d, count=%d, header.li[header.N_li]=%d)\n", carryover, it->buf->N_bytes, count, header.li[header.N_li]); } + tmpit = it; if(rlc_am_end_aligned(it->header.fi) && ++tmpit != pdu->segments.end()) { - header.li[header.N_li++] = carryover; + log->debug("Header is end-aligned, overwrite header.li[%d]=%d\n", header.N_li, carryover); + header.li[header.N_li] = carryover; + header.N_li++; carryover = 0; } count = 0; } + log->debug("Finished header reconstruction of %zd segments\n", pdu->segments.size()); + // Copy data byte_buffer_t *full_pdu = pool_allocate_blocking; if (full_pdu == NULL) { @@ -2091,7 +2140,7 @@ bool rlc_am_is_pdu_segment(uint8_t *payload) return ((*(payload) >> 6) & 0x01) == 1; } -std::string rlc_am_to_string(rlc_status_pdu_t *status) +std::string rlc_am_status_pdu_to_string(rlc_status_pdu_t *status) { std::stringstream ss; ss << "ACK_SN = " << status->ack_sn; @@ -2112,6 +2161,28 @@ std::string rlc_am_to_string(rlc_status_pdu_t *status) return ss.str(); } +std::string rlc_amd_pdu_header_to_string(const rlc_amd_pdu_header_t &header) +{ + std::stringstream ss; + ss << "[" << rlc_dc_field_text[header.dc]; + ss << ", RF=" << (header.rf ? "1":"0"); + ss << ", P=" << (header.p ? "1":"0"); + ss << ", FI=" << (header.fi ? "1":"0"); + ss << ", SN=" << header.sn; + ss << ", LSF=" << (header.lsf ? "1":"0"); + ss << ", SO=" << header.so; + ss << ", N_li=" << header.N_li; + if (header.N_li > 0) { + ss << " ("; + for (uint32_t i = 0; i < header.N_li; i++) { + ss << header.li[i] << ", "; + } + ss << ")"; + } + ss << "]"; + return ss.str(); +} + bool rlc_am_start_aligned(const uint8_t fi) { return (fi == RLC_FI_FIELD_START_AND_END_ALIGNED || fi == RLC_FI_FIELD_NOT_END_ALIGNED); From a1eca433b08510ced24710aa9a360fff5c60728a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 2 Oct 2018 17:02:45 +0200 Subject: [PATCH 38/71] fix RLC AM tests accordingly --- lib/test/upper/rlc_am_test.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 0913dd264..bb6628279 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -732,11 +732,11 @@ bool resegment_test_2() // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); - assert(16 == rlc1.get_buffer_state()); + assert(18 == rlc1.get_buffer_state()); // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 16); // 6 byte header + 10 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 18); // 6 byte header + 12 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -959,9 +959,11 @@ bool resegment_test_4() // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); + assert(23 == rlc1.get_buffer_state()); + // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 21); // 6 byte header + 15 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 23); // 6 byte header + 18 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -1069,9 +1071,11 @@ bool resegment_test_5() // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); + assert(31 == rlc1.get_buffer_state()); + // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 27); // 7 byte header + 20 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 34); // 7 byte header + 24 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -1195,11 +1199,11 @@ bool resegment_test_6() // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); - assert(155 == rlc1.get_buffer_state()); + assert(159 == rlc1.get_buffer_state()); // Read the remaining segment byte_buffer_t retx2; - len = rlc1.read_pdu(retx2.msg, 157); + len = rlc1.read_pdu(retx2.msg, 162); retx2.N_bytes = len; // Write the retx PDU to RLC2 @@ -1214,6 +1218,7 @@ bool resegment_test_6() } for(int i=3;i<9;i++) { + if (i >= tester.n_sdus) return -1; if(tester.sdus[i]->N_bytes != 54) return -1; for(int j=0;j<54;j++) { if (tester.sdus[i]->msg[j] != j) return -1; From 27df357a66f6613e04a5b98c97de4f6af6d01ca1 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 4 Oct 2018 10:37:59 +0200 Subject: [PATCH 39/71] Fixes #273 --- lib/src/phy/phch/pusch.c | 4 ++++ srsue/src/phy/phch_worker.cc | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index 3525f754c..0f06ef1bb 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -533,6 +533,10 @@ int srslte_pusch_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softb srslte_sequence_t *seq = get_user_sequence(q, rnti, cfg->sf_idx, cfg->nbits.nof_bits); // Run scrambling + if (!seq) { + fprintf(stderr, "Error getting scrambling sequence\n"); + return SRSLTE_ERROR; + } srslte_scrambling_bytes(seq, (uint8_t*) q->q, cfg->nbits.nof_bits); // Correct UCI placeholder/repetition bits diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index ee2dc132b..53ca93273 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1269,6 +1269,22 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui char timestr[64]; timestr[0]='\0'; + /* Check input values ranges */ + if (rnti == 0) { + Warning("Encode PUSCH: Invalid RNTI (= 0)\n"); + return; + } else if (rv > 3) { + Warning("Encode PUSCH: Invalid RV (= %ud)\n", rv); + return; + } else if (payload == NULL) { + Warning("Encode PUSCH: NULL payload\n"); + return; + } else if (softbuffer == NULL) { + Warning("Encode PUSCH: NULL softbuffer\n"); + return; + } + + /* Configure and encode */ if (srslte_ue_ul_cfg_grant(&ue_ul, grant, TTI_TX(tti), rv, current_tx_nb)) { Error("Configuring UL grant\n"); } From e06e5b8b602d721193549ee376272d22782426f4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 4 Oct 2018 13:17:35 +0200 Subject: [PATCH 40/71] limit maximum allowd RLC SDU size --- lib/include/srslte/upper/rlc_common.h | 2 +- lib/include/srslte/upper/rlc_um.h | 2 -- lib/src/upper/rlc.cc | 7 +++++++ lib/src/upper/rlc_am.cc | 2 +- lib/src/upper/rlc_um.cc | 5 ----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index 71fe934df..3b1cec6a2 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -37,7 +37,7 @@ namespace srslte { ***************************************************************************/ #define RLC_AM_WINDOW_SIZE 512 - +#define RLC_MAX_SDU_SIZE ((1<<11)-1) // Length of LI field is 11bits typedef enum{ diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index 92a7822d5..b0fb2c13d 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -39,8 +39,6 @@ namespace srslte { -#define RLC_UM_MAX_SDU_SIZE (2048-1) // Length of LI field is 11bits - struct rlc_umd_pdu_t{ rlc_umd_pdu_header_t header; byte_buffer_t *buf; diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 5cf561415..886de474a 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -210,6 +210,13 @@ void rlc::empty_queue() void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking) { + // FIXME: rework build PDU logic to allow large SDUs (without concatenation) + if (sdu->N_bytes > RLC_MAX_SDU_SIZE) { + rlc_log->warning("Dropping too long SDU of size %d B (Max. size %d B).\n", sdu->N_bytes, RLC_MAX_SDU_SIZE); + pool->deallocate(sdu); + return; + } + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { rlc_array.at(lcid)->write_sdu(sdu, blocking); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 7c2e18b0f..bd0acbeff 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -920,7 +920,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) } // Pull SDUs from queue - while (pdu_space > head_len + 1 && tx_sdu_queue.size() > 0) { + while (pdu_space > head_len + 1 && tx_sdu_queue.size() > 0 && header.N_li < RLC_AM_WINDOW_SIZE) { if (last_li > 0) { header.li[header.N_li] = last_li; header.N_li++; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 7145a8b66..4fee0e7b6 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -151,11 +151,6 @@ uint32_t rlc_um::get_bearer() ***************************************************************************/ void rlc_um::write_sdu(byte_buffer_t *sdu, bool blocking) { - if (sdu->N_bytes > RLC_UM_MAX_SDU_SIZE) { - log->warning("Dropping too long SDU of size %d B (Max. size %d B).", sdu->N_bytes, RLC_UM_MAX_SDU_SIZE); - pool->deallocate(sdu); - } - if (blocking) { tx.write_sdu(sdu); } else { From 796e3fd7074dfd54bccb49bce81c67cda1e5ae79 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 15 Jun 2018 12:42:17 +0100 Subject: [PATCH 41/71] Adding M1-U options to eNB config --- srsenb/hdr/enb.h | 2 ++ srsenb/hdr/upper/gtpu.h | 4 +++- srsenb/src/enb.cc | 4 ++-- srsenb/src/main.cc | 14 ++++++++++---- srsenb/src/upper/gtpu.cc | 18 ++++++++++++------ 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 2f00f5f62..4176fbb82 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -128,6 +128,8 @@ typedef struct { float metrics_period_secs; bool enable_mbsfn; bool print_buffer_state; + std::string m1u_multiaddr; + std::string m1u_if_addr; }expert_args_t; typedef struct { diff --git a/srsenb/hdr/upper/gtpu.h b/srsenb/hdr/upper/gtpu.h index 3771ec402..b25139a17 100644 --- a/srsenb/hdr/upper/gtpu.h +++ b/srsenb/hdr/upper/gtpu.h @@ -49,7 +49,7 @@ public: gtpu(); - bool init(std::string gtp_bind_addr_, std::string mme_addr_, pdcp_interface_gtpu *pdcp_, srslte::log *gtpu_log_, bool enable_mbsfn = false); + bool init(std::string gtp_bind_addr_, std::string mme_addr_, std::string m1u_multiaddr_, std::string m1u_if_addr_, pdcp_interface_gtpu *pdcp_, srslte::log *gtpu_log_, bool enable_mbsfn = false); void stop(); // gtpu_interface_rrc @@ -70,6 +70,8 @@ private: bool enable_mbsfn; std::string gtp_bind_addr; std::string mme_addr; + std::string m1u_multiaddr; + std::string m1u_if_addr; srsenb::pdcp_interface_gtpu *pdcp; srslte::log *gtpu_log; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 23cd63882..a1906400b 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -241,8 +241,8 @@ bool enb::init(all_args_t *args_) pdcp.init(&rlc, &rrc, >pu, &pdcp_log); rrc.init(&rrc_cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &rrc_log); s1ap.init(args->enb.s1ap, &rrc, &s1ap_log); - gtpu.init(args->enb.s1ap.gtp_bind_addr, args->enb.s1ap.mme_addr, &pdcp, >pu_log, args->expert.enable_mbsfn); - + gtpu.init(args->enb.s1ap.gtp_bind_addr, args->enb.s1ap.mme_addr, args->expert.m1u_multiaddr, args->expert.m1u_if_addr, &pdcp, >pu_log, args->expert.enable_mbsfn); + started = true; return true; } diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index d36cf7ef8..c9cecbebd 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -145,9 +145,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { bpo::value(&args->expert.mac.sched.nof_ctrl_symbols)->default_value(3), "Number of control symbols") - /* Expert section */ - ("expert.metrics_period_secs", bpo::value(&args->expert.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds") @@ -191,14 +189,22 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("expert.rrc_inactivity_timer", bpo::value(&args->expert.rrc_inactivity_timer)->default_value(60000), "Inactivity timer in ms") - + ("expert.enable_mbsfn", bpo::value(&args->expert.enable_mbsfn)->default_value(false), - "enables mbms in the enodeb") + "Enables MBMS in the eNB") ("expert.print_buffer_state", bpo::value(&args->expert.print_buffer_state)->default_value(false), "Prints on the console the buffer state every 10 seconds") + + ("expert.m1u_multiaddr", + bpo::value(&args->expert.m1u_multiaddr)->default_value("239.255.0.1"), + "M1-U Multicast address the eNB joins.") + + ("expert.m1u_if_addr", + bpo::value(&args->expert.m1u_if_addr)->default_value("127.0.1.201"), + "IP address of the interface the eNB will listen for M1-U traffic.") ; // Positional options - config file location diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index d6cc3fc89..4f4df81b5 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -43,12 +43,14 @@ gtpu::gtpu():mchthread() } -bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_interface_gtpu* pdcp_, srslte::log* gtpu_log_, bool enable_mbsfn) +bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, std::string m1u_multiaddr_, std::string m1u_if_addr_, srsenb::pdcp_interface_gtpu* pdcp_, srslte::log* gtpu_log_, bool enable_mbsfn) { pdcp = pdcp_; gtpu_log = gtpu_log_; gtp_bind_addr = gtp_bind_addr_; mme_addr = mme_addr_; + m1u_multiaddr = m1u_multiaddr_; + m1u_if_addr = m1u_if_addr_; pool = byte_buffer_pool::get_instance(); @@ -93,8 +95,7 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ void gtpu::stop() { - - if(enable_mbsfn){ + if(enable_mbsfn){ mchthread.stop(); } @@ -327,8 +328,12 @@ bool gtpu::mch_thread::init(pdcp_interface_gtpu *pdcp, srslte::log *gtpu_log) this->pdcp = pdcp; this->gtpu_log = gtpu_log; + +gtpu_log->info("M1-U initialized\n"); +return true; +} struct sockaddr_in bindaddr; - + // Set up sink socket m1u_sd = socket(AF_INET, SOCK_DGRAM, 0); if (m1u_sd < 0) { @@ -350,11 +355,12 @@ bool gtpu::mch_thread::init(pdcp_interface_gtpu *pdcp, srslte::log *gtpu_log) /* Send an ADD MEMBERSHIP message via setsockopt */ struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = inet_addr("239.255.0.1"); //Multicast address of the service - mreq.imr_interface.s_addr = inet_addr("127.0.1.200"); //Address of the IF the socket will listen to. + mreq.imr_multiaddr.s_addr = inet_addr(m1u_multiaddr.c_str()); //Multicast address of the service + mreq.imr_interface.s_addr = inet_addr(m1u_if_addr.c_str()); //Address of the IF the socket will listen to. if (setsockopt(m1u_sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { gtpu_log->error("Register musticast group for M1-U\n"); + gtpu_log->error("M1-U infterface IP: %s, M1-U Multicast Address %s\n", m1u_if_addr.c_str(),m1u_multiaddr.c_str()); return false; } gtpu_log->info("M1-U initialized\n"); From de75a74932d1721f44d1933ce8d1bc2e03fa03f3 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 2 Oct 2018 12:25:15 +0100 Subject: [PATCH 42/71] Fixed some compilation issues. --- srsenb/hdr/upper/gtpu.h | 6 +++--- srsenb/src/upper/gtpu.cc | 13 ++++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/srsenb/hdr/upper/gtpu.h b/srsenb/hdr/upper/gtpu.h index b25139a17..a71f187f6 100644 --- a/srsenb/hdr/upper/gtpu.h +++ b/srsenb/hdr/upper/gtpu.h @@ -70,8 +70,6 @@ private: bool enable_mbsfn; std::string gtp_bind_addr; std::string mme_addr; - std::string m1u_multiaddr; - std::string m1u_if_addr; srsenb::pdcp_interface_gtpu *pdcp; srslte::log *gtpu_log; @@ -79,7 +77,7 @@ private: class mch_thread : public thread { public: mch_thread() : initiated(false),running(false),run_enable(false),pool(NULL) {} - bool init(pdcp_interface_gtpu *pdcp_, srslte::log *gtpu_log_); + bool init(std::string m1u_multiaddr_, std::string m1u_if_addr_, pdcp_interface_gtpu *pdcp_, srslte::log *gtpu_log_); void stop(); private: void run_thread(); @@ -94,6 +92,8 @@ private: srslte::log *gtpu_log; int m1u_sd; int lcid_counter; + std::string m1u_multiaddr; + std::string m1u_if_addr; srslte::byte_buffer_pool *pool; }; diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 4f4df81b5..a1262956f 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -49,9 +49,6 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, std::string m gtpu_log = gtpu_log_; gtp_bind_addr = gtp_bind_addr_; mme_addr = mme_addr_; - m1u_multiaddr = m1u_multiaddr_; - m1u_if_addr = m1u_if_addr_; - pool = byte_buffer_pool::get_instance(); // Set up socket @@ -88,7 +85,7 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, std::string m // Start MCH thread if enabled this->enable_mbsfn = enable_mbsfn; if(enable_mbsfn) { - mchthread.init(pdcp, gtpu_log); + mchthread.init(m1u_multiaddr_, m1u_if_addr_, pdcp, gtpu_log); } return true; } @@ -322,16 +319,14 @@ void gtpu::rntilcid_to_teidin(uint16_t rnti, uint16_t lcid, uint32_t *teidin) /**************************************************************************** * Class to run the MCH thread ***************************************************************************/ -bool gtpu::mch_thread::init(pdcp_interface_gtpu *pdcp, srslte::log *gtpu_log) +bool gtpu::mch_thread::init(std::string m1u_multiaddr_, std::string m1u_if_addr_, pdcp_interface_gtpu *pdcp, srslte::log *gtpu_log) { pool = byte_buffer_pool::get_instance(); this->pdcp = pdcp; this->gtpu_log = gtpu_log; + m1u_multiaddr = m1u_multiaddr_; + m1u_if_addr = m1u_if_addr_; - -gtpu_log->info("M1-U initialized\n"); -return true; -} struct sockaddr_in bindaddr; // Set up sink socket From 2c761069d416cf125dcf31f450ce9f07feba1123 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 2 Oct 2018 13:02:50 +0100 Subject: [PATCH 43/71] Adding m1u config to enb.conf.example. --- srsenb/enb.conf.example | 5 +++++ srsenb/src/upper/gtpu.cc | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 67b83afb5..4836fdb4f 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -150,6 +150,9 @@ nof_ctrl_symbols = 3 # link_failure_nof_err: Number of PUSCH failures after which a radio-link failure is triggered. # a link failure is when SNR<0 and CRC=KO # max_prach_offset_us: Maximum allowed RACH offset (in us) +# enable_mbsfn: Enable MBMS transmission in the eNB +# m1u_multiaddr: Multicast addres the M1-U socket will register to +# m1u_if_addr: Address of the inteferface the M1-U interface will listen for multicast packets. # ##################################################################### [expert] @@ -162,3 +165,5 @@ nof_ctrl_symbols = 3 #rrc_inactivity_timer = 60000 #max_prach_offset_us = 30 #enable_mbsfn = false +#m1u_multiaddr = 239.255.0.1 +#m1u_if_addr = 127.0.1.201 \ No newline at end of file diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index a1262956f..d7eabf46e 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -403,7 +403,7 @@ void gtpu::mch_thread::run_thread() } while (n == -1 && errno == EAGAIN); pdu->N_bytes = (uint32_t) n; - + gtpu_header_t header; gtpu_read_header(pdu, &header, gtpu_log); From a42c71f8ee79e168055d7d3e12575ceb0e38e30d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 2 Oct 2018 14:00:54 +0100 Subject: [PATCH 44/71] Added some debug logs to the eNB GTPU. --- srsenb/src/upper/gtpu.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index d7eabf46e..cfe34b7e9 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -223,6 +223,7 @@ void gtpu::run_thread() gtpu_log->error("Failed to read from socket\n"); } + gtpu_log->debug("Received %d bytes from S1-U interface\n", n); pdu->N_bytes = (uint32_t) n; gtpu_header_t header; @@ -401,12 +402,12 @@ void gtpu::mch_thread::run_thread() do{ n = recvfrom(m1u_sd, pdu->msg, SRSENB_MAX_BUFFER_SIZE_BYTES - SRSENB_BUFFER_HEADER_OFFSET, 0, (struct sockaddr *) &src_addr, &addrlen); } while (n == -1 && errno == EAGAIN); + gtpu_log->debug("Received %d bytes from M1-U interface\n", n); pdu->N_bytes = (uint32_t) n; gtpu_header_t header; gtpu_read_header(pdu, &header, gtpu_log); - pdcp->write_sdu(SRSLTE_MRNTI, lcid, pdu); do { pdu = pool_allocate; From 3ecacdf3a6332048def4d1f007b202ab4db628db Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 2 Oct 2018 16:29:45 +0100 Subject: [PATCH 45/71] Adding selection of local interface at the MBMS-GW. --- srsepc/hdr/mbms-gw/mbms-gw.h | 1 + srsepc/mbms.conf.example | 1 + srsepc/src/mbms-gw/main.cc | 3 +++ srsepc/src/mbms-gw/mbms-gw.cc | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index c238c0a18..45046b1d9 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -51,6 +51,7 @@ typedef struct { std::string sgi_mb_if_addr; std::string sgi_mb_if_mask; std::string m1u_multi_addr; + std::string m1u_multi_if; } mbms_gw_args_t; struct pseudo_hdr diff --git a/srsepc/mbms.conf.example b/srsepc/mbms.conf.example index d92306328..efe8489d8 100644 --- a/srsepc/mbms.conf.example +++ b/srsepc/mbms.conf.example @@ -15,6 +15,7 @@ name = srsmbmsgw01 sgi_mb_if_addr = 172.16.0.254 sgi_mb_if_mask = 255.255.255.255 m1u_multi_addr = 239.255.0.1 +m1u_multi_if = 127.0.1.200 #################################################################### # Log configuration diff --git a/srsepc/src/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index f99356071..046b9e27b 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -85,6 +85,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { string mbms_gw_sgi_mb_if_addr; string mbms_gw_sgi_mb_if_mask; string mbms_gw_m1u_multi_addr; + string mbms_gw_m1u_multi_if; string log_filename; @@ -103,6 +104,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("mbms_gw.sgi_mb_if_addr", bpo::value(&mbms_gw_sgi_mb_if_addr)->default_value("172.16.1.1"), "SGi-mb TUN interface Address.") ("mbms_gw.sgi_mb_if_mask", bpo::value(&mbms_gw_sgi_mb_if_mask)->default_value("255.255.255.255"), "SGi-mb TUN interface mask.") ("mbms_gw.m1u_multi_addr", bpo::value(&mbms_gw_m1u_multi_addr)->default_value("239.255.0.1"), "M1-u GTPu destination multicast address.") + ("mbms_gw.m1u_multi_if", bpo::value(&mbms_gw_m1u_multi_if)->default_value("127.0.1.200"), "Local interface IP for M1-U multicast packets.") ("log.all_level", bpo::value(&args->log_args.all_level)->default_value("info"), "ALL log level") ("log.all_hex_limit", bpo::value(&args->log_args.all_hex_limit)->default_value(32), "ALL log hex dump limit") @@ -156,6 +158,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { args->mbms_gw_args.sgi_mb_if_addr = mbms_gw_sgi_mb_if_addr; args->mbms_gw_args.sgi_mb_if_mask = mbms_gw_sgi_mb_if_mask; args->mbms_gw_args.m1u_multi_addr = mbms_gw_m1u_multi_addr; + args->mbms_gw_args.m1u_multi_if = mbms_gw_m1u_multi_if; // Apply all_level to any unset layers if (vm.count("log.all_level")) { diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index dc8199e27..d8ae96182 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -234,7 +234,7 @@ mbms_gw::init_m1_u(mbms_gw_args_t *args) /* Set local interface for outbound multicast packets*/ /* The IP must be associated with a local multicast capable interface */ struct in_addr local_if; - local_if.s_addr = inet_addr("127.0.1.200"); + local_if.s_addr = inet_addr(args->m1u_multi_if.c_str()); if(setsockopt(m_m1u, IPPROTO_IP, IP_MULTICAST_IF, (char*)&local_if, sizeof(struct in_addr))<0){ perror("Error setting multicast interface.\n"); } else { From 35ca9ffd348921ea1c56fdf09efcffd120e742c2 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 2 Oct 2018 16:47:55 +0100 Subject: [PATCH 46/71] Adding TTL option --- srsepc/hdr/mbms-gw/mbms-gw.h | 1 + srsepc/mbms.conf.example | 1 + srsepc/src/mbms-gw/main.cc | 1 + srsepc/src/mbms-gw/mbms-gw.cc | 8 +++++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index 45046b1d9..ba1641c27 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -52,6 +52,7 @@ typedef struct { std::string sgi_mb_if_mask; std::string m1u_multi_addr; std::string m1u_multi_if; + int m1u_multi_ttl; } mbms_gw_args_t; struct pseudo_hdr diff --git a/srsepc/mbms.conf.example b/srsepc/mbms.conf.example index efe8489d8..3c0a03696 100644 --- a/srsepc/mbms.conf.example +++ b/srsepc/mbms.conf.example @@ -16,6 +16,7 @@ sgi_mb_if_addr = 172.16.0.254 sgi_mb_if_mask = 255.255.255.255 m1u_multi_addr = 239.255.0.1 m1u_multi_if = 127.0.1.200 +m1u_multi_ttl = 1 #################################################################### # Log configuration diff --git a/srsepc/src/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index 046b9e27b..64037c0ad 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -105,6 +105,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("mbms_gw.sgi_mb_if_mask", bpo::value(&mbms_gw_sgi_mb_if_mask)->default_value("255.255.255.255"), "SGi-mb TUN interface mask.") ("mbms_gw.m1u_multi_addr", bpo::value(&mbms_gw_m1u_multi_addr)->default_value("239.255.0.1"), "M1-u GTPu destination multicast address.") ("mbms_gw.m1u_multi_if", bpo::value(&mbms_gw_m1u_multi_if)->default_value("127.0.1.200"), "Local interface IP for M1-U multicast packets.") + ("mbms_gw.m1u_multi_ttl", bpo::value(&args->mbms_gw_args.m1u_multi_ttl)->default_value(1), "TTL for M1-U multicast packets.") ("log.all_level", bpo::value(&args->log_args.all_level)->default_value("info"), "ALL log level") ("log.all_hex_limit", bpo::value(&args->log_args.all_hex_limit)->default_value(32), "ALL log hex dump limit") diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index d8ae96182..eed2f5b95 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -238,7 +238,13 @@ mbms_gw::init_m1_u(mbms_gw_args_t *args) if(setsockopt(m_m1u, IPPROTO_IP, IP_MULTICAST_IF, (char*)&local_if, sizeof(struct in_addr))<0){ perror("Error setting multicast interface.\n"); } else { - printf("Multicast interface specified.\n"); + printf("Multicast interface specified. Address: %s\n", args->m1u_multi_if.c_str()); + } + + /*Set Multicast TTL*/ + if ( setsockopt(m_m1u, IPPROTO_IP,IP_MULTICAST_TTL,&args->m1u_multi_ttl,sizeof(args->m1u_multi_ttl)) <0 ) { + perror("Error setting multicast ttl.\n"); + return srslte::ERROR_CANT_START; } bzero(&m_m1u_multi_addr,sizeof(m_m1u_multi_addr)); From 3cddad79ccf98ab8139b0c517e2c1e3d5a585812 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 5 Oct 2018 10:12:31 +0100 Subject: [PATCH 47/71] Adding ability to configure names of TUN interfaces. (#277) * added config option for tun dev names vs fixed names added config option for M1-U interface addr * Added options to sgi_mb tun name. * Added some comments to mbms.conf.example * Added some comments to example configs to explain the new values. --- srsepc/epc.conf.example | 5 ++++- srsepc/hdr/mbms-gw/mbms-gw.h | 1 + srsepc/hdr/spgw/spgw.h | 1 + srsepc/mbms.conf.example | 9 +++++++-- srsepc/src/main.cc | 3 +++ srsepc/src/mbms-gw/main.cc | 3 +++ srsepc/src/mbms-gw/mbms-gw.cc | 20 ++++++++++---------- srsepc/src/spgw/spgw.cc | 3 +-- srsue/hdr/ue_base.h | 1 + srsue/hdr/upper/gw.h | 2 ++ srsue/src/main.cc | 4 ++++ srsue/src/ue.cc | 1 + srsue/src/upper/gw.cc | 10 +++++++--- srsue/ue.conf.example | 2 ++ 14 files changed, 47 insertions(+), 18 deletions(-) diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 6d857f78a..12562f1f0 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -40,13 +40,16 @@ db_file = user_db.csv ##################################################################### # SP-GW configuration # -# gtpu_bind_addr: GTP-U bind adress. +# gtpu_bind_addr: GTP-U bind address. +# sgi_if_addr: SGi TUN interface IP address. +# sgi_if_name: SGi TUN interface name. # ##################################################################### [spgw] gtpu_bind_addr = 127.0.1.100 sgi_if_addr = 172.16.0.1 +sgi_if_name = srs_spgw_sgi #################################################################### # PCAP configuration diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index ba1641c27..58bfcc277 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -48,6 +48,7 @@ const uint16_t GTPU_RX_PORT = 2152; typedef struct { std::string name; + std::string sgi_mb_if_name; std::string sgi_mb_if_addr; std::string sgi_mb_if_mask; std::string m1u_multi_addr; diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 98ad59403..3222f5120 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -50,6 +50,7 @@ const uint16_t GTPU_RX_PORT = 2152; typedef struct { std::string gtpu_bind_addr; std::string sgi_if_addr; + std::string sgi_if_name; } spgw_args_t; diff --git a/srsepc/mbms.conf.example b/srsepc/mbms.conf.example index 3c0a03696..19993e1fa 100644 --- a/srsepc/mbms.conf.example +++ b/srsepc/mbms.conf.example @@ -1,17 +1,22 @@ ##################################################################### -# srsEPC configuration file +# srsMBMS configuration file ##################################################################### ##################################################################### # MBMS-GW configuration # # name: MBMS-GW name +# sgi_mb_if_name: SGi-mb TUN interface name # sgi_mb_if_addr: SGi-mb interface IP address -# m1u_addr: Multicast group for eNBs (FIXME this should be setup with M2/M3) +# sgi_mb_if_mask: SGi-mb interface IP mask +# m1u_multi_addr: Multicast group for eNBs (FIXME this should be setup with M2/M3) +# m1u_multi_if: IP of local interface for multicast traffic +# m1u_multi_ttl: TTL for M1-U multicast traffic # ##################################################################### [mbms_gw] name = srsmbmsgw01 +sgi_mb_if_name = sgi_mb sgi_mb_if_addr = 172.16.0.254 sgi_mb_if_mask = 255.255.255.255 m1u_multi_addr = 239.255.0.1 diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 984f81dd6..6131c4457 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -87,6 +87,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { string mme_apn; string spgw_bind_addr; string sgi_if_addr; + string sgi_if_name; string dns_addr; string hss_db_file; string hss_auth_algo; @@ -116,6 +117,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("hss.auth_algo", bpo::value(&hss_auth_algo)->default_value("milenage"), "HSS uthentication algorithm.") ("spgw.gtpu_bind_addr", bpo::value(&spgw_bind_addr)->default_value("127.0.0.1"), "IP address of SP-GW for the S1-U connection") ("spgw.sgi_if_addr", bpo::value(&sgi_if_addr)->default_value("176.16.0.1"), "IP address of TUN interface for the SGi connection") + ("spgw.sgi_if_name", bpo::value(&sgi_if_name)->default_value("srs_spgw_sgi"), "Name of TUN interface for the SGi connection") ("pcap.enable", bpo::value(&args->mme_args.s1ap_args.pcap_enable)->default_value(false), "Enable S1AP PCAP") ("pcap.filename", bpo::value(&args->mme_args.s1ap_args.pcap_filename)->default_value("/tmp/epc.pcap"), "PCAP filename") @@ -219,6 +221,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { args->mme_args.s1ap_args.mme_apn = mme_apn; args->spgw_args.gtpu_bind_addr = spgw_bind_addr; args->spgw_args.sgi_if_addr = sgi_if_addr; + args->spgw_args.sgi_if_name = sgi_if_name; args->hss_args.db_file = hss_db_file; args->hss_args.auth_algo = hss_auth_algo; diff --git a/srsepc/src/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index 64037c0ad..02d16d65d 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -82,6 +82,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { string mbms_gw_name; + string mbms_gw_sgi_mb_if_name; string mbms_gw_sgi_mb_if_addr; string mbms_gw_sgi_mb_if_mask; string mbms_gw_m1u_multi_addr; @@ -101,6 +102,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { common.add_options() ("mbms_gw.name", bpo::value(&mbms_gw_name)->default_value("srsmbmsgw01"), "MBMS-GW Name") + ("mbms_gw.sgi_mb_if_name", bpo::value(&mbms_gw_sgi_mb_if_name)->default_value("sgi_mb"), "SGi-mb TUN interface Address.") ("mbms_gw.sgi_mb_if_addr", bpo::value(&mbms_gw_sgi_mb_if_addr)->default_value("172.16.1.1"), "SGi-mb TUN interface Address.") ("mbms_gw.sgi_mb_if_mask", bpo::value(&mbms_gw_sgi_mb_if_mask)->default_value("255.255.255.255"), "SGi-mb TUN interface mask.") ("mbms_gw.m1u_multi_addr", bpo::value(&mbms_gw_m1u_multi_addr)->default_value("239.255.0.1"), "M1-u GTPu destination multicast address.") @@ -156,6 +158,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { bpo::notify(vm); args->mbms_gw_args.name = mbms_gw_name; + args->mbms_gw_args.sgi_mb_if_name = mbms_gw_sgi_mb_if_name; args->mbms_gw_args.sgi_mb_if_addr = mbms_gw_sgi_mb_if_addr; args->mbms_gw_args.sgi_mb_if_mask = mbms_gw_sgi_mb_if_mask; args->mbms_gw_args.m1u_multi_addr = mbms_gw_m1u_multi_addr; diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index eed2f5b95..bec61596b 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -126,7 +126,6 @@ mbms_gw::stop() srslte::error_t mbms_gw::init_sgi_mb_if(mbms_gw_args_t *args) { - char dev[IFNAMSIZ] = "sgi_mb"; struct ifreq ifr; if(m_sgi_mb_up) @@ -138,22 +137,22 @@ mbms_gw::init_sgi_mb_if(mbms_gw_args_t *args) // Construct the TUN device m_sgi_mb_if = open("/dev/net/tun", O_RDWR); m_mbms_gw_log->info("TUN file descriptor = %d\n", m_sgi_mb_if); - if(m_sgi_mb_if < 0) - { + if (m_sgi_mb_if < 0) { m_mbms_gw_log->error("Failed to open TUN device: %s\n", strerror(errno)); return(srslte::ERROR_CANT_START); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ-1); + strncpy(ifr.ifr_ifrn.ifrn_name, args->sgi_mb_if_name.c_str(), std::min(args->sgi_mb_if_name.length(), (size_t)IFNAMSIZ-1) ); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1]='\0'; - if(ioctl(m_sgi_mb_if, TUNSETIFF, &ifr) < 0) - { - m_mbms_gw_log->error("Failed to set TUN device name: %s\n", strerror(errno)); - close(m_sgi_mb_if); - return(srslte::ERROR_CANT_START); + if (ioctl(m_sgi_mb_if, TUNSETIFF, &ifr) < 0) { + m_mbms_gw_log->error("Failed to set TUN device name: %s\n", strerror(errno)); + close(m_sgi_mb_if); + return(srslte::ERROR_CANT_START); + } else { + m_mbms_gw_log->debug("Set TUN device name: %s\n", args->sgi_mb_if_name.c_str()); } // Bring up the interface @@ -236,7 +235,8 @@ mbms_gw::init_m1_u(mbms_gw_args_t *args) struct in_addr local_if; local_if.s_addr = inet_addr(args->m1u_multi_if.c_str()); if(setsockopt(m_m1u, IPPROTO_IP, IP_MULTICAST_IF, (char*)&local_if, sizeof(struct in_addr))<0){ - perror("Error setting multicast interface.\n"); + m_mbms_gw_log->error("Error %s setting multicast interface %s.\n", strerror(errno), args->m1u_multi_if.c_str()); + return srslte::ERROR_CANT_START; } else { printf("Multicast interface specified. Address: %s\n", args->m1u_multi_if.c_str()); } diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 0a867d51c..ed706ba85 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -157,7 +157,6 @@ spgw::stop() srslte::error_t spgw::init_sgi_if(spgw_args_t *args) { - char dev[IFNAMSIZ] = "srs_spgw_sgi"; struct ifreq ifr; if(m_sgi_up) @@ -177,7 +176,7 @@ spgw::init_sgi_if(spgw_args_t *args) memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ-1); + strncpy(ifr.ifr_ifrn.ifrn_name, args->sgi_if_name.c_str(), std::min(args->sgi_if_name.length(), (size_t)(IFNAMSIZ-1))); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1]='\0'; if(ioctl(m_sgi_if, TUNSETIFF, &ifr) < 0) diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index 0f362160a..af487a406 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -111,6 +111,7 @@ typedef struct { typedef struct { std::string ip_netmask; + std::string ip_devname; phy_args_t phy; float metrics_period_secs; bool pregenerate_signals; diff --git a/srsue/hdr/upper/gw.h b/srsue/hdr/upper/gw.h index 46059b517..ed3ae4fbb 100644 --- a/srsue/hdr/upper/gw.h +++ b/srsue/hdr/upper/gw.h @@ -52,6 +52,7 @@ public: void get_metrics(gw_metrics_t &m); void set_netmask(std::string netmask); + void set_tundevname(const std::string & devname); // PDCP interface void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu); @@ -67,6 +68,7 @@ private: bool default_netmask; std::string netmask; + std::string tundevname; static const int GW_THREAD_PRIO = 7; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index a79fbd710..861c1ded5 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -142,6 +142,10 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.ip_netmask)->default_value("255.255.255.0"), "Netmask of the tun_srsue device") + ("expert.ip_devname", + bpo::value(&args->expert.ip_devname)->default_value("tun_srsue"), + "Name of the tun_srsue device") + ("expert.mbms_service", bpo::value(&args->expert.mbms_service)->default_value(-1), "automatically starts an mbms service of the number given") diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 2a6b05425..882f29f1d 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -225,6 +225,7 @@ bool ue::init(all_args_t *args_) { nas.init(usim, &rrc, &gw, &nas_log, nas_cfg); gw.init(&pdcp, &nas, &gw_log, 3 /* RB_ID_DRB1 */); gw.set_netmask(args->expert.ip_netmask); + gw.set_tundevname(args->expert.ip_devname); // Get current band from provided EARFCN args->rrc.supported_bands[0] = srslte_band_get_band(args->rf.dl_earfcn); diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index e78bd70bb..62d1e84a8 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -45,6 +45,7 @@ gw::gw() { current_ip_addr = 0; default_netmask = true; + tundevname = ""; } void gw::init(pdcp_interface_gw *pdcp_, nas_interface_gw *nas_, srslte::log *gw_log_, srslte::srslte_gw_config_t cfg_) @@ -125,6 +126,11 @@ void gw::set_netmask(std::string netmask) this->netmask = netmask; } +void gw::set_tundevname(const std::string & devname) +{ + tundevname = devname; +} + /******************************************************************************* PDCP interface @@ -242,8 +248,6 @@ srslte::error_t gw::init_if(char *err_str) return(srslte::ERROR_ALREADY_STARTED); } - char dev[IFNAMSIZ] = "tun_srsue"; - // Construct the TUN device tun_fd = open("/dev/net/tun", O_RDWR); gw_log->info("TUN file descriptor = %d\n", tun_fd); @@ -255,7 +259,7 @@ srslte::error_t gw::init_if(char *err_str) } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ-1); + strncpy(ifr.ifr_ifrn.ifrn_name, tundevname.c_str(), std::min(tundevname.length(), (size_t)(IFNAMSIZ-1))); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1] = 0; if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) { diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index d2bc4bb12..1209fe89d 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -137,6 +137,7 @@ enable = false # Expert configuration options # # ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0 +# ip_devname: Nanme of the tun_srsue device. Default: tun_srsue # rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but # can cause UHD instability for long-duration testing. Default true. # rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings @@ -209,6 +210,7 @@ enable = false ##################################################################### [expert] #ip_netmask = 255.255.255.0 +#ip_devname = tun_srsue #mbms_service = -1 #rssi_sensor_enabled = false #rx_gain_offset = 62 From 2645fb50b1fa739b4a3ffabb06ee3f62f3812e76 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 20 Sep 2018 12:29:46 +0200 Subject: [PATCH 48/71] add aligned attribute to liblte_bit_msg_struct to fix issues on ARM --- lib/include/srslte/asn1/liblte_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/asn1/liblte_common.h b/lib/include/srslte/asn1/liblte_common.h index 3b7eccf6f..b7587f340 100644 --- a/lib/include/srslte/asn1/liblte_common.h +++ b/lib/include/srslte/asn1/liblte_common.h @@ -102,7 +102,7 @@ typedef struct{ uint32 N_bits; uint8 header[LIBLTE_MSG_HEADER_OFFSET]; uint8 msg[LIBLTE_MAX_MSG_SIZE_BITS]; -}LIBLTE_BIT_MSG_STRUCT; +}LIBLTE_BIT_MSG_STRUCT __attribute__ ((aligned (8))); typedef struct{ uint32 N_bytes; From 273087ce006d79ea250b724412c21670fe59ecc2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 5 Oct 2018 14:50:49 +0200 Subject: [PATCH 49/71] use blocking pool allocate for all NAS/RRC allocs and first GW alloc --- srsue/src/upper/gw.cc | 2 +- srsue/src/upper/nas.cc | 2 +- srsue/src/upper/rrc.cc | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 62d1e84a8..576271b5b 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -313,7 +313,7 @@ void gw::run_thread() struct iphdr *ip_pkt; uint32 idx = 0; int32 N_bytes; - srslte::byte_buffer_t *pdu = pool_allocate; + srslte::byte_buffer_t *pdu = pool_allocate_blocking; if (!pdu) { gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); return; diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index b7fb0caaf..4cf6b04e0 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -1490,7 +1490,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) { esm_info_resp.protocol_cnfg_opts_present = false; } - byte_buffer_t *pdu = pool_allocate; + byte_buffer_t *pdu = pool_allocate_blocking; if (!pdu) { nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n"); return; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 080de4b27..bae3049a3 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1582,7 +1582,7 @@ bool rrc::con_reconfig(LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig) { byte_buffer_t *nas_sdu; for (uint32_t i = 0; i < reconfig->N_ded_info_nas; i++) { - nas_sdu = pool_allocate; + nas_sdu = pool_allocate_blocking; if (nas_sdu) { 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; @@ -1887,7 +1887,7 @@ byte_buffer_t* rrc::byte_align_and_pack() } // Reset and reuse sdu buffer if provided - byte_buffer_t *pdcp_buf = pool_allocate; + byte_buffer_t *pdcp_buf = pool_allocate_blocking; if (pdcp_buf) { srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); pdcp_buf->N_bytes = bit_buf.N_bits / 8; @@ -2051,7 +2051,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { switch (dl_dcch_msg.msg_type) { case LIBLTE_RRC_DL_DCCH_MSG_TYPE_DL_INFO_TRANSFER: - pdu = pool_allocate; + pdu = pool_allocate_blocking; if (!pdu) { rrc_log->error("Fatal error: out of buffers in pool\n"); return; From 15d439761a3d14fe8e70eeecbae0f89161bcf621 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 5 Oct 2018 14:58:09 +0200 Subject: [PATCH 50/71] log build info in eNB/EPC logs --- srsenb/src/enb.cc | 1 + srsepc/src/main.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index a1906400b..97a3ca56a 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -85,6 +85,7 @@ bool enb::init(all_args_t *args_) } else { logger_file.init(args->log.filename, args->log.file_max_size); logger_file.log("\n\n"); + logger_file.log(get_build_string().c_str()); logger = &logger_file; } diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 6131c4457..b34114363 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -330,6 +330,8 @@ main (int argc,char * argv[] ) logger = &logger_stdout; } else { logger_file.init(args.log_args.filename); + logger_file.log("\n\n"); + logger_file.log(get_build_string().c_str()); logger_file.log("\n--- Software Radio Systems EPC log ---\n\n"); logger = &logger_file; } From bbfd09b62ecfab6a978a5564f278cfe8715d0da1 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 26 Sep 2018 17:39:59 +0100 Subject: [PATCH 51/71] add the prach fit checks for PRB=6 --- srsenb/src/enb.cc | 24 ++++++++++++++++-------- srsenb/src/mac/scheduler.cc | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 97a3ca56a..a97382f3e 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -217,15 +217,23 @@ bool enb::init(all_args_t *args_) uint32_t prach_freq_offset = rrc_cfg.sibs[1].sib.sib2.rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset; - if (prach_freq_offset + 6 > cell_cfg.nof_prb) { - fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", prach_freq_offset); - return false; - } + if(cell_cfg.nof_prb>10) { + if (prach_freq_offset + 6 > cell_cfg.nof_prb - SRSLTE_MAX(rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb)) { + fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", prach_freq_offset); + return false; + } - if (prach_freq_offset < rrc_cfg.cqi_cfg.nof_prb || prach_freq_offset < rrc_cfg.sr_cfg.nof_prb ) { - fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d lower than CQI offset: %d or SR offset: %d\n", - prach_freq_offset, rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb); - return false; + if (prach_freq_offset < SRSLTE_MAX(rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb)) { + fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d lower than CQI offset: %d or SR offset: %d\n", + prach_freq_offset, rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb); + return false; + } + } else { // 6 PRB case + if (prach_freq_offset+6 > cell_cfg.nof_prb) { + fprintf(stderr, "Invalid PRACH configuration: frequency interval=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n", + prach_freq_offset, prach_freq_offset+6, cell_cfg.nof_prb); + return false; + } } rrc_cfg.inactivity_timeout_ms = args->expert.rrc_inactivity_timer; diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 8737d9168..f8f8fdc37 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -796,7 +796,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched return 0; } - if (cfg.prach_freq_offset + 6 > cfg.cell.nof_prb) { + if (cfg.prach_freq_offset + 6 > cfg.cell.nof_prb and cfg.cell.nof_prb>10) { fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset); return -1; } From d234f4a614bf997955b35b9c774f0a378c3fc84b Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 25 Sep 2018 18:20:19 +0100 Subject: [PATCH 52/71] fix MCS assignment for 6 PRBs - cherry-picked and resolved conflicts from 0960ef5c6dcd2f9b96169b3f4c266197b922c46e --- srsenb/src/mac/scheduler.cc | 7 ++++++- srsenb/src/mac/scheduler_ue.cc | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index f8f8fdc37..e2ca881bd 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -677,7 +677,12 @@ int sched::dl_sched_rar(dl_sched_rar_t rar[MAX_RAR_LIST]) // Schedules data to users int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST]) { - uint32_t nof_ctrl_symbols = (cfg.cell.nof_prb<10)?(current_cfi+1):current_cfi; + // NOTE: In case of 6 PRBs, do not transmit if there is going to be a PRACH in the UL to avoid collisions + if (cfg.cell.nof_prb<10 and srslte_prach_tti_opportunity_config(cfg.prach_config, current_tti+4, -1)) { + start_rbg = avail_rbg; + } + + uint32_t nof_ctrl_symbols = (cfg.cell.nof_prb<10)?(current_cfi+1):current_cfi; dl_metric->new_tti(ue_db, start_rbg, avail_rbg, nof_ctrl_symbols, current_tti); int nof_data_elems = 0; diff --git a/srsenb/src/mac/scheduler_ue.cc b/srsenb/src/mac/scheduler_ue.cc index c4cc38e48..f985b2fde 100644 --- a/srsenb/src/mac/scheduler_ue.cc +++ b/srsenb/src/mac/scheduler_ue.cc @@ -498,7 +498,10 @@ int sched_ue::generate_format1(dl_harq_proc *h, srslte_ra_dl_dci_to_grant_prb_allocation(dci, &grant, cell.nof_prb); uint32_t nof_ctrl_symbols = cfi+(cell.nof_prb<10?1:0); uint32_t nof_re = srslte_ra_dl_grant_nof_re(&grant, cell, sf_idx, nof_ctrl_symbols); - if (fixed_mcs_dl < 0) { + if(need_conres_ce and cell.nof_prb<10) { // SRB0 Tx. Use a higher MCS for the PRACH to fit in 6 PRBs + tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(4), nof_prb)/8; + mcs = 4; + } else if (fixed_mcs_dl < 0) { tbs = alloc_tbs_dl(nof_prb, nof_re, req_bytes, &mcs); } else { tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_dl), nof_prb)/8; @@ -1221,6 +1224,7 @@ int sched_ue::alloc_tbs(uint32_t nof_prb, // Avoid the unusual case n_prb=1, mcs=6 tbs=328 (used in voip) if (nof_prb == 1 && sel_mcs == 6) { sel_mcs--; + tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(sel_mcs), nof_prb)/8; } if (mcs && tbs >= 0) { From 580ce3e29873f6f73ac9c97cdf26075958ae136a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 5 Oct 2018 12:17:44 +0200 Subject: [PATCH 53/71] add extra length check for RLC UM --- lib/src/upper/rlc_tm.cc | 2 +- lib/src/upper/rlc_um.cc | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 14cfe37ea..e006072c6 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -153,7 +153,7 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) { uint32_t pdu_size = ul_queue.size_tail_bytes(); if (pdu_size > nof_bytes) { - log->error("TX %s PDU size larger than MAC opportunity\n", rrc->get_rb_name(lcid).c_str()); + log->error("TX %s PDU size larger than MAC opportunity (%d > %d)\n", rrc->get_rb_name(lcid).c_str(), pdu_size, nof_bytes); return -1; } byte_buffer_t *buf; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 4fee0e7b6..24e66389c 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -774,6 +774,11 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { log->warning_hex(rx_window[vr_ur].buf->msg, len, "Dropping first %d B of SN %d due to lost start segment\n", len, vr_ur); + if (rx_window[vr_ur].buf->N_bytes < len) { + log->error("Dropping remaining remainder of SN %d too (N_bytes=%u < len=%d)\n", vr_ur, rx_window[vr_ur].buf->N_bytes, len); + goto clean_up_rx_window; + } + // Advance data pointers and continue with next segment rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; From 5a3fa7c3056eabf8476dfda514ac1baf18c22669 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 5 Oct 2018 12:41:05 +0200 Subject: [PATCH 54/71] fix scheduler issues for 6 PRBs --- srsenb/hdr/mac/scheduler.h | 1 + srsenb/hdr/mac/scheduler_metric.h | 4 ++- srsenb/src/mac/scheduler.cc | 45 +++++++++++++++++------------- srsenb/src/mac/scheduler_metric.cc | 17 +++++------ srsenb/src/mac/scheduler_ue.cc | 4 +-- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/srsenb/hdr/mac/scheduler.h b/srsenb/hdr/mac/scheduler.h index 519343097..f4889c5e7 100644 --- a/srsenb/hdr/mac/scheduler.h +++ b/srsenb/hdr/mac/scheduler.h @@ -153,6 +153,7 @@ private: rrc_interface_mac *rrc; pthread_rwlock_t rwlock; + pthread_mutex_t sched_mutex; cell_cfg_t cfg; sched_args_t sched_cfg; diff --git a/srsenb/hdr/mac/scheduler_metric.h b/srsenb/hdr/mac/scheduler_metric.h index f4335fd68..583ceac2b 100644 --- a/srsenb/hdr/mac/scheduler_metric.h +++ b/srsenb/hdr/mac/scheduler_metric.h @@ -34,6 +34,7 @@ namespace srsenb { class dl_metric_rr : public sched::metric_dl { public: + //interface void new_tti(std::map &ue_db, uint32_t start_rbg, uint32_t nof_rbg, uint32_t nof_ctrl_symbols, uint32_t tti); dl_harq_proc* get_user_allocation(sched_ue *user); private: @@ -62,6 +63,7 @@ private: class ul_metric_rr : public sched::metric_ul { public: + // interface void new_tti(std::map &ue_db, uint32_t nof_rb, uint32_t tti); ul_harq_proc* get_user_allocation(sched_ue *user); bool update_allocation(ul_harq_proc::ul_alloc_t alloc); @@ -79,7 +81,7 @@ private: bool used_rb[MAX_PRB]; uint32_t current_tti; - uint32_t nof_rb; + uint32_t nof_rb; }; diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index e2ca881bd..b79396549 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -64,6 +64,7 @@ sched::sched() : bc_aggr_level(0), rar_aggr_level(0), avail_rbg(0), P(0), start_ reset(); pthread_rwlock_init(&rwlock, NULL); + pthread_mutex_init(&sched_mutex, NULL); } sched::~sched() @@ -72,6 +73,7 @@ sched::~sched() pthread_rwlock_wrlock(&rwlock); pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); + pthread_mutex_destroy(&sched_mutex); } void sched::init(rrc_interface_mac *rrc_, srslte::log* log) @@ -773,6 +775,7 @@ int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result) rar_aggr_level = 2; bzero(sched_result, sizeof(sched_interface::dl_sched_res_t)); + pthread_mutex_lock(&sched_mutex); pthread_rwlock_rdlock(&rwlock); /* Schedule Broadcast data */ @@ -785,6 +788,7 @@ int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result) sched_result->nof_data_elems += dl_sched_data(sched_result->data); pthread_rwlock_unlock(&rwlock); + pthread_mutex_unlock(&sched_mutex); /* Set CFI */ sched_result->cfi = current_cfi; @@ -820,14 +824,15 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched sf_idx = (tti+10240-HARQ_DELAY_MS)%10; } int nof_dci_elems = 0; - int nof_phich_elems = 0; - - // current_cfi is set in dl_sched() + int nof_phich_elems = 0; + + pthread_mutex_lock(&sched_mutex); + pthread_rwlock_rdlock(&rwlock); + + // current_cfi is set in dl_sched() bzero(sched_result, sizeof(sched_interface::ul_sched_res_t)); ul_metric->reset_allocation(cfg.cell.nof_prb); - pthread_rwlock_rdlock(&rwlock); - // Get HARQ process for this TTI for(it_t iter=ue_db.begin(); iter!=ue_db.end(); ++iter) { sched_ue *user = (sched_ue*) &iter->second; @@ -845,7 +850,19 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched } } + // reserve PRBs for PRACH + if(srslte_prach_tti_opportunity_config(cfg.prach_config, tti, -1)) { + ul_harq_proc::ul_alloc_t prach = {cfg.prach_freq_offset, 6}; + if(!ul_metric->update_allocation(prach)) { + log_h->warning("SCHED: Failed to allocate PRACH RBs within (%d,%d)\n", prach.RB_start, prach.RB_start + prach.L); + } + else { + log_h->debug("SCHED: Allocated PRACH RBs within (%d,%d)\n", prach.RB_start, prach.RB_start + prach.L); + } + } + // Update available allocation if there's a pending RAR + // NOTE: It has priority over PUCCH. if (pending_msg3[tti%10].enabled) { ul_harq_proc::ul_alloc_t msg3 = {pending_msg3[tti%10].n_prb, pending_msg3[tti%10].L}; if(ul_metric->update_allocation(msg3)) { @@ -860,14 +877,12 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched if (cfg.nrb_pucch >= 0) { ul_harq_proc::ul_alloc_t pucch = {0, (uint32_t) cfg.nrb_pucch}; if(!ul_metric->update_allocation(pucch)) { - log_h->warning("SCHED: Failed to allocate PUCCH\n"); + log_h->warning("SCHED: There was a collision with the PUCCH (%d, %d)\n", pucch.RB_start, pucch.RB_start+pucch.L); } pucch.RB_start = cfg.cell.nof_prb-cfg.nrb_pucch; pucch.L = (uint32_t) cfg.nrb_pucch; if(!ul_metric->update_allocation(pucch)) { - log_h->warning("SCHED: Failed to allocate PUCCH\n"); - } else { - log_h->debug("Allocating PUCCH (%d,%d)\n", pucch.RB_start, pucch.RB_start+pucch.L); + log_h->warning("SCHED: There was a collision with the PUCCH (%d, %d)\n", pucch.RB_start, pucch.RB_start+pucch.L); } } else { for(it_t iter=ue_db.begin(); iter!=ue_db.end(); ++iter) { @@ -885,17 +900,6 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched } } - // reserve PRBs for PRACH - if(srslte_prach_tti_opportunity_config(cfg.prach_config, tti, -1)) { - ul_harq_proc::ul_alloc_t prach = {cfg.prach_freq_offset, 6}; - if(!ul_metric->update_allocation(prach)) { - log_h->warning("SCHED: Failed to allocate PRACH RBs within (%d,%d)\n", prach.RB_start, prach.RB_start + prach.L); - } - else { - log_h->debug("SCHED: Allocated PRACH RBs within (%d,%d)\n", prach.RB_start, prach.RB_start + prach.L); - } - } - ul_metric->new_tti(ue_db, cfg.cell.nof_prb, current_tti); // Now allocate PUSCH @@ -999,6 +1003,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched } pthread_rwlock_unlock(&rwlock); + pthread_mutex_unlock(&sched_mutex); sched_result->nof_dci_elems = nof_dci_elems; sched_result->nof_phich_elems = nof_phich_elems; diff --git a/srsenb/src/mac/scheduler_metric.cc b/srsenb/src/mac/scheduler_metric.cc index 517590c6d..154cd823e 100644 --- a/srsenb/src/mac/scheduler_metric.cc +++ b/srsenb/src/mac/scheduler_metric.cc @@ -41,9 +41,9 @@ namespace srsenb { * * Downlink Metric * - *****************************************************************/ - -uint32_t dl_metric_rr::calc_rbg_mask(bool mask[MAX_RBG]) + *****************************************************************/ + +uint32_t dl_metric_rr::calc_rbg_mask(bool mask[MAX_RBG]) { // Build RBG bitmask uint32_t rbg_bitmask = 0; @@ -301,13 +301,14 @@ bool ul_metric_rr::new_allocation(uint32_t L, ul_harq_proc::ul_alloc_t* alloc) bool ul_metric_rr::update_allocation(ul_harq_proc::ul_alloc_t alloc) { + bool ret = false; if(allocation_is_valid(alloc)) { - for (uint32_t n=alloc.RB_start;n Date: Fri, 5 Oct 2018 15:12:06 +0200 Subject: [PATCH 55/71] suppress scheduler warning for failed PUCCH allocation for 6 PRBs --- srsenb/src/mac/scheduler.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index b79396549..cac75af2d 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -876,12 +876,12 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched // Allocate PUCCH resources if (cfg.nrb_pucch >= 0) { ul_harq_proc::ul_alloc_t pucch = {0, (uint32_t) cfg.nrb_pucch}; - if(!ul_metric->update_allocation(pucch)) { + if (!ul_metric->update_allocation(pucch) and cfg.cell.nof_prb != 6) { log_h->warning("SCHED: There was a collision with the PUCCH (%d, %d)\n", pucch.RB_start, pucch.RB_start+pucch.L); } pucch.RB_start = cfg.cell.nof_prb-cfg.nrb_pucch; pucch.L = (uint32_t) cfg.nrb_pucch; - if(!ul_metric->update_allocation(pucch)) { + if (!ul_metric->update_allocation(pucch) and cfg.cell.nof_prb != 6) { log_h->warning("SCHED: There was a collision with the PUCCH (%d, %d)\n", pucch.RB_start, pucch.RB_start+pucch.L); } } else { From 02d7747aaf0ba4998925b36cd08e4340d2187e8d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 9 Oct 2018 21:15:01 +0200 Subject: [PATCH 56/71] fix typo --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index bae3049a3..675ec5222 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1398,7 +1398,7 @@ void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) { void rrc::send_ul_info_transfer(byte_buffer_t *nas_msg) { bzero(&ul_dcch_msg, sizeof(LIBLTE_RRC_UL_DCCH_MSG_STRUCT)); - rrc_log->debug("Preparing RX Info Transfer\n"); + rrc_log->debug("Preparing UL Info Transfer\n"); // Prepare RX INFO packet ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UL_INFO_TRANSFER; From feccce5a016abb45bc712e67316cbffc2f1bede2 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 9 Oct 2018 14:33:05 +0100 Subject: [PATCH 57/71] fixed the deadlock issue --- srsue/src/phy/phch_worker.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 53ca93273..0e4d6bcc4 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -463,11 +463,6 @@ void phch_worker::work_imp() tr_log_end(); - if (next_offset > 0) { - phy->worker_end(tx_tti, signal_ready, signal_ptr, SRSLTE_SF_LEN_PRB(cell.nof_prb)+next_offset, tx_time); - } else { - phy->worker_end(tx_tti, signal_ready, &signal_ptr[-next_offset], SRSLTE_SF_LEN_PRB(cell.nof_prb)+next_offset, tx_time); - } if(SUBFRAME_TYPE_REGULAR == sf_cfg.sf_type) { if (!dl_action.generate_ack_callback) { @@ -491,6 +486,13 @@ void phch_worker::work_imp() phy->set_mch_period_stop(0); } } + + if (next_offset > 0) { + phy->worker_end(tx_tti, signal_ready, signal_ptr, SRSLTE_SF_LEN_PRB(cell.nof_prb)+next_offset, tx_time); + } else { + phy->worker_end(tx_tti, signal_ready, &signal_ptr[-next_offset], SRSLTE_SF_LEN_PRB(cell.nof_prb)+next_offset, tx_time); + } + if(SUBFRAME_TYPE_REGULAR == sf_cfg.sf_type){ update_measurements(); } From f7d907f1b266578c0613e3fefe55ef73e6243893 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 8 Oct 2018 13:13:45 +0200 Subject: [PATCH 58/71] remove pedantic flag from RLC stress test --- lib/test/upper/rlc_stress_test.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 230286305..9627c6565 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -58,7 +58,6 @@ typedef struct { uint32_t avg_opp_size; bool random_opp; bool zero_seed; - bool pedantic; } stress_test_args_t; void parse_args(stress_test_args_t *args, int argc, char *argv[]) { @@ -85,8 +84,7 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { ("loglevel", bpo::value(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug)") ("singletx", bpo::value(&args->single_tx)->default_value(false), "If set to true, only one node is generating data") ("pcap", bpo::value(&args->write_pcap)->default_value(false), "Whether to write all RLC PDU to PCAP file") - ("zeroseed", bpo::value(&args->zero_seed)->default_value(false), "Whether to initialize random seed to zero") - ("pedantic", bpo::value(&args->pedantic)->default_value(true), "Whether to perform strict SDU size checking at receiver"); + ("zeroseed", bpo::value(&args->zero_seed)->default_value(false), "Whether to initialize random seed to zero"); // these options are allowed on the command line bpo::options_description cmdline_options; @@ -240,10 +238,7 @@ public: assert(rx_lcid == lcid); if (sdu->N_bytes != args.sdu_size) { log.error_hex(sdu->msg, sdu->N_bytes, "Received SDU with size %d, expected %d.\n", sdu->N_bytes, args.sdu_size); - // exit if in pedantic mode or SDU is not a multiple of the expected size - if (args.pedantic || sdu->N_bytes % args.sdu_size != 0) { - exit(-1); - } + exit(-1); } byte_buffer_pool::get_instance()->deallocate(sdu); From 6ca0d4494a33fb034908a001772a3bd2854f5816 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 8 Oct 2018 13:16:08 +0200 Subject: [PATCH 59/71] do not transmit new PDUs after calling stop --- lib/include/srslte/upper/rlc_um.h | 1 - lib/src/upper/rlc_um.cc | 26 +++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index b0fb2c13d..eee0d284f 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -200,7 +200,6 @@ private: // helper functions void debug_state(); - bool reordering_timeout_running(); const char* get_rb_name(); }; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 24e66389c..ab00b9e73 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -376,6 +376,12 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) { pthread_mutex_lock(&mutex); log->debug("MAC opportunity - %d bytes\n", nof_bytes); + + if (not tx_enabled) { + pthread_mutex_unlock(&mutex); + return 0; + } + if(!tx_sdu && tx_sdu_queue.size() == 0) { log->info("No data available to be sent\n"); pthread_mutex_unlock(&mutex); @@ -475,7 +481,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) memcpy(payload, pdu->msg, pdu->N_bytes); uint32_t ret = pdu->N_bytes; - log->info("%s Tx PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes); + log->info_hex(payload, ret, "%s Tx PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes); pool->deallocate(pdu); debug_state(); @@ -670,19 +676,22 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() return; } } - + // First catch up with lower edge of reordering window while(!inside_reordering_window(vr_ur)) { + log->debug("SN=%d is not inside reordering windows\n", vr_ur); + if(rx_window.end() == rx_window.find(vr_ur)) { + log->debug("SN=%d not in rx_window. Reset received SDU\n", vr_ur); rx_sdu->reset(); }else{ // Handle any SDU segments for(uint32_t i=0; idebug_hex(rx_window[vr_ur].buf->msg, len, "Handling segment %d/%d of length %d B of SN=%d\n", i+1, rx_window[vr_ur].header.N_li, len, vr_ur); // Check if we received a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { log->warning("Dropping PDU %d due to lost start segment\n", vr_ur); @@ -768,8 +777,8 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() // Handle any SDU segments for(uint32_t i=0; idebug("Handling SDU egment i=%d with len=%d of vr_ur=%d N_li=%d [%s]\n", i, len, vr_ur, rx_window[vr_ur].header.N_li, rlc_fi_field_text[rx_window[vr_ur].header.fi]); + uint16_t len = rx_window[vr_ur].header.li[i]; + log->debug("Handling SDU segment i=%d with len=%d of vr_ur=%d N_li=%d [%s]\n", i, len, vr_ur, rx_window[vr_ur].header.N_li, rlc_fi_field_text[rx_window[vr_ur].header.fi]); // Check if the first part of the PDU is a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { log->warning_hex(rx_window[vr_ur].buf->msg, len, "Dropping first %d B of SN %d due to lost start segment\n", len, vr_ur); @@ -948,7 +957,7 @@ void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id) reassemble_rx_sdus(); log->debug("Finished reassemble from timeout id=%d\n", timeout_id); } - reordering_timer->stop(); + if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) { reordering_timer->reset(); reordering_timer->run(); @@ -960,11 +969,6 @@ void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id) } } -bool rlc_um::rlc_um_rx::reordering_timeout_running() -{ - return reordering_timer->is_running(); -} - /**************************************************************************** * Helper functions ***************************************************************************/ From 42747edb547437b27d02011ba18f252be4fa69c7 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 8 Oct 2018 14:15:46 +0200 Subject: [PATCH 60/71] fix issue where successfully rx'ed SDU was not detected --- lib/src/upper/rlc_um.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index ab00b9e73..06feb7451 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -676,7 +676,7 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() return; } } - + // First catch up with lower edge of reordering window while(!inside_reordering_window(vr_ur)) { @@ -820,7 +820,7 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus() rx_window[vr_ur].buf->N_bytes -= len; vr_ur_in_rx_sdu = vr_ur; - if (not pdu_lost && pdu_belongs_to_rx_sdu()) { + if (pdu_belongs_to_rx_sdu()) { log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", get_rb_name(), vr_ur, i); rx_sdu->set_timestamp(); if(cfg.is_mrb){ From cecc28540bef85122bc57f5c41b5cd0a7fb6d3c6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 9 Oct 2018 10:42:35 +0200 Subject: [PATCH 61/71] add crash handler to rlc_stress_test --- lib/test/upper/rlc_stress_test.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 9627c6565..0846a61fe 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -36,6 +36,7 @@ #include #include #include +#include "srslte/common/crash_handler.h" #define LOG_HEX_LIMIT (-1) @@ -407,7 +408,10 @@ void stress_test(stress_test_args_t args) } -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ + srslte_debug_handle_crash(argc, argv); + stress_test_args_t args = {}; parse_args(&args, argc, argv); From aebea06f15dabf5af625f6c15076119ac25e643d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 9 Oct 2018 15:38:29 +0200 Subject: [PATCH 62/71] fix RLC UM timer expiration after stopping entity --- lib/src/upper/rlc_um.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 06feb7451..eba812d53 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -939,9 +939,8 @@ void rlc_um::rlc_um_rx::reset_metrics() void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id) { - if (reordering_timer_id == timeout_id) { - pthread_mutex_lock(&mutex); - + pthread_mutex_lock(&mutex); + if (reordering_timer != NULL && reordering_timer_id == timeout_id) { // 36.322 v10 Section 5.1.2.2.4 log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", get_rb_name()); @@ -965,8 +964,8 @@ void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id) } debug_state(); - pthread_mutex_unlock(&mutex); } + pthread_mutex_unlock(&mutex); } /**************************************************************************** From 3ebf4792de197cf785d41d68f67c4351b7c56b23 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 10 Oct 2018 16:01:51 +0200 Subject: [PATCH 63/71] fix missing length reset in NAS test --- srsue/test/upper/nas_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 101d403fc..eec65c7f9 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -175,6 +175,7 @@ int security_command_test() nas.write_pdu(LCID, tmp); // TODO: add check for authentication response + rrc_dummy.reset(); // reuse buffer for security mode command memcpy(tmp->msg, sec_mode_command_pdu, sizeof(sec_mode_command_pdu)); From 93d17fed3e39f4d9f9f777d6aed5b7e5f285f4b6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 10 Oct 2018 16:29:57 +0200 Subject: [PATCH 64/71] disable buffer pool logging by default --- lib/include/srslte/common/buffer_pool.h | 8 ++++++++ lib/include/srslte/common/common.h | 3 ++- srsenb/hdr/phy/prach_worker.h | 1 - 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index bfd021d1b..fa497c352 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -204,9 +204,17 @@ public: b->reset(); if (!pool->deallocate(b)) { if (log) { +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED log->error("Deallocating PDU: Addr=0x%lx, name=%s not found in pool\n", (uint64_t) b, b->debug_name); +#else + log->error("Deallocating PDU: Addr=0x%lx\n", (uint64_t) b); +#endif } else { +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED printf("Error deallocating PDU: Addr=0x%lx, name=%s not found in pool\n", (uint64_t) b, b->debug_name); +#else + printf("Error deallocating PDU: Addr=0x%lx\n", (uint64_t) b); +#endif } } b = NULL; diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 27e8bf2a9..eb157f368 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -65,7 +65,7 @@ #define SRSLTE_MAX_BUFFER_SIZE_BYTES (SRSLTE_MAX_BUFFER_SIZE_BITS/8) #define SRSLTE_BUFFER_HEADER_OFFSET 1020 -#define SRSLTE_BUFFER_POOL_LOG_ENABLED +//#define SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #define pool_allocate (pool->allocate(__PRETTY_FUNCTION__)) @@ -73,6 +73,7 @@ #define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128 #else #define pool_allocate (pool->allocate()) +#define pool_allocate_blocking (pool->allocate(NULL, true)) #endif #define ZERO_OBJECT(x) memset(&(x), 0x0, sizeof((x))) diff --git a/srsenb/hdr/phy/prach_worker.h b/srsenb/hdr/phy/prach_worker.h index c1c4c978c..45ca75745 100644 --- a/srsenb/hdr/phy/prach_worker.h +++ b/srsenb/hdr/phy/prach_worker.h @@ -73,7 +73,6 @@ private: cf_t samples[sf_buffer_sz]; uint32_t nof_samples; uint32_t tti; - char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN]; }; srslte::buffer_pool buffer_pool; srslte::block_queue pending_buffers; From 30834968b240c29b8ac90b38558eaca4f487044c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 10 Oct 2018 16:31:24 +0200 Subject: [PATCH 65/71] bump version and add changelog for 18.09 --- CHANGELOG | 10 ++++++++++ cmake/modules/SRSLTEVersion.cmake | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 72831718a..0cc4a20f3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,16 @@ Change Log for Releases ============================== +## 18.09 + * Improved Turbo Decoder performance + * Configurable SGi interface name and M1U params + * Support for GPTU echo mechanism + * Added UE detach capability + * Refactor RLC/PDCP classes + * Various fixes for ARM-based devices + * Added support for bladeRF 2.0 micro + * Many bug-fixes and improved stability and performance in all parts + ## 18.06.1 * Fixed RLC reestablish * Fixed aperiodic QCI retx diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index e79f7f88e..b4a6a1c58 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -19,6 +19,6 @@ # SET(SRSLTE_VERSION_MAJOR 18) -SET(SRSLTE_VERSION_MINOR 6) -SET(SRSLTE_VERSION_PATCH 1) +SET(SRSLTE_VERSION_MINOR 9) +SET(SRSLTE_VERSION_PATCH 0) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") From 8559af55c5ca4f3635f75c2bf446fbe3d507666e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 11 Oct 2018 08:48:22 +0200 Subject: [PATCH 66/71] Detect BladeRF Micro compatible drivers --- cmake/modules/FindbladeRF.cmake | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindbladeRF.cmake b/cmake/modules/FindbladeRF.cmake index b154a9cf1..565603000 100644 --- a/cmake/modules/FindbladeRF.cmake +++ b/cmake/modules/FindbladeRF.cmake @@ -15,8 +15,14 @@ if(NOT BLADERF_FOUND) ) if(BLADERF_INCLUDE_DIRS AND BLADERF_LIBRARIES) - set(BLADERF_FOUND TRUE CACHE INTERNAL "libbladeRF found") - message(STATUS "Found libbladeRF: ${BLADERF_INCLUDE_DIRS}, ${BLADERF_LIBRARIES}") + CHECK_LIBRARY_EXISTS(bladeRF bladerf_get_board_name BLADERF_LIBRARIES BLADERF_VERSION_OK) + if (BLADERF_VERSION_OK) + set(BLADERF_FOUND TRUE CACHE INTERNAL "libbladeRF found") + message(STATUS "Found libbladeRF: ${BLADERF_INCLUDE_DIRS}, ${BLADERF_LIBRARIES}") + else (BLADERF_VERSION_OK) + set(BLADERF_FOUND FALSE CACHE INTERNAL "libbladeRF found") + message(STATUS "libbladeRF found but not compatible. Upgrade your driver or use SoapySDR.") + endif (BLADERF_VERSION_OK) else(BLADERF_INCLUDE_DIRS AND BLADERF_LIBRARIES) set(BLADERF_FOUND FALSE CACHE INTERNAL "libbladeRF found") message(STATUS "libbladeRF not found.") From 2979e43b37a657491eafa6445dcae99c312067a9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 11 Oct 2018 13:28:07 +0200 Subject: [PATCH 67/71] reword PDCP log when dropping PDU --- lib/src/upper/pdcp_entity.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index 9d0300820..c26c6b9f0 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -204,7 +204,7 @@ void pdcp_entity::write_pdu(byte_buffer_t *pdu) } else { // Handle SRB messages if (cfg.is_control) { - uint32_t sn; + uint32_t sn = 0; if (do_encryption) { cipher_decrypt(&(pdu->msg[sn_len_bytes]), rx_count, @@ -218,7 +218,7 @@ void pdcp_entity::write_pdu(byte_buffer_t *pdu) rx_count, pdu->N_bytes - 4, &(pdu->msg[pdu->N_bytes - 4]))) { - log->error_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d (Dropping PDU)", rrc->get_rb_name(lcid).c_str(), sn); + log->error_hex(pdu->msg, pdu->N_bytes, "%s Dropping PDU", rrc->get_rb_name(lcid).c_str()); goto exit; } } From 270707b7a8b2346a587bba509c8bb4f2b7cabe48 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 15 Oct 2018 09:39:21 +0200 Subject: [PATCH 68/71] add missing initialization in block_queue --- lib/include/srslte/common/block_queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/common/block_queue.h b/lib/include/srslte/common/block_queue.h index 1098e3db5..107c93272 100644 --- a/lib/include/srslte/common/block_queue.h +++ b/lib/include/srslte/common/block_queue.h @@ -108,7 +108,7 @@ public: } myobj wait_pop() { // blocking pop - myobj value; + myobj value = myobj(); pop_(&value, true); return value; } From 1c015aab62a2958d5af5bed36cc859a4290d17e0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 15 Oct 2018 10:09:39 +0200 Subject: [PATCH 69/71] update changelog for deb package --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 51063a6db..98d83a27a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +srslte (18.09-0ubuntu1) bionic; urgency=medium + + * Update to srsLTE 18.09 + + -- Andre Puschmann Wed, 15 Oct 2018 10:05:00 +0200 + srslte (18.06.1-0ubuntu1) bionic; urgency=medium * Update to srsLTE 18.06.1 From 481a1829dd14536ab236d2eb25731297e8ac3958 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 15 Oct 2018 11:01:59 +0200 Subject: [PATCH 70/71] stop metrics hub thread before calling stop on listeners --- lib/include/srslte/common/metrics_hub.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/include/srslte/common/metrics_hub.h b/lib/include/srslte/common/metrics_hub.h index 4c27b2b2a..6123119e3 100644 --- a/lib/include/srslte/common/metrics_hub.h +++ b/lib/include/srslte/common/metrics_hub.h @@ -44,6 +44,7 @@ public: return true; } void stop() { + stop_thread(); // stop all listeners for (uint32_t i=0;istop(); From 3f36594f1edf828f32869b7ae7f0252283b4a651 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 16 Oct 2018 14:20:21 +0200 Subject: [PATCH 71/71] fix copy ctors in bit_buffer_t --- lib/include/srslte/common/common.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index eb157f368..e44f115ef 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -216,13 +216,16 @@ struct bit_buffer_t{ #endif } bit_buffer_t(const bit_buffer_t& buf){ + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; N_bits = buf.N_bits; memcpy(msg, buf.msg, N_bits); } bit_buffer_t & operator= (const bit_buffer_t & buf){ // avoid self assignment - if (&buf == this) + if (&buf == this) { return *this; + } + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; N_bits = buf.N_bits; memcpy(msg, buf.msg, N_bits); return *this;