1 /* CCCH passive sniffer */
2 /* (C) 2010-2011 by Holger Hans Peter Freyther
3 * (C) 2010 by Harald Welte <laforge@gnumonks.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <osmocore/msgb.h>
28 #include <osmocore/rsl.h>
29 #include <osmocore/tlv.h>
30 #include <osmocore/gsm48_ie.h>
31 #include <osmocore/signal.h>
32 #include <osmocore/protocol/gsm_04_08.h>
34 #include <osmocom/bb/common/logging.h>
35 #include <osmocom/bb/common/lapdm.h>
36 #include <osmocom/bb/misc/rslms.h>
37 #include <osmocom/bb/misc/layer3.h>
38 #include <osmocom/bb/common/osmocom_data.h>
39 #include <osmocom/bb/common/l1ctl.h>
40 #include <osmocom/bb/common/l23_app.h>
47 struct gsm_sysinfo_freq cell_arfcns[1024];
51 static void dump_bcch(struct osmocom_ms *ms, uint8_t tc, const uint8_t *data)
53 struct gsm48_system_information_type_header *si_hdr;
54 si_hdr = (struct gsm48_system_information_type_header *) data;
56 /* GSM 05.02 ยง6.3.1.3 Mapping of BCCH data */
57 switch (si_hdr->system_information) {
58 case GSM48_MT_RR_SYSINFO_1:
59 fprintf(stderr, "\tSI1");
62 fprintf(stderr, " on wrong TC");
64 if (!app_state.has_si1) {
65 struct gsm48_system_information_type_1 *si1 =
66 (struct gsm48_system_information_type_1 *)data;
68 gsm48_decode_freq_list(app_state.cell_arfcns,
69 si1->cell_channel_description,
70 sizeof(si1->cell_channel_description),
73 app_state.has_si1 = 1;
76 case GSM48_MT_RR_SYSINFO_2:
77 fprintf(stderr, "\tSI2");
80 fprintf(stderr, " on wrong TC");
83 case GSM48_MT_RR_SYSINFO_3:
84 fprintf(stderr, "\tSI3");
86 if (tc != 2 && tc != 6)
87 fprintf(stderr, " on wrong TC");
89 if (app_state.ccch_mode == CCCH_MODE_NONE) {
90 struct gsm48_system_information_type_3 *si3 =
91 (struct gsm48_system_information_type_3 *)data;
93 if (si3->control_channel_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C)
94 app_state.ccch_mode = CCCH_MODE_COMBINED;
96 app_state.ccch_mode = CCCH_MODE_NON_COMBINED;
98 l1ctl_tx_ccch_mode_req(ms, app_state.ccch_mode);
101 case GSM48_MT_RR_SYSINFO_4:
102 fprintf(stderr, "\tSI4");
104 if (tc != 3 && tc != 7)
105 fprintf(stderr, " on wrong TC");
108 case GSM48_MT_RR_SYSINFO_5:
109 fprintf(stderr, "\tSI5");
111 case GSM48_MT_RR_SYSINFO_6:
112 fprintf(stderr, "\tSI6");
114 case GSM48_MT_RR_SYSINFO_7:
115 fprintf(stderr, "\tSI7");
118 fprintf(stderr, " on wrong TC");
121 case GSM48_MT_RR_SYSINFO_8:
122 fprintf(stderr, "\tSI8");
125 fprintf(stderr, " on wrong TC");
128 case GSM48_MT_RR_SYSINFO_9:
129 fprintf(stderr, "\tSI9");
132 fprintf(stderr, " on wrong TC");
135 case GSM48_MT_RR_SYSINFO_13:
136 fprintf(stderr, "\tSI13");
138 if (tc != 4 && tc != 0)
139 fprintf(stderr, " on wrong TC");
142 case GSM48_MT_RR_SYSINFO_16:
143 fprintf(stderr, "\tSI16");
146 fprintf(stderr, " on wrong TC");
149 case GSM48_MT_RR_SYSINFO_17:
150 fprintf(stderr, "\tSI17");
153 fprintf(stderr, " on wrong TC");
156 case GSM48_MT_RR_SYSINFO_2bis:
157 fprintf(stderr, "\tSI2bis");
160 fprintf(stderr, " on wrong TC");
163 case GSM48_MT_RR_SYSINFO_2ter:
164 fprintf(stderr, "\tSI2ter");
166 if (tc != 5 && tc != 4)
167 fprintf(stderr, " on wrong TC");
170 case GSM48_MT_RR_SYSINFO_5bis:
171 fprintf(stderr, "\tSI5bis");
173 case GSM48_MT_RR_SYSINFO_5ter:
174 fprintf(stderr, "\tSI5ter");
177 fprintf(stderr, "\tUnknown SI");
181 fprintf(stderr, "\n");
186 * This method used to send a l1ctl_tx_dm_est_req_h0 or
187 * a l1ctl_tx_dm_est_req_h1 to the layer1 to follow this
188 * assignment. The code has been removed.
190 int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
192 struct gsm48_imm_ass *ia = msgb_l3(msg);
193 uint8_t ch_type, ch_subch, ch_ts;
195 /* Discard packet TBF assignement */
196 if (ia->page_mode & 0xf0)
199 /* FIXME: compare RA and GSM time with when we sent RACH req */
201 rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts);
203 if (!ia->chan_desc.h0.h) {
207 arfcn = ia->chan_desc.h0.arfcn_low | (ia->chan_desc.h0.arfcn_high << 8);
209 DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
210 "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
211 ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
212 ia->chan_desc.h0.tsc);
216 uint8_t maio, hsn, ma_len;
217 uint16_t ma[64], arfcn;
220 hsn = ia->chan_desc.h1.hsn;
221 maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high << 2);
223 DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
224 "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
225 ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch,
226 ia->chan_desc.h1.tsc);
228 /* decode mobile allocation */
230 for (i=1, j=0; i<=1024; i++) {
232 if (app_state.cell_arfcns[arfcn].mask & 0x01) {
233 k = ia->mob_alloc_len - (j>>3) - 1;
234 if (ia->mob_alloc[k] & (1 << (j&7))) {
235 ma[ma_len++] = arfcn;
246 int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
248 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
251 if (sih->rr_protocol_discriminator != GSM48_PDISC_RR)
252 LOGP(DRR, LOGL_ERROR, "PCH pdisc != RR\n");
254 switch (sih->system_information) {
255 case GSM48_MT_RR_PAG_REQ_1:
256 case GSM48_MT_RR_PAG_REQ_2:
257 case GSM48_MT_RR_PAG_REQ_3:
258 /* FIXME: implement decoding of paging request */
260 case GSM48_MT_RR_IMM_ASS:
261 LOGP(DRR, LOGL_NOTICE, "Immediate assignment.\n");
264 LOGP(DRR, LOGL_NOTICE, "unknown PCH/AGCH type 0x%02x\n",
265 sih->system_information);
272 int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms)
274 /* FIXME: we have lost the gsm frame time until here, need to store it
275 * in some msgb context */
276 //dump_bcch(dl->time.tc, ccch->data);
277 dump_bcch(ms, 0, msg->l3h);
279 /* Req channel logic */
280 if (app_state.ccch_enabled && (app_state.rach_count < 2)) {
281 l1ctl_tx_rach_req(ms, app_state.rach_count, 0,
282 app_state.ccch_mode == CCCH_MODE_COMBINED);
283 app_state.rach_count++;
289 void layer3_app_reset(void)
292 app_state.has_si1 = 0;
293 app_state.ccch_mode = CCCH_MODE_NONE;
294 app_state.ccch_enabled = 0;
295 app_state.rach_count = 0;
297 memset(&app_state.cell_arfcns, 0x00, sizeof(app_state.cell_arfcns));
300 static int signal_cb(unsigned int subsys, unsigned int signal,
301 void *handler_data, void *signal_data)
303 struct osmocom_ms *ms;
305 if (subsys != SS_L1CTL)
312 return l1ctl_tx_fbsb_req(ms, ms->test_arfcn,
313 L1CTL_FBSB_F_FB01SB, 100, 0,
321 int l23_app_init(struct osmocom_ms *ms)
323 register_signal_handler(SS_L1CTL, &signal_cb, NULL);
324 l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
325 return layer3_init(ms);
328 static struct l23_app_info info = {
329 .copyright = "Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>\n",
330 .contribution = "Contributions by Holger Hans Peter Freyther\n",
333 struct l23_app_info *l23_app_info()