summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2011-09-03 00:27:12 +0200
committerHarald Welte <laforge@gnumonks.org>2017-01-15 09:29:18 +0100
commitbd957da24bbce620c4256a1e144fde5eda482070 (patch)
treefb48a02aa0edb4d19b2a0ff9e7567037b1eaa28f
parent56183c4feddc79b6c4576fa75fe68e7bfa20783d (diff)
[HACK] host/layer23: Wire application logic for a simple demo sniff app
This listen for IMM.ASS and follows them Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--src/host/layer23/src/misc/app_ccch_scan.c166
1 files changed, 151 insertions, 15 deletions
diff --git a/src/host/layer23/src/misc/app_ccch_scan.c b/src/host/layer23/src/misc/app_ccch_scan.c
index f92b13b..7bc85bf 100644
--- a/src/host/layer23/src/misc/app_ccch_scan.c
+++ b/src/host/layer23/src/misc/app_ccch_scan.c
@@ -23,6 +23,7 @@
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
+#include <time.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/rsl.h>
@@ -41,12 +42,24 @@
#include <l1ctl_proto.h>
+enum dch_state_t {
+ DCH_NONE,
+ DCH_WAIT_EST,
+ DCH_ACTIVE,
+ DCH_WAIT_REL,
+};
+
static struct {
- int has_si1;
- int ccch_mode;
- int ccch_enabled;
- int rach_count;
- struct gsm_sysinfo_freq cell_arfcns[1024];
+ int has_si1;
+ int ccch_mode;
+
+ enum dch_state_t dch_state;
+ uint8_t dch_nr;
+ int dch_badcnt;
+
+ FILE * fh;
+
+ struct gsm_sysinfo_freq cell_arfcns[1024];
} app_state;
@@ -177,12 +190,15 @@ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
{
struct gsm48_imm_ass *ia = msgb_l3(msg);
uint8_t ch_type, ch_subch, ch_ts;
+ int rv;
/* Discard packet TBF assignement */
if (ia->page_mode & 0xf0)
return 0;
- /* FIXME: compare RA and GSM time with when we sent RACH req */
+ /* If we're not ready yet, or just busy ... */
+ if ((!app_state.has_si1) || (app_state.dch_state != DCH_NONE))
+ return 0;
rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts);
@@ -197,6 +213,10 @@ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
ia->chan_desc.h0.tsc);
+ /* request L1 to go to dedicated mode on assigned channel */
+ rv = l1ctl_tx_dm_est_req_h0(ms,
+ arfcn, ia->chan_desc.chan_nr, ia->chan_desc.h0.tsc,
+ GSM48_CMODE_SIGN, 0);
} else {
/* Hopping */
uint8_t maio, hsn, ma_len;
@@ -223,10 +243,22 @@ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
j++;
}
}
+
+ /* request L1 to go to dedicated mode on assigned channel */
+ rv = l1ctl_tx_dm_est_req_h1(ms,
+ maio, hsn, ma, ma_len,
+ ia->chan_desc.chan_nr, ia->chan_desc.h1.tsc,
+ GSM48_CMODE_SIGN, 0);
}
LOGPC(DRR, LOGL_NOTICE, "\n");
- return 0;
+
+ /* Set state */
+ app_state.dch_state = DCH_WAIT_EST;
+ app_state.dch_nr = ia->chan_desc.chan_nr;
+ app_state.dch_badcnt = 0;
+
+ return rv;
}
static const char *pag_print_mode(int mode)
@@ -411,6 +443,10 @@ int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
struct gsm48_system_information_type_header *sih = msgb_l3(msg);
int rc = 0;
+ /* CCCH marks the end of WAIT_REL */
+ if (app_state.dch_state == DCH_WAIT_REL)
+ app_state.dch_state = DCH_NONE;
+
if (sih->rr_protocol_discriminator != GSM48_PDISC_RR)
LOGP(DRR, LOGL_ERROR, "PCH pdisc != RR\n");
@@ -444,19 +480,109 @@ int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms)
{
+ /* BCCH marks the end of WAIT_REL */
+ if (app_state.dch_state == DCH_WAIT_REL)
+ app_state.dch_state = DCH_NONE;
+
/* FIXME: we have lost the gsm frame time until here, need to store it
* in some msgb context */
//dump_bcch(dl->time.tc, ccch->data);
dump_bcch(ms, 0, msg->l3h);
- /* Req channel logic */
- if (app_state.ccch_enabled && (app_state.rach_count < 2)) {
- l1ctl_tx_rach_req(ms, app_state.rach_count, 0,
- app_state.ccch_mode == CCCH_MODE_COMBINED);
- app_state.rach_count++;
+ return 0;
+}
+
+static char *
+gen_filename(struct osmocom_ms *ms, struct l1ctl_burst_ind *bi)
+{
+ static char buffer[256];
+ time_t d;
+ struct tm lt;
+
+ time(&d);
+ localtime_r(&d, &lt);
+
+ snprintf(buffer, 256, "bursts_%04d%02d%02d_%02d%02d_%d_%d_%02x.dat",
+ lt.tm_year + 1900, lt.tm_mon, lt.tm_mday,
+ lt.tm_hour, lt.tm_min,
+ ms->test_arfcn,
+ ntohl(bi->frame_nr),
+ bi->chan_nr
+ );
+
+ return buffer;
+}
+
+void layer3_rx_burst(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct l1ctl_burst_ind *bi;
+ int16_t rx_dbm;
+ uint16_t arfcn;
+ int ul, do_rel=0;
+
+ /* Header handling */
+ bi = (struct l1ctl_burst_ind *) msg->l1h;
+
+ arfcn = ntohs(bi->band_arfcn);
+ rx_dbm = rxlev2dbm(bi->rx_level);
+ ul = !!(arfcn & ARFCN_UPLINK);
+
+ /* Check for channel start */
+ if (app_state.dch_state == DCH_WAIT_EST) {
+ if (bi->chan_nr == app_state.dch_nr) {
+ if (bi->snr > 64) {
+ /* Change state */
+ app_state.dch_state = DCH_ACTIVE;
+ app_state.dch_badcnt = 0;
+
+ /* Open output */
+ app_state.fh = fopen(gen_filename(ms, bi), "wb");
+ } else {
+ /* Abandon ? */
+ do_rel = (app_state.dch_badcnt++) >= 4;
+ }
+ }
}
- return 0;
+ /* Check for channel end */
+ if (app_state.dch_state == DCH_ACTIVE) {
+ if (!ul) {
+ /* Bad burst counting */
+ if (bi->snr < 64)
+ app_state.dch_badcnt++;
+ else if (app_state.dch_badcnt >= 2)
+ app_state.dch_badcnt -= 2;
+ else
+ app_state.dch_badcnt = 0;
+
+ /* Release condition */
+ do_rel = app_state.dch_badcnt >= 6;
+ }
+ }
+
+ /* Release ? */
+ if (do_rel) {
+ /* L1 release */
+ l1ctl_tx_dm_rel_req(ms);
+ l1ctl_tx_fbsb_req(ms, ms->test_arfcn,
+ L1CTL_FBSB_F_FB01SB, 100, 0,
+ app_state.ccch_mode);
+
+ /* Change state */
+ app_state.dch_state = DCH_WAIT_REL;
+ app_state.dch_badcnt = 0;
+
+ /* Close output */
+ if (app_state.fh) {
+ fclose(app_state.fh);
+ app_state.fh = NULL;
+ }
+ }
+
+ /* Save the burst */
+ if (app_state.dch_state == DCH_ACTIVE)
+ fwrite(bi, sizeof(*bi), 1, app_state.fh);
+
}
void layer3_app_reset(void)
@@ -464,8 +590,12 @@ void layer3_app_reset(void)
/* Reset state */
app_state.has_si1 = 0;
app_state.ccch_mode = CCCH_MODE_NONE;
- app_state.ccch_enabled = 0;
- app_state.rach_count = 0;
+ app_state.dch_state = DCH_NONE;
+ app_state.dch_badcnt = 0;
+
+ if (app_state.fh)
+ fclose(app_state.fh);
+ app_state.fh = NULL;
memset(&app_state.cell_arfcns, 0x00, sizeof(app_state.cell_arfcns));
}
@@ -474,11 +604,17 @@ static int signal_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct osmocom_ms *ms;
+ struct osmobb_msg_ind *mi;
if (subsys != SS_L1CTL)
return 0;
switch (signal) {
+ case S_L1CTL_BURST_IND:
+ mi = signal_data;
+ layer3_rx_burst(mi->ms, mi->msg);
+ break;
+
case S_L1CTL_RESET:
ms = signal_data;
layer3_app_reset();