diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 3cd8a1202..24b9c5c41 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -29,6 +29,7 @@ #include #include "srslte/common/common.h" +#include "srslte/common/log.h" namespace srslte { @@ -58,8 +59,8 @@ typedef struct{ }gtpu_header_t; -bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header); -bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu); +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) { diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 668af8915..a8046aa4d 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -35,18 +35,18 @@ namespace srslte { * Ref: 3GPP TS 29.281 v10.1.0 Section 5 ***************************************************************************/ -bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu) +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); + gtpu_log->error("gtpu_write_header - Unhandled header flags: 0x%x\n", header->flags); return false; } if(header->message_type != 0xFF) { - //gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); + gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); return false; } if(pdu->get_headroom() < GTPU_HEADER_LEN) { - //gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); + gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); return false; } @@ -66,7 +66,7 @@ bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu) return true; } -bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header) +bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header, srslte::log *gtpu_log) { uint8_t *ptr = pdu->msg; @@ -82,11 +82,11 @@ bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header) uint8_to_uint32(ptr, &header->teid); if(header->flags != 0x30) { - //gtpu_log->error("gtpu_read_header - Unhandled header flags: 0x%x\n", header->flags); + gtpu_log->error("gtpu_read_header - Unhandled header flags: 0x%x\n", header->flags); return false; } if(header->message_type != 0xFF) { - //gtpu_log->error("gtpu_read_header - Unhandled message type: 0x%x\n", header->message_type); + gtpu_log->error("gtpu_read_header - Unhandled message type: 0x%x\n", header->message_type); return false; } diff --git a/srsenb/hdr/upper/gtpu.h b/srsenb/hdr/upper/gtpu.h index 1a8d6daaa..4dc05585d 100644 --- a/srsenb/hdr/upper/gtpu.h +++ b/srsenb/hdr/upper/gtpu.h @@ -58,33 +58,25 @@ namespace srsenb { #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 - uint16_t length; - uint32_t teid; -}gtpu_header_t; - - class gtpu :public gtpu_interface_rrc ,public gtpu_interface_pdcp ,public thread { -public: - +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); void stop(); - + // gtpu_interface_rrc void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t *teid_in); void rem_bearer(uint16_t rnti, uint32_t lcid); void rem_user(uint16_t rnti); - + // gtpu_interface_pdcp - void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu); + void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu); private: static const int THREAD_PRIO = 65; @@ -92,8 +84,6 @@ private: srslte::byte_buffer_pool *pool; bool running; bool run_enable; - - bool enable_mbsfn; std::string gtp_bind_addr; @@ -141,14 +131,7 @@ private: //Threading void run_thread(); - pthread_mutex_t mutex; - - /**************************************************************************** - * Header pack/unpack helper functions - * Ref: 3GPP TS 29.281 v10.1.0 Section 5 - ***************************************************************************/ - bool gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu); - bool gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header); + pthread_mutex_t mutex; /**************************************************************************** * TEID to RNIT/LCID helper functions diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 334878941..0f8bc3325 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -23,7 +23,7 @@ * and at http://www.gnu.org/licenses/. * */ - +#include "srslte/upper/gtpu.h" #include "srsenb/hdr/upper/gtpu.h" #include #include @@ -31,13 +31,12 @@ #include using namespace srslte; - namespace srsenb { - - gtpu::gtpu():mchthread() - { - } - + +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) { pdcp = pdcp_; @@ -45,8 +44,8 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ gtp_bind_addr = gtp_bind_addr_; mme_addr = mme_addr_; - pthread_mutex_init(&mutex, NULL); - + pthread_mutex_init(&mutex, NULL); + pool = byte_buffer_pool::get_instance(); // Set up sink socket @@ -106,11 +105,11 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ void gtpu::stop() { - + if(enable_mbsfn){ mchthread.stop(); } - + if (run_enable) { run_enable = false; // Wait thread to exit gracefully otherwise might leave a mutex locked @@ -124,7 +123,7 @@ void gtpu::stop() } wait_thread_finish(); } - + if (snk_fd) { close(snk_fd); } @@ -148,7 +147,7 @@ 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_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) { perror("sendto"); } @@ -230,7 +229,7 @@ void gtpu::run_thread() pdu->N_bytes = (uint32_t) n; gtpu_header_t header; - gtpu_read_header(pdu, &header); + gtpu_read_header(pdu, &header,gtpu_log); uint16_t rnti = 0; uint16_t lcid = 0; @@ -265,69 +264,6 @@ void gtpu::run_thread() running = false; } -/**************************************************************************** -* Header pack/unpack helper functions -* Ref: 3GPP TS 29.281 v10.1.0 Section 5 -***************************************************************************/ - -bool gtpu::gtpu_write_header(gtpu_header_t *header, srslte::byte_buffer_t *pdu) -{ - if(header->flags != 0x30) { - gtpu_log->error("gtpu_write_header - Unhandled header flags: 0x%x\n", header->flags); - return false; - } - if(header->message_type != 0xFF) { - gtpu_log->error("gtpu_write_header - Unhandled message type: 0x%x\n", header->message_type); - return false; - } - if(pdu->get_headroom() < GTPU_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; - - uint8_t *ptr = pdu->msg; - - *ptr = header->flags; - ptr++; - *ptr = header->message_type; - ptr++; - uint16_to_uint8(header->length, ptr); - ptr += 2; - uint32_to_uint8(header->teid, ptr); - - return true; -} - -bool gtpu::gtpu_read_header(srslte::byte_buffer_t *pdu, gtpu_header_t *header) -{ - uint8_t *ptr = pdu->msg; - - pdu->msg += GTPU_HEADER_LEN; - pdu->N_bytes -= GTPU_HEADER_LEN; - - header->flags = *ptr; - 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); - return false; - } - if(header->message_type != 0xFF) { - gtpu_log->error("gtpu_read_header - Unhandled message type: 0x%x\n", header->message_type); - return false; - } - - return true; -} - /**************************************************************************** * TEID to RNIT/LCID helper functions ***************************************************************************/ @@ -427,6 +363,9 @@ 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); pdcp->write_sdu(SRSLTE_MRNTI, lcid, pdu); do { diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index 2beca7dcb..c238c0a18 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -49,6 +49,7 @@ const uint16_t GTPU_RX_PORT = 2152; typedef struct { std::string name; std::string sgi_mb_if_addr; + std::string sgi_mb_if_mask; std::string m1u_multi_addr; } mbms_gw_args_t; diff --git a/srsepc/mbms.conf.example b/srsepc/mbms.conf.example index 393be7648..d92306328 100644 --- a/srsepc/mbms.conf.example +++ b/srsepc/mbms.conf.example @@ -12,7 +12,8 @@ ##################################################################### [mbms_gw] name = srsmbmsgw01 -sgi_mb_if_addr = 172.16.1.1 +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/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index a54f071c8..f99356071 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -83,6 +83,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { string mbms_gw_name; string mbms_gw_sgi_mb_if_addr; + string mbms_gw_sgi_mb_if_mask; string mbms_gw_m1u_multi_addr; string log_filename; @@ -99,8 +100,9 @@ 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_addr", bpo::value(&mbms_gw_sgi_mb_if_addr)->default_value("172.16.1.1"), "SGi-mb TUN interface Address") - ("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.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.") ("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") @@ -152,7 +154,9 @@ parse_args(all_args_t *args, int argc, char* argv[]) { args->mbms_gw_args.name = mbms_gw_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; + // Apply all_level to any unset layers if (vm.count("log.all_level")) { if(!vm.count("log.mbms_gw_level")) { diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index a3d18a68d..b373df4e7 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -196,7 +196,7 @@ mbms_gw::init_sgi_mb_if(mbms_gw_args_t *args) } ifr.ifr_netmask.sa_family = AF_INET; - ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0"); + ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr(args->sgi_mb_if_mask.c_str()); if (ioctl(sgi_mb_sock, SIOCSIFNETMASK, &ifr) < 0) { m_mbms_gw_log->error("Failed to set TUN interface Netmask. Error: %s\n", strerror(errno)); close(m_sgi_mb_if); @@ -285,8 +285,6 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg) { uint8_t version; srslte::gtpu_header_t header; - in_addr_t baddr = inet_addr("172.16.0.255"); - in_addr_t saddr = inet_addr("172.16.0.254"); //Setup GTP-U header header.flags = 0x30; @@ -301,46 +299,16 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg) return; } - //IP+UDP Headers + //IP Headers struct iphdr *iph = (struct iphdr *) msg->msg; - struct udphdr *udph = (struct udphdr *) (msg->msg + iph->ihl*4); if(iph->version != 4) { m_mbms_gw_log->warning("IPv6 not supported yet.\n"); return; } - //Replace Destination IP with broadcast address - iph->daddr = baddr; - - //Replace Source IP with address in same subnet - iph->saddr = saddr; - - //Replace IP cheksum - iph->check = 0; - iph->check = in_cksum((uint16_t*)msg->msg,4*(msg->msg[0] & 0x0F)); - - //Set Pseudo Header - struct pseudo_hdr phdr; - phdr.src_addr = iph->saddr; - phdr.dst_addr = iph->daddr; - phdr.protocol = IPPROTO_UDP; - phdr.placeholder = 0; - phdr.udp_len = udph->len; - - //Set Pseudo Datagram - udph->check = 0; - int psize = sizeof(struct pseudo_hdr) + ntohs(udph->len); - uint8_t * pseudo_dgram = (uint8_t*) malloc(psize); - memcpy(pseudo_dgram, &phdr,sizeof(struct pseudo_hdr)); - memcpy(pseudo_dgram+sizeof(pseudo_hdr),udph,ntohs(udph->len)); - - //Recompute UDP checksum - udph->check = in_cksum((uint16_t*) pseudo_dgram, psize); - free(pseudo_dgram); - //Write GTP-U header into packet - if(!srslte::gtpu_write_header(&header, msg)) + if(!srslte::gtpu_write_header(&header, msg, m_mbms_gw_log)) { m_mbms_gw_log->console("Error writing GTP-U header on PDU\n"); } @@ -355,31 +323,4 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg) } } -uint16_t -mbms_gw::in_cksum(uint16_t *iphdr, int count) -{ - - //RFC 1071 - uint32_t sum = 0; - uint16_t padd = 0; - uint16_t result; - while(count > 1) - { - sum+= *iphdr++; - count -= 2; - } - if( count > 0 ) - { - padd = * (uint8_t *) iphdr; - sum += padd; - } - /*Fold 32-bit sum to 16-bit*/ - // while(sum>>16) - // sum = (sum & 0xffff) + (sum >> 16); - sum = (sum>>16)+(sum & 0xFFFF); - sum = sum + (sum >> 16); - result = (uint16_t) ~sum; - return result; -} - } //namespace srsepc diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index a527cf029..1bb871fb1 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -770,6 +770,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, } //Store context based on MME UE S1AP id m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); + m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,ecm_ctx->mme_ue_s1ap_id); //NAS integrity failed. Re-start authentication process. m_s1ap_log->console("GUTI Attach request NAS integrity failed.\n"); diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 4877ddeb9..20311cc16 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -369,7 +369,7 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) header.teid = enb_fteid.teid; //Write header into packet - if(!srslte::gtpu_write_header(&header, msg)) + if(!srslte::gtpu_write_header(&header, msg, m_spgw_log)) { m_spgw_log->console("Error writing GTP-U header on PDU\n"); } @@ -395,7 +395,7 @@ spgw::handle_s1u_pdu(srslte::byte_buffer_t *msg) { //m_spgw_log->console("Received PDU from S1-U. Bytes=%d\n",msg->N_bytes); srslte::gtpu_header_t header; - srslte::gtpu_read_header(msg, &header); + srslte::gtpu_read_header(msg, &header, m_spgw_log); //m_spgw_log->console("TEID 0x%x. Bytes=%d\n", header.teid, msg->N_bytes); int n = write(m_sgi_if, msg->msg, msg->N_bytes);