Add README, various compile fixes
This commit is contained in:
parent
10f2fcca8d
commit
602a3c8aa8
|
@ -0,0 +1,25 @@
|
|||
gsmstack - A GSM Um Layer 1 implementation
|
||||
(C) 2008 by Harald Welte <laforge@gnumonks.org>, portions from gsm-tvoid
|
||||
========================================================================
|
||||
|
||||
This is a GSM Layer 1 implementation mainly aimed at the requirements of
|
||||
a GSM protocol analyzer. It starts off where the demodulation ends: With
|
||||
the raw bits of the differential-decoded GSM Um burst.
|
||||
|
||||
Based on that input, the stack takes care of demultiplexing the bursts into the
|
||||
various physical and logical channels, decoding the various burst types,
|
||||
convolutional decode and parity checking (where applicable).
|
||||
|
||||
For the CCCH, it includes FCH and SCH processing. Frequency correction
|
||||
informaiton can be signalled to the decoder/demodulator by callback functions.
|
||||
|
||||
The recovereed TDMA Frame Number will be passed along with all MAC blocks
|
||||
to the Layer2 protocol instance on top.
|
||||
|
||||
The output of this Layer1 stack are the 23byte MAC blocks for control
|
||||
channels, and the 260bits (32.5byte) speech frames for TCH/F channels
|
||||
|
||||
The codebase is currently unfinished and highly experimental.
|
||||
|
||||
Patches/contributions are welcome, please send them to laforge@gnumonks.org
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
#ifndef __GSMSTACK_CCH_H__
|
||||
#define __GSMSTACK_CCH_H__ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gsmstack.h"
|
||||
|
||||
/*
|
||||
* decode_cch
|
||||
*
|
||||
* Decode a "common" control channel. Most control channels use
|
||||
* the same burst, interleave, Viterbi and parity configuration.
|
||||
* The documentation for the control channels defines SACCH first
|
||||
* and then just keeps referring to that.
|
||||
*
|
||||
* The current (investigated) list is as follows:
|
||||
*
|
||||
* BCCH Norm
|
||||
* BCCH Ext
|
||||
* PCH
|
||||
* AGCH
|
||||
* CBCH (SDCCH/4)
|
||||
* CBCH (SDCCH/8)
|
||||
* SDCCH/4
|
||||
* SACCH/C4
|
||||
* SDCCH/8
|
||||
* SACCH/C8
|
||||
*
|
||||
* We provide two functions, one for where all four bursts are
|
||||
* contiguous, and one where they aren't.
|
||||
*/
|
||||
unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,7 +1,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "gsmstack.h"
|
||||
#include "cch.h"
|
||||
#include "tch.h"
|
||||
|
||||
/* convert an 18byte 8-bit-per-byte burst to a 142byte 1bit-per-byte */
|
||||
static void bit_per_byte(unsigned char *dest, const unsigned char *src)
|
||||
|
@ -21,26 +24,34 @@ static void bit_per_byte(unsigned char *dest, const unsigned char *src)
|
|||
static int add_burst_to_lchan(struct gsm_logi_chan *lchan,
|
||||
struct gsm_burst *burst)
|
||||
{
|
||||
struct gsm_phys_chan *pchan = burst->pchan;
|
||||
int rc = 0;
|
||||
|
||||
/* copy burst to burst buffer */
|
||||
memcpy(lchan->burst_buf[lchan->next_burst], burst, sizeof(*burst));
|
||||
lchan->next_burst++;
|
||||
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_TCH_F:
|
||||
/* FIXME */
|
||||
break;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
/* FIXME */
|
||||
default:
|
||||
if (lchan->next_burst == 4) {
|
||||
lchan->next_burst = 0;
|
||||
/* FIXME: decode the four bursts into a MAC block */
|
||||
|
||||
/* pass the resulting MAC block up the stack */
|
||||
rc = gsm_lchan_macblock()
|
||||
if (lchan->next_burst == 4) {
|
||||
lchan->next_burst = 0;
|
||||
/* decode the four bursts into a MAC block */
|
||||
switch (pchan->config) {
|
||||
case GSM_PCHAN_TCH_H:
|
||||
/* FIXME */
|
||||
break;
|
||||
case GSM_PCHAN_TCH_F:
|
||||
rc = tch_decode();
|
||||
break;
|
||||
case GSM_PCHAN_CCCH:
|
||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||
rc = cch_decode();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown pchan config %u\n",
|
||||
pchan->config);
|
||||
}
|
||||
/* pass the resulting MAC block up the stack */
|
||||
if (rc)
|
||||
rc = gsm_lchan_macblock()
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -65,7 +76,7 @@ static int gsm_rx_sdcch8(struct gsm_burst *burst)
|
|||
return add_burst_to_lchan(lchan, burst);
|
||||
}
|
||||
|
||||
static int gsm_rx_tch(struct gsm_burst *burst)
|
||||
static int gsm_rx_tch_f(struct gsm_burst *burst)
|
||||
{
|
||||
struct gsm_phys_chan *pchan = burst->gsm_pchan;
|
||||
struct gsm_logi_chan *lchan;
|
||||
|
@ -131,8 +142,9 @@ int gsm_rx_burst(struct gsm_burst *burst, int bits)
|
|||
rc = gsm_rx_sdcch8(burst);
|
||||
break;
|
||||
case GSM_PCHAN_TCH_F:
|
||||
rc =
|
||||
rc = gsm_rx_tch_h(burst);
|
||||
break;
|
||||
case GSM_PCHAN_TCH_H:
|
||||
case GSM_PCHAN_UNKNOWN:
|
||||
default:
|
||||
fprintf(stderr, "unknown pchan config (ts=%u\n)\n",
|
||||
|
|
|
@ -81,6 +81,8 @@ static int get_lctype_for_tch_f(unsigned int fnr)
|
|||
return lc_type;
|
||||
}
|
||||
|
||||
/* get the logical channel type based on frame number and
|
||||
* physical channel configuration */
|
||||
int get_lctype(struct gsm_phys_chan *pchan, int fnr)
|
||||
{
|
||||
switch (pchan->config) {
|
||||
|
@ -98,8 +100,10 @@ int get_lctype(struct gsm_phys_chan *pchan, int fnr)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* get a pointer to the logical channel structure based on frame number
|
||||
* and physical channel configuration */
|
||||
struct gsm_logi_chan *get_lchan(struct gsm_phys_chan *pchan, int fnr)
|
||||
{
|
||||
int lctype = get_lctype(pchan, fnr);
|
||||
return pchan->logi_chan[lctype];
|
||||
return &pchan->logi_chan[lctype];
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ struct gsm_rf_chan *gsm_init_rfchan(unsigned int arfcn)
|
|||
for (i = 0; i < NR_TIMESLOTS; i++) {
|
||||
struct gsm_phys_chan *pchan;
|
||||
|
||||
pchan = rf->phys_chan[i];
|
||||
pchan = &rf->phys_chan[i];
|
||||
pchan->timeslot = i;
|
||||
pchan->rf_chan = rf;
|
||||
}
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
#define NR_TIMESLOTS 8
|
||||
#define NR_ARFCN 1024
|
||||
|
||||
#define USEFUL_BITS 142
|
||||
#define BURST_BITS (USEFUL_BITS/8 + 1)
|
||||
|
||||
#include "gsmtap.h"
|
||||
enum gsm_burst_type {
|
||||
GSM_BURST_UNKNOWN = GSMTAP_BURST_UNKNOWN,
|
||||
GSM_BURST_FCCH = GSMTAP_BURST_FCCH,
|
||||
GSM_BURST_PARTIAL_FCCH = GSMTAP_BURST_PARTIAL_FCCH,
|
||||
GSM_BURST_PARTIAL_SCH = GSMTAP_BURST_PARTIAL_SCH,
|
||||
GSM_BURST_SCH = GSMTAP_BURST_SCH,
|
||||
GSM_BURST_CTS_SCH = GSMTAP_BURST_CTS_SCH,
|
||||
GSM_BURST_COMPACT_SCH = GSMTAP_BURST_COMPACT_SCH,
|
||||
|
@ -72,7 +73,8 @@ enum gsm_logical_channel_type {
|
|||
GSM_LCHAN_SACCH8C, /* Slow Associated Control CH */
|
||||
|
||||
/* TCH */
|
||||
GSM_LCHAN_TCH, /* Traffic CH */
|
||||
GSM_LCHAN_TCH_F, /* Traffic CH */
|
||||
GSM_LCHAN_TCH_H, /* Traffic CH */
|
||||
GSM_LCHAN_SACCH, /* Slow Associated Control CH */
|
||||
|
||||
/* uplink */
|
||||
|
|
|
@ -43,6 +43,9 @@ struct gsmtap_hdr {
|
|||
|
||||
/* 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;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "gsmstack.h"
|
||||
|
@ -16,7 +19,7 @@
|
|||
*/
|
||||
|
||||
|
||||
static struct gsm_rf_chan rfchans[NR_ARFCN];
|
||||
static struct gsm_rf_chan *rfchans[NR_ARFCN];
|
||||
|
||||
static int read_pcap_hdr(int fd)
|
||||
{
|
||||
|
@ -59,7 +62,7 @@ static int send_burst(struct gsmtap_hdr *gh, int burst_len,
|
|||
}
|
||||
|
||||
rfchan = rfchans[arfcn];
|
||||
pchan = rfchan->phys_chan[gh->timeslot];
|
||||
pchan = &rfchan->phys_chan[gh->timeslot];
|
||||
|
||||
memset(&burst, 0, sizeof(burst));
|
||||
burst.phys_chan = pchan;
|
||||
|
@ -95,11 +98,11 @@ static int read_one_pkt(int fd, unsigned char *buf, int bufsize,
|
|||
return -4;
|
||||
|
||||
if (tv) {
|
||||
tv.tv_sec = pkthdr.tv_sec;
|
||||
tv.tv_usec = pkthdr.tv_usec;
|
||||
tv->tv_sec = pkthdr.ts.tv_sec;
|
||||
tv->tv_usec = pkthdr.ts.tv_usec;
|
||||
}
|
||||
|
||||
len = read(fd, buf, pkthdr.caplen)
|
||||
len = read(fd, buf, pkthdr.caplen);
|
||||
if (len < pkthdr.caplen)
|
||||
return -5;
|
||||
|
||||
|
@ -138,7 +141,7 @@ int main(int argc, char **argv)
|
|||
unsigned char buf[1024];
|
||||
struct timeval tv;
|
||||
int burst_len;
|
||||
burst_len = read_one_pkt(fd, &tv, sbuf, sizeof(buf));
|
||||
burst_len = read_one_pkt(fd, buf, sizeof(buf), &tv);
|
||||
if (burst_len < 0) {
|
||||
fprintf(stderr, "read_one_pkt() = %d\n", burst_len);
|
||||
exit(3);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "burst_types.h"
|
||||
//#include "burst_types.h"
|
||||
#include "tch.h"
|
||||
//#include "fire_crc.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __GSMSTACK_TCH_H__
|
||||
#define __GSMSTACK_TCH_H__ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gsmstack.h"
|
||||
|
||||
unsigned char *decode_tch(GS_CTX *ctx, unsigned char *burst, unsigned int *len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue