From 689c0e5f8dac7aef9f2cce4e52b02d446e4b1cbd Mon Sep 17 00:00:00 2001 From: Alex Badea Date: Sun, 21 Nov 2010 22:46:11 +0200 Subject: host layer23: add a small cbch_sniff application Tune to the ARFCN specified on the commandline (-a). Then, if a CBCH Channel Description IE is found in System Information Type 4, switch to dedicated mode on that particular channel to receive the CBCH. --- src/host/layer23/src/misc/Makefile.am | 5 +- src/host/layer23/src/misc/app_cbch_sniff.c | 188 +++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 src/host/layer23/src/misc/app_cbch_sniff.c (limited to 'src/host/layer23/src') diff --git a/src/host/layer23/src/misc/Makefile.am b/src/host/layer23/src/misc/Makefile.am index da2628e5..f8a0b737 100644 --- a/src/host/layer23/src/misc/Makefile.am +++ b/src/host/layer23/src/misc/Makefile.am @@ -2,7 +2,7 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) -bin_PROGRAMS = bcch_scan layer23 echo_test cell_log +bin_PROGRAMS = bcch_scan layer23 echo_test cell_log cbch_sniff bcch_scan_SOURCES = ../common/main.c app_bcch_scan.c bcch_scan.c layer23_SOURCES = ../common/main.c app_phone.c layer3.c rslms.c @@ -10,5 +10,4 @@ echo_test_SOURCES = ../common/main.c app_echo_test.c cell_log_LDADD = $(LDADD) -lm cell_log_SOURCES = ../common/main.c app_cell_log.c cell_log.c \ ../../../gsmmap/geo.c - - +cbch_sniff_SOURCES = ../common/main.c app_cbch_sniff.c diff --git a/src/host/layer23/src/misc/app_cbch_sniff.c b/src/host/layer23/src/misc/app_cbch_sniff.c new file mode 100644 index 00000000..19a9aced --- /dev/null +++ b/src/host/layer23/src/misc/app_cbch_sniff.c @@ -0,0 +1,188 @@ +/* CBCH passive sniffer */ + +/* (C) 2010 by Holger Hans Peter Freyther + * (C) 2010 by Harald Welte + * (C) 2010 by Alex Badea + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct osmocom_ms *g_ms; +struct gsm48_sysinfo g_sysinfo = {}; + +static int try_cbch(struct osmocom_ms *ms, struct gsm48_sysinfo *s) +{ + if (!s->si1 || !s->si4) + return 0; + if (!s->chan_nr) { + LOGP(DRR, LOGL_INFO, "no CBCH chan_nr found\n"); + return 0; + } + + if (s->h) { + LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d MAIO = %d " + "HSN = %d hseq (%d): %s\n", + s->chan_nr, s->tsc, s->maio, s->hsn, + s->hopp_len, + hexdump((unsigned char *) s->hopping, s->hopp_len * 2)); + return l1ctl_tx_dm_est_req_h1(ms, + s->maio, s->hsn, s->hopping, s->hopp_len, + s->chan_nr, s->tsc, + GSM48_CMODE_SIGN); + } else { + LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d ARFCN = %d\n", + s->chan_nr, s->tsc, s->arfcn); + return l1ctl_tx_dm_est_req_h0(ms, s->arfcn, + s->chan_nr, s->tsc, GSM48_CMODE_SIGN); + } +} + + +/* receive BCCH at RR layer */ +static int bcch(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm48_system_information_type_header *sih = msgb_l3(msg); + struct gsm48_sysinfo *s = &g_sysinfo; + + if (msgb_l3len(msg) != 23) { + LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n"); + return -EINVAL; + } + switch (sih->system_information) { + case GSM48_MT_RR_SYSINFO_1: + LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n"); + gsm48_decode_sysinfo1(s, + (struct gsm48_system_information_type_1 *) sih, + msgb_l3len(msg)); + return try_cbch(ms, s); + case GSM48_MT_RR_SYSINFO_4: + LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n"); + gsm48_decode_sysinfo4(s, + (struct gsm48_system_information_type_4 *) sih, + msgb_l3len(msg)); + return try_cbch(ms, s); + default: + return 0; + } +} + +static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) +{ + struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); + struct tlv_parsed tv; + uint8_t ch_type, ch_subch, ch_ts; + + DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n", + rllh->chan_nr, rllh->link_id); + + rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh)); + if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) { + DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n"); + return -EIO; + } + msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO); + + rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts); + switch (ch_type) { + case RSL_CHAN_BCCH: + return bcch(ms, msg); + default: + return 0; + } +} + +static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg) +{ + struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); + int msg_type = rllh->c.msg_type; + + if (msg_type == RSL_MT_UNIT_DATA_IND) { + unit_data_ind(ms, msg); + } else + LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n"); + + msgb_free(msg); + + return 0; +} + +static int rcv_rsl(struct msgb *msg, struct osmocom_ms *ms) +{ + struct abis_rsl_common_hdr *rslh = msgb_l2(msg); + int rc = 0; + + switch (rslh->msg_discr & 0xfe) { + case ABIS_RSL_MDISC_RLL: + rc = rcv_rll(ms, msg); + break; + default: + LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n", + rslh->msg_discr); + msgb_free(msg); + rc = -EINVAL; + break; + } + + return rc; +} + +static int signal_cb(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct osmocom_ms *ms; + + if (subsys != SS_L1CTL) + return 0; + + switch (signal) { + case S_L1CTL_RESET: + case S_L1CTL_FBSB_ERR: + ms = g_ms; + return l1ctl_tx_fbsb_req(ms, ms->test_arfcn, + L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED); + case S_L1CTL_FBSB_RESP: + return 0; + } + return 0; +} + +int l23_app_init(struct osmocom_ms *ms) +{ + /* don't do layer3_init() as we don't want an actualy L3 */ + + g_ms = ms; + osmol2_register_handler(ms, &rcv_rsl); + + l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL); + /* FIXME: L1CTL_RES_T_FULL doesn't reset dedicated mode + * (if previously set), so we release it here. */ + l1ctl_tx_dm_rel_req(ms); + return register_signal_handler(SS_L1CTL, &signal_cb, NULL); +} -- cgit v1.2.3