aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2017-07-19 03:05:07 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2017-07-19 14:02:49 +0700
commitac3a527c9897c71ae463c6af58829a6232dda2e5 (patch)
tree735cc1e36c7c3bd637883d11c1bfb18492c2076d /lib
parent948f70463f45241bf931e7dbb6107c478d58ca54 (diff)
trx_interface: implement incoming data handler
This change implements a receive path for UL bursts, namely the OsmoTRX style header conversation to GSMTAP.
Diffstat (limited to 'lib')
-rw-r--r--lib/trx_interface/trx_impl.cc69
-rw-r--r--lib/trx_interface/trx_impl.h1
-rw-r--r--lib/trx_interface/udp_socket.cc14
-rw-r--r--lib/trx_interface/udp_socket.h6
4 files changed, 80 insertions, 10 deletions
diff --git a/lib/trx_interface/trx_impl.cc b/lib/trx_interface/trx_impl.cc
index abcd45e..48ef51a 100644
--- a/lib/trx_interface/trx_impl.cc
+++ b/lib/trx_interface/trx_impl.cc
@@ -30,6 +30,9 @@
#include "udp_socket.h"
#include "trx_impl.h"
+#define BURST_SIZE 148
+#define DATA_IF_MTU 160
+
namespace gr {
namespace grgsm {
@@ -53,6 +56,9 @@ namespace gr {
gr::io_signature::make(0, 0, 0))
{
message_port_register_in(pmt::mp("bursts"));
+ message_port_register_out(pmt::mp("bursts"));
+
+ // Bind a port handler
set_msg_handler(pmt::mp("bursts"),
boost::bind(&trx_impl::handle_dl_burst, this, _1));
@@ -62,9 +68,15 @@ namespace gr {
std::string data_src_port = boost::lexical_cast<std::string> (base_port + 2);
std::string data_dst_port = boost::lexical_cast<std::string> (base_port + 102);
- // Init DATA interface
- d_data_sock = new udp_socket(remote_addr, data_src_port, data_dst_port);
- d_clck_sock = new udp_socket(remote_addr, clck_src_port, clck_dst_port);
+ // Init DATA & CLCK interfaces
+ d_data_sock = new udp_socket(remote_addr,
+ data_src_port, data_dst_port, DATA_IF_MTU);
+ d_clck_sock = new udp_socket(remote_addr,
+ clck_src_port, clck_dst_port, DATA_IF_MTU);
+
+ // Bind DATA interface handler
+ d_data_sock->udp_rx_handler = boost::bind(
+ &trx_impl::handle_ul_burst, this, _1, _2);
}
/*
@@ -156,5 +168,56 @@ namespace gr {
d_data_sock->udp_send(buf, 158);
}
+ void
+ trx_impl::handle_ul_burst(uint8_t *payload, size_t len)
+ {
+ // Check length according to the protocol
+ if (len != 154)
+ return;
+
+ /* Make sure TS index is correct */
+ if (payload[0] >= 8)
+ return;
+
+ /* Unpack and check frame number */
+ uint32_t fn = (payload[1] << 24)
+ | (payload[2] << 16)
+ | (payload[3] << 8)
+ | payload[4];
+
+ if (fn >= 2715648)
+ return;
+
+ // Prepare a buffer for GSMTAP header and burst
+ uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];
+
+ // Set up pointer to GSMTAP header structure
+ struct gsmtap_hdr *header = (struct gsmtap_hdr *) buf;
+ memset(header, 0x00, sizeof(struct gsmtap_hdr));
+
+ // Fill in basic info
+ header->version = GSMTAP_VERSION;
+ header->hdr_len = sizeof(gsmtap_hdr) / 4;
+ header->type = GSMTAP_TYPE_UM_BURST;
+
+ // Set timeslot index and frame number
+ header->timeslot = payload[0];
+ header->frame_number = htobe32(fn);
+
+ // HACK: use GSMTAP_BURST_NORMAL for now
+ // FIXME: We will need to distinguish between RACN and NORMAL
+ header->sub_type = GSMTAP_BURST_NORMAL;
+
+ // Copy burst bits (0 & 1) for source message
+ memcpy(buf + sizeof(gsmtap_hdr), payload + 6, BURST_SIZE);
+
+ // Create a pmt blob
+ pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
+ pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob);
+
+ /* Send a message to the output */
+ message_port_pub(pmt::mp("bursts"), msg);
+ }
+
} /* namespace grgsm */
} /* namespace gr */
diff --git a/lib/trx_interface/trx_impl.h b/lib/trx_interface/trx_impl.h
index 41a4788..29545b1 100644
--- a/lib/trx_interface/trx_impl.h
+++ b/lib/trx_interface/trx_impl.h
@@ -45,6 +45,7 @@ namespace gr {
~trx_impl();
void handle_dl_burst(pmt::pmt_t msg);
+ void handle_ul_burst(uint8_t *payload, size_t len);
};
} // namespace grgsm
diff --git a/lib/trx_interface/udp_socket.cc b/lib/trx_interface/udp_socket.cc
index 4bbf206..be4bb66 100644
--- a/lib/trx_interface/udp_socket.cc
+++ b/lib/trx_interface/udp_socket.cc
@@ -40,8 +40,12 @@ namespace gr {
udp_socket::udp_socket(
const std::string &remote_addr,
const std::string &src_port,
- const std::string &dst_port)
+ const std::string &dst_port,
+ size_t mtu)
{
+ // Resize receive buffer according to MTU value
+ d_rxbuf.resize(mtu);
+
// Resolve remote host address
udp::resolver resolver(d_io_service);
@@ -100,11 +104,9 @@ namespace gr {
if (error)
return;
- pmt::pmt_t vector = pmt::init_u8vector(bytes_transferred,
- (const uint8_t *) &d_rxbuf[0]);
- pmt::pmt_t pdu = pmt::cons(pmt::PMT_NIL, vector);
-
- // TODO: call handler here
+ // Call incoming data handler
+ if (udp_rx_handler != NULL)
+ udp_rx_handler((uint8_t *) &d_rxbuf[0], bytes_transferred);
d_udp_socket->async_receive_from(
boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx,
diff --git a/lib/trx_interface/udp_socket.h b/lib/trx_interface/udp_socket.h
index 2f424c9..5bcc42b 100644
--- a/lib/trx_interface/udp_socket.h
+++ b/lib/trx_interface/udp_socket.h
@@ -25,8 +25,10 @@
#include <gnuradio/thread/thread.h>
+#include <boost/function.hpp>
#include <boost/array.hpp>
#include <boost/asio.hpp>
+#include <boost/bind.hpp>
#include <pmt/pmt.h>
namespace gr {
@@ -53,10 +55,12 @@ namespace gr {
udp_socket(
const std::string &remote_addr,
const std::string &src_port,
- const std::string &dst_port);
+ const std::string &dst_port,
+ size_t mtu);
~udp_socket();
void udp_send(uint8_t *data, size_t len);
+ boost::function<void (uint8_t *, size_t)> udp_rx_handler;
};
} /* namespace blocks */