blob: f503684f722ef5373bd657855fee06c4f2a3570a [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>
5 * All Rights Reserved
6 *
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.
11 *
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.
16 *
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.
20 *
21 */
22
23#include <stdio.h>
24#include <errno.h>
25#include <sys/types.h>
26
27#include "gsm_data.h"
28#include "gsm_04_08.h"
29#include "abis_rsl.h"
30#include "debug.h"
31#include "tlv.h"
32
33#define RSL_ALLOC_SIZE 1024
34
35static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
36{
37 /* mask off the transparent bit ? */
38 msg_type &= 0xfe;
39
40 if (msg_type & 0xf0 == 0x00)
41 return ABIS_RSL_MDISC_RLL;
42 if (msg_type & 0xf0 == 0x10) {
43 if (msg_type >= 0x19 && msg_type <= 0x22)
44 return ABIS_RSL_MDISC_TRX;
45 else
46 return ABIS_RSL_MDISC_COM_CHAN;
47 }
48 if (msg_type & 0xc == 0x00)
49 return ABIS_RSL_MDISC_DED_CHAN;
50
51 return ABIS_RSL_MDISC_LOC;
52}
53
54static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
55 u_int8_t msg_type)
56{
57 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
58 dh->c.msg_type = msg_type;
59 dh->ie_chan = RSL_IE_CHAN_NR;
60}
61
62static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
63 u_int8_t msg_type)
64{
65 /* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
66 dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
67 dh->c.msg_type = msg_type;
68 dh->ie_chan = RSL_IE_CHAN_NR;
69 dh->ie_link_id = RSL_IE_LINK_IDENT;
70}
71
72
73/* encode channel number as per Section 9.3.1 */
74u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
75{
76 u_int8_t ret;
77
78 ret = (timeslot & 0x07) | type;
79
80 switch (type) {
81 case RSL_CHAN_Lm_ACCHs:
82 subch &= 0x01;
83 break;
84 case RSL_CHAN_SDCCH4_ACCH:
85 subch &= 0x07;
86 break;
87 case RSL_CHAN_SDCCH8_ACCH:
88 subch &= 0x07;
89 break;
90 default:
91 /* no subchannels allowed */
92 subch = 0x00;
93 break;
94 }
95 ret |= (subch << 3);
96
97 return ret;
98}
99
100/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
101u_int64_t str_to_imsi(const char *imsi_str)
102{
103 u_int64_t ret;
104
105 ret = strtoull(imsi_str, NULL, 10);
106
107 return ret;
108}
109
110/* Table 5 Clause 7 TS 05.02 */
111unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
112{
113 if (!bs_ccch_sdcch_comb)
114 return 9 - bs_ag_blks_res;
115 else
116 return 3 - bs_ag_blks_res;
117}
118
119/* Chapter 6.5.2 of TS 05.02 */
120unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
121 unsigned int n_pag_blocks)
122{
123 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
124}
125
126/* Chapter 6.5.2 of TS 05.02 */
127unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
128 int n_pag_blocks)
129{
130 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
131}
132
133/* Send a BCCH_INFO message as per Chapter 8.5.1 */
134int rsl_bcch_info(struct gsm_bts *bts, u_int8_t type,
135 const u_int8_t *data, int len)
136{
137 struct abis_rsl_dchan_hdr *dh;
138 struct msgb *msg = msgb_alloc(RSL_ALLOC_SIZE);
139
140 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
141 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
142 dh->chan_nr = RSL_CHAN_BCCH;
143
144 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
145 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
146
147 return abis_rsl_sendmsg(bts, msg);
148}
149
150int rsl_sacch_filling(struct gsm_bts *bts, u_int8_t type,
151 const u_int8_t *data, int len)
152{
153 struct abis_rsl_common_hdr *ch;
154 struct msgb *msg = msgb_alloc(RSL_ALLOC_SIZE);
155
156 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
157 ch->msg_discr = ABIS_RSL_MDISC_TRX;
158 ch->msg_type = RSL_MT_SACCH_FILL;
159
160 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
161 msgb_tlv_put(msg, RSL_IE_L3_INFO, len, data);
162
163 return abis_rsl_sendmsg(bts, msg);
164}
165
166/* Chapter 8.4.1 */
167int rsl_chan_activate(struct gsm_bts *bts, u_int8_t chan_nr,
168 u_int8_t act_type,
169 struct rsl_ie_chan_mode *chan_mode,
170 struct rsl_ie_chan_ident *chan_ident,
171 u_int8_t bs_power, u_int8_t ms_power,
172 u_int8_t ta)
173{
174 struct abis_rsl_dchan_hdr *dh;
175 struct msgb *msg = msgb_alloc(RSL_ALLOC_SIZE);
176 u_int8_t encr_info = 0x01;
177
178 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
179 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
180 dh->chan_nr = chan_nr;
181
182 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
183 /* For compatibility with Phase 1 */
184 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
185 (u_int8_t *) chan_mode);
186 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
187 (u_int8_t *) &chan_ident);
188 /* FIXME: this shoould be optional */
189 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
190 (u_int8_t *) &encr_info);
191 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
192 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
193 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
194
195 return abis_rsl_sendmsg(bts, msg);
196}
197
198#define TSC 7
199
200int rsl_chan_activate_tch_f(struct gsm_bts_trx_ts *ts)
201{
202 u_int8_t chan_nr = rsl_enc_chan_nr(RSL_CHAN_Bm_ACCHs, 0, ts->nr);
203 u_int16_t arfcn = ts->trx->arfcn;
204 struct rsl_ie_chan_mode cm;
205 struct rsl_ie_chan_ident ci;
206
207 cm.dtx_dtu = 0;
208 cm.spd_ind = RSL_CMOD_SPD_SPEECH;
209 cm.chan_rt = RSL_CMOD_CRT_TCH_Bm;
210 cm.chan_rate = RSL_CMOD_SP_GSM1;
211
212 ci.chan_desc.iei = 0x64;
213 ci.chan_desc.chan_nr = chan_nr;
214 /* FIXME: this doesn't support hopping */
215 ci.chan_desc.oct3 = (TSC << 5) | ((arfcn & 0x3ff) >> 8);
216 ci.chan_desc.oct4 = arfcn & 0xff;
217#if 0
218 ci.mobile_alloc.tag = 0x72;
219 ci.mobile_alloc.len = 0; /* as per Section 9.3.5 */
220#endif
221
222 return rsl_chan_activate(ts->trx->bts, chan_nr, 0x01, &cm, &ci, 0x01, 0x0f, 0x00);
223}
224
225int rsl_chan_activate_sdcch(struct gsm_bts_trx_ts *ts)
226{
227 u_int8_t chan_nr = rsl_enc_chan_nr(RSL_CHAN_SDCCH4_ACCH, 0, ts->nr);
228 u_int16_t arfcn = ts->trx->arfcn;
229 struct rsl_ie_chan_mode cm;
230 struct rsl_ie_chan_ident ci;
231
232 cm.dtx_dtu = 0x00;
233 cm.spd_ind = RSL_CMOD_SPD_SIGN;
234 cm.chan_rt = RSL_CMOD_CRT_SDCCH;
235 cm.chan_rate = 0x00;
236
237 ci.chan_desc.iei = 0x64;
238 ci.chan_desc.chan_nr = chan_nr;
239 ci.chan_desc.oct3 = (TSC << 5) | ((arfcn & 0x3ff) >> 8);
240 ci.chan_desc.oct4 = arfcn & 0xff;
241
242 /* FIXME: we're sending BS power IE, whcih Abissim doesn't */
243 return rsl_chan_activate(ts->trx->bts, chan_nr, 0x00, &cm, &ci, 0x01, 0x0f, 0x00);
244}
245
246int rsl_chan_release(struct gsm_bts_trx_ts *ts, u_int8_t chan_nr)
247{
248 struct abis_rsl_dchan_hdr *dh;
249 struct msgb *msg = msgb_alloc(RSL_ALLOC_SIZE);
250
251 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
252 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
253 dh->chan_nr = chan_nr;
254
255 return abis_rsl_sendmsg(ts->trx->bts, msg);
256}
257
258int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
259 u_int8_t *ms_ident, u_int8_t chan_needed)
260{
261 struct abis_rsl_dchan_hdr *dh;
262 struct msgb *msg = msgb_alloc(RSL_ALLOC_SIZE);
263
264 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
265 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
266 dh->chan_nr = RSL_CHAN_PCH_AGCH;
267
268 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
269 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len, ms_ident);
270 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
271
272 return abis_rsl_sendmsg(bts, msg);
273}
274
275int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
276{
277 int i, len = strlen(str_in);
278
279 for (i = 0; i < len; i++) {
280 int num = str_in[i] - 0x30;
281 if (num < 0 || num > 9)
282 return -1;
283 if (i % 2 == 0)
284 bcd_out[i/2] = num;
285 else
286 bcd_out[i/2] |= (num << 4);
287 }
288
289 return 0;
290}
291
292# if 0
293int rsl_paging_cmd_imsi(struct gsm_bts *bts, u_int8_t chan_needed, const char *imsi_str)
294{
295 /* FIXME: derive the MS Identity */
296 return rsl_paging_cmd(bts, paging_group, x, y, chan_needed);
297}
298#endif
299
300int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
301{
302 struct msgb *msg = msgb_alloc(RSL_ALLOC_SIZE);
303 struct abis_rsl_dchan_hdr *dh;
304
305 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
306 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
307 dh->chan_nr = RSL_CHAN_PCH_AGCH;
308
309 /* If phase 2, FULL_IMM_ASS_INFO */
310
311 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
312
313 return abis_rsl_sendmsg(bts, msg);
314}
315
316/* Chapter 8.3.1 */
317int rsl_data_request(struct gsm_bts *bts, struct msgb *msg)
318{
319 /* FIXME: prepend RSL header to layer 3 message */
320 u_int8_t len = msg->len;
321 struct abis_rsl_rll_hdr *rh;
322
323 msgb_tv_push(msg, RSL_IE_L3_INFO, len);
324
325 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
326 init_llm_hdr(rh, RSL_MT_DATA_REQ);
327 rh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* FIXME: don't harcode */
328
329 return abis_rsl_sendmsg(bts, msg);
330}
331
332static int abis_rsl_rx_dchan(struct msgb *msg)
333{
334 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
335
336 switch (rslh->msg_type) {
337 case RSL_MT_CHAN_ACTIV_ACK:
338 case RSL_MT_CHAN_ACTIV_NACK:
339 case RSL_MT_CONN_FAIL:
340 case RSL_MT_MEAS_RES:
341 case RSL_MT_MODE_MODIFY_ACK:
342 case RSL_MT_MODE_MODIFY_NACK:
343 case RSL_MT_PHY_CONTEXT_CONF:
344 case RSL_MT_PREPROC_MEAS_RES:
345 case RSL_MT_RF_CHAN_REL_ACK:
346 case RSL_MT_TALKER_DET:
347 case RSL_MT_LISTENER_DET:
348 case RSL_MT_REMOTE_CODEC_CONF_REP:
349 case RSL_MT_MR_CODEC_MOD_ACK:
350 case RSL_MT_MR_CODEC_MOD_NACK:
351 case RSL_MT_MR_CODEC_MOD_PER:
352 fprintf(stderr, "Unimplemented Abis RSL DChan msg 0x%02x\n",
353 rslh->msg_type);
354 break;
355 default:
356 fprintf(stderr, "unknown Abis RSL DChan msg 0x%02x\n",
357 rslh->msg_type);
358 return -EINVAL;
359 }
360}
361
362static int abis_rsl_rx_trx(struct msgb *msg)
363{
364 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
365
366 switch (rslh->msg_type) {
367 case RSL_MT_RF_RES_IND:
368 /* interference on idle channels of TRX */
369 case RSL_MT_OVERLOAD:
370 /* indicate CCCH / ACCH / processor overload */
371 case RSL_MT_ERROR_REPORT:
372 fprintf(stderr, "Unimplemented Abis RSL TRX message type 0x%02x\n",
373 rslh->msg_type);
374 break;
375 default:
376 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
377 rslh->msg_type);
378 return -EINVAL;
379 }
380
381}
382
383static int rsl_rx_chan_rqd(struct msgb *msg)
384{
385 struct gsm_bts *bts = msg->bts_link->bts;
386 struct gsm48_imm_ass ia;
387 u_int16_t arfcn;
388 u_int8_t ts_number, subch;
389
390 /* MS has requested a channel on the RACH */
391 /* parse channel number, request reference, access delay */
392 /* FIXME: check permission/availability */
393 ts_number = 0;
394 arfcn = HARDCODED_ARFCN;
395 subch = 0;
396
397 /* send CHANNEL ACTIVATION on RSL to BTS */
398 rsl_chan_activate_sdcch(&bts->trx[0].ts[ts_number]);
399
400 /* create IMMEDIATE ASSIGN 04.08 messge */
401 memset(&ia, 0, sizeof(ia));
402 ia.l2_plen = 0x2d;
403 ia.proto_discr = GSM48_PDISC_RR;
404 ia.msg_type = GSM48_MT_RR_IMM_ASS;
405 ia.page_mode = GSM48_PM_NORMAL;
406 ia.chan_desc.chan_nr = rsl_enc_chan_nr(RSL_CHAN_SDCCH4_ACCH, subch, ts_number);
407 ia.chan_desc.h0.h = 0;
408 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
409 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
410 ia.chan_desc.h0.tsc = 7;
411 /* FIXME: use real request reference extracted from CHAN_RQD */
412 ia.req_ref.ra = 0x80 | 0x1e;
413 ia.req_ref.t2 = 0x0c;
414 ia.req_ref.t1_ = 0x12;
415 ia.req_ref.t3_low = 0x19 & 3;
416 ia.req_ref.t3_high = 0x19 >> 3;
417 ia.timing_advance = 0;
418 ia.mob_alloc_len = 0;
419
420 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
421 return rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
422}
423
424static int abis_rsl_rx_cchan(struct msgb *msg)
425{
426 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
427 int rc;
428
429 switch (rslh->msg_type) {
430 case RSL_MT_CHAN_RQD:
431 /* MS has requested a channel on the RACH */
432 rc = rsl_rx_chan_rqd(msg);
433 break;
434 case RSL_MT_DELETE_IND:
435 /* CCCH overloaded, IMM_ASSIGN was dropped */
436 case RSL_MT_CBCH_LOAD_IND:
437 /* current load on the CBCH */
438 case RSL_MT_CCCH_LOAD_IND:
439 /* current load on the CCCH */
440 fprintf(stderr, "Unimplemented Abis RSL TRX message type 0x%02x\n",
441 rslh->msg_type);
442 break;
443 default:
444 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
445 rslh->msg_type);
446 return -EINVAL;
447 }
448}
449
450/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
451 0x02, 0x06,
452 0x01, 0x20,
453 0x02, 0x00,
454 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
455
456static int abis_rsl_rx_rll(struct msgb *msg)
457{
458 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
459 int rc;
460
461 switch (rllh->c.msg_type) {
462 case RSL_MT_DATA_IND:
463 DEBUGP(DRLL, "DATA INDICATION\n");
464 /* FIXME: parse L3 info element */
465 rc = gsm0408_rcvmsg(msg);
466 break;
467 case RSL_MT_EST_IND:
468 DEBUGP(DRLL, "ESTABLISH INDICATION\n");
469 /* FIXME: parse L3 info element */
470 rc = gsm0408_rcvmsg(msg);
471 break;
472 case RSL_MT_ERROR_IND:
473 case RSL_MT_REL_IND:
474 case RSL_MT_UNIT_DATA_IND:
475 fprintf(stderr, "unimplemented Abis RLL message type 0x%02x\n",
476 rllh->c.msg_type);
477 break;
478 default:
479 fprintf(stderr, "unknown Abis RLL message type 0x%02x\n",
480 rllh->c.msg_type);
481 }
482}
483
484/* Entry-point where L2 RSL from BTS enters */
485int abis_rsl_rx(struct msgb *msg)
486{
487 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
488 unsigned int l2_len = (void *)msg->tail - msgb_l2(msg);
489 int rc;
490
491 switch (rslh->msg_discr & 0xfe) {
492 case ABIS_RSL_MDISC_RLL:
493 rc = abis_rsl_rx_rll(msg);
494 break;
495 case ABIS_RSL_MDISC_DED_CHAN:
496 rc = abis_rsl_rx_dchan(msg);
497 break;
498 case ABIS_RSL_MDISC_COM_CHAN:
499 case ABIS_RSL_MDISC_TRX:
500 rc = abis_rsl_rx_cchan(msg);
501 break;
502 case ABIS_RSL_MDISC_LOC:
503 default:
504 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
505 rslh->msg_discr);
506 return -EINVAL;
507 }
508}