1 /* CBCH passive sniffer */
3 /* (C) 2010 by Holger Hans Peter Freyther
4 * (C) 2010 by Harald Welte <laforge@gnumonks.org>
5 * (C) 2010 by Alex Badea <vamposdecampos@gmail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <osmocom/bb/common/osmocom_data.h>
26 #include <osmocom/bb/common/l1ctl.h>
27 #include <osmocom/bb/common/lapdm.h>
28 #include <osmocom/bb/common/logging.h>
29 #include <osmocom/bb/common/l23_app.h>
30 #include <osmocom/bb/misc/layer3.h>
32 #include <osmocom/core/msgb.h>
33 #include <osmocom/core/talloc.h>
34 #include <osmocom/core/select.h>
35 #include <osmocom/core/signal.h>
36 #include <osmocom/gsm/rsl.h>
38 struct osmocom_ms *g_ms;
39 struct gsm48_sysinfo g_sysinfo = {};
41 static int try_cbch(struct osmocom_ms *ms, struct gsm48_sysinfo *s)
43 if (!s->si1 || !s->si4)
46 LOGP(DRR, LOGL_INFO, "no CBCH chan_nr found\n");
51 LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d MAIO = %d "
52 "HSN = %d hseq (%d): %s\n",
53 s->chan_nr, s->tsc, s->maio, s->hsn,
55 osmo_hexdump((unsigned char *) s->hopping, s->hopp_len * 2));
56 return l1ctl_tx_dm_est_req_h1(ms,
57 s->maio, s->hsn, s->hopping, s->hopp_len,
61 LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d ARFCN = %d\n",
62 s->chan_nr, s->tsc, s->arfcn);
63 return l1ctl_tx_dm_est_req_h0(ms, s->arfcn,
64 s->chan_nr, s->tsc, GSM48_CMODE_SIGN);
69 /* receive BCCH at RR layer */
70 static int bcch(struct osmocom_ms *ms, struct msgb *msg)
72 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
73 struct gsm48_sysinfo *s = &g_sysinfo;
75 if (msgb_l3len(msg) != 23) {
76 LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n");
79 switch (sih->system_information) {
80 case GSM48_MT_RR_SYSINFO_1:
81 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
82 gsm48_decode_sysinfo1(s,
83 (struct gsm48_system_information_type_1 *) sih,
85 return try_cbch(ms, s);
86 case GSM48_MT_RR_SYSINFO_4:
87 LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
88 gsm48_decode_sysinfo4(s,
89 (struct gsm48_system_information_type_4 *) sih,
91 return try_cbch(ms, s);
97 static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
99 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
100 struct tlv_parsed tv;
101 uint8_t ch_type, ch_subch, ch_ts;
103 DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
104 rllh->chan_nr, rllh->link_id);
106 rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
107 if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
108 DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
111 msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
113 rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
116 return bcch(ms, msg);
122 static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
124 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
125 int msg_type = rllh->c.msg_type;
127 if (msg_type == RSL_MT_UNIT_DATA_IND) {
128 unit_data_ind(ms, msg);
130 LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
137 static int rcv_rsl(struct msgb *msg, struct osmocom_ms *ms)
139 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
142 switch (rslh->msg_discr & 0xfe) {
143 case ABIS_RSL_MDISC_RLL:
144 rc = rcv_rll(ms, msg);
147 LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
157 static int signal_cb(unsigned int subsys, unsigned int signal,
158 void *handler_data, void *signal_data)
160 struct osmocom_ms *ms;
162 if (subsys != SS_L1CTL)
167 case S_L1CTL_FBSB_ERR:
169 return l1ctl_tx_fbsb_req(ms, ms->test_arfcn,
170 L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED);
171 case S_L1CTL_FBSB_RESP:
177 int l23_app_init(struct osmocom_ms *ms)
179 /* don't do layer3_init() as we don't want an actualy L3 */
182 osmol2_register_handler(ms, &rcv_rsl);
184 l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
185 /* FIXME: L1CTL_RES_T_FULL doesn't reset dedicated mode
186 * (if previously set), so we release it here. */
187 l1ctl_tx_dm_rel_req(ms);
188 return osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
191 static struct l23_app_info info = {
192 .copyright = "Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>\n",
193 .contribution = "Contributions by Holger Hans Peter Freyther\n",
196 struct l23_app_info *l23_app_info()