5 #include <osmocore/msgb.h>
6 #include <osmocore/rsl.h>
7 #include <osmocore/tlv.h>
8 #include <osmocore/protocol/gsm_04_08.h>
10 #include <osmocom/logging.h>
11 #include <osmocom/lapdm.h>
12 #include <osmocom/rslms.h>
13 #include <osmocom/layer3.h>
14 #include <osmocom/osmocom_data.h>
15 #include <osmocom/l1ctl.h>
17 static int ccch_mode = CCCH_MODE_NONE;
19 static void dump_bcch(struct osmocom_ms *ms, uint8_t tc, const uint8_t *data)
21 struct gsm48_system_information_type_header *si_hdr;
22 si_hdr = (struct gsm48_system_information_type_header *) data;
24 /* GSM 05.02 ยง6.3.1.3 Mapping of BCCH data */
25 switch (si_hdr->system_information) {
26 case GSM48_MT_RR_SYSINFO_1:
27 fprintf(stderr, "\tSI1");
30 fprintf(stderr, " on wrong TC");
33 case GSM48_MT_RR_SYSINFO_2:
34 fprintf(stderr, "\tSI2");
37 fprintf(stderr, " on wrong TC");
40 case GSM48_MT_RR_SYSINFO_3:
41 fprintf(stderr, "\tSI3");
43 if (tc != 2 && tc != 6)
44 fprintf(stderr, " on wrong TC");
46 if (ccch_mode == CCCH_MODE_NONE) {
47 struct gsm48_system_information_type_3 *si3 =
48 (struct gsm48_system_information_type_3 *)data;
50 if (si3->control_channel_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C)
51 ccch_mode = CCCH_MODE_COMBINED;
53 ccch_mode = CCCH_MODE_NON_COMBINED;
55 l1ctl_tx_ccch_mode_req(ms, ccch_mode);
58 case GSM48_MT_RR_SYSINFO_4:
59 fprintf(stderr, "\tSI4");
61 if (tc != 3 && tc != 7)
62 fprintf(stderr, " on wrong TC");
65 case GSM48_MT_RR_SYSINFO_5:
66 fprintf(stderr, "\tSI5");
68 case GSM48_MT_RR_SYSINFO_6:
69 fprintf(stderr, "\tSI6");
71 case GSM48_MT_RR_SYSINFO_7:
72 fprintf(stderr, "\tSI7");
75 fprintf(stderr, " on wrong TC");
78 case GSM48_MT_RR_SYSINFO_8:
79 fprintf(stderr, "\tSI8");
82 fprintf(stderr, " on wrong TC");
85 case GSM48_MT_RR_SYSINFO_9:
86 fprintf(stderr, "\tSI9");
89 fprintf(stderr, " on wrong TC");
92 case GSM48_MT_RR_SYSINFO_13:
93 fprintf(stderr, "\tSI13");
95 if (tc != 4 && tc != 0)
96 fprintf(stderr, " on wrong TC");
99 case GSM48_MT_RR_SYSINFO_16:
100 fprintf(stderr, "\tSI16");
103 fprintf(stderr, " on wrong TC");
106 case GSM48_MT_RR_SYSINFO_17:
107 fprintf(stderr, "\tSI17");
110 fprintf(stderr, " on wrong TC");
113 case GSM48_MT_RR_SYSINFO_2bis:
114 fprintf(stderr, "\tSI2bis");
117 fprintf(stderr, " on wrong TC");
120 case GSM48_MT_RR_SYSINFO_2ter:
121 fprintf(stderr, "\tSI2ter");
123 if (tc != 5 && tc != 4)
124 fprintf(stderr, " on wrong TC");
127 case GSM48_MT_RR_SYSINFO_5bis:
128 fprintf(stderr, "\tSI5bis");
130 case GSM48_MT_RR_SYSINFO_5ter:
131 fprintf(stderr, "\tSI5ter");
134 fprintf(stderr, "\tUnknown SI");
138 fprintf(stderr, "\n");
142 /* send location updating request * (as part of RSLms EST IND /
144 static int gsm48_tx_loc_upd_req(struct osmocom_ms *ms, uint8_t chan_nr)
146 struct msgb *msg = msgb_alloc_headroom(256, 16, "loc_upd_req");
147 struct gsm48_hdr *gh;
148 struct gsm48_loc_upd_req *lu_r;
150 DEBUGP(DMM, "chan_nr=%u\n", chan_nr);
152 msg->l3h = msgb_put(msg, sizeof(*gh));
153 gh = (struct gsm48_hdr *) msg->l3h;
154 gh->proto_discr = GSM48_PDISC_MM;
155 gh->msg_type = GSM48_MT_MM_LOC_UPD_REQUEST;
156 lu_r = (struct gsm48_loc_upd_req *) msgb_put(msg, sizeof(*lu_r));
157 lu_r->type = GSM48_LUPD_IMSI_ATT;
159 /* FIXME: set LAI and CM1 */
163 return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, chan_nr, 0, msg);
166 static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
168 struct gsm48_imm_ass *ia = msgb_l3(msg);
169 uint8_t ch_type, ch_subch, ch_ts;
172 rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts);
173 arfcn = ia->chan_desc.h0.arfcn_low | (ia->chan_desc.h0.arfcn_high << 8);
175 DEBUGP(DRR, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
176 "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
177 ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
178 ia->chan_desc.h0.tsc);
180 /* FIXME: compare RA and GSM time with when we sent RACH req */
182 /* check if we can support this type of channel at the moment */
183 if (ch_type != RSL_CHAN_SDCCH4_ACCH || ch_ts != 0 ||
184 ia->chan_desc.h0.h == 1) {
185 DEBUGPC(DRR, "UNSUPPORTED!\n");
189 /* request L1 to go to dedicated mode on assigned channel */
190 tx_ph_dm_est_req_h0(ms, arfcn, ia->chan_desc.chan_nr,
191 ia->chan_desc.h0.tsc);
193 /* request L2 to establish the SAPI0 connection */
194 gsm48_tx_loc_upd_req(ms, ia->chan_desc.chan_nr);
201 int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
203 struct gsm48_system_information_type_header *sih = msgb_l3(msg);
206 if (sih->rr_protocol_discriminator != GSM48_PDISC_RR)
207 LOGP(DRR, LOGL_ERROR, "PCH pdisc != RR\n");
209 switch (sih->system_information) {
210 case GSM48_MT_RR_PAG_REQ_1:
211 case GSM48_MT_RR_PAG_REQ_2:
212 case GSM48_MT_RR_PAG_REQ_3:
213 /* FIXME: implement decoding of paging request */
215 case GSM48_MT_RR_IMM_ASS:
216 rc = gsm48_rx_imm_ass(msg, ms);
219 LOGP(DRR, LOGL_NOTICE, "unknown PCH/AGCH type 0x%02x\n",
220 sih->system_information);
227 int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms)
229 /* FIXME: we have lost the gsm frame time until here, need to store it
230 * in some msgb context */
231 //dump_bcch(dl->time.tc, ccch->data);
232 dump_bcch(ms, 0, msg->l3h);