diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 24e997f21..1f6fba9d6 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -276,85 +276,81 @@ void gw::run_thread() { if (SRSLTE_MAX_BUFFER_SIZE_BYTES-SRSLTE_BUFFER_HEADER_OFFSET > idx) { N_bytes = read(tun_fd, &pdu->msg[idx], SRSLTE_MAX_BUFFER_SIZE_BYTES-SRSLTE_BUFFER_HEADER_OFFSET - idx); - if (N_bytes <= 0) { - gw_log->error("Failed to read from TUN interface - gw receive thread exiting.\n"); - gw_log->console("Failed to read from TUN interface - gw receive thread exiting.\n"); - break; - } } else { gw_log->error("GW pdu buffer full - gw receive thread exiting.\n"); gw_log->console("GW pdu buffer full - gw receive thread exiting.\n"); break; } - gw_log->debug("Read %d bytes from TUN fd=%d, idx=%d\n", N_bytes, tun_fd, idx); - struct iphdr* ip_pkt = (struct iphdr*)pdu->msg; - struct ipv6hdr* ip6_pkt = (struct ipv6hdr*)pdu->msg; - uint16_t pkt_len = 0; - pdu->N_bytes = idx + N_bytes; - - // Check valid IP version - if (ip_pkt->version != 4 && ip_pkt->version != 6) { - gw_log->error("IP Version not handled. Version %d\n", ip_pkt->version); - gw_log->error_hex(pdu->msg, pdu->N_bytes, "IP Version not handled."); - continue; - } - - // Get packet length - if (ip_pkt->version == 4) { - pkt_len = ntohs(ip_pkt->tot_len); - } else if (ip_pkt->version == 6) { - pkt_len = ntohs(ip6_pkt->payload_len) + 40; - } - gw_log->debug("IPv%d packet total length: %d Bytes\n", ip_pkt->version, pkt_len); - - // Check if entire packet was received - if (pkt_len == pdu->N_bytes) { - gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU"); - - // Wait for attach - while (run_enable && !pdcp->is_lcid_enabled(default_lcid) && attach_wait < ATTACH_WAIT_TOUT) { - if (!attach_wait) { - gw_log->info( - "LCID=%d not active, requesting NAS attach (%d/%d)\n", default_lcid, attach_wait, ATTACH_WAIT_TOUT); - if (!nas->attach_request()) { - gw_log->warning("Could not re-establish the connection\n"); - } + if (N_bytes > 0) { + struct iphdr *ip_pkt = (struct iphdr*)pdu->msg; + struct ipv6hdr *ip6_pkt = (struct ipv6hdr*)pdu->msg; + uint16_t pkt_len = 0; + pdu->N_bytes = idx + N_bytes; + if (ip_pkt->version == 4 || ip_pkt->version == 6) { + if (ip_pkt->version == 4){ + pkt_len = ntohs(ip_pkt->tot_len); + } else if (ip_pkt->version == 6){ + pkt_len = ntohs(ip6_pkt->payload_len)+40; + } else { + gw_log->error_hex(pdu->msg, pdu->N_bytes, "Unsupported IP version. Dropping packet.\n"); + continue; } - usleep(100000); - attach_wait++; - } - attach_wait = 0; + gw_log->debug("IPv%d packet total length: %d Bytes\n", ip_pkt->version, pkt_len); + // Check if entire packet was received + if (pkt_len == pdu->N_bytes) { + gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU"); + + while (run_enable && !pdcp->is_lcid_enabled(default_lcid) && attach_wait < ATTACH_WAIT_TOUT) { + if (!attach_wait) { + gw_log->info( + "LCID=%d not active, requesting NAS attach (%d/%d)\n", default_lcid, attach_wait, ATTACH_WAIT_TOUT); + if (!nas->attach_request()) { + gw_log->warning("Could not re-establish the connection\n"); + } + } + usleep(100000); + attach_wait++; + } - if (!run_enable) { - break; - } + attach_wait = 0; - // Check to which LCID to send the packet - uint8_t lcid = check_tft_filter_match(pdu); - - // Send PDU directly to PDCP - if (pdcp->is_lcid_enabled(default_lcid)) { - pdu->set_timestamp(); - ul_tput_bytes += pdu->N_bytes; - pdcp->write_sdu(default_lcid, std::move(pdu), false); - do { - pdu = srslte::allocate_unique_buffer(*pool); - if (!pdu) { - gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); - usleep(100000); + if (!run_enable) { + break; } - } while (!pdu); - idx = 0; + + // Check to which LCID to send the packet + uint8_t lcid = check_tft_filter_match(pdu); + + // Send PDU directly to PDCP + if (pdcp->is_lcid_enabled(default_lcid)) { + pdu->set_timestamp(); + ul_tput_bytes += pdu->N_bytes; + pdcp->write_sdu(default_lcid, std::move(pdu), false); + do { + pdu = srslte::allocate_unique_buffer(*pool); + if (!pdu) { + gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); + usleep(100000); + } + } while(!pdu); + idx = 0; + } + }else{ + idx += N_bytes; + gw_log->debug("Entire packet not read from socket. Total Length %d, N_Bytes %d.\n", ip_pkt->tot_len, pdu->N_bytes); + } + } else { + gw_log->error("IP Version not handled. Version %d\n", ip_pkt->version); } - } else { - idx += N_bytes; - gw_log->debug( - "Entire packet not read from socket. Total Length %d, N_Bytes %d.\n", ip_pkt->tot_len, pdu->N_bytes); + }else{ + gw_log->error("Failed to read from TUN interface - gw receive thread exiting.\n"); + gw_log->console("Failed to read from TUN interface - gw receive thread exiting.\n"); + break; } - running = false; - gw_log->info("GW IP receiver thread exiting.\n"); } + running = false; + gw_log->info("GW IP receiver thread exiting.\n"); } uint8_t gw::check_tft_filter_match(const srslte::unique_byte_buffer_t& pdu) {