laforge
/
openbts-osmo
Archived
1
0
Fork 0

gsm: Update and enhance the GSM Tap functionality

* switch to the new format
* add uplink frame dump as well
* fill more fields than before (not fully complete yet tough)

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2010-07-15 21:30:25 +02:00
parent b6b3f6ace1
commit e6d5057d5d
4 changed files with 151 additions and 46 deletions

View File

@ -659,6 +659,10 @@ void XCCHL1Decoder::handleGoodFrame()
OBJLOG(DEEPDEBUG) <<"XCCHL1Decoder d[]=" << mD;
if (mUpstream) {
// Send all bits to GSMTAP
gWriteGSMTAP(ARFCN(),TN(),mReadTime.FN(),
typeAndOffset(),mMapping.repeatLength()>51,true,
mD);
// Build an L2 frame and pass it up.
const BitVector L2Part(mD.tail(headerOffset()));
OBJLOG(DEEPDEBUG) <<"XCCHL1Decoder L2=" << L2Part;
@ -810,14 +814,18 @@ void XCCHL1Encoder::sendFrame(const L2Frame& frame)
// GSM 05.03 4.1.1.
//assert(mD.size()==headerOffset()+frame.size());
frame.copyToSegment(mU,headerOffset());
// Send to GSMTAP (must send mU = real bits !)
gWriteGSMTAP(ARFCN(),TN(),mNextWriteTime.FN(),
typeAndOffset(),mMapping.repeatLength()>51,false,mU);
// Encode data into bursts
OBJLOG(DEEPDEBUG) << "XCCHL1Encoder d[]=" << mD;
mD.LSB8MSB();
OBJLOG(DEEPDEBUG) << "XCCHL1Encoder d[]=" << mD;
encode(); // Encode u[] to c[], GSM 05.03 4.1.2 and 4.1.3.
interleave(); // Interleave c[] to i[][], GSM 05.03 4.1.4.
transmit(); // Send the bursts to the radio, GSM 05.03 4.1.5.
// FIXME: is this FN OK, or do we need to back it up by 4?
gWriteGSMTAP(ARFCN(),mTN,mPrevWriteTime.FN(),frame);
}

View File

@ -30,21 +30,107 @@
UDPSocket GSMTAPSocket;
void gWriteGSMTAP(unsigned ARFCN, unsigned TS, unsigned FN, const GSM::L2Frame& frame)
void gWriteGSMTAP(unsigned ARFCN, unsigned TS, unsigned FN,
GSM::TypeAndOffset to, bool is_saach, bool ul_dln,
const BitVector& frame)
{
char buffer[MAX_UDP_LENGTH];
int ofs = 0;
// Check if GSMTap is enabled
if (!gConfig.defines("GSMTAP.TargetIP")) return;
// Port configuration
unsigned port = GSMTAP_UDP_PORT; // default port for GSM-TAP
if (gConfig.defines("GSMTAP.TargetPort"))
port = gConfig.getNum("GSMTAP.TargetPort");
// Write a GSMTAP packet to the configured destination.
// Set socket destination
GSMTAPSocket.destination(port,gConfig.getStr("GSMTAP.TargetIP"));
char buffer[MAX_UDP_LENGTH];
gsmtap_hdr header(ARFCN,TS,FN);
memcpy(buffer,&header,sizeof(header));
frame.pack((unsigned char*)buffer+sizeof(header));
GSMTAPSocket.write(buffer, sizeof(header) + frame.size()/8);
// Decode TypeAndOffset
uint8_t stype, scn;
switch (to) {
case GSM::TDMA_BEACON_BCCH:
stype = GSMTAP_CHANNEL_BCCH;
scn = 0;
break;
case GSM::TDMA_BEACON_CCCH:
stype = GSMTAP_CHANNEL_CCCH;
scn = 0;
break;
case GSM::SDCCH_4_0:
case GSM::SDCCH_4_1:
case GSM::SDCCH_4_2:
case GSM::SDCCH_4_3:
stype = GSMTAP_CHANNEL_SDCCH4;
scn = to - GSM::SDCCH_4_0;
break;
case GSM::SDCCH_8_0:
case GSM::SDCCH_8_1:
case GSM::SDCCH_8_2:
case GSM::SDCCH_8_3:
case GSM::SDCCH_8_4:
case GSM::SDCCH_8_5:
case GSM::SDCCH_8_6:
case GSM::SDCCH_8_7:
stype = GSMTAP_CHANNEL_SDCCH8;
scn = to - GSM::SDCCH_8_0;
break;
case GSM::TCHF_0:
stype = GSMTAP_CHANNEL_TCH_F;
scn = 0;
break;
case GSM::TCHH_0:
case GSM::TCHH_1:
stype = GSMTAP_CHANNEL_TCH_H;
scn = to - GSM::TCHH_0;
break;
default:
stype = GSMTAP_CHANNEL_UNKNOWN;
scn = 0;
}
if (is_saach)
stype |= GSMTAP_CHANNEL_ACCH;
// Flags in ARFCN
if (gConfig.getNum("GSM.Band") == 1900)
ARFCN |= GSMTAP_ARFCN_F_PCS;
if (ul_dln)
ARFCN |= GSMTAP_ARFCN_F_UPLINK;
// Build header
struct gsmtap_hdr *header = (struct gsmtap_hdr *)buffer;
header->version = GSMTAP_VERSION;
header->hdr_len = sizeof(struct gsmtap_hdr) >> 2;
header->type = GSMTAP_TYPE_UM;
header->timeslot = TS;
header->arfcn = htons(ARFCN);
header->signal_dbm = 0; /* FIXME */
header->snr_db = 0; /* FIXME */
header->frame_number = htonl(FN);
header->sub_type = stype;
header->antenna_nr = 0;
header->sub_slot = scn;
header->res = 0;
ofs += sizeof(*header);
// Add frame data
frame.pack((unsigned char*)&buffer[ofs]);
ofs += (frame.size() + 7) >> 3;
// Write the GSMTAP packet
GSMTAPSocket.write(buffer, ofs);
}

View File

@ -28,10 +28,13 @@
#define GSMTAPDUMP_H
#include "gsmtap.h"
#include "GSMCommon.h"
#include "GSMTransfer.h"
void gWriteGSMTAP(unsigned ARFCN, unsigned TS, unsigned FN, const GSM::L2Frame& frame);
void gWriteGSMTAP(unsigned ARFCN, unsigned TS, unsigned FN,
GSM::TypeAndOffset to, bool is_sacch, bool ul_dln,
const BitVector& frame);
#endif

View File

@ -1,14 +1,20 @@
#ifndef _GSMTAP_H
#define _GSMTAP_H
/* gsmtap header, pseudo-header in front of the actua GSM payload*/
/* gsmtap header, pseudo-header in front of the actua GSM payload */
#include <sys/types.h>
#ifdef __linux__
# include <arpa/inet.h>
#endif
/* GSMTAP is a generic header format for GSM protocol captures,
* it uses the IANA-assigned UDP port number 4729 and carries
* payload in various formats of GSM interfaces such as Um MAC
* blocks or Um bursts.
*
* Example programs generating GSMTAP data are airprobe
* (http://airprobe.org/) or OsmocomBB (http://bb.osmocom.org/)
*/
#define GSMTAP_VERSION 0x01
#include <stdint.h>
#define GSMTAP_VERSION 0x02
#define GSMTAP_TYPE_UM 0x01 /* A Layer 2 MAC block (23 bytes) */
#define GSMTAP_TYPE_ABIS 0x02
@ -25,38 +31,41 @@
#define GSMTAP_BURST_ACCESS 0x08
#define GSMTAP_BURST_NONE 0x09
#define GSMTAP_CHANNEL_UNKNOWN 0x00
#define GSMTAP_CHANNEL_BCCH 0x01
#define GSMTAP_CHANNEL_CCCH 0x02
#define GSMTAP_CHANNEL_RACH 0x03
#define GSMTAP_CHANNEL_AGCH 0x04
#define GSMTAP_CHANNEL_PCH 0x05
#define GSMTAP_CHANNEL_SDCCH 0x06
#define GSMTAP_CHANNEL_SDCCH4 0x07
#define GSMTAP_CHANNEL_SDCCH8 0x08
#define GSMTAP_CHANNEL_TCH_F 0x09
#define GSMTAP_CHANNEL_TCH_H 0x0a
#define GSMTAP_CHANNEL_ACCH 0x80
#define GSMTAP_ARFCN_F_PCS 0x8000
#define GSMTAP_ARFCN_F_UPLINK 0x4000
#define GSMTAP_ARFCN_MASK 0x3fff
#define GSMTAP_UDP_PORT 4729 /* officially registered with IANA */
struct gsmtap_hdr {
u_int8_t version; /* version, set to 0x01 currently */
u_int8_t hdr_len; /* length in number of 32bit words */
u_int8_t type; /* see GSMTAP_TYPE_* */
u_int8_t timeslot; /* timeslot (0..7 on Um) */
uint8_t version; /* version, set to GSMTAP_VERSION */
uint8_t hdr_len; /* length in number of 32bit words */
uint8_t type; /* see GSMTAP_TYPE_* */
uint8_t timeslot; /* timeslot (0..7 on Um) */
u_int16_t arfcn; /* ARFCN (frequency).
* highest bit 1 == uplink */
u_int8_t noise_db; /* noise figure in dB */
u_int8_t signal_db; /* signal level in dB */
uint16_t arfcn; /* ARFCN (frequency) */
int8_t signal_dbm; /* signal level in dBm */
int8_t snr_db; /* signal/noise ratio in dB */
u_int32_t frame_number; /* GSM Frame Number (FN) */
uint32_t frame_number; /* GSM Frame Number (FN) */
u_int8_t burst_type; /* Type of burst, see above */
u_int8_t antenna_nr; /* Antenna Number */
u_int16_t res; /* reserved for future use (RFU) */
gsmtap_hdr(unsigned ARFCN, unsigned TS, unsigned FN)
{
version = GSMTAP_VERSION;
type = GSMTAP_TYPE_UM;
burst_type = GSMTAP_BURST_NONE;
antenna_nr = 0;
noise_db = 0;
signal_db = 0;
timeslot = TS;
arfcn = htons(ARFCN);
frame_number = htonl(FN);
}
uint8_t sub_type; /* Type of burst/channel, see above */
uint8_t antenna_nr; /* Antenna Number */
uint8_t sub_slot; /* sub-slot within timeslot */
uint8_t res; /* reserved for future use (RFU) */
} __attribute__((packed));
@ -70,12 +79,11 @@ struct pcap_timeval {
int32_t tv_sec;
int32_t tv_usec;
};
struct pcap_sf_pkthdr {
struct pcap_timeval ts; /* time stamp */
u_int32_t caplen; /* lenght of portion present */
u_int32_t len; /* length of this packet */
uint32_t caplen; /* lenght of portion present */
uint32_t len; /* length of this packet */
};
#endif /* _GSMTAP_H */