Merged in patches from features/SylvainsPatches.

git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@2324 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
David Burgess
2011-10-12 22:22:03 +00:00
parent 1231145a74
commit d23ba7ddfa
19 changed files with 875 additions and 40910 deletions

View File

@@ -266,7 +266,9 @@ enum TypeAndOffset {
SDCCH_4_0=4, SDCCH_4_1=5, SDCCH_4_2=6, SDCCH_4_3=7,
SDCCH_8_0=8, SDCCH_8_1=9, SDCCH_8_2=10, SDCCH_8_3=11,
SDCCH_8_4=12, SDCCH_8_5=13, SDCCH_8_6=14, SDCCH_8_7=15,
/// An extra one for our internal use.
/// Some extra ones for our internal use.
TDMA_BEACON_BCCH=253,
TDMA_BEACON_CCCH=252,
TDMA_BEACON=255
};

View File

@@ -312,6 +312,19 @@ unsigned L1Encoder::ARFCN() const
unsigned L1Decoder::ARFCN() const
{
assert(mParent);
return mParent->ARFCN();
}
TypeAndOffset L1Decoder::typeAndOffset() const
{
return mMapping.typeAndOffset();
}
void L1Decoder::open()
{
ScopedLock lock(mLock);
@@ -569,6 +582,10 @@ bool XCCHL1Decoder::processBurst(const RxBurst& inBurst)
inBurst.data1().copyToSegment(mI[B],0);
inBurst.data2().copyToSegment(mI[B],57);
// If the burst index is 0, save the time
if (B==0)
mReadTime = inBurst.time();
// If the burst index is 3, then this is the last burst in the L2 frame.
// Return true to indicate that we are ready to deinterleave.
return B==3;
@@ -645,6 +662,9 @@ void XCCHL1Decoder::handleGoodFrame()
OBJLOG(DEBUG) <<"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(DEBUG) <<"XCCHL1Decoder L2=" << L2Part;
@@ -797,14 +817,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(DEBUG) << "XCCHL1Encoder d[]=" << mD;
mD.LSB8MSB();
OBJLOG(DEBUG) << "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

@@ -302,8 +302,12 @@ class L1Decoder {
/** Accept an RxBurst and process it into the deinterleaver. */
virtual void writeLowSide(const RxBurst&) = 0;
/** Return the decoder timeslot number. */
/**@name Components of the channel description. */
//@{
unsigned TN() const { return mTN; }
unsigned ARFCN() const; ///< this comes from mUpstream
TypeAndOffset typeAndOffset() const; ///< this comes from mMapping
//@}
protected:
@@ -491,6 +495,7 @@ class XCCHL1Decoder : public L1Decoder {
BitVector mD; ///< d[], as per GSM 05.03 2.2
//@}
GSM::Time mReadTime; ///< timestamp of the first burst
unsigned mRSSIHistory[4];
public:

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").c_str());
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

@@ -25,10 +25,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

@@ -71,7 +71,7 @@ const unsigned SCHFrames[] = {1,11,21,31,41};
MAKE_TDMA_MAPPING(SCH,TDMA_BEACON,true,false,0x01,true,51);
const unsigned BCCHFrames[] = {2,3,4,5};
MAKE_TDMA_MAPPING(BCCH,TDMA_BEACON,true,false,0x55,true,51);
MAKE_TDMA_MAPPING(BCCH,TDMA_BEACON_BCCH,true,false,0x55,true,51);
// Note that we removed frames for the SDCCH components of the Combination-V C0T0.
const unsigned RACHC5Frames[] = {4,5,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,45,46};
@@ -80,16 +80,16 @@ MAKE_TDMA_MAPPING(RACHC5,TDMA_BEACON,false,true,0x55,true,51);
// CCCH 0-2 are used in C-IV and C-V. The others are used in C-IV only.
const unsigned CCCH_0Frames[] = {6,7,8,9};
MAKE_TDMA_MAPPING(CCCH_0,TDMA_BEACON,true,false,0x55,true,51);
MAKE_TDMA_MAPPING(CCCH_0,TDMA_BEACON_CCCH,true,false,0x55,true,51);
const unsigned CCCH_1Frames[] = {12,13,14,15};
MAKE_TDMA_MAPPING(CCCH_1,TDMA_BEACON,true,false,0x55,true,51);
MAKE_TDMA_MAPPING(CCCH_1,TDMA_BEACON_CCCH,true,false,0x55,true,51);
const unsigned CCCH_2Frames[] = {16,17,18,19};
MAKE_TDMA_MAPPING(CCCH_2,TDMA_BEACON,true,false,0x55,true,51);
MAKE_TDMA_MAPPING(CCCH_2,TDMA_BEACON_CCCH,true,false,0x55,true,51);
const unsigned CCCH_3Frames[] = {22,23,24,25};
MAKE_TDMA_MAPPING(CCCH_3,TDMA_BEACON,true,false,0x55,true,51);
MAKE_TDMA_MAPPING(CCCH_3,TDMA_BEACON_CCCH,true,false,0x55,true,51);
// TODO -- Other CCCH subchannels 4-8 for support of C-IV.

View File

@@ -1,19 +1,50 @@
#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_TYPE_UM 0x01 /* A Layer 2 MAC block (23 bytes) */
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* The GSMTAP format definition is maintained in libosmocore,
* specifically the latest version can always be obtained from
* http://cgit.osmocom.org/cgit/libosmocore/tree/include/osmocom/core/gsmtap.h
*
* If you want to introduce new protocol/burst/channel types or extend
* GSMTAP in any way, please contact the GSMTAP maintainer at either the
* public openbsc@lists.osmocom.org mailing list, or privately at
* Harald Welte <laforge@gnumonks.org>.
*
* Your cooperation ensures that all projects will use the same GSMTAP
* definitions and remain compatible with each other.
*/
#define GSMTAP_VERSION 0x02
#define GSMTAP_TYPE_UM 0x01
#define GSMTAP_TYPE_ABIS 0x02
#define GSMTAP_TYPE_UM_BURST 0x03 /* raw burst bits */
#define GSMTAP_TYPE_SIM 0x04
#define GSMTAP_TYPE_TETRA_I1 0x05 /* tetra air interface */
#define GSMTAP_TYPE_TETRA_I1_BURST 0x06 /* tetra air interface */
#define GSMTAP_TYPE_WMX_BURST 0x07 /* WiMAX burst */
#define GSMTAP_TYPE_GB_LLC 0x08 /* GPRS Gb interface: LLC */
#define GSMTAP_TYPE_GB_SNDCP 0x09 /* GPRS Gb interface: SNDCP */
#define GSMTAP_TYPE_GMR1_UM 0x0a /* GMR-1 L2 packets */
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_UM_BURST */
#define GSMTAP_BURST_UNKNOWN 0x00
#define GSMTAP_BURST_FCCH 0x01
#define GSMTAP_BURST_PARTIAL_SCH 0x02
@@ -24,58 +55,97 @@
#define GSMTAP_BURST_DUMMY 0x07
#define GSMTAP_BURST_ACCESS 0x08
#define GSMTAP_BURST_NONE 0x09
/* WiMAX bursts */
#define GSMTAP_BURST_CDMA_CODE 0x10 /* WiMAX CDMA Code Attribute burst */
#define GSMTAP_BURST_FCH 0x11 /* WiMAX FCH burst */
#define GSMTAP_BURST_FFB 0x12 /* WiMAX Fast Feedback burst */
#define GSMTAP_BURST_PDU 0x13 /* WiMAX PDU burst */
#define GSMTAP_BURST_HACK 0x14 /* WiMAX HARQ ACK burst */
#define GSMTAP_BURST_PHY_ATTRIBUTES 0x15 /* WiMAX PHY Attributes burst */
#define GSMTAP_UDP_PORT 4729 /* officially registered with IANA */
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_UM */
#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_CBCH51 0x0b
#define GSMTAP_CHANNEL_CBCH52 0x0c
#define GSMTAP_CHANNEL_PDCH 0x0d
#define GSMTAP_CHANNEL_PTCCH 0x0e
#define GSMTAP_CHANNEL_PACCH 0x0f
#define GSMTAP_CHANNEL_ACCH 0x80
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_TETRA_AIR */
#define GSMTAP_TETRA_BSCH 0x01
#define GSMTAP_TETRA_AACH 0x02
#define GSMTAP_TETRA_SCH_HU 0x03
#define GSMTAP_TETRA_SCH_HD 0x04
#define GSMTAP_TETRA_SCH_F 0x05
#define GSMTAP_TETRA_BNCH 0x06
#define GSMTAP_TETRA_STCH 0x07
#define GSMTAP_TETRA_TCH_F 0x08
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_GMR1_UM */
#define GSMTAP_GMR1_UNKNOWN 0x00
#define GSMTAP_GMR1_BCCH 0x01
#define GSMTAP_GMR1_CCCH 0x02 /* either AGCH or PCH */
#define GSMTAP_GMR1_PCH 0x03
#define GSMTAP_GMR1_AGCH 0x04
#define GSMTAP_GMR1_BACH 0x05
#define GSMTAP_GMR1_RACH 0x06
#define GSMTAP_GMR1_CBCH 0x07
#define GSMTAP_GMR1_SDCCH 0x08
#define GSMTAP_GMR1_TACCH 0x09
#define GSMTAP_GMR1_GBCH 0x0a
#define GSMTAP_GMR1_SACCH 0x01 /* to be combined with _TCH{6,9} */
#define GSMTAP_GMR1_FACCH 0x02 /* to be combines with _TCH{3,6,9} */
#define GSMTAP_GMR1_DKAB 0x03 /* to be combined with _TCH3 */
#define GSMTAP_GMR1_TCH3 0x10
#define GSMTAP_GMR1_TCH6 0x14
#define GSMTAP_GMR1_TCH9 0x18
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* flags for the ARFCN */
#define GSMTAP_ARFCN_F_PCS 0x8000
#define GSMTAP_ARFCN_F_UPLINK 0x4000
#define GSMTAP_ARFCN_MASK 0x3fff
/* IANA-assigned well-known UDP port for GSMTAP messages */
#define GSMTAP_UDP_PORT 4729
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
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 0x01 currently */
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));
/* PCAP related definitions */
#define TCPDUMP_MAGIC 0xa1b2c3d4
#ifndef LINKTYPE_GSMTAP
#define LINKTYPE_GSMTAP 2342
#endif
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 */
};
#endif /* _GSMTAP_H */