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/protocol/gsm_04_08.h>
33 #include <osmocom/bb/common/logging.h>
34 #include <osmocom/bb/common/lapdm.h>
35 #include <osmocom/bb/misc/rslms.h>
36 #include <osmocom/bb/misc/layer3.h>
37 #include <osmocom/bb/common/osmocom_data.h>
38 #include <osmocom/bb/common/l1ctl.h>
45 struct gsm_sysinfo_freq cell_arfcns[1024];
49 static void dump_bcch(struct osmocom_ms *ms, uint8_t tc, const uint8_t *data)
51 struct gsm48_system_information_type_header *si_hdr;
52 si_hdr = (struct gsm48_system_information_type_header *) data;
54 /* GSM 05.02 ยง6.3.1.3 Mapping of BCCH data */
55 switch (si_hdr->system_information) {
56 case GSM48_MT_RR_SYSINFO_1:
57 fprintf(stderr, "\tSI1");
60 fprintf(stderr, " on wrong TC");
62 if (!app_state.has_si1) {
63 struct gsm48_system_information_type_1 *si1 =
64 (struct gsm48_system_information_type_1 *)data;
66 gsm48_decode_freq_list(&app_state.cell_arfcns,
67 si1->cell_channel_description,
68 sizeof(si1->cell_channel_description),
71 app_state.has_si1 = 1;
74 case GSM48_MT_RR_SYSINFO_2:
75 fprintf(stderr, "\tSI2");
78 fprintf(stderr, " on wrong TC");
81 case GSM48_MT_RR_SYSINFO_3:
82 fprintf(stderr, "\tSI3");
84 if (tc != 2 && tc != 6)
85 fprintf(stderr, " on wrong TC");
87 if (app_state.ccch_mode == CCCH_MODE_NONE) {
88 struct gsm48_system_information_type_3 *si3 =
89 (struct gsm48_system_information_type_3 *)data;
91 if (si3->control_channel_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C)
92 app_state.ccch_mode = CCCH_MODE_COMBINED;
94 app_state.ccch_mode = CCCH_MODE_NON_COMBINED;
96 l1ctl_tx_ccch_mode_req(ms, app_state.ccch_mode);
99 case GSM48_MT_RR_SYSINFO_4:
100 fprintf(stderr, "\tSI4");
102 if (tc != 3 && tc != 7)
103 fprintf(stderr, " on wrong TC");
106 case GSM48_MT_RR_SYSINFO_5:
107 fprintf(stderr, "\tSI5");
109 case GSM48_MT_RR_SYSINFO_6:
110 fprintf(stderr, "\tSI6");
112 case GSM48_MT_RR_SYSINFO_7:
113 fprintf(stderr, "\tSI7");
116 fprintf(stderr, " on wrong TC");
119 case GSM48_MT_RR_SYSINFO_8:
120 fprintf(stderr, "\tSI8");
123 fprintf(stderr, " on wrong TC");
126 case GSM48_MT_RR_SYSINFO_9:
127 fprintf(stderr, "\tSI9");
130 fprintf(stderr, " on wrong TC");
133 case GSM48_MT_RR_SYSINFO_13:
134 fprintf(stderr, "\tSI13");
136 if (tc != 4 && tc != 0)
137 fprintf(stderr, " on wrong TC");
140 case GSM48_MT_RR_SYSINFO_16:
141 fprintf(stderr, "\tSI16");
144 fprintf(stderr, " on wrong TC");
147 case GSM48_MT_RR_SYSINFO_17:
148 fprintf(stderr, "\tSI17");
151 fprintf(stderr, " on wrong TC");
154 case GSM48_MT_RR_SYSINFO_2bis:
155 fprintf(stderr, "\tSI2bis");
158 fprintf(stderr, " on wrong TC");
161 case GSM48_MT_RR_SYSINFO_2ter:
162 fprintf(stderr, "\tSI2ter");
164 if (tc != 5 && tc != 4)
165 fprintf(stderr, " on wrong TC");
168 case GSM48_MT_RR_SYSINFO_5bis:
169 fprintf(stderr, "\tSI5bis");
171 case GSM48_MT_RR_SYSINFO_5ter:
172 fprintf(stderr, "\tSI5ter");
175 fprintf(stderr, "\tUnknown SI");
179 fprintf(stderr, "\n");
183 /* send location updating request * (as part of RSLms EST IND /
185 static int gsm48_tx_loc_upd_req(struct osmocom_ms *ms, uint8_t chan_nr)
187 struct msgb *msg = msgb_alloc_headroom(256, 16, "loc_upd_req");
188 struct gsm48_hdr *gh;
189 struct gsm48_loc_upd_req *lu_r;
191 DEBUGP(DMM, "chan_nr=%u\n", chan_nr);
193 msg->l3h = msgb_put(msg, sizeof(*gh));
194 gh = (struct gsm48_hdr *) msg->l3h;
195 gh->proto_discr = GSM48_PDISC_MM;
196 gh->msg_type = GSM48_MT_MM_LOC_UPD_REQUEST;
197 lu_r = (struct gsm48_loc_upd_req *) msgb_put(msg, sizeof(*lu_r));
198 lu_r->type = GSM48_LUPD_IMSI_ATT;
200 /* FIXME: set LAI and CM1 */
204 return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, chan_nr, 0, msg);
207 static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
209 struct gsm48_imm_ass *ia = msgb_l3(msg);
210 uint8_t ch_type, ch_subch, ch_ts;
213 /* Discard packet TBF assignement */
214 if (ia->page_mode & 0xf0)
217 /* FIXME: compare RA and GSM time with when we sent RACH req */
219 rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts);
221 if (!ia->chan_desc.h0.h) {
225 arfcn = ia->chan_desc.h0.arfcn_low | (ia->chan_desc.h0.arfcn_high << 8);
227 DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
228 "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
229 ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
230 ia->chan_desc.h0.tsc);
232 /* request L1 to go to dedicated mode on assigned channel */
233 rv = l1ctl_tx_dm_est_req_h0(ms,
234 arfcn, ia->chan_desc.chan_nr, ia->chan_desc.h0.tsc,
238 uint8_t maio, hsn, ma_len;
239 uint16_t ma[64], arfcn;
242 hsn = ia->chan_desc.h1.hsn;
243 maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high << 2);
245 DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
246 "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
247 ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch,
248 ia->chan_desc.h1.tsc);
250 /* decode mobile allocation */
252 for (i=1, j=0; i<=1024; i++) {
254 if (app_state.cell_arfcns[arfcn].mask & 0x01) {
255 k = ia->mob_alloc_len - (j>>3) - 1;
256 if (ia->mob_alloc[k] & (1 << (j&7))) {
257 ma[ma_len++] = arfcn;
263 /* request L1 to go to dedicated mode on assigned channel */
264 rv = l1ctl_tx_dm_est_req_h1(ms,
265 maio, hsn, ma, ma_len,
266 ia->chan_desc.chan_nr, ia->chan_desc.h1.tsc,
272 rv = gsm48_tx_loc_upd_req(ms, ia->chan_desc.chan_nr);
277 int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
279 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
282 if (sih->rr_protocol_discriminator != GSM48_PDISC_RR)
283 LOGP(DRR, LOGL_ERROR, "PCH pdisc != RR\n");
285 switch (sih->system_information) {
286 case GSM48_MT_RR_PAG_REQ_1:
287 case GSM48_MT_RR_PAG_REQ_2:
288 case GSM48_MT_RR_PAG_REQ_3:
289 /* FIXME: implement decoding of paging request */
291 case GSM48_MT_RR_IMM_ASS:
292 rc = gsm48_rx_imm_ass(msg, ms);
295 LOGP(DRR, LOGL_NOTICE, "unknown PCH/AGCH type 0x%02x\n",
296 sih->system_information);
303 int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms)
305 /* FIXME: we have lost the gsm frame time until here, need to store it
306 * in some msgb context */
307 //dump_bcch(dl->time.tc, ccch->data);
308 dump_bcch(ms, 0, msg->l3h);
310 /* Req channel logic */
311 if (app_state.ccch_enabled && (app_state.rach_count < 2)) {
312 l1ctl_tx_rach_req(ms, app_state.rach_count, 0,
313 app_state.ccch_mode == CCCH_MODE_COMBINED);
314 app_state.rach_count++;
320 void layer3_app_reset(void)
323 app_state.has_si1 = 0;
324 app_state.ccch_mode = CCCH_MODE_NONE;
325 app_state.ccch_enabled = 0;
326 app_state.rach_count = 0;
328 memset(&app_state.cell_arfcns, 0x00, sizeof(app_state.cell_arfcns));