mirror of
https://github.com/brmlab/osmo-tetra.git
synced 2025-06-07 09:24:04 +02:00
Merge remote-tracking branch 'jenda/master'
This commit is contained in:
commit
4ff53b8822
6 changed files with 209 additions and 13 deletions
|
@ -40,6 +40,7 @@ class top_block(grc_wxgui.top_block_gui):
|
|||
|
||||
self.ifreq = options.frequency
|
||||
self.rfgain = options.gain
|
||||
self.offset = options.frequency_offset
|
||||
|
||||
self.src = osmosdr.source(options.args)
|
||||
self.src.set_center_freq(self.ifreq)
|
||||
|
@ -173,8 +174,8 @@ class top_block(grc_wxgui.top_block_gui):
|
|||
if abs(x / (sample_rate / 2)) > 0.9:
|
||||
set_ifreq(self.ifreq + x / 2)
|
||||
else:
|
||||
sys.stderr.write("coarse tuned to: %d Hz\n" % x)
|
||||
self.offset = -x
|
||||
sys.stderr.write("coarse tuned to: %d Hz => %d Hz\n" % (self.offset, (self.ifreq + self.offset)))
|
||||
self.tuner.set_center_freq(self.offset)
|
||||
|
||||
self.scope = fftsink2.fft_sink_c(self.Main.GetPage(0).GetWin(),
|
||||
|
@ -195,7 +196,7 @@ class top_block(grc_wxgui.top_block_gui):
|
|||
|
||||
def fftsink2_callback2(x, y):
|
||||
self.offset = self.offset - (x / 10)
|
||||
sys.stderr.write("fine tuned to: %d Hz\n" % self.offset)
|
||||
sys.stderr.write("fine tuned to: %d Hz => %d Hz\n" % (self.offset, (self.ifreq + self.offset)))
|
||||
self.tuner.set_center_freq(self.offset)
|
||||
|
||||
self.scope2 = fftsink2.fft_sink_c(self.Main.GetPage(1).GetWin(),
|
||||
|
@ -240,6 +241,8 @@ def get_options():
|
|||
help="set receiver sample rate (default 1800000)")
|
||||
parser.add_option("-f", "--frequency", type="eng_float", default=394.4e6,
|
||||
help="set receiver center frequency")
|
||||
parser.add_option("-F", "--frequency-offset", type="eng_float", default=0,
|
||||
help="set receiver offset frequency")
|
||||
parser.add_option("-g", "--gain", type="eng_float", default=None,
|
||||
help="set receiver gain")
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "tetra_upper_mac.h"
|
||||
#include <lower_mac/viterbi.h>
|
||||
|
||||
extern int ssi;
|
||||
extern int tsn;
|
||||
|
||||
struct tetra_blk_param {
|
||||
const char *name;
|
||||
uint16_t type345_bits;
|
||||
|
@ -184,6 +187,57 @@ void tp_sap_udata_ind(enum tp_sap_data_type type, const uint8_t *bits, unsigned
|
|||
DEBUGP("%s %s type4: %s\n", tbp->name, time_str,
|
||||
osmo_ubit_dump(type4, tbp->type345_bits));
|
||||
|
||||
|
||||
/* ###### Begin traffic dump patch ###### */
|
||||
|
||||
extern char *dumpdir;
|
||||
if ((type == TPSAP_T_SCH_F) && (tms->cur_burst.is_traffic) && dumpdir) {
|
||||
printf("SAVING FRAME\n");
|
||||
char fname[200];
|
||||
int16_t block[690];
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
/* Open target file */
|
||||
//snprintf(fname, 100, "traffic_%d_%d.out", tcd->time.tn, tms->cur_burst.is_traffic);
|
||||
//snprintf(fname, 100, "traffic_%d.out", tcd->time.tn);
|
||||
snprintf(fname, 199, "%s/traffic_%d_%d.out", dumpdir, tms->cur_burst.is_traffic, tsn);
|
||||
f = fopen(fname, "ab");
|
||||
|
||||
/* Generate a block */
|
||||
memset(block, 0x00, sizeof(int16_t) * 690);
|
||||
for (i=0; i<6; i++)
|
||||
block[115*i] = 0x6b21 + i;
|
||||
|
||||
for (i=0; i<114; i++)
|
||||
block[ 1+i] = type4[ i] ? -127 : 127;
|
||||
|
||||
for (i=0; i<114; i++)
|
||||
block[116+i] = type4[114+i] ? -127 : 127;
|
||||
|
||||
for (i=0; i<114; i++)
|
||||
block[231+i] = type4[228+i] ? -127 : 127;
|
||||
|
||||
for (i=0; i<90; i++)
|
||||
block[346+i] = type4[342+i] ? -127 : 127;
|
||||
|
||||
/* Write it */
|
||||
fwrite(block, sizeof(int16_t), 690, f);
|
||||
|
||||
/* Close */
|
||||
fclose(f);
|
||||
memset(fname, 0x0, sizeof(char)*200);
|
||||
snprintf(fname, 199, "%s/traffic_%d_%d.txt", dumpdir, tms->cur_burst.is_traffic, tsn);
|
||||
/* Write used ssi */
|
||||
f=fopen(fname, "a");
|
||||
memset(fname, 0x0, sizeof(char)*200);
|
||||
snprintf(fname, 199, "%d\n", ssi);
|
||||
fwrite(fname, sizeof(char), strlen(fname), f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* end traffic dump patch */
|
||||
|
||||
if (tbp->interleave_a) {
|
||||
/* Run block deinterleaving: type-3 bits */
|
||||
block_deinterleave(tbp->type345_bits, tbp->interleave_a, type4, type3);
|
||||
|
|
50
src/pcap.h
Normal file
50
src/pcap.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef PCAP_H
|
||||
#define PCAP_H
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint32_t guint32;
|
||||
typedef uint16_t guint16;
|
||||
typedef int32_t gint32;
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) pcap_hdr_s {
|
||||
guint32 magic_number; /* magic number */
|
||||
guint16 version_major; /* major version number */
|
||||
guint16 version_minor; /* minor version number */
|
||||
gint32 thiszone; /* GMT to local correction */
|
||||
guint32 sigfigs; /* accuracy of timestamps */
|
||||
guint32 snaplen; /* max length of captured packets, in octets */
|
||||
guint32 network; /* data link type */
|
||||
} pcap_hdr_t;
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) pcaprec_hdr_s {
|
||||
guint32 ts_sec; /* timestamp seconds */
|
||||
guint32 ts_usec; /* timestamp microseconds */
|
||||
guint32 incl_len; /* number of octets of packet saved in file */
|
||||
guint32 orig_len; /* actual length of packet */
|
||||
} pcaprec_hdr_t;
|
||||
|
||||
#define PCAP_MAGIC 0xa1b2c3d4
|
||||
#define PCAP_MAJOR 2
|
||||
#define PCAP_MINOR 4
|
||||
#define PCAP_SNAPLEN 65535
|
||||
#define PCAP_ETHERNET 1
|
||||
|
||||
unsigned char fake_frame_header[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ethernet frame, dst and src MAC
|
||||
0x08, 0x00, // EtherType 0800 = IPv4
|
||||
0x45, // IPv4 (0x4_), 20B header (0x_5)
|
||||
0x00, // no diffserv
|
||||
0x00, 0xff, // length
|
||||
0xc6, 0xd1, // some random frag
|
||||
0x40, 0x00, // don't frag
|
||||
0x3f, // TTL
|
||||
0x11, // IP proto = UDP
|
||||
0x00, 0x00, // checksum
|
||||
0x7f, 0x00, 0x00, 0x01, // src = 127.0.0.1
|
||||
0x7f, 0x00, 0x00, 0x01, // dst = 127.0.0.1
|
||||
0xbb, 0x13, // source port
|
||||
0x12, 0x79, // dst port = 4729
|
||||
0x00, 0xeb, // length = iplen-20
|
||||
0x00, 0x00 // checksum
|
||||
};
|
||||
#endif
|
|
@ -35,32 +35,70 @@
|
|||
#include "tetra_gsmtap.h"
|
||||
|
||||
void *tetra_tall_ctx;
|
||||
char *dumpdir;
|
||||
|
||||
char *pcap_file_path;
|
||||
int arfcn;
|
||||
int ssi;
|
||||
int tsn;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
int opt;
|
||||
|
||||
struct tetra_rx_state *trs;
|
||||
struct tetra_mac_state *tms;
|
||||
|
||||
if (argc < 2) {
|
||||
char no_udp_tap = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "a:t:d:n")) != -1) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
arfcn = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
//pcap_file_path = malloc(strlen(optarg));
|
||||
//memcpy(pcap_file_path, optarg, strlen(optarg));
|
||||
pcap_file_path = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
dumpdir = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
fprintf(stderr, "-n does not work\n");
|
||||
exit(1);
|
||||
no_udp_tap = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown option %c\n", opt);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= optind) {
|
||||
fprintf(stderr, "Usage: %s [-a ARFCN] [-t GSMTAP_PATH] [-d DUMPDIR] [-n] -s [-v] <filestream>\n", argv[0]);
|
||||
fprintf(stderr, "Usage: -n .. no UDP GSMTAP messages\n");
|
||||
fprintf(stderr, "Usage: %s <file_with_1_byte_per_bit>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fd = open(argv[1], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(2);
|
||||
if (no_udp_tap == 0) {
|
||||
tetra_gsmtap_init("localhost", 0);
|
||||
}
|
||||
|
||||
tetra_gsmtap_init("localhost", 0);
|
||||
|
||||
tms = talloc_zero(tetra_tall_ctx, struct tetra_mac_state);
|
||||
tetra_mac_state_init(tms);
|
||||
|
||||
trs = talloc_zero(tetra_tall_ctx, struct tetra_rx_state);
|
||||
trs->burst_cb_priv = tms;
|
||||
|
||||
fd = open(argv[optind], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
uint8_t buf[64];
|
||||
int len;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
|
@ -14,7 +15,13 @@
|
|||
#include "tetra_common.h"
|
||||
#include "tetra_tdma.h"
|
||||
|
||||
#include "pcap.h"
|
||||
|
||||
static struct gsmtap_inst *g_gti = NULL;
|
||||
FILE *pcap_file;
|
||||
extern char *pcap_file_path;
|
||||
extern int arfcn;
|
||||
extern int tsn;
|
||||
|
||||
static const uint8_t lchan2gsmtap[] = {
|
||||
[TETRA_LC_SCH_F] = GSMTAP_TETRA_SCH_F,
|
||||
|
@ -27,7 +34,6 @@ static const uint8_t lchan2gsmtap[] = {
|
|||
[TETRA_LC_BNCH] = GSMTAP_TETRA_BNCH,
|
||||
};
|
||||
|
||||
|
||||
struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_chan lchan,
|
||||
uint8_t ts, uint8_t ss, int8_t signal_dbm,
|
||||
uint8_t snr, const ubit_t *bitdata, unsigned int bitlen)
|
||||
|
@ -47,8 +53,10 @@ struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_cha
|
|||
gh->hdr_len = sizeof(*gh)/4;
|
||||
gh->type = GSMTAP_TYPE_TETRA_I1;
|
||||
gh->timeslot = ts;
|
||||
tsn = ts;
|
||||
gh->sub_slot = ss;
|
||||
gh->snr_db = snr;
|
||||
gh->arfcn = htons(arfcn);
|
||||
gh->signal_dbm = signal_dbm;
|
||||
gh->frame_number = htonl(fn);
|
||||
gh->sub_type = lchan2gsmtap[lchan];
|
||||
|
@ -61,8 +69,31 @@ struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_cha
|
|||
return msg;
|
||||
}
|
||||
|
||||
void pcap_pipe(char * buf, size_t n)
|
||||
{
|
||||
if (pcap_file) {
|
||||
fwrite(buf, n, 1, pcap_file);
|
||||
fflush(pcap_file);
|
||||
}
|
||||
}
|
||||
|
||||
int tetra_gsmtap_sendmsg(struct msgb *msg)
|
||||
{
|
||||
pcaprec_hdr_t hdr;
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
|
||||
hdr.ts_sec = now.tv_sec;
|
||||
hdr.ts_usec = now.tv_nsec/1000;
|
||||
hdr.incl_len = msg->len + sizeof(fake_frame_header);
|
||||
hdr.orig_len = hdr.incl_len;
|
||||
|
||||
pcap_pipe((char*)&hdr, sizeof(pcaprec_hdr_t));
|
||||
pcap_pipe((char*)&fake_frame_header, sizeof(fake_frame_header));
|
||||
pcap_pipe((char*)msg->data, msg->len);
|
||||
|
||||
if (g_gti)
|
||||
return gsmtap_sendmsg(g_gti, msg);
|
||||
else
|
||||
|
@ -76,5 +107,20 @@ int tetra_gsmtap_init(const char *host, uint16_t port)
|
|||
return -EINVAL;
|
||||
gsmtap_source_add_sink(g_gti);
|
||||
|
||||
if (pcap_file_path) {
|
||||
pcap_hdr_t hdr;
|
||||
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
|
||||
hdr.magic_number = PCAP_MAGIC;
|
||||
hdr.version_major = PCAP_MAJOR;
|
||||
hdr.version_minor = PCAP_MINOR;
|
||||
hdr.snaplen = PCAP_SNAPLEN;
|
||||
hdr.network = PCAP_ETHERNET;
|
||||
|
||||
pcap_file = fopen(pcap_file_path, "wb");
|
||||
//pcap_pipe((char*)&hdr, sizeof(pcap_hdr_t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "tetra_mle_pdu.h"
|
||||
#include "tetra_gsmtap.h"
|
||||
|
||||
extern int ssi;
|
||||
|
||||
static int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len);
|
||||
|
||||
static void rx_bcast(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms)
|
||||
|
@ -181,6 +183,8 @@ static void rx_resrc(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms
|
|||
rx_tm_sdu(tms, msg, len_bits);
|
||||
}
|
||||
|
||||
ssi = rsd.addr.ssi;
|
||||
|
||||
out:
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -240,11 +244,12 @@ static void rx_aach(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms)
|
|||
printf("UL_USAGE: %s ", tetra_get_ul_usage_name(aad.ul_usage));
|
||||
|
||||
/* save the state whether the current burst is traffic or not */
|
||||
if (aad.dl_usage > 3)
|
||||
if (aad.dl_usage > 3) {
|
||||
tms->cur_burst.is_traffic = 1;
|
||||
else
|
||||
tms->cur_burst.is_traffic = aad.dl_usage;
|
||||
} else {
|
||||
tms->cur_burst.is_traffic = 0;
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue