First attempt at MAC pcap support

master
Paul Sutton 10 years ago
parent 5109498353
commit d1ed052a97

@ -47,7 +47,7 @@ class demux
{
public:
demux();
void init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_);
void init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_, bool pcap_=false, FILE *pcap_file_=0);
void add_sdu_handler(sdu_handler *handler);
@ -72,6 +72,10 @@ private:
bool pending_temp_rnti;
bool has_pending_contention_resolution_id;
/* Write MAC PDUs to file in PCACP format? */
bool pcap;
FILE *pcap_file;
phy *phy_h;
log *log_h;
mac_io *mac_io_h;

@ -60,7 +60,8 @@ class mac : public timer_callback
{
public:
mac() : timers_db((uint32_t) NOF_MAC_TIMERS), tr_end_time(1024*10), tr_start_time(1024*10) {started=false;}
bool init(phy *phy_h, tti_sync *ttisync, log *log_h);
~mac();
bool init(phy *phy_h, tti_sync *ttisync, log *log_h, bool pcap_=false);
void stop();
int get_tti();
void main_radio_loop(); // called after thread creation
@ -150,6 +151,10 @@ private:
void setup_timers();
void timeAlignmentTimerExpire();
/* Write MAC PDUs to file in PCACP format? */
bool pcap;
FILE *pcap_file;
trace<uint32_t> tr_start_time;
trace<uint32_t> tr_end_time;
bool tr_enabled;

@ -47,7 +47,7 @@ class mux
public:
mux();
void reset();
void init(log *log_h, mac_io *mac_io_h, bsr_proc *bsr_procedure);
void init(log *log_h, mac_io *mac_io_h, bsr_proc *bsr_procedure, bool pcap_=false, FILE *pcap_file_=0);
bool is_pending_ccch_sdu();
bool is_pending_any_sdu();
@ -98,6 +98,10 @@ private:
sch_pdu pdu_msg;
bool msg3_has_been_transmitted;
/* Write MAC PDUs to file in PCACP format? */
bool pcap;
FILE *pcap_file;
};
}
}

@ -0,0 +1,218 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef UEPCAP_H
#define UEPCAP_H
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/time.h>
#define MAC_LTE_DLT 147
/* This structure gets written to the start of the file */
typedef struct pcap_hdr_s {
unsigned int magic_number; /* magic number */
unsigned short version_major; /* major version number */
unsigned short version_minor; /* minor version number */
unsigned int thiszone; /* GMT to local correction */
unsigned int sigfigs; /* accuracy of timestamps */
unsigned int snaplen; /* max length of captured packets, in octets */
unsigned int network; /* data link type */
} pcap_hdr_t;
/* This structure precedes each packet */
typedef struct pcaprec_hdr_s {
unsigned int ts_sec; /* timestamp seconds */
unsigned int ts_usec; /* timestamp microseconds */
unsigned int incl_len; /* number of octets of packet saved in file */
unsigned int orig_len; /* actual length of packet */
} pcaprec_hdr_t;
/* radioType */
#define FDD_RADIO 1
#define TDD_RADIO 2
/* Direction */
#define DIRECTION_UPLINK 0
#define DIRECTION_DOWNLINK 1
/* rntiType */
#define NO_RNTI 0 /* Used for BCH-BCH */
#define P_RNTI 1
#define RA_RNTI 2
#define C_RNTI 3
#define SI_RNTI 4
#define SPS_RNTI 5
#define M_RNTI 6
#define MAC_LTE_START_STRING "mac-lte"
#define MAC_LTE_RNTI_TAG 0x02
/* 2 bytes, network order */
#define MAC_LTE_UEID_TAG 0x03
/* 2 bytes, network order */
#define MAC_LTE_SUBFRAME_TAG 0x04
/* 2 bytes, network order */
#define MAC_LTE_PREDFINED_DATA_TAG 0x05
/* 1 byte */
#define MAC_LTE_RETX_TAG 0x06
/* 1 byte */
#define MAC_LTE_CRC_STATUS_TAG 0x07
/* 1 byte */
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
continues until the end of the frame) */
#define MAC_LTE_PAYLOAD_TAG 0x01
/* Context information for every MAC PDU that will be logged */
typedef struct MAC_Context_Info_t {
unsigned short radioType;
unsigned char direction;
unsigned char rntiType;
unsigned short rnti;
unsigned short ueid;
unsigned char isRetx;
unsigned char crcStatusOK;
unsigned short sysFrameNumber;
unsigned short subFrameNumber;
} MAC_Context_Info_t;
/**************************************************************************/
/* API functions for opening/writing/closing MAC-LTE PCAP files */
/* Open the file and write file header */
inline FILE *MAC_LTE_PCAP_Open(const char *fileName)
{
pcap_hdr_t file_header =
{
0xa1b2c3d4, /* magic number */
2, 4, /* version number is 2.4 */
0, /* timezone */
0, /* sigfigs - apparently all tools do this */
65535, /* snaplen - this should be long enough */
MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
};
FILE *fd = fopen(fileName, "w");
if (fd == NULL) {
printf("Failed to open file \"%s\" for writing\n", fileName);
return NULL;
}
/* Write the file header */
fwrite(&file_header, sizeof(pcap_hdr_t), 1, fd);
return fd;
}
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
inline int MAC_LTE_PCAP_WritePDU(FILE *fd, MAC_Context_Info_t *context,
const unsigned char *PDU, unsigned int length)
{
pcaprec_hdr_t packet_header;
char context_header[256];
int offset = 0;
unsigned short tmp16;
/* Can't write if file wasn't successfully opened */
if (fd == NULL) {
printf("Error: Can't write to empty file handle\n");
return 0;
}
/*****************************************************************/
/* Context information (same as written by UDP heuristic clients */
context_header[offset++] = context->radioType;
context_header[offset++] = context->direction;
context_header[offset++] = context->rntiType;
/* RNTI */
context_header[offset++] = MAC_LTE_RNTI_TAG;
tmp16 = htons(context->rnti);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* UEId */
context_header[offset++] = MAC_LTE_UEID_TAG;
tmp16 = htons(context->ueid);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* Subframe number */
context_header[offset++] = MAC_LTE_SUBFRAME_TAG;
tmp16 = htons(context->subFrameNumber);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* CRC Status */
context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
context_header[offset++] = context->crcStatusOK;
/* Data tag immediately preceding PDU */
context_header[offset++] = MAC_LTE_PAYLOAD_TAG;
/****************************************************************/
/* PCAP Header */
struct timeval t;
gettimeofday(&t, NULL);
packet_header.ts_sec = t.tv_sec;
packet_header.ts_usec = t.tv_usec;
packet_header.incl_len = offset + length;
packet_header.orig_len = offset + length;
/***************************************************************/
/* Now write everything to the file */
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, fd);
fwrite(context_header, 1, offset, fd);
fwrite(PDU, 1, length, fd);
return 1;
}
/* Close the PCAP file */
inline void MAC_LTE_PCAP_Close(FILE *fd)
{
fclose(fd);
}
#endif /* UEPCAP_H */

@ -124,7 +124,7 @@ public:
}
// Section 6.1.2
void parse_packet(uint8_t *ptr) {
void parse_packet(uint8_t *ptr, FILE *pcap_file=0) {
uint8_t *init_ptr = ptr;
nof_subheaders = 0;
while(subheaders[nof_subheaders].read_subheader(&ptr)) {
@ -139,7 +139,7 @@ public:
return pdu_is_ul;
}
virtual bool write_packet(uint8_t *ptr) = 0;
virtual bool write_packet(uint8_t *ptr, FILE *pcap_file=0) = 0;
protected:
std::vector<SubH> subheaders;
@ -238,8 +238,8 @@ public:
sch_pdu(uint32_t max_rars) : pdu(max_rars) {}
void parse_packet(uint8_t *ptr);
bool write_packet(uint8_t *ptr);
void parse_packet(uint8_t *ptr, FILE *pcap_file=0);
bool write_packet(uint8_t *ptr, FILE *pcap_file=0);
bool has_space_ce(uint32_t nbytes);
bool has_space_sdu(uint32_t nbytes);
bool has_space_sdu(uint32_t nbytes, bool is_first);
@ -295,7 +295,7 @@ public:
bool has_backoff();
uint8_t get_backoff();
bool write_packet(uint8_t* ptr);
bool write_packet(uint8_t* ptr, FILE *pcap_file=0);
void fprint(FILE *stream);
private:

@ -40,12 +40,14 @@ demux::demux() : mac_msg(20),pending_mac_msg(20)
sdu_handler_ = NULL;
}
void demux::init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_)
void demux::init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_, bool pcap_, FILE *pcap_file_)
{
phy_h = phy_h_;
log_h = log_h_;
mac_io_h = mac_io_h_;
timers_db = timers_db_;
pcap = pcap_;
pcap_file = pcap_file_;
}
void demux::add_sdu_handler(sdu_handler* handler)
@ -91,7 +93,7 @@ void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits)
if (!pending_temp_rnti) {
// Unpack DLSCH MAC PDU
pending_mac_msg.init(nof_bits/8);
pending_mac_msg.parse_packet(mac_pdu);
pending_mac_msg.parse_packet(mac_pdu, pcap_file);
//pending_mac_msg.fprint(stdout);
// Look for Contention Resolution UE ID
@ -115,7 +117,7 @@ void demux::push_pdu(uint8_t *mac_pdu, uint32_t nof_bits)
{
// Unpack DLSCH MAC PDU
mac_msg.init(nof_bits/8);
mac_msg.parse_packet(mac_pdu);
mac_msg.parse_packet(mac_pdu, pcap_file);
//mac_msg.fprint(stdout);
process_pdu(&mac_msg);
Debug("Normal MAC PDU processed\n");

@ -35,24 +35,41 @@
#include "srsapps/common/log.h"
#include "srsapps/ue/mac/mac.h"
#include "srsapps/ue/mac/mac_params.h"
#include "srsapps/ue/mac/pcap.h"
namespace srslte {
namespace ue {
bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
mac::~mac()
{
if(pcap && pcap_file) {
MAC_LTE_PCAP_Close(pcap_file);
}
}
bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_, bool pcap_)
{
started = false;
ttisync = ttisync_;
phy_h = phy_h_;
log_h = log_h_;
pcap = pcap_;
tti = 0;
is_synchronized = false;
last_temporal_crnti = 0;
phy_rnti = 0;
if(pcap) {
pcap_file = MAC_LTE_PCAP_Open("/tmp/ue_mac.pcap");
if(!pcap_file) {
Info("Failed to open pcap for writing\n");
pcap = false;
}
}
bsr_procedure.init(log_h, &timers_db, &params_db, &mac_io_lch);
mux_unit.init(log_h, &mac_io_lch, &bsr_procedure);
demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db);
mux_unit.init(log_h, &mac_io_lch, &bsr_procedure, pcap, pcap_file);
demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db, pcap, pcap_file);
ra_procedure.init(&params_db, phy_h, log_h, &timers_db, &mux_unit, &demux_unit);
sr_procedure.init(log_h, &params_db, phy_h);
reset();

@ -52,11 +52,13 @@ mux::mux() : pdu_msg(20)
}
}
void mux::init(log *log_h_, mac_io *mac_io_h_, bsr_proc *bsr_procedure_)
void mux::init(log *log_h_, mac_io *mac_io_h_, bsr_proc *bsr_procedure_, bool pcap_, FILE *pcap_file_)
{
log_h = log_h_;
mac_io_h = mac_io_h_;
bsr_procedure = bsr_procedure_;
pcap = pcap_;
pcap_file = pcap_file_;
}
void mux::reset()
@ -285,7 +287,7 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
//pdu_msg.fprint(stdout);
/* Generate MAC PDU and save to buffer */
if (pdu_msg.write_packet(buff)) {
if (pdu_msg.write_packet(buff, pcap_file)) {
pdu_buff.push(pdu_sz_nbits);
} else {
Error("Writing PDU message to packet\n");

@ -30,6 +30,7 @@
#include <stdlib.h>
#include "srsapps/ue/mac/pdu.h"
#include "srsapps/ue/mac/pcap.h"
#include "srslte/srslte.h"
namespace srslte {
@ -85,8 +86,24 @@ void sch_subh::fprint(FILE* stream)
}
}
void sch_pdu::parse_packet(uint8_t *ptr)
void sch_pdu::parse_packet(uint8_t *ptr, FILE *pcap_file)
{
if(pcap_file) {
MAC_Context_Info_t context =
{
FDD_RADIO, DIRECTION_DOWNLINK, C_RNTI,
50, /* RNTI */
102, /* UEId */
0, /* Retx */
1, /* CRC Stsatus (i.e. OK) */
1, /* Sysframe number */
4 /* Subframe number */
};
MAC_LTE_PCAP_WritePDU(pcap_file, &context, ptr, pdu_len);
fprintf(stdout, "Wrote DL MAC PDU, len=%d\n", pdu_len);
}
pdu::parse_packet(ptr);
// Correct size for last SDU
@ -104,7 +121,7 @@ void sch_pdu::parse_packet(uint8_t *ptr)
}
// Section 6.1.2
bool sch_pdu::write_packet(uint8_t* ptr)
bool sch_pdu::write_packet(uint8_t* ptr, FILE *pcap_file)
{
uint8_t *init_ptr = ptr;
bool last_is_padding = false;
@ -173,6 +190,21 @@ bool sch_pdu::write_packet(uint8_t* ptr)
// Set paddint to zeros (if any)
bzero(ptr, rem_len*sizeof(uint8_t)*8);
if(pcap_file) {
MAC_Context_Info_t context =
{
FDD_RADIO, DIRECTION_UPLINK, C_RNTI,
50, /* RNTI */
102, /* UEId */
0, /* Retx */
1, /* CRC Stsatus (i.e. OK) */
1, /* Sysframe number */
4 /* Subframe number */
};
MAC_LTE_PCAP_WritePDU(pcap_file, &context, init_ptr, pdu_len);
fprintf(stdout, "Wrote UL MAC PDU, len=%d\n", pdu_len);
}
}
uint32_t sch_pdu::rem_size() {
@ -554,7 +586,7 @@ void rar_pdu::set_backoff(uint8_t bi)
}
// Section 6.1.5
bool rar_pdu::write_packet(uint8_t* ptr)
bool rar_pdu::write_packet(uint8_t* ptr, FILE *pcap_file)
{
// Write Backoff Indicator, if any
if (has_backoff_indicator) {

@ -282,10 +282,10 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac
}
}
}
for (int i=0;i<msg->rr_cnfg.drb_to_add_mod_list_size;i++) {
printf("Setting up DRB%d\n", msg->rr_cnfg.drb_to_add_mod_list[i].drb_id);
// todo
}
// for (int i=0;i<msg->rr_cnfg.drb_to_add_mod_list_size;i++) {
// printf("Setting up DRB%d\n", msg->rr_cnfg.drb_to_add_mod_list[i].drb_id);
// // todo
// }
}

Loading…
Cancel
Save