blob: 374a45064fc030f680d0eb8a7c50991e78ade039 [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* GSM Radio Signalling Link messages on the A-bis interface
2 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
4/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
Harald Welte8470bf22008-12-25 23:28:35 +00005 *
Harald Welte52b1f982008-12-23 20:25:15 +00006 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
27#include <sys/types.h>
28
Harald Welte8470bf22008-12-25 23:28:35 +000029#include <openbsc/gsm_data.h>
30#include <openbsc/gsm_04_08.h>
31#include <openbsc/abis_rsl.h>
32#include <openbsc/chan_alloc.h>
33#include <openbsc/debug.h>
34#include <openbsc/tlv.h>
Harald Welte52b1f982008-12-23 20:25:15 +000035
Harald Welte8470bf22008-12-25 23:28:35 +000036#define RSL_ALLOC_SIZE 1024
37#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000038
39static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
40{
41 /* mask off the transparent bit ? */
42 msg_type &= 0xfe;
43
Harald Welte8470bf22008-12-25 23:28:35 +000044 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000045 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000046 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000047 if (msg_type >= 0x19 && msg_type <= 0x22)
48 return ABIS_RSL_MDISC_TRX;
49 else
50 return ABIS_RSL_MDISC_COM_CHAN;
51 }
Harald Welte2d5b6382008-12-27 19:46:06 +000052 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000053 return ABIS_RSL_MDISC_DED_CHAN;
54
55 return ABIS_RSL_MDISC_LOC;
56}
57
58static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
59 u_int8_t msg_type)
60{
61 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
62 dh->c.msg_type = msg_type;
63 dh->ie_chan = RSL_IE_CHAN_NR;
64}
65
66static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
67 u_int8_t msg_type)
68{
69 /* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
70 dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
71 dh->c.msg_type = msg_type;
72 dh->ie_chan = RSL_IE_CHAN_NR;
73 dh->ie_link_id = RSL_IE_LINK_IDENT;
74}
75
76
77/* encode channel number as per Section 9.3.1 */
78u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
79{
80 u_int8_t ret;
81
82 ret = (timeslot & 0x07) | type;
83
84 switch (type) {
85 case RSL_CHAN_Lm_ACCHs:
86 subch &= 0x01;
87 break;
88 case RSL_CHAN_SDCCH4_ACCH:
89 subch &= 0x07;
90 break;
91 case RSL_CHAN_SDCCH8_ACCH:
92 subch &= 0x07;
93 break;
94 default:
95 /* no subchannels allowed */
96 subch = 0x00;
97 break;
98 }
99 ret |= (subch << 3);
100
101 return ret;
102}
103
Harald Welte8470bf22008-12-25 23:28:35 +0000104/* determine logical channel based on TRX and channel number IE */
105struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
106{
107 struct gsm_lchan *lchan;
108 u_int8_t ts_nr = chan_nr & 0x07;
109 u_int8_t cbits = chan_nr >> 3;
110 u_int8_t lch_idx;
111 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
112
113 if (cbits == 0x01) {
114 lch_idx = 0; /* TCH/F */
115 if (ts->pchan != GSM_PCHAN_TCH_F)
116 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
117 chan_nr, ts->pchan);
118 } else if ((cbits & 0x1e) == 0x02) {
119 lch_idx = cbits & 0x1; /* TCH/H */
120 if (ts->pchan != GSM_PCHAN_TCH_H)
121 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
122 chan_nr, ts->pchan);
123 } else if ((cbits & 0x1c) == 0x04) {
124 lch_idx = cbits & 0x3; /* SDCCH/4 */
125 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
126 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
127 chan_nr, ts->pchan);
128 } else if ((cbits & 0x18) == 0x08) {
129 lch_idx = cbits & 0x7; /* SDCCH/8 */
130 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
131 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
132 chan_nr, ts->pchan);
133 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
134 lch_idx = 0;
135 if (ts->pchan != GSM_PCHAN_CCCH &&
136 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
137 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
138 chan_nr, ts->pchan);
139 /* FIXME: we should not return first sdcch4 !!! */
140 } else {
141 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
142 return NULL;
143 }
144
145 lchan = &ts->lchan[lch_idx];
146
147 return lchan;
148}
149
150u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
151{
152 struct gsm_bts_trx_ts *ts = lchan->ts;
153 u_int8_t cbits, chan_nr;
154
155 switch (ts->pchan) {
156 case GSM_PCHAN_TCH_F:
157 cbits = 0x01;
158 break;
159 case GSM_PCHAN_TCH_H:
160 cbits = 0x02;
161 cbits += lchan->nr;
162 break;
163 case GSM_PCHAN_CCCH_SDCCH4:
164 cbits = 0x04;
165 cbits += lchan->nr;
166 break;
167 case GSM_PCHAN_SDCCH8_SACCH8C:
168 cbits = 0x08;
169 cbits += lchan->nr;
170 break;
171 default:
172 case GSM_PCHAN_CCCH:
173 cbits = 0x10;
174 break;
175 }
176
177 chan_nr = (cbits << 3) | (ts->nr & 0x7);
178
179 return chan_nr;
180}
181
Harald Welte52b1f982008-12-23 20:25:15 +0000182/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
183u_int64_t str_to_imsi(const char *imsi_str)
184{
185 u_int64_t ret;
186
187 ret = strtoull(imsi_str, NULL, 10);
188
189 return ret;
190}
191
192/* Table 5 Clause 7 TS 05.02 */
193unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
194{
195 if (!bs_ccch_sdcch_comb)
196 return 9 - bs_ag_blks_res;
197 else
198 return 3 - bs_ag_blks_res;
199}
200
201/* Chapter 6.5.2 of TS 05.02 */
202unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
203 unsigned int n_pag_blocks)
204{
205 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
206}
207
208/* Chapter 6.5.2 of TS 05.02 */
209unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
210 int n_pag_blocks)
211{
212 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
213}
214
Harald Welte8470bf22008-12-25 23:28:35 +0000215static struct msgb *rsl_msgb_alloc(void)
216{
217 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM);
218}
219
Harald Welte52b1f982008-12-23 20:25:15 +0000220/* Send a BCCH_INFO message as per Chapter 8.5.1 */
221int rsl_bcch_info(struct gsm_bts *bts, u_int8_t type,
222 const u_int8_t *data, int len)
223{
224 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000225 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000226
227 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
228 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
229 dh->chan_nr = RSL_CHAN_BCCH;
230
231 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
232 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
233
Harald Welte8470bf22008-12-25 23:28:35 +0000234 msg->trx = bts->c0;
235
236 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000237}
238
239int rsl_sacch_filling(struct gsm_bts *bts, u_int8_t type,
240 const u_int8_t *data, int len)
241{
242 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000243 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000244
245 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
246 ch->msg_discr = ABIS_RSL_MDISC_TRX;
247 ch->msg_type = RSL_MT_SACCH_FILL;
248
249 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000250 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000251
Harald Welte8470bf22008-12-25 23:28:35 +0000252 msg->trx = bts->c0;
253
254 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000255}
256
257/* Chapter 8.4.1 */
258int rsl_chan_activate(struct gsm_bts *bts, u_int8_t chan_nr,
259 u_int8_t act_type,
260 struct rsl_ie_chan_mode *chan_mode,
261 struct rsl_ie_chan_ident *chan_ident,
262 u_int8_t bs_power, u_int8_t ms_power,
263 u_int8_t ta)
264{
265 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000266 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000267
268 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
269 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
270 dh->chan_nr = chan_nr;
271
272 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
273 /* For compatibility with Phase 1 */
274 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
275 (u_int8_t *) chan_mode);
276 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Harald Welte702d8702008-12-26 20:25:35 +0000277 (u_int8_t *) chan_ident);
Harald Welte52b1f982008-12-23 20:25:15 +0000278 /* FIXME: this shoould be optional */
Harald Welte702d8702008-12-26 20:25:35 +0000279#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000280 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
281 (u_int8_t *) &encr_info);
282 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte702d8702008-12-26 20:25:35 +0000283#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000284 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
285 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
286
Harald Welte8470bf22008-12-25 23:28:35 +0000287 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000288}
289
290#define TSC 7
291
Harald Welte4b634542008-12-27 01:55:51 +0000292int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type, u_int8_t ta)
293{
294 struct abis_rsl_dchan_hdr *dh;
295 struct msgb *msg = rsl_msgb_alloc();
296 /* FXIME: don't hardcode these!! */
Harald Welte4b634542008-12-27 01:55:51 +0000297 u_int8_t ms_power = 0x0f;
Harald Welte4b634542008-12-27 01:55:51 +0000298
299 u_int8_t chan_nr = lchan2chan_nr(lchan);
300 u_int16_t arfcn = lchan->ts->trx->arfcn;
301 struct rsl_ie_chan_mode cm;
302 struct rsl_ie_chan_ident ci;
303
304 /* FIXME: what to do with data calls ? */
305 cm.dtx_dtu = 0x00;
306 switch (lchan->type) {
307 case GSM_LCHAN_SDCCH:
308 cm.spd_ind = RSL_CMOD_SPD_SIGN;
309 cm.chan_rt = RSL_CMOD_CRT_SDCCH;
310 cm.chan_rate = 0x00;
311 break;
312 case GSM_LCHAN_TCH_F:
313 cm.spd_ind = RSL_CMOD_SPD_SPEECH;
314 cm.chan_rt = RSL_CMOD_CRT_TCH_Bm;
315 cm.chan_rate = 0x11; /* speech coding alg version 2*/
316 break;
Holger Freytherca362a62009-01-04 21:05:01 +0000317 case GSM_LCHAN_TCH_H:
318 DEBUGP(DRSL, "Unimplemented TCH_H activation in %s:%d\n", __FILE__, __LINE__);
319 return -1;
320 case GSM_LCHAN_UNKNOWN:
321 case GSM_LCHAN_NONE:
322 return -1;
Harald Welte4b634542008-12-27 01:55:51 +0000323 }
324
325 ci.chan_desc.iei = 0x64;
326 ci.chan_desc.chan_nr = chan_nr;
327 ci.chan_desc.oct3 = (TSC << 5) | ((arfcn & 0x3ff) >> 8);
328 ci.chan_desc.oct4 = arfcn & 0xff;
329
330 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
331 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
332 dh->chan_nr = chan_nr;
333
334 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
335 /* For compatibility with Phase 1 */
336 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
337 (u_int8_t *) &cm);
338 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
339 (u_int8_t *) &ci);
Holger Freytherca362a62009-01-04 21:05:01 +0000340 /* FIXME: this should be optional */
Harald Welte4b634542008-12-27 01:55:51 +0000341#if 0
342 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
343 (u_int8_t *) &encr_info);
344 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
345#endif
346 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
347 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
348
349 return abis_rsl_sendmsg(msg);
350}
351
Holger Freyther36cbeff2008-12-30 19:15:20 +0000352/* Chapter 9.1.7 of 04.08 */
Harald Welte8470bf22008-12-25 23:28:35 +0000353int rsl_chan_release(struct gsm_lchan *lchan)
Harald Welte52b1f982008-12-23 20:25:15 +0000354{
355 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000356 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000357
358 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
359 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000360 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000361
Harald Welte8470bf22008-12-25 23:28:35 +0000362 msg->lchan = lchan;
363 msg->trx = lchan->ts->trx;
364
Harald Welte2d5b6382008-12-27 19:46:06 +0000365 DEBUGP(DRSL, "Channel Release CMD, chan_nr=0x%02x\n", dh->chan_nr);
366
Harald Welte8470bf22008-12-25 23:28:35 +0000367 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000368}
369
370int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
371 u_int8_t *ms_ident, u_int8_t chan_needed)
372{
373 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000374 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000375
376 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
377 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
378 dh->chan_nr = RSL_CHAN_PCH_AGCH;
379
380 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000381 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000382 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
383
Harald Welte8470bf22008-12-25 23:28:35 +0000384 msg->trx = bts->c0;
385
386 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000387}
388
Holger Freyther7448a532009-01-04 20:18:23 +0000389int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
390 struct gsm_subscriber *subscr)
391{
Holger Freytherca362a62009-01-04 21:05:01 +0000392#if 0
Holger Freyther7448a532009-01-04 20:18:23 +0000393 u_int8_t mi[128];
394 unsigned int mi_len;
395 u_int8_t paging_group;
Holger Freytherca362a62009-01-04 21:05:01 +0000396#endif
Holger Freyther7448a532009-01-04 20:18:23 +0000397
398 return -1;
399}
400
Harald Welte52b1f982008-12-23 20:25:15 +0000401int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
402{
403 int i, len = strlen(str_in);
404
405 for (i = 0; i < len; i++) {
406 int num = str_in[i] - 0x30;
407 if (num < 0 || num > 9)
408 return -1;
409 if (i % 2 == 0)
410 bcd_out[i/2] = num;
411 else
412 bcd_out[i/2] |= (num << 4);
413 }
414
415 return 0;
416}
417
Harald Welte702d8702008-12-26 20:25:35 +0000418/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000419int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
420{
Harald Welte8470bf22008-12-25 23:28:35 +0000421 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000422 struct abis_rsl_dchan_hdr *dh;
423
424 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
425 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
426 dh->chan_nr = RSL_CHAN_PCH_AGCH;
427
428 /* If phase 2, FULL_IMM_ASS_INFO */
429
430 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
431
Harald Welte8470bf22008-12-25 23:28:35 +0000432 msg->trx = bts->c0;
433
434 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000435}
436
Harald Welte8470bf22008-12-25 23:28:35 +0000437/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000438/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000439int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000440{
Harald Welte8470bf22008-12-25 23:28:35 +0000441 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000442 struct abis_rsl_rll_hdr *rh;
443
Harald Welte8470bf22008-12-25 23:28:35 +0000444 if (msg->lchan == NULL) {
445 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
446 return -EINVAL;
447 }
Harald Welte52b1f982008-12-23 20:25:15 +0000448
Harald Welte8470bf22008-12-25 23:28:35 +0000449 /* First push the L3 IE tag and length */
Harald Welte4b634542008-12-27 01:55:51 +0000450 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
Harald Welte8470bf22008-12-25 23:28:35 +0000451
452 /* Then push the RSL header */
Harald Welte52b1f982008-12-23 20:25:15 +0000453 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
454 init_llm_hdr(rh, RSL_MT_DATA_REQ);
Harald Welte8470bf22008-12-25 23:28:35 +0000455 rh->chan_nr = lchan2chan_nr(msg->lchan);
456 rh->link_id = link_id;
Harald Welte52b1f982008-12-23 20:25:15 +0000457
Harald Welte8470bf22008-12-25 23:28:35 +0000458 msg->trx = msg->lchan->ts->trx;
459
460 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000461}
462
Harald Welte702d8702008-12-26 20:25:35 +0000463/* Chapter 8.4.2: Channel Activate Acknowledge */
464static int rsl_rx_chan_act_ack(struct msgb *msg)
465{
466 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
467
468 /* BTS has confirmed channel activation, we now need
469 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000470 if (rslh->ie_chan != RSL_IE_CHAN_NR)
471 return -EINVAL;
472
473 DEBUGP(DRSL, "Channel Activate ACK Channel 0x%02x\n", rslh->chan_nr);
Harald Welte702d8702008-12-26 20:25:35 +0000474
Harald Welte4b634542008-12-27 01:55:51 +0000475 return 0;
476}
Harald Welte702d8702008-12-26 20:25:35 +0000477
Harald Welte4b634542008-12-27 01:55:51 +0000478/* Chapter 8.4.3: Channel Activate NACK */
479static int rsl_rx_chan_act_nack(struct msgb *msg)
480{
481 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
482
483 /* BTS has confirmed channel activation, we now need
484 * to assign the activated channel to the MS */
485 if (rslh->ie_chan != RSL_IE_CHAN_NR)
486 return -EINVAL;
487
488 DEBUGP(DRSL, "Channel Activate NACK Channel 0x%02x\n", rslh->chan_nr);
489
490 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000491}
492
Harald Welte52b1f982008-12-23 20:25:15 +0000493static int abis_rsl_rx_dchan(struct msgb *msg)
494{
Harald Welte8470bf22008-12-25 23:28:35 +0000495 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
496 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000497
Harald Welte8470bf22008-12-25 23:28:35 +0000498 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
499
500 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +0000501 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte4b634542008-12-27 01:55:51 +0000502 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +0000503 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000504 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +0000505 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +0000506 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000507 case RSL_MT_CONN_FAIL:
Harald Welte2d5b6382008-12-27 19:46:06 +0000508 DEBUGP(DRSL, "Connection Fail, release channel\n");
Harald Welte14537e52008-12-27 10:29:08 +0000509 rc = rsl_chan_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +0000510 /* only free it after channel release ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000511 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000512 case RSL_MT_MEAS_RES:
Harald Welte2d5b6382008-12-27 19:46:06 +0000513 DEBUGP(DRSL, "Measurement Result\n");
514 break;
515 case RSL_MT_RF_CHAN_REL_ACK:
516 DEBUGP(DRSL, "RF CHANNEL RELEASE ACK chan_nr=0x%02x\n", rslh->chan_nr);
517 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +0000518 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000519 case RSL_MT_MODE_MODIFY_ACK:
520 case RSL_MT_MODE_MODIFY_NACK:
521 case RSL_MT_PHY_CONTEXT_CONF:
522 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +0000523 case RSL_MT_TALKER_DET:
524 case RSL_MT_LISTENER_DET:
525 case RSL_MT_REMOTE_CODEC_CONF_REP:
526 case RSL_MT_MR_CODEC_MOD_ACK:
527 case RSL_MT_MR_CODEC_MOD_NACK:
528 case RSL_MT_MR_CODEC_MOD_PER:
529 fprintf(stderr, "Unimplemented Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000530 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +0000531 break;
532 default:
533 fprintf(stderr, "unknown Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000534 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +0000535 return -EINVAL;
536 }
Harald Welte8470bf22008-12-25 23:28:35 +0000537 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000538}
539
Harald Welte702d8702008-12-26 20:25:35 +0000540static int rsl_rx_error_rep(struct msgb *msg)
541{
542 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
543 u_int8_t cause_len;
544
545 if (rslh->data[0] != RSL_IE_CAUSE)
546 return -EINVAL;
547
548 cause_len = rslh->data[1];
Harald Welte4b634542008-12-27 01:55:51 +0000549 fprintf(stdout, "RSL ERROR REPORT, Cause ");
Harald Welte702d8702008-12-26 20:25:35 +0000550 hexdump(&rslh->data[2], cause_len);
551
552 return 0;
553}
554
Harald Welte52b1f982008-12-23 20:25:15 +0000555static int abis_rsl_rx_trx(struct msgb *msg)
556{
Harald Welte702d8702008-12-26 20:25:35 +0000557 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +0000558 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000559
560 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +0000561 case RSL_MT_ERROR_REPORT:
562 rc = rsl_rx_error_rep(msg);
563 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000564 case RSL_MT_RF_RES_IND:
565 /* interference on idle channels of TRX */
566 case RSL_MT_OVERLOAD:
567 /* indicate CCCH / ACCH / processor overload */
Holger Freyther342a2c62009-01-27 22:49:48 +0000568 fprintf(stderr, "Overload: Unimplemented Abis RSL TRX message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +0000569 rslh->msg_type);
570 break;
571 default:
572 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
573 rslh->msg_type);
574 return -EINVAL;
575 }
Harald Welte8470bf22008-12-25 23:28:35 +0000576 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000577}
578
Harald Welte8470bf22008-12-25 23:28:35 +0000579/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +0000580static int rsl_rx_chan_rqd(struct msgb *msg)
581{
Harald Welte702d8702008-12-26 20:25:35 +0000582 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +0000583 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
584 struct gsm48_req_ref *rqd_ref;
Harald Welte52b1f982008-12-23 20:25:15 +0000585 struct gsm48_imm_ass ia;
Harald Welte8470bf22008-12-25 23:28:35 +0000586 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +0000587 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +0000588 struct gsm_lchan *lchan;
589 u_int8_t rqd_ta;
Holger Freyther3186bf22008-12-29 06:23:49 +0000590 int ret;
Harald Welte8470bf22008-12-25 23:28:35 +0000591
Harald Welte52b1f982008-12-23 20:25:15 +0000592 u_int16_t arfcn;
593 u_int8_t ts_number, subch;
594
Harald Welte8470bf22008-12-25 23:28:35 +0000595 /* parse request reference to be used in immediate assign */
596 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
597 return -EINVAL;
598
599 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
600
601 /* parse access delay and use as TA */
602 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
603 return -EINVAL;
604 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
605
606 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
607 * request reference RA */
608 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
Harald Welte2cbe0922008-12-29 04:09:31 +0000609 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
610
Harald Welte8470bf22008-12-25 23:28:35 +0000611 /* check availability / allocate channel */
612 lchan = lchan_alloc(bts, lctype);
613 if (!lchan) {
614 fprintf(stderr, "CHAN RQD: no resources\n");
615 /* FIXME: send some kind of reject ?!? */
616 return -ENOMEM;
617 }
618
619 ts_number = lchan->ts->nr;
620 arfcn = lchan->ts->trx->arfcn;
621 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +0000622
Harald Welte4b634542008-12-27 01:55:51 +0000623 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte52b1f982008-12-23 20:25:15 +0000624
625 /* create IMMEDIATE ASSIGN 04.08 messge */
626 memset(&ia, 0, sizeof(ia));
627 ia.l2_plen = 0x2d;
628 ia.proto_discr = GSM48_PDISC_RR;
629 ia.msg_type = GSM48_MT_RR_IMM_ASS;
Harald Welte2d5b6382008-12-27 19:46:06 +0000630 ia.page_mode = GSM48_PM_SAME;
Harald Welte4b634542008-12-27 01:55:51 +0000631 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000632 ia.chan_desc.h0.h = 0;
633 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
634 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
635 ia.chan_desc.h0.tsc = 7;
Harald Welte8470bf22008-12-25 23:28:35 +0000636 /* use request reference extracted from CHAN_RQD */
637 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
638 ia.timing_advance = rqd_ta;
Harald Welte52b1f982008-12-23 20:25:15 +0000639 ia.mob_alloc_len = 0;
640
Harald Welteca64da92009-01-04 16:54:12 +0000641 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s chan_nr=0x%02x r=%s\n",
642 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
643 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason));
Harald Welte75a983f2008-12-27 21:34:06 +0000644
Holger Freyther3186bf22008-12-29 06:23:49 +0000645
Harald Welte52b1f982008-12-23 20:25:15 +0000646 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Freyther3186bf22008-12-29 06:23:49 +0000647 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
648
Harald Welte817f3c82008-12-30 14:57:59 +0000649 return ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000650}
651
Harald Welteea280442009-02-02 22:29:56 +0000652/* MS has requested a channel on the RACH */
653static int rsl_rx_ccch_load(struct msgb *msg)
654{
655 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
656 u_int16_t pg_buf_space;
657
658 switch (rslh->data[0]) {
659 case RSL_IE_PAGING_LOAD:
660 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
661 DEBUGP(DRSL, "CCCH LOAD IND, free paging buffer space: %u\n",
662 pg_buf_space);
663 break;
664 case RSL_IE_RACH_LOAD:
665 DEBUGP(DRSL, "CCCH LOAD IND, RACH Load\n");
666 break;
667 default:
668 break;
669 }
670
671 return 0;
672}
673
Harald Welte52b1f982008-12-23 20:25:15 +0000674static int abis_rsl_rx_cchan(struct msgb *msg)
675{
Harald Welteea280442009-02-02 22:29:56 +0000676 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +0000677 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000678
Harald Welte8470bf22008-12-25 23:28:35 +0000679 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
680
681 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +0000682 case RSL_MT_CHAN_RQD:
683 /* MS has requested a channel on the RACH */
684 rc = rsl_rx_chan_rqd(msg);
685 break;
Harald Welteea280442009-02-02 22:29:56 +0000686 case RSL_MT_CCCH_LOAD_IND:
687 /* current load on the CCCH */
688 rc = rsl_rx_ccch_load(msg);
689 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000690 case RSL_MT_DELETE_IND:
691 /* CCCH overloaded, IMM_ASSIGN was dropped */
692 case RSL_MT_CBCH_LOAD_IND:
693 /* current load on the CBCH */
Harald Welte52b1f982008-12-23 20:25:15 +0000694 fprintf(stderr, "Unimplemented Abis RSL TRX message type 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000695 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +0000696 break;
697 default:
698 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000699 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +0000700 return -EINVAL;
701 }
Harald Welte8470bf22008-12-25 23:28:35 +0000702
703 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000704}
705
Harald Welte4b634542008-12-27 01:55:51 +0000706static int rsl_rx_rll_err_ind(struct msgb *msg)
707{
708 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
709 u_int8_t *rlm_cause = rllh->data;
710
711 DEBUGP(DRLL, "RLL ERROR INDICATION: chan_nr=0x%02x cause=0x%02x\n",
712 rllh->chan_nr, rlm_cause[1]);
713
714 return 0;
715}
Harald Welte52b1f982008-12-23 20:25:15 +0000716/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
717 0x02, 0x06,
718 0x01, 0x20,
719 0x02, 0x00,
720 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
721
722static int abis_rsl_rx_rll(struct msgb *msg)
723{
724 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
725 int rc;
Harald Welte8470bf22008-12-25 23:28:35 +0000726
727 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte52b1f982008-12-23 20:25:15 +0000728
729 switch (rllh->c.msg_type) {
730 case RSL_MT_DATA_IND:
Harald Welte4b634542008-12-27 01:55:51 +0000731 DEBUGP(DRLL, "DATA INDICATION chan_nr=0x%02x\n", rllh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000732 /* FIXME: Verify L3 info element */
Harald Welte702d8702008-12-26 20:25:35 +0000733 msg->l3h = &rllh->data[3];
Harald Welte52b1f982008-12-23 20:25:15 +0000734 rc = gsm0408_rcvmsg(msg);
735 break;
736 case RSL_MT_EST_IND:
Harald Welte4b634542008-12-27 01:55:51 +0000737 DEBUGP(DRLL, "ESTABLISH INDICATION chan_nr=0x%02x\n", rllh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000738 /* FIXME: Verify L3 info element */
Harald Welte702d8702008-12-26 20:25:35 +0000739 msg->l3h = &rllh->data[3];
Harald Welte52b1f982008-12-23 20:25:15 +0000740 rc = gsm0408_rcvmsg(msg);
741 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000742 case RSL_MT_REL_IND:
Harald Welte4b634542008-12-27 01:55:51 +0000743 DEBUGP(DRLL, "RELEASE INDICATION chan_nr=0x%02x\n", rllh->chan_nr);
Harald Welte2d5b6382008-12-27 19:46:06 +0000744 break;
745 case RSL_MT_REL_CONF:
746 DEBUGP(DRLL, "RELEASE CONFIRMATION chan_nr=0x%02x\n", rllh->chan_nr);
Harald Welte4b634542008-12-27 01:55:51 +0000747 break;
748 case RSL_MT_ERROR_IND:
749 rc = rsl_rx_rll_err_ind(msg);
750 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000751 case RSL_MT_UNIT_DATA_IND:
752 fprintf(stderr, "unimplemented Abis RLL message type 0x%02x\n",
753 rllh->c.msg_type);
754 break;
755 default:
756 fprintf(stderr, "unknown Abis RLL message type 0x%02x\n",
757 rllh->c.msg_type);
758 }
Harald Welte8470bf22008-12-25 23:28:35 +0000759 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000760}
761
762/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +0000763int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +0000764{
765 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
Harald Welte52b1f982008-12-23 20:25:15 +0000766 int rc;
767
768 switch (rslh->msg_discr & 0xfe) {
769 case ABIS_RSL_MDISC_RLL:
770 rc = abis_rsl_rx_rll(msg);
771 break;
772 case ABIS_RSL_MDISC_DED_CHAN:
773 rc = abis_rsl_rx_dchan(msg);
774 break;
775 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +0000776 rc = abis_rsl_rx_cchan(msg);
777 break;
Harald Welte8470bf22008-12-25 23:28:35 +0000778 case ABIS_RSL_MDISC_TRX:
779 rc = abis_rsl_rx_trx(msg);
780 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000781 case ABIS_RSL_MDISC_LOC:
782 default:
783 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
784 rslh->msg_discr);
785 return -EINVAL;
786 }
Harald Welte4f4a3902008-12-26 00:04:49 +0000787 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +0000788 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000789}