OBECA Receive Process
Public Member Functions | List of all members
Gw Class Reference

Network gateway component. More...

#include <Gw.h>

Inheritance diagram for Gw:
Inheritance graph
[legend]
Collaboration diagram for Gw:
Collaboration graph
[legend]

Public Member Functions

 Gw (const libconfig::Config &cfg, Phy &phy)
 Default constructor. More...
 
virtual ~Gw ()
 Default destructor.
 
void init ()
 Creates the TUN interface according to params from Cfg.
 
void write_pdu_mch (uint32_t lcid, srslte::unique_byte_buffer_t pdu) override
 Handle a MCH PDU. More...
 
void add_mch_port (uint32_t lcid, uint32_t port) override
 
void write_pdu (uint32_t lcid, srslte::unique_byte_buffer_t pdu) override
 
int setup_if_addr (uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_id, char *err_str) override
 
int apply_traffic_flow_template (const uint8_t &eps_bearer_id, const uint8_t &lcid, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT *tft) override
 
void set_test_loop_mode (const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms=0) override
 

Detailed Description

Network gateway component.

Creates a TUN network interface, and writes the received MCH PDU contents out on it.

Definition at line 34 of file Gw.h.

Constructor & Destructor Documentation

◆ Gw()

Gw::Gw ( const libconfig::Config &  cfg,
Phy &  phy 
)
inline

Default constructor.

Parameters
cfgConfig singleton reference
phyPHY reference

Definition at line 42 of file Gw.h.

43  : _cfg(cfg)
44  , _phy(phy)
45  {}

Member Function Documentation

◆ write_pdu_mch()

void Gw::write_pdu_mch ( uint32_t  lcid,
srslte::unique_byte_buffer_t  pdu 
)
override

Handle a MCH PDU.

Verifies the contents start with an IP header, checks the IP header checksum and corrects it if necessary, and writes the packet out to the TUN interface.

Definition at line 36 of file Gw.cpp.

36  {
37  char* err_str = nullptr;
38  if (pdu->N_bytes > 2) {
39  spdlog::debug("RX MCH PDU ({} B). Stack latency: {} us", pdu->N_bytes, pdu->get_latency_us());
40 
41  if (_tun_fd < 0) {
42  spdlog::warn("TUN/TAP not up - dropping gw RX message\n");
43  } else {
44  auto ip_hdr = reinterpret_cast<iphdr*>(pdu->msg);
45  if (ip_hdr->protocol == 17 /*UDP*/) {
46  auto udp_hdr = reinterpret_cast<udphdr*>(pdu->msg + 4U * ip_hdr->ihl);
47  char dest[INET6_ADDRSTRLEN] = ""; // NOLINT
48  inet_ntop(AF_INET, (const void*)&ip_hdr->daddr, dest, sizeof(dest));
49 
50  _phy.set_dest_for_lcid(lcid, std::string(dest) + ":" + std::to_string(ntohs(udp_hdr->dest)));
51 
52  auto ptr = reinterpret_cast<uint16_t*>(ip_hdr);
53  int32_t sum = 0;
54  sum += *ptr++; // ihl / version / dscp
55  sum += *ptr++; // total len
56  sum += *ptr++; // id
57  sum += *ptr++; // frag offset
58  sum += *ptr++; // ttl + protocol
59  ptr++; // skip checksum
60  sum += *ptr++; // src
61  sum += *ptr++; // src
62  sum += *ptr++; // dst
63  sum += *ptr; // dst
64 
65  sum = (sum >> 16) + (sum & 0xffff);
66  sum += (sum >> 16);
67 
68  uint16_t chk = ~sum;
69  if (ip_hdr->check != chk) {
70  spdlog::info("Wrong IP header checksum {}, should be {}. Correcting.", ip_hdr->check, chk);
71  ip_hdr->check = chk;
72  }
73  }
74 
75  _wr_mutex.lock();
76  int n = write(_tun_fd, pdu->msg, pdu->N_bytes);
77  _wr_mutex.unlock();
78 
79  if (n > 0 && (pdu->N_bytes != static_cast<uint32_t>(n))) {
80  spdlog::warn("DL TUN/TAP short write");
81  }
82  if (n == 0) {
83  spdlog::warn("DL TUN/TAP 0 write");
84  }
85  if (n < 0) {
86  err_str = strerror(errno);
87  spdlog::warn("DL TUN/TAP write error {}", err_str);
88  }
89  }
90  }
91 }

The documentation for this class was generated from the following files: