blob: 047c768084049b6b263c8d678e58d2094983fa42 [file] [log] [blame]
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte59b04682009-06-10 05:40:52 +08002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Weltea22d36b2010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte59b04682009-06-10 05:40:52 +08005 *
6 * 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>
25#include <stdlib.h>
26#include <errno.h>
27#include <sys/types.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30
31#include <openbsc/gsm_data.h>
32#include <openbsc/gsm_04_08.h>
Harald Weltef4625b12010-02-20 16:24:02 +010033#include <osmocore/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080034#include <openbsc/abis_rsl.h>
35#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020036#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080037#include <openbsc/debug.h>
Harald Weltef4625b12010-02-20 16:24:02 +010038#include <osmocore/tlv.h>
Harald Welte59b04682009-06-10 05:40:52 +080039#include <openbsc/paging.h>
40#include <openbsc/signal.h>
Harald Weltec20bd1d2009-11-29 19:07:28 +010041#include <openbsc/meas_rep.h>
Harald Welte50517742009-12-20 15:42:44 +010042#include <openbsc/rtp_proxy.h>
Harald Welte1fa8bac2010-03-01 21:59:06 +010043#include <osmocore/rsl.h>
Harald Welte59b04682009-06-10 05:40:52 +080044
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080045#include <osmocore/talloc.h>
46
Harald Welte59b04682009-06-10 05:40:52 +080047#define RSL_ALLOC_SIZE 1024
48#define RSL_ALLOC_HEADROOM 128
49
50#define MAX(a, b) (a) >= (b) ? (a) : (b)
51
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080052static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
53
Harald Welte59b04682009-06-10 05:40:52 +080054static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
55{
56 /* mask off the transparent bit ? */
57 msg_type &= 0xfe;
58
59 if ((msg_type & 0xf0) == 0x00)
60 return ABIS_RSL_MDISC_RLL;
61 if ((msg_type & 0xf0) == 0x10) {
62 if (msg_type >= 0x19 && msg_type <= 0x22)
63 return ABIS_RSL_MDISC_TRX;
64 else
65 return ABIS_RSL_MDISC_COM_CHAN;
66 }
67 if ((msg_type & 0xe0) == 0x20)
68 return ABIS_RSL_MDISC_DED_CHAN;
69
70 return ABIS_RSL_MDISC_LOC;
71}
72
73static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
74 u_int8_t msg_type)
75{
76 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
77 dh->c.msg_type = msg_type;
78 dh->ie_chan = RSL_IE_CHAN_NR;
79}
80
Harald Welte59b04682009-06-10 05:40:52 +080081/* determine logical channel based on TRX and channel number IE */
82struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
83{
84 struct gsm_lchan *lchan;
85 u_int8_t ts_nr = chan_nr & 0x07;
86 u_int8_t cbits = chan_nr >> 3;
87 u_int8_t lch_idx;
88 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
89
90 if (cbits == 0x01) {
91 lch_idx = 0; /* TCH/F */
Harald Welte37884ed2009-10-24 10:25:50 +020092 if (ts->pchan != GSM_PCHAN_TCH_F &&
93 ts->pchan != GSM_PCHAN_PDCH &&
94 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +010095 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +080096 chan_nr, ts->pchan);
97 } else if ((cbits & 0x1e) == 0x02) {
98 lch_idx = cbits & 0x1; /* TCH/H */
99 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100100 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800101 chan_nr, ts->pchan);
102 } else if ((cbits & 0x1c) == 0x04) {
103 lch_idx = cbits & 0x3; /* SDCCH/4 */
104 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100105 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800106 chan_nr, ts->pchan);
107 } else if ((cbits & 0x18) == 0x08) {
108 lch_idx = cbits & 0x7; /* SDCCH/8 */
109 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100110 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800111 chan_nr, ts->pchan);
112 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
113 lch_idx = 0;
114 if (ts->pchan != GSM_PCHAN_CCCH &&
115 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100116 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800117 chan_nr, ts->pchan);
118 /* FIXME: we should not return first sdcch4 !!! */
119 } else {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100120 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800121 return NULL;
122 }
123
124 lchan = &ts->lchan[lch_idx];
Harald Welte51d2a592010-03-26 21:28:59 +0800125 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800126 if (lchan->conn)
127 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800128
129 return lchan;
130}
131
Holger Hans Peter Freyther942ff172009-10-22 11:47:45 +0200132/* See Table 10.5.25 of GSM04.08 */
Harald Welteb5586242009-12-09 19:18:32 +0100133u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800134{
135 struct gsm_bts_trx_ts *ts = lchan->ts;
136 u_int8_t cbits, chan_nr;
137
138 switch (ts->pchan) {
139 case GSM_PCHAN_TCH_F:
Harald Welte37884ed2009-10-24 10:25:50 +0200140 case GSM_PCHAN_PDCH:
141 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte59b04682009-06-10 05:40:52 +0800142 cbits = 0x01;
143 break;
144 case GSM_PCHAN_TCH_H:
145 cbits = 0x02;
146 cbits += lchan->nr;
147 break;
148 case GSM_PCHAN_CCCH_SDCCH4:
149 cbits = 0x04;
150 cbits += lchan->nr;
151 break;
152 case GSM_PCHAN_SDCCH8_SACCH8C:
153 cbits = 0x08;
154 cbits += lchan->nr;
155 break;
156 default:
157 case GSM_PCHAN_CCCH:
158 cbits = 0x10;
159 break;
160 }
161
162 chan_nr = (cbits << 3) | (ts->nr & 0x7);
163
164 return chan_nr;
165}
166
167/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
168u_int64_t str_to_imsi(const char *imsi_str)
169{
170 u_int64_t ret;
171
172 ret = strtoull(imsi_str, NULL, 10);
173
174 return ret;
175}
176
177/* Table 5 Clause 7 TS 05.02 */
178unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
179{
180 if (!bs_ccch_sdcch_comb)
181 return 9 - bs_ag_blks_res;
182 else
183 return 3 - bs_ag_blks_res;
184}
185
186/* Chapter 6.5.2 of TS 05.02 */
187unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
188 unsigned int n_pag_blocks)
189{
190 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
191}
192
193/* Chapter 6.5.2 of TS 05.02 */
194unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
195 int n_pag_blocks)
196{
197 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
198}
199
200static struct msgb *rsl_msgb_alloc(void)
201{
Harald Welte9cfc9352009-06-26 19:39:35 +0200202 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
203 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800204}
205
206#define MACBLOCK_SIZE 23
207static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
208{
209 memcpy(out, in, len);
210
211 if (len < MACBLOCK_SIZE)
212 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
213}
214
Harald Welted2dd9de2009-08-30 15:37:11 +0900215/* Chapter 9.3.7: Encryption Information */
216static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
217{
218 *out++ = lchan->encr.alg_id & 0xff;
219 if (lchan->encr.key_len)
220 memcpy(out, lchan->encr.key, lchan->encr.key_len);
221 return lchan->encr.key_len + 1;
222}
223
Harald Weltede4477a2009-12-24 12:20:20 +0100224static void print_rsl_cause(int lvl, const u_int8_t *cause_v, u_int8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200225{
Harald Welte59b04682009-06-10 05:40:52 +0800226 int i;
227
Harald Weltede4477a2009-12-24 12:20:20 +0100228 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200229 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200230 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100231 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800232}
233
234/* Send a BCCH_INFO message as per Chapter 8.5.1 */
235int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
236 const u_int8_t *data, int len)
237{
238 struct abis_rsl_dchan_hdr *dh;
239 struct msgb *msg = rsl_msgb_alloc();
240
241 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
242 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
243 dh->chan_nr = RSL_CHAN_BCCH;
244
245 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
246 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
247
248 msg->trx = trx;
249
250 return abis_rsl_sendmsg(msg);
251}
252
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200253int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte59b04682009-06-10 05:40:52 +0800254 const u_int8_t *data, int len)
255{
256 struct abis_rsl_common_hdr *ch;
257 struct msgb *msg = rsl_msgb_alloc();
258
259 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
260 ch->msg_discr = ABIS_RSL_MDISC_TRX;
261 ch->msg_type = RSL_MT_SACCH_FILL;
262
263 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
264 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
265
266 msg->trx = trx;
267
268 return abis_rsl_sendmsg(msg);
269}
270
Harald Welte91afe4c2009-06-20 18:15:19 +0200271int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
272{
273 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200274 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200275 u_int8_t chan_nr = lchan2chan_nr(lchan);
276
277 db = abs(db);
278 if (db > 30)
279 return -EINVAL;
280
Harald Welteed831842009-06-27 03:09:08 +0200281 msg = rsl_msgb_alloc();
282
Harald Welte91afe4c2009-06-20 18:15:19 +0200283 lchan->bs_power = db/2;
284 if (fpc)
285 lchan->bs_power |= 0x10;
286
287 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
288 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
289 dh->chan_nr = chan_nr;
290
291 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
292
293 msg->trx = lchan->ts->trx;
294
295 return abis_rsl_sendmsg(msg);
296}
297
Harald Welte91afe4c2009-06-20 18:15:19 +0200298int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
299{
300 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200301 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200302 u_int8_t chan_nr = lchan2chan_nr(lchan);
303 int ctl_lvl;
304
Harald Weltec4dcda02009-08-09 14:45:18 +0200305 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200306 if (ctl_lvl < 0)
307 return ctl_lvl;
308
Harald Welteed831842009-06-27 03:09:08 +0200309 msg = rsl_msgb_alloc();
310
Harald Welte91afe4c2009-06-20 18:15:19 +0200311 lchan->ms_power = ctl_lvl;
312
313 if (fpc)
314 lchan->ms_power |= 0x20;
315
316 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
317 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
318 dh->chan_nr = chan_nr;
319
320 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
321
322 msg->trx = lchan->ts->trx;
323
324 return abis_rsl_sendmsg(msg);
325}
326
Harald Welte39274f42009-07-29 15:41:29 +0200327static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
328 struct gsm_lchan *lchan)
329{
330 memset(cm, 0, sizeof(cm));
331
332 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther21d63ff2010-09-06 09:25:48 +0800333 if (lchan->ts->trx->bts->network->dtx_enabled)
334 cm->dtx_dtu = 0x03;
335 else
336 cm->dtx_dtu = 0x00;
Harald Welte39274f42009-07-29 15:41:29 +0200337
338 /* set TCH Speech/Data */
339 cm->spd_ind = lchan->rsl_cmode;
340
Harald Welte951e3512009-11-27 08:55:16 +0100341 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
342 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100343 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100344 "but tch_mode != signalling\n");
345
Harald Welte39274f42009-07-29 15:41:29 +0200346 switch (lchan->type) {
347 case GSM_LCHAN_SDCCH:
348 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
349 break;
350 case GSM_LCHAN_TCH_F:
351 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
352 break;
353 case GSM_LCHAN_TCH_H:
354 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
355 break;
356 case GSM_LCHAN_NONE:
357 case GSM_LCHAN_UNKNOWN:
358 default:
359 return -EINVAL;
360 }
361
362 switch (lchan->tch_mode) {
363 case GSM48_CMODE_SIGN:
364 cm->chan_rate = 0;
365 break;
366 case GSM48_CMODE_SPEECH_V1:
367 cm->chan_rate = RSL_CMOD_SP_GSM1;
368 break;
369 case GSM48_CMODE_SPEECH_EFR:
370 cm->chan_rate = RSL_CMOD_SP_GSM2;
371 break;
372 case GSM48_CMODE_SPEECH_AMR:
373 cm->chan_rate = RSL_CMOD_SP_GSM3;
374 break;
375 case GSM48_CMODE_DATA_14k5:
376 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
377 break;
378 case GSM48_CMODE_DATA_12k0:
379 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
380 break;
381 case GSM48_CMODE_DATA_6k0:
382 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
383 break;
384 default:
385 return -EINVAL;
386 }
387
388 return 0;
389}
390
Harald Welte59b04682009-06-10 05:40:52 +0800391/* Chapter 8.4.1 */
392#if 0
393int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
394 u_int8_t act_type,
395 struct rsl_ie_chan_mode *chan_mode,
396 struct rsl_ie_chan_ident *chan_ident,
397 u_int8_t bs_power, u_int8_t ms_power,
398 u_int8_t ta)
399{
400 struct abis_rsl_dchan_hdr *dh;
401 struct msgb *msg = rsl_msgb_alloc();
402
403 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
404 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
405 dh->chan_nr = chan_nr;
406
407 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
408 /* For compatibility with Phase 1 */
409 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
410 (u_int8_t *) chan_mode);
411 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
412 (u_int8_t *) chan_ident);
413#if 0
414 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
415 (u_int8_t *) &encr_info);
416#endif
417 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
418 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
419 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
420
421 msg->trx = trx;
422
423 return abis_rsl_sendmsg(msg);
424}
425#endif
426
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200427int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welteb90d7bd2009-12-17 00:31:10 +0100428 u_int8_t ta, u_int8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800429{
430 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200431 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200432 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200433 uint8_t *len;
Harald Welte59b04682009-06-10 05:40:52 +0800434
435 u_int8_t chan_nr = lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800436 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200437 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800438
Harald Welte39274f42009-07-29 15:41:29 +0200439 rc = channel_mode_from_lchan(&cm, lchan);
440 if (rc < 0)
441 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800442
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800443 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200444 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800445
Harald Welteed831842009-06-27 03:09:08 +0200446 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800447 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
448 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
449 dh->chan_nr = chan_nr;
450
451 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800452 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
453 (u_int8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800454
455 /*
456 * The Channel Identification is needed for Phase1 phones
457 * and it contains the GSM48 Channel Description and the
458 * Mobile Allocation. The GSM 08.58 asks for the Mobile
459 * Allocation to have a length of zero. We are using the
460 * msgb_l3len to calculate the length of both messages.
461 */
laforgef723cf02010-06-20 21:38:19 +0200462 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200463 len = msgb_put(msg, 1);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800464 msgb_tlv_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800465
466 if (lchan->ts->hopping.enabled)
467 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
468 lchan->ts->hopping.ma_data);
469 else
470 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800471
472 /* update the calculated size */
473 msg->l3h = len + 1;
474 *len = msgb_l3len(msg);
475
Harald Welted2dd9de2009-08-30 15:37:11 +0900476 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
477 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
478 rc = build_encr_info(encr_info, lchan);
479 if (rc > 0)
480 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
481 }
482
Harald Welteb90d7bd2009-12-17 00:31:10 +0100483 switch (act_type) {
484 case RSL_ACT_INTER_ASYNC:
485 case RSL_ACT_INTER_SYNC:
486 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
487 break;
488 default:
489 break;
490 }
491
Harald Welte59b04682009-06-10 05:40:52 +0800492 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
493 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
494 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
495
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100496 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
497 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
498 (u_int8_t *) &lchan->mr_conf);
499
Harald Welte59b04682009-06-10 05:40:52 +0800500 msg->trx = lchan->ts->trx;
501
502 return abis_rsl_sendmsg(msg);
503}
504
Harald Welte8e770492009-07-29 11:38:15 +0200505/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800506int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
507{
508 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200509 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200510 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800511
512 u_int8_t chan_nr = lchan2chan_nr(lchan);
513 struct rsl_ie_chan_mode cm;
514
Harald Welte39274f42009-07-29 15:41:29 +0200515 rc = channel_mode_from_lchan(&cm, lchan);
516 if (rc < 0)
517 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800518
Harald Welteed831842009-06-27 03:09:08 +0200519 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800520 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
521 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
522 dh->chan_nr = chan_nr;
523
524 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
525 (u_int8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900526
527 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
528 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
529 rc = build_encr_info(encr_info, lchan);
530 if (rc > 0)
531 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
532 }
533
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100534 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
535 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
536 (u_int8_t *) &lchan->mr_conf);
537 }
538
Harald Welted2dd9de2009-08-30 15:37:11 +0900539 msg->trx = lchan->ts->trx;
540
541 return abis_rsl_sendmsg(msg);
542}
543
544/* Chapter 8.4.6: Send the encryption command with given L3 info */
545int rsl_encryption_cmd(struct msgb *msg)
546{
547 struct abis_rsl_dchan_hdr *dh;
548 struct gsm_lchan *lchan = msg->lchan;
549 u_int8_t chan_nr = lchan2chan_nr(lchan);
550 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut01f1caf2009-09-27 11:13:18 +0200551 u_int8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900552 int rc;
553
554 /* First push the L3 IE tag and length */
555 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
556
557 /* then the link identifier (SAPI0, main sign link) */
558 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
559
560 /* then encryption information */
561 rc = build_encr_info(encr_info, lchan);
562 if (rc <= 0)
563 return rc;
564 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
565
566 /* and finally the DCHAN header */
567 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
568 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
569 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800570
571 msg->trx = lchan->ts->trx;
572
573 return abis_rsl_sendmsg(msg);
574}
575
Harald Welte85a163c2009-08-10 11:43:22 +0200576/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200577int rsl_deact_sacch(struct gsm_lchan *lchan)
578{
579 struct abis_rsl_dchan_hdr *dh;
580 struct msgb *msg = rsl_msgb_alloc();
581
582 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
583 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
584 dh->chan_nr = lchan2chan_nr(lchan);
585
586 msg->lchan = lchan;
587 msg->trx = lchan->ts->trx;
588
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100589 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200590
591 return abis_rsl_sendmsg(msg);
592}
593
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800594static void error_timeout_cb(void *data)
595{
596 struct gsm_lchan *lchan = data;
597 if (lchan->state != LCHAN_S_REL_ERR) {
598 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
599 gsm_lchan_name(lchan), lchan->state);
600 return;
601 }
602
603 /* go back to the none state */
604 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800605 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800606}
607
Harald Welte85a163c2009-08-10 11:43:22 +0200608/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800609static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte59b04682009-06-10 05:40:52 +0800610{
611 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800612 struct msgb *msg;
Harald Welte59b04682009-06-10 05:40:52 +0800613
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800614 if (lchan->state == LCHAN_S_REL_ERR) {
615 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
616 gsm_lchan_name(lchan));
617 return -1;
618 }
619
620 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800621 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
622 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
623 dh->chan_nr = lchan2chan_nr(lchan);
624
625 msg->lchan = lchan;
626 msg->trx = lchan->ts->trx;
627
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800628 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
629
630 if (error) {
631 /*
632 * the nanoBTS sends RLL release indications after the channel release. This can
633 * be a problem when we have reassigned the channel to someone else and then can
634 * not figure out who used this channel.
635 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800636 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800637 lchan->error_timer.data = lchan;
638 lchan->error_timer.cb = error_timeout_cb;
639 bsc_schedule_timer(&lchan->error_timer,
640 msg->trx->bts->network->T3111 + 2, 0);
641 }
Harald Welte59b04682009-06-10 05:40:52 +0800642
Harald Welte85a163c2009-08-10 11:43:22 +0200643 /* BTS will respond by RF CHAN REL ACK */
Harald Welte59b04682009-06-10 05:40:52 +0800644 return abis_rsl_sendmsg(msg);
645}
646
647int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
648 u_int8_t *ms_ident, u_int8_t chan_needed)
649{
650 struct abis_rsl_dchan_hdr *dh;
651 struct msgb *msg = rsl_msgb_alloc();
652
653 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
654 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
655 dh->chan_nr = RSL_CHAN_PCH_AGCH;
656
657 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
658 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
659 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
660
661 msg->trx = bts->c0;
662
663 return abis_rsl_sendmsg(msg);
664}
665
666int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
667 struct gsm_subscriber *subscr)
668{
669#if 0
670 u_int8_t mi[128];
671 unsigned int mi_len;
672 u_int8_t paging_group;
673#endif
674
675 return -1;
676}
677
678int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
679{
680 int i, len = strlen(str_in);
681
682 for (i = 0; i < len; i++) {
683 int num = str_in[i] - 0x30;
684 if (num < 0 || num > 9)
685 return -1;
686 if (i % 2 == 0)
687 bcd_out[i/2] = num;
688 else
689 bcd_out[i/2] |= (num << 4);
690 }
691
692 return 0;
693}
694
695/* Chapter 8.5.6 */
696int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
697{
698 struct msgb *msg = rsl_msgb_alloc();
699 struct abis_rsl_dchan_hdr *dh;
700 u_int8_t buf[MACBLOCK_SIZE];
701
702 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
703 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
704 dh->chan_nr = RSL_CHAN_PCH_AGCH;
705
706 switch (bts->type) {
707 case GSM_BTS_TYPE_BS11:
708 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
709 break;
710 default:
711 /* If phase 2, construct a FULL_IMM_ASS_INFO */
712 pad_macblock(buf, val, len);
713 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
714 break;
715 }
716
717 msg->trx = bts->c0;
718
719 return abis_rsl_sendmsg(msg);
720}
721
Harald Welte4684e632009-08-10 09:51:40 +0200722/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200723int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200724{
725 struct msgb *msg = rsl_msgb_alloc();
726 struct abis_rsl_dchan_hdr *dh;
727
728 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
729 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200730 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte4684e632009-08-10 09:51:40 +0200731 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte12090752009-08-10 10:07:33 +0200732 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200733
Harald Weltede4477a2009-12-24 12:20:20 +0100734 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100735 gsm_lchan_name(lchan), *(u_int8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200736
737 msg->trx = lchan->ts->trx;
738
Harald Welte4684e632009-08-10 09:51:40 +0200739 return abis_rsl_sendmsg(msg);
740}
741
742
Harald Welte59b04682009-06-10 05:40:52 +0800743/* Send "DATA REQUEST" message with given L3 Info payload */
744/* Chapter 8.3.1 */
745int rsl_data_request(struct msgb *msg, u_int8_t link_id)
746{
Harald Welte59b04682009-06-10 05:40:52 +0800747 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100748 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800749 return -EINVAL;
750 }
751
Harald Weltea22d36b2010-03-04 10:33:10 +0100752 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, lchan2chan_nr(msg->lchan),
753 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800754
755 msg->trx = msg->lchan->ts->trx;
756
757 return abis_rsl_sendmsg(msg);
758}
759
Harald Welteed9a5ab2009-08-09 13:47:35 +0200760/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
761/* Chapter 8.3.1 */
762int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
763{
Harald Weltea22d36b2010-03-04 10:33:10 +0100764 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200765
Harald Weltea22d36b2010-03-04 10:33:10 +0100766 msg = rsl_rll_simple(RSL_MT_EST_REQ, lchan2chan_nr(lchan),
767 link_id, 0);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200768 msg->trx = lchan->ts->trx;
769
770 return abis_rsl_sendmsg(msg);
771}
772
Harald Welte0f2e3c12009-08-08 13:15:07 +0200773/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
774 This is what higher layers should call. The BTS then responds with
775 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
776 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
777 lchan_free() */
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800778int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200779{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200780
Harald Weltea22d36b2010-03-04 10:33:10 +0100781 struct msgb *msg;
782
783 msg = rsl_rll_simple(RSL_MT_REL_REQ, lchan2chan_nr(lchan),
784 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800785 /* 0 is normal release, 1 is local end */
786 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200787
Harald Weltec88a4432009-12-29 10:44:17 +0100788 /* FIXME: start some timer in case we don't receive a REL ACK ? */
789
Harald Welte0f2e3c12009-08-08 13:15:07 +0200790 msg->trx = lchan->ts->trx;
791
792 return abis_rsl_sendmsg(msg);
793}
794
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200795int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
796{
797 lchan->state = state;
798 return 0;
799}
800
Harald Welte59b04682009-06-10 05:40:52 +0800801/* Chapter 8.4.2: Channel Activate Acknowledge */
802static int rsl_rx_chan_act_ack(struct msgb *msg)
803{
804 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
805
806 /* BTS has confirmed channel activation, we now need
807 * to assign the activated channel to the MS */
808 if (rslh->ie_chan != RSL_IE_CHAN_NR)
809 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100810
Harald Weltec88a4432009-12-29 10:44:17 +0100811 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100812 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
813 gsm_lchan_name(msg->lchan),
814 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200815 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100816
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800817 if (msg->lchan->rqd_ref) {
818 rsl_send_imm_assignment(msg->lchan);
819 talloc_free(msg->lchan->rqd_ref);
820 msg->lchan->rqd_ref = NULL;
821 msg->lchan->rqd_ta = 0;
822 }
823
Harald Welte6720a432009-11-29 22:45:52 +0100824 dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
825
Harald Welte59b04682009-06-10 05:40:52 +0800826 return 0;
827}
828
829/* Chapter 8.4.3: Channel Activate NACK */
830static int rsl_rx_chan_act_nack(struct msgb *msg)
831{
832 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
833 struct tlv_parsed tp;
834
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100835 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100836 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100837
Harald Welte59b04682009-06-10 05:40:52 +0800838 /* BTS has rejected channel activation ?!? */
839 if (dh->ie_chan != RSL_IE_CHAN_NR)
840 return -EINVAL;
841
842 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100843 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
844 const u_int8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
845 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +0200846 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100847 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200848 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100849 } else
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200850 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200851
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100852 LOGPC(DRSL, LOGL_ERROR, "\n");
853
Harald Welte6720a432009-11-29 22:45:52 +0100854 dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
855
Harald Weltecddb9802009-08-09 19:50:08 +0200856 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800857 return 0;
858}
859
860/* Chapter 8.4.4: Connection Failure Indication */
861static int rsl_rx_conn_fail(struct msgb *msg)
862{
863 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
864 struct tlv_parsed tp;
865
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100866 /* FIXME: print which channel */
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100867 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100868 gsm_lchan_name(msg->lchan));
Harald Welte59b04682009-06-10 05:40:52 +0800869
870 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
871
Harald Weltef1a168d2009-07-28 17:58:09 +0200872 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +0100873 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +0200874 TLVP_LEN(&tp, RSL_IE_CAUSE));
875
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100876 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800877 /* FIXME: only free it after channel release ACK */
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +0200878 counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800879 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800880}
881
Harald Weltec20bd1d2009-11-29 19:07:28 +0100882static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
883 const char *prefix)
884{
Harald Welte0e4fa782009-12-16 16:52:07 +0100885 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
886 prefix, rxlev2dbm(mru->full.rx_lev),
887 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +0100888 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
889 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
890}
891
892static void print_meas_rep(struct gsm_meas_rep *mr)
893{
Harald Welte0e4fa782009-12-16 16:52:07 +0100894 int i;
895
Harald Weltec20bd1d2009-11-29 19:07:28 +0100896 DEBUGP(DMEAS, "MEASUREMENT RESULT NR=%d ", mr->nr);
897
898 if (mr->flags & MEAS_REP_F_DL_DTX)
899 DEBUGPC(DMEAS, "DTXd ");
900
901 print_meas_rep_uni(&mr->ul, "ul");
902 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
903 if (mr->flags & MEAS_REP_F_MS_TO)
904 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
905
906 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +0100907 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100908 DEBUGPC(DMEAS, "L1_FPC=%u ",
909 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
910 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
911 }
912
913 if (mr->flags & MEAS_REP_F_UL_DTX)
914 DEBUGPC(DMEAS, "DTXu ");
915 if (mr->flags & MEAS_REP_F_BA1)
916 DEBUGPC(DMEAS, "BA1 ");
917 if (!(mr->flags & MEAS_REP_F_DL_VALID))
918 DEBUGPC(DMEAS, "NOT VALID ");
919 else
920 print_meas_rep_uni(&mr->dl, "dl");
921
922 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +0100923 if (mr->num_cell == 7)
924 return;
Harald Welte0e4fa782009-12-16 16:52:07 +0100925 for (i = 0; i < mr->num_cell; i++) {
926 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +0100927 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
928 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +0100929 }
Harald Weltec20bd1d2009-11-29 19:07:28 +0100930}
931
Harald Welte59b04682009-06-10 05:40:52 +0800932static int rsl_rx_meas_res(struct msgb *msg)
933{
934 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
935 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +0100936 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100937 u_int8_t len;
938 const u_int8_t *val;
939 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800940
Harald Welte4baa9c52009-12-21 13:27:11 +0100941 /* check if this channel is actually active */
942 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +0100943 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +0800944 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +0100945 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +0100946 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +0100947 }
Harald Welte4baa9c52009-12-21 13:27:11 +0100948
Harald Weltef9476812009-12-15 21:36:05 +0100949 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +0100950 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +0100951
Harald Welte59b04682009-06-10 05:40:52 +0800952 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
953
Harald Weltec20bd1d2009-11-29 19:07:28 +0100954 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
955 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
956 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
957 return -EIO;
958
959 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +0100960 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100961
962 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
963 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
964 if (len >= 3) {
965 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +0100966 mr->flags |= MEAS_REP_F_DL_DTX;
967 mr->ul.full.rx_lev = val[0] & 0x3f;
968 mr->ul.sub.rx_lev = val[1] & 0x3f;
969 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
970 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +0800971 }
Harald Weltec20bd1d2009-11-29 19:07:28 +0100972
Harald Weltef9476812009-12-15 21:36:05 +0100973 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100974
975 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +0800976 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +0100977 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +0100978 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
979
Harald Weltea1467eb2009-06-20 18:44:35 +0200980 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Weltec20bd1d2009-11-29 19:07:28 +0100981 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +0100982 mr->flags |= MEAS_REP_F_MS_L1;
983 mr->ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100984 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +0100985 mr->flags |= MEAS_REP_F_FPC;
986 mr->ms_l1.ta = val[1];
Harald Weltea1467eb2009-06-20 18:44:35 +0200987 }
Harald Welte59b04682009-06-10 05:40:52 +0800988 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther6d0c8b42009-10-22 15:43:55 +0200989 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +0100990 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100991 if (rc < 0)
992 return rc;
993 }
994
Harald Weltef9476812009-12-15 21:36:05 +0100995 print_meas_rep(mr);
Harald Welte59b04682009-06-10 05:40:52 +0800996
Harald Weltef9476812009-12-15 21:36:05 +0100997 dispatch_signal(SS_LCHAN, S_LCHAN_MEAS_REP, mr);
Harald Welte4efcc542009-11-30 19:16:47 +0100998
Harald Welte59b04682009-06-10 05:40:52 +0800999 return 0;
1000}
1001
Harald Welte6720a432009-11-29 22:45:52 +01001002/* Chapter 8.4.7 */
1003static int rsl_rx_hando_det(struct msgb *msg)
1004{
1005 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1006 struct tlv_parsed tp;
1007
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001008 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001009
1010 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1011
1012 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1013 DEBUGPC(DRSL, "access delay = %u\n",
1014 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1015 else
1016 DEBUGPC(DRSL, "\n");
1017
1018 dispatch_signal(SS_LCHAN, S_LCHAN_HANDOVER_DETECT, msg->lchan);
1019
1020 return 0;
1021}
1022
Harald Welte59b04682009-06-10 05:40:52 +08001023static int abis_rsl_rx_dchan(struct msgb *msg)
1024{
1025 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1026 int rc = 0;
1027 char *ts_name;
1028
1029 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001030 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001031
Harald Welte59b04682009-06-10 05:40:52 +08001032 switch (rslh->c.msg_type) {
1033 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001034 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001035 rc = rsl_rx_chan_act_ack(msg);
1036 break;
1037 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001038 rc = rsl_rx_chan_act_nack(msg);
1039 break;
1040 case RSL_MT_CONN_FAIL:
1041 rc = rsl_rx_conn_fail(msg);
1042 break;
1043 case RSL_MT_MEAS_RES:
1044 rc = rsl_rx_meas_res(msg);
1045 break;
Harald Welte6720a432009-11-29 22:45:52 +01001046 case RSL_MT_HANDO_DET:
1047 rc = rsl_rx_hando_det(msg);
1048 break;
Harald Welte59b04682009-06-10 05:40:52 +08001049 case RSL_MT_RF_CHAN_REL_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001050 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", ts_name);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001051 if (msg->lchan->state != LCHAN_S_REL_REQ && msg->lchan->state != LCHAN_S_REL_ERR)
Harald Welteab2534c2009-12-29 10:52:38 +01001052 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
1053 gsm_lchan_name(msg->lchan),
1054 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001055 bsc_del_timer(&msg->lchan->T3111);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001056 /* we have an error timer pending to release that */
1057 if (msg->lchan->state != LCHAN_S_REL_ERR)
1058 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte59b04682009-06-10 05:40:52 +08001059 lchan_free(msg->lchan);
1060 break;
1061 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001062 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001063 break;
1064 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001065 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001066 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001067 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001068 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001069 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001070 break;
1071 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001072 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001073 break;
1074 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001075 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001076 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001077 break;
1078 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001079 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001080 break;
Harald Welte59b04682009-06-10 05:40:52 +08001081 case RSL_MT_PHY_CONTEXT_CONF:
1082 case RSL_MT_PREPROC_MEAS_RES:
1083 case RSL_MT_TALKER_DET:
1084 case RSL_MT_LISTENER_DET:
1085 case RSL_MT_REMOTE_CODEC_CONF_REP:
1086 case RSL_MT_MR_CODEC_MOD_ACK:
1087 case RSL_MT_MR_CODEC_MOD_NACK:
1088 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001089 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1090 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001091 break;
1092 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001093 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1094 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001095 return -EINVAL;
1096 }
1097
1098 return rc;
1099}
1100
1101static int rsl_rx_error_rep(struct msgb *msg)
1102{
1103 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001104 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001105
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001106 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001107
1108 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1109
1110 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001111 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001112 TLVP_LEN(&tp, RSL_IE_CAUSE));
1113
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001114 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001115
1116 return 0;
1117}
1118
1119static int abis_rsl_rx_trx(struct msgb *msg)
1120{
1121 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1122 int rc = 0;
1123
1124 switch (rslh->msg_type) {
1125 case RSL_MT_ERROR_REPORT:
1126 rc = rsl_rx_error_rep(msg);
1127 break;
1128 case RSL_MT_RF_RES_IND:
1129 /* interference on idle channels of TRX */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001130 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001131 break;
1132 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001133 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001134 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
1135 gsm_trx_name(msg->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001136 break;
1137 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001138 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
1139 "type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001140 return -EINVAL;
1141 }
1142 return rc;
1143}
1144
Harald Welte427dbc42009-08-10 00:26:10 +02001145/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1146static void t3101_expired(void *data)
1147{
1148 struct gsm_lchan *lchan = data;
1149
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001150 rsl_rf_chan_release(lchan, 1);
Harald Welte427dbc42009-08-10 00:26:10 +02001151}
1152
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001153/* If T3111 expires, we will send the RF Channel Request */
1154static void t3111_expired(void *data)
1155{
1156 struct gsm_lchan *lchan = data;
1157
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001158 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001159}
1160
laforge50312e82010-06-21 12:08:52 +02001161#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1162
Harald Welte59b04682009-06-10 05:40:52 +08001163/* MS has requested a channel on the RACH */
1164static int rsl_rx_chan_rqd(struct msgb *msg)
1165{
1166 struct gsm_bts *bts = msg->trx->bts;
1167 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1168 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001169 enum gsm_chan_t lctype;
1170 enum gsm_chreq_reason_t chreq_reason;
1171 struct gsm_lchan *lchan;
1172 u_int8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001173 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001174
1175 u_int16_t arfcn;
1176 u_int8_t ts_number, subch;
1177
1178 /* parse request reference to be used in immediate assign */
1179 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1180 return -EINVAL;
1181
1182 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1183
1184 /* parse access delay and use as TA */
1185 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1186 return -EINVAL;
1187 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1188
1189 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1190 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001191 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1192 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001193
Harald Weltebdbb7442009-12-22 19:07:32 +01001194 counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001195
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001196 /*
1197 * We want LOCATION UPDATES to succeed and will assign a TCH
1198 * if we have no SDCCH available.
1199 */
1200 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1201
Harald Welte59b04682009-06-10 05:40:52 +08001202 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001203 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001204 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001205 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001206 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Harald Weltebdbb7442009-12-22 19:07:32 +01001207 counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte59b04682009-06-10 05:40:52 +08001208 /* FIXME: send some kind of reject ?!? */
1209 return -ENOMEM;
1210 }
1211
Harald Weltec88a4432009-12-29 10:44:17 +01001212 if (lchan->state != LCHAN_S_NONE)
1213 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001214 "in state %s\n", gsm_lchan_name(lchan),
1215 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +02001216 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001217
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001218 /* save the RACH data as we need it after the CHAN ACT ACK */
1219 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1220 if (!lchan->rqd_ref) {
1221 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1222 lchan_free(lchan);
1223 return -ENOMEM;
1224 }
1225
1226 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1227 lchan->rqd_ta = rqd_ta;
1228
Harald Welte59b04682009-06-10 05:40:52 +08001229 ts_number = lchan->ts->nr;
1230 arfcn = lchan->ts->trx->arfcn;
1231 subch = lchan->nr;
1232
Harald Welted2dd9de2009-08-30 15:37:11 +09001233 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001234 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001235 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001236 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001237 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001238
1239 /* FIXME: Start another timer or assume the BTS sends a ACK/NACK? */
Harald Welteb90d7bd2009-12-17 00:31:10 +01001240 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001241
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001242 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1243 "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
1244 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1245 rqd_ref->ra);
1246 return 0;
1247}
1248
1249static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1250{
1251 struct gsm_bts *bts = lchan->ts->trx->bts;
1252 u_int8_t buf[GSM_MACBLOCK_LEN];
1253 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1254
Harald Welte59b04682009-06-10 05:40:52 +08001255 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001256 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001257 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001258 ia->proto_discr = GSM48_PDISC_RR;
1259 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1260 ia->page_mode = GSM48_PM_SAME;
1261 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001262
Harald Welte59b04682009-06-10 05:40:52 +08001263 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001264 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1265 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001266 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001267 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001268 } else {
laforgee06d5982010-06-20 15:18:46 +02001269 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1270 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001271 }
Harald Welte07f32182010-06-28 18:41:27 +02001272 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1273 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001274
Harald Welte427dbc42009-08-10 00:26:10 +02001275 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1276 lchan->T3101.cb = t3101_expired;
1277 lchan->T3101.data = lchan;
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +01001278 bsc_schedule_timer(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001279
1280 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001281 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (u_int8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001282}
1283
1284/* MS has requested a channel on the RACH */
1285static int rsl_rx_ccch_load(struct msgb *msg)
1286{
1287 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1288 u_int16_t pg_buf_space;
1289 u_int16_t rach_slot_count = -1;
1290 u_int16_t rach_busy_count = -1;
1291 u_int16_t rach_access_count = -1;
1292
1293 switch (rslh->data[0]) {
1294 case RSL_IE_PAGING_LOAD:
1295 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Harald Welte008a4922010-04-19 10:24:07 +02001296 if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
1297 /* paging load below configured threshold, use 50 as default */
1298 pg_buf_space = 50;
1299 }
Harald Welte59b04682009-06-10 05:40:52 +08001300 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1301 break;
1302 case RSL_IE_RACH_LOAD:
1303 if (msg->data_len >= 7) {
1304 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1305 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1306 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1307 }
1308 break;
1309 default:
1310 break;
1311 }
1312
1313 return 0;
1314}
1315
1316static int abis_rsl_rx_cchan(struct msgb *msg)
1317{
1318 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1319 int rc = 0;
1320
1321 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1322
1323 switch (rslh->c.msg_type) {
1324 case RSL_MT_CHAN_RQD:
1325 /* MS has requested a channel on the RACH */
1326 rc = rsl_rx_chan_rqd(msg);
1327 break;
1328 case RSL_MT_CCCH_LOAD_IND:
1329 /* current load on the CCCH */
1330 rc = rsl_rx_ccch_load(msg);
1331 break;
1332 case RSL_MT_DELETE_IND:
1333 /* CCCH overloaded, IMM_ASSIGN was dropped */
1334 case RSL_MT_CBCH_LOAD_IND:
1335 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001336 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1337 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001338 break;
1339 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001340 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1341 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001342 return -EINVAL;
1343 }
1344
1345 return rc;
1346}
1347
1348static int rsl_rx_rll_err_ind(struct msgb *msg)
1349{
1350 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1351 u_int8_t *rlm_cause = rllh->data;
1352
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001353 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001354 gsm_lchan_name(msg->lchan),
Harald Welteb30935e2010-03-25 12:13:02 +08001355 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteed9a5ab2009-08-09 13:47:35 +02001356
1357 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001358
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001359 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
1360 counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001361 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001362 }
Harald Welte692f5852009-07-04 09:40:05 +02001363
Harald Welte59b04682009-06-10 05:40:52 +08001364 return 0;
1365}
1366
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001367static void rsl_handle_release(struct gsm_lchan *lchan)
1368{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001369 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001370 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001371
1372 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001373 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001374 return;
1375
1376 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1377 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1378 continue;
1379 LOGP(DRSL, LOGL_NOTICE, "%s waiting for SAPI=%d to be released.\n",
1380 gsm_lchan_name(lchan), sapi);
1381 return;
1382 }
1383
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001384
1385
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001386 /* wait a bit to send the RF Channel Release */
1387 lchan->T3111.cb = t3111_expired;
1388 lchan->T3111.data = lchan;
1389 bts = lchan->ts->trx->bts;
1390 bsc_schedule_timer(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001391}
1392
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001393/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001394 0x02, 0x06,
1395 0x01, 0x20,
1396 0x02, 0x00,
1397 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1398
1399static int abis_rsl_rx_rll(struct msgb *msg)
1400{
1401 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1402 int rc = 0;
1403 char *ts_name;
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001404 u_int8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001405
1406 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001407 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001408 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001409
1410 switch (rllh->c.msg_type) {
1411 case RSL_MT_DATA_IND:
1412 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001413 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001414 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1415 rllh->data[0] == RSL_IE_L3_INFO) {
1416 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001417 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001418 }
1419 break;
1420 case RSL_MT_EST_IND:
1421 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001422 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001423 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welte427dbc42009-08-10 00:26:10 +02001424 bsc_del_timer(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001425 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001426 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1427 rllh->data[0] == RSL_IE_L3_INFO) {
1428 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001429 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001430 }
1431 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001432 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001433 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001434 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001435 rll_indication(msg->lchan, rllh->link_id,
1436 BSC_RLLR_IND_EST_CONF);
1437 break;
Harald Welte59b04682009-06-10 05:40:52 +08001438 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001439 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001440 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001441 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001442 rll_indication(msg->lchan, rllh->link_id,
1443 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001444 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001445 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001446 break;
1447 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001448 /* BTS informs us of having received UA from MS,
1449 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001450 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001451 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001452 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001453 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001454 break;
1455 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001456 rc = rsl_rx_rll_err_ind(msg);
1457 break;
1458 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001459 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1460 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001461 break;
1462 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001463 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1464 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001465 }
Harald Welte59b04682009-06-10 05:40:52 +08001466 return rc;
1467}
1468
Harald Welteb284b472009-12-02 01:58:23 +05301469static u_int8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001470{
Harald Welteb284b472009-12-02 01:58:23 +05301471 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001472 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301473 switch (lchan->type) {
1474 case GSM_LCHAN_TCH_F:
1475 return 0x00;
1476 case GSM_LCHAN_TCH_H:
1477 return 0x03;
1478 default:
1479 break;
1480 }
Harald Welte98d79f92009-07-28 18:11:56 +02001481 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301482 switch (lchan->type) {
1483 case GSM_LCHAN_TCH_F:
1484 return 0x01;
1485 /* there's no half-rate EFR */
1486 default:
1487 break;
1488 }
Harald Welte98d79f92009-07-28 18:11:56 +02001489 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301490 switch (lchan->type) {
1491 case GSM_LCHAN_TCH_F:
1492 return 0x02;
1493 case GSM_LCHAN_TCH_H:
1494 return 0x05;
1495 default:
1496 break;
1497 }
1498 default:
1499 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001500 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001501 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301502 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001503 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001504}
1505
Sylvain Munaut1338a552009-12-20 22:06:40 +01001506static u_int8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
1507{
1508 switch (lchan->tch_mode) {
1509 case GSM48_CMODE_SPEECH_V1:
1510 switch (lchan->type) {
1511 case GSM_LCHAN_TCH_F:
1512 return RTP_PT_GSM_FULL;
1513 case GSM_LCHAN_TCH_H:
1514 return RTP_PT_GSM_HALF;
1515 default:
1516 break;
1517 }
1518 case GSM48_CMODE_SPEECH_EFR:
1519 switch (lchan->type) {
1520 case GSM_LCHAN_TCH_F:
1521 return RTP_PT_GSM_EFR;
1522 /* there's no half-rate EFR */
1523 default:
1524 break;
1525 }
1526 case GSM48_CMODE_SPEECH_AMR:
1527 switch (lchan->type) {
1528 case GSM_LCHAN_TCH_F:
1529 return RTP_PT_AMR_FULL;
1530 case GSM_LCHAN_TCH_H:
1531 return RTP_PT_AMR_HALF;
1532 default:
1533 break;
1534 }
1535 default:
1536 break;
1537 }
1538 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1539 "tch_mode == 0x%02x\n & lchan_type == %d",
1540 lchan->tch_mode, lchan->type);
1541 return 0;
1542}
1543
Harald Welte59b04682009-06-10 05:40:52 +08001544/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001545static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1546{
1547 struct in_addr ip;
1548 u_int16_t port, conn_id;
1549
1550 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
1551 ip.s_addr = *((u_int32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
1552 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1553 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1554 }
1555
1556 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
1557 port = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
1558 port = ntohs(port);
1559 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1560 lchan->abis_ip.bound_port = port;
1561 }
1562
1563 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
1564 conn_id = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
1565 conn_id = ntohs(conn_id);
1566 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1567 lchan->abis_ip.conn_id = conn_id;
1568 }
1569
1570 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1571 lchan->abis_ip.rtp_payload2 =
1572 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1573 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1574 lchan->abis_ip.rtp_payload2);
1575 }
1576
1577 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1578 lchan->abis_ip.speech_mode =
1579 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1580 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1581 lchan->abis_ip.speech_mode);
1582 }
1583
1584 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
1585 ip.s_addr = *((u_int32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
1586 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1587 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1588 }
1589
1590 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
1591 port = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
1592 port = ntohs(port);
1593 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1594 lchan->abis_ip.connect_port = port;
1595 }
1596}
1597
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001598int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001599{
1600 struct msgb *msg = rsl_msgb_alloc();
1601 struct abis_rsl_dchan_hdr *dh;
1602
1603 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001604 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001605 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1606 dh->chan_nr = lchan2chan_nr(lchan);
1607
Harald Welte98d79f92009-07-28 18:11:56 +02001608 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001609 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001610 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001611 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001612 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001613
Sylvain Munaut1338a552009-12-20 22:06:40 +01001614 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1615 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1616 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001617
Harald Welte59b04682009-06-10 05:40:52 +08001618 msg->trx = lchan->ts->trx;
1619
1620 return abis_rsl_sendmsg(msg);
1621}
1622
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001623int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Weltebffa4992009-12-19 16:42:06 +01001624 u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001625{
1626 struct msgb *msg = rsl_msgb_alloc();
1627 struct abis_rsl_dchan_hdr *dh;
Harald Weltebffa4992009-12-19 16:42:06 +01001628 u_int32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001629 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001630
1631 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001632 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001633 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1634 dh->chan_nr = lchan2chan_nr(lchan);
1635
Harald Weltebffa4992009-12-19 16:42:06 +01001636 /* we need to store these now as MDCX_ACK does not return them :( */
1637 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1638 lchan->abis_ip.connect_port = port;
1639 lchan->abis_ip.connect_ip = ip;
1640
Harald Weltefb4a9e92009-07-29 12:12:18 +02001641 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001642 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001643 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001644
Harald Welte98d79f92009-07-28 18:11:56 +02001645 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001646 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1647 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1648 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1649 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001650
Harald Weltebffa4992009-12-19 16:42:06 +01001651 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1652 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
1653 att_ip = (u_int32_t *) msgb_put(msg, sizeof(ip));
1654 *att_ip = ia.s_addr;
1655 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1656 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001657 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001658 if (rtp_payload2)
1659 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1660
Harald Welte59b04682009-06-10 05:40:52 +08001661 msg->trx = lchan->ts->trx;
1662
1663 return abis_rsl_sendmsg(msg);
1664}
1665
Harald Welte9947d9f2009-12-20 16:51:09 +01001666/* tell BTS to connect RTP stream to our local RTP socket */
1667int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1668{
1669 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1670 int rc;
1671
1672 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1673 ntohs(rs->rtp.sin_local.sin_port),
1674 /* FIXME: use RTP payload of bound socket, not BTS*/
1675 lchan->abis_ip.rtp_payload2);
1676
1677 return rc;
1678}
1679
Harald Welte2b361522010-03-28 14:42:09 +08001680int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02001681{
1682 struct msgb *msg = rsl_msgb_alloc();
1683 struct abis_rsl_dchan_hdr *dh;
Harald Welte2b361522010-03-28 14:42:09 +08001684 u_int8_t msg_type;
1685
1686 if (act)
1687 msg_type = RSL_MT_IPAC_PDCH_ACT;
1688 else
1689 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welteaed946e2009-10-24 10:29:22 +02001690
1691 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08001692 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02001693 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1694 dh->chan_nr = lchan2chan_nr(lchan);
1695
Harald Welte2b361522010-03-28 14:42:09 +08001696 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_lchan_name(lchan),
1697 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02001698
1699 msg->trx = lchan->ts->trx;
1700
1701 return abis_rsl_sendmsg(msg);
1702}
1703
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001704static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001705{
1706 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1707 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05301708 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001709
1710 /* the BTS has acknowledged a local bind, it now tells us the IP
1711 * address and port number to which it has bound the given logical
1712 * channel */
1713
1714 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1715 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1716 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001717 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001718 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08001719 return -EINVAL;
1720 }
Harald Welte50517742009-12-20 15:42:44 +01001721
Harald Weltebffa4992009-12-19 16:42:06 +01001722 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01001723
1724 /* in case we don't use direct BTS-to-BTS RTP */
1725 if (!ipacc_rtp_direct) {
1726 int rc;
1727 /* the BTS has successfully bound a TCH to a local ip/port,
1728 * which means we can connect our UDP socket to it */
1729 if (lchan->abis_ip.rtp_socket) {
1730 rtp_socket_free(lchan->abis_ip.rtp_socket);
1731 lchan->abis_ip.rtp_socket = NULL;
1732 }
1733
1734 lchan->abis_ip.rtp_socket = rtp_socket_create();
1735 if (!lchan->abis_ip.rtp_socket)
1736 goto out_err;
1737
1738 rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
1739 lchan->abis_ip.bound_ip,
1740 lchan->abis_ip.bound_port);
1741 if (rc < 0)
1742 goto out_err;
1743 }
1744
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001745 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001746
1747 return 0;
Harald Welte50517742009-12-20 15:42:44 +01001748out_err:
1749 return -EIO;
Harald Welte59b04682009-06-10 05:40:52 +08001750}
1751
Harald Weltebffa4992009-12-19 16:42:06 +01001752static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1753{
1754 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1755 struct tlv_parsed tv;
1756 struct gsm_lchan *lchan = msg->lchan;
1757
1758 /* the BTS has acknowledged a remote connect request and
1759 * it now tells us the IP address and port number to which it has
1760 * connected the given logical channel */
1761
1762 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1763 ipac_parse_rtp(lchan, &tv);
1764 dispatch_signal(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
1765
1766 return 0;
1767}
1768
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001769static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001770{
1771 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1772 struct tlv_parsed tv;
Harald Welte50517742009-12-20 15:42:44 +01001773 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001774
1775 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001776
Harald Weltef1a168d2009-07-28 17:58:09 +02001777 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001778 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001779 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001780
Harald Welte50517742009-12-20 15:42:44 +01001781 /* the BTS tells us a RTP stream has been disconnected */
1782 if (lchan->abis_ip.rtp_socket) {
1783 rtp_socket_free(lchan->abis_ip.rtp_socket);
1784 lchan->abis_ip.rtp_socket = NULL;
1785 }
1786
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001787 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001788
Harald Welte59b04682009-06-10 05:40:52 +08001789 return 0;
1790}
1791
1792static int abis_rsl_rx_ipacc(struct msgb *msg)
1793{
1794 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01001795 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08001796 int rc = 0;
1797
1798 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001799 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001800
1801 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001802 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001803 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001804 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001805 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001806 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001807 /* somehow the BTS was unable to bind the lchan to its local
1808 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01001809 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001810 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001811 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001812 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01001813 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01001814 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001815 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001816 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001817 /* somehow the BTS was unable to connect the lchan to a remote
1818 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01001819 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001820 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001821 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01001822 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001823 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001824 break;
1825 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001826 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001827 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001828 break;
1829 }
1830 DEBUGPC(DRSL, "\n");
1831
1832 return rc;
1833}
1834
1835
1836/* Entry-point where L2 RSL from BTS enters */
1837int abis_rsl_rcvmsg(struct msgb *msg)
1838{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001839 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08001840 int rc = 0;
1841
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001842 if (!msg) {
1843 DEBUGP(DRSL, "Empty RSL msg?..\n");
1844 return -1;
1845 }
1846
1847 if (msgb_l2len(msg) < sizeof(*rslh)) {
1848 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
1849 return -1;
1850 }
1851
1852 rslh = msgb_l2(msg);
1853
Harald Welte59b04682009-06-10 05:40:52 +08001854 switch (rslh->msg_discr & 0xfe) {
1855 case ABIS_RSL_MDISC_RLL:
1856 rc = abis_rsl_rx_rll(msg);
1857 break;
1858 case ABIS_RSL_MDISC_DED_CHAN:
1859 rc = abis_rsl_rx_dchan(msg);
1860 break;
1861 case ABIS_RSL_MDISC_COM_CHAN:
1862 rc = abis_rsl_rx_cchan(msg);
1863 break;
1864 case ABIS_RSL_MDISC_TRX:
1865 rc = abis_rsl_rx_trx(msg);
1866 break;
1867 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001868 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001869 rslh->msg_discr);
1870 break;
1871 case ABIS_RSL_MDISC_IPACCESS:
1872 rc = abis_rsl_rx_ipacc(msg);
1873 break;
1874 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001875 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1876 "0x%02x\n", rslh->msg_discr);
Harald Welte59b04682009-06-10 05:40:52 +08001877 return -EINVAL;
1878 }
1879 msgb_free(msg);
1880 return rc;
1881}
1882
Harald Welte59b04682009-06-10 05:40:52 +08001883/* From Table 10.5.33 of GSM 04.08 */
1884int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1885{
Harald Weltea54a2bb2009-12-01 18:04:30 +05301886 if (bts->si_common.chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1887 return MAX(1, (3 - bts->si_common.chan_desc.bs_ag_blks_res))
1888 * (bts->si_common.chan_desc.bs_pa_mfrms + 2);
Harald Welte59b04682009-06-10 05:40:52 +08001889 } else {
Harald Weltea54a2bb2009-12-01 18:04:30 +05301890 return (9 - bts->si_common.chan_desc.bs_ag_blks_res)
1891 * (bts->si_common.chan_desc.bs_pa_mfrms + 2);
Harald Welte59b04682009-06-10 05:40:52 +08001892 }
1893}
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08001894
1895int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1896 uint8_t cb_command, const uint8_t *data, int len)
1897{
1898 struct abis_rsl_dchan_hdr *dh;
1899 struct msgb *cb_cmd;
1900
1901 cb_cmd = rsl_msgb_alloc();
1902 if (!cb_cmd)
1903 return -1;
1904
1905 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1906 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
1907 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
1908
1909 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
1910 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
1911
1912 cb_cmd->trx = bts->c0;
1913
1914 return abis_rsl_sendmsg(cb_cmd);
1915}