blob: 5b708aaa633c4beba488ab5f8c4a9aa88d666603 [file] [log] [blame]
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte52b1f982008-12-23 20:25:15 +00002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Welte3c9c5f92010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte8470bf22008-12-25 23:28:35 +00005 *
Harald Welte52b1f982008-12-23 20:25:15 +00006 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
27#include <sys/types.h>
Harald Welte75099262009-02-16 21:12:08 +000028#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000029#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000030
Harald Welte8470bf22008-12-25 23:28:35 +000031#include <openbsc/gsm_data.h>
32#include <openbsc/gsm_04_08.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010033#include <osmocore/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000034#include <openbsc/abis_rsl.h>
35#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020036#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000037#include <openbsc/debug.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010038#include <osmocore/tlv.h>
Holger Freyther392209c2009-02-10 00:06:19 +000039#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000040#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010041#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010042#include <openbsc/rtp_proxy.h>
Harald Welte2e411c72010-03-01 21:59:06 +010043#include <osmocore/rsl.h>
Harald Welte52b1f982008-12-23 20:25:15 +000044
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080045#include <osmocore/talloc.h>
46
Harald Welte8470bf22008-12-25 23:28:35 +000047#define RSL_ALLOC_SIZE 1024
48#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000049
Holger Freyther3b72a892009-02-04 00:31:39 +000050#define MAX(a, b) (a) >= (b) ? (a) : (b)
51
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080052static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
53
Harald Welte52b1f982008-12-23 20:25:15 +000054static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
55{
56 /* mask off the transparent bit ? */
57 msg_type &= 0xfe;
58
Harald Welte8470bf22008-12-25 23:28:35 +000059 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000060 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000061 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000062 if (msg_type >= 0x19 && msg_type <= 0x22)
63 return ABIS_RSL_MDISC_TRX;
64 else
65 return ABIS_RSL_MDISC_COM_CHAN;
66 }
Harald Welte2d5b6382008-12-27 19:46:06 +000067 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000068 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 Welte8470bf22008-12-25 23:28:35 +000081/* 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 Weltea1499d02009-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 Welteb1d4c8e2009-12-17 23:10:46 +010095 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +000096 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 Welteb1d4c8e2009-12-17 23:10:46 +0100100 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000101 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 Welteb1d4c8e2009-12-17 23:10:46 +0100105 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000106 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 Welteb1d4c8e2009-12-17 23:10:46 +0100110 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000111 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 Welteb1d4c8e2009-12-17 23:10:46 +0100116 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000117 chan_nr, ts->pchan);
118 /* FIXME: we should not return first sdcch4 !!! */
119 } else {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100120 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000121 return NULL;
122 }
123
124 lchan = &ts->lchan[lch_idx];
Harald Weltedc5062b2010-03-26 21:28:59 +0800125 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800126 if (lchan->conn)
127 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000128
129 return lchan;
130}
131
Holger Hans Peter Freythere81a6102009-10-22 11:47:45 +0200132/* See Table 10.5.25 of GSM04.08 */
Harald Welte24766092009-12-09 19:18:32 +0100133u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan)
Harald Welte8470bf22008-12-25 23:28:35 +0000134{
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 Weltea1499d02009-10-24 10:25:50 +0200140 case GSM_PCHAN_PDCH:
141 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte8470bf22008-12-25 23:28:35 +0000142 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
Harald Welte52b1f982008-12-23 20:25:15 +0000167/* 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
Harald Welte8470bf22008-12-25 23:28:35 +0000200static struct msgb *rsl_msgb_alloc(void)
201{
Harald Welte966636f2009-06-26 19:39:35 +0200202 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
203 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000204}
205
Harald Welte362322e2009-02-15 14:36:38 +0000206#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 Welte08d91a52009-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 Welte5b8ed432009-12-24 12:20:20 +0100224static void print_rsl_cause(int lvl, const u_int8_t *cause_v, u_int8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200225{
Harald Welte7f93cea2009-02-23 00:02:59 +0000226 int i;
227
Harald Welte5b8ed432009-12-24 12:20:20 +0100228 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200229 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200230 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100231 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000232}
233
Harald Welte52b1f982008-12-23 20:25:15 +0000234/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Harald Weltee79769b2009-02-07 00:48:17 +0000235int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000236 const u_int8_t *data, int len)
237{
238 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000239 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000240
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
Harald Weltee79769b2009-02-07 00:48:17 +0000248 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000249
250 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000251}
252
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200253int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000254 const u_int8_t *data, int len)
255{
256 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000257 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000258
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);
Harald Welte702d8702008-12-26 20:25:35 +0000264 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000265
Harald Weltee79769b2009-02-07 00:48:17 +0000266 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000267
268 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000269}
270
Harald Weltefcd24452009-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 Welteeab33352009-06-27 03:09:08 +0200274 struct msgb *msg;
Harald Weltefcd24452009-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 Welteeab33352009-06-27 03:09:08 +0200281 msg = rsl_msgb_alloc();
282
Harald Weltefcd24452009-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 Weltefcd24452009-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 Welteeab33352009-06-27 03:09:08 +0200301 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200302 u_int8_t chan_nr = lchan2chan_nr(lchan);
303 int ctl_lvl;
304
Harald Welte66b6a8d2009-08-09 14:45:18 +0200305 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200306 if (ctl_lvl < 0)
307 return ctl_lvl;
308
Harald Welteeab33352009-06-27 03:09:08 +0200309 msg = rsl_msgb_alloc();
310
Harald Weltefcd24452009-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 Welte9943c5b2009-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 Freyther5a3a61d2010-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 Welte9943c5b2009-07-29 15:41:29 +0200337
338 /* set TCH Speech/Data */
339 cm->spd_ind = lchan->rsl_cmode;
340
Harald Welte1a79d362009-11-27 08:55:16 +0100341 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
342 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100343 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100344 "but tch_mode != signalling\n");
345
Harald Welte9943c5b2009-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 Welte52b1f982008-12-23 20:25:15 +0000391/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000392#if 0
Harald Weltee79769b2009-02-07 00:48:17 +0000393int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
Harald Welte52b1f982008-12-23 20:25:15 +0000394 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;
Harald Welte8470bf22008-12-25 23:28:35 +0000401 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000402
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,
Harald Welte702d8702008-12-26 20:25:35 +0000412 (u_int8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000413#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000414 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
415 (u_int8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000416#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000417 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000418 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
419 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
420
Harald Weltee79769b2009-02-07 00:48:17 +0000421 msg->trx = trx;
422
Harald Welte8470bf22008-12-25 23:28:35 +0000423 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000424}
Harald Welteddab3c72009-02-28 13:19:15 +0000425#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000426
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200427int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte8d77b952009-12-17 00:31:10 +0100428 u_int8_t ta, u_int8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000429{
430 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200431 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200432 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200433 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000434
435 u_int8_t chan_nr = lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000436 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200437 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000438
Harald Welte9943c5b2009-07-29 15:41:29 +0200439 rc = channel_mode_from_lchan(&cm, lchan);
440 if (rc < 0)
441 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000442
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800443 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200444 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000445
Harald Welteeab33352009-06-27 03:09:08 +0200446 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000447 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 Welte4b634542008-12-27 01:55:51 +0000452 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
453 (u_int8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-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 */
laforge694a5cf2010-06-20 21:38:19 +0200462 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200463 len = msgb_put(msg, 1);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800464 msgb_tlv_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-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 Freythere38bd6c2010-06-30 11:56:43 +0800471
472 /* update the calculated size */
473 msg->l3h = len + 1;
474 *len = msgb_l3len(msg);
475
Harald Welte08d91a52009-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 Welte8d77b952009-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 Welted4c9bf32009-02-15 16:56:18 +0000492 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
493 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000494 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
495
Holger Hans Peter Freyther93b6c652010-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 Weltee79769b2009-02-07 00:48:17 +0000500 msg->trx = lchan->ts->trx;
501
Harald Welte4b634542008-12-27 01:55:51 +0000502 return abis_rsl_sendmsg(msg);
503}
504
Harald Welte470abb72009-07-29 11:38:15 +0200505/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000506int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
507{
508 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200509 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200510 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000511
512 u_int8_t chan_nr = lchan2chan_nr(lchan);
513 struct rsl_ie_chan_mode cm;
514
Harald Welte9943c5b2009-07-29 15:41:29 +0200515 rc = channel_mode_from_lchan(&cm, lchan);
516 if (rc < 0)
517 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000518
Harald Welteeab33352009-06-27 03:09:08 +0200519 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000520 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 Welte08d91a52009-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 Freytherea528022009-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 Welte08d91a52009-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 Munaut82aa6842009-09-27 11:13:18 +0200551 u_int8_t l3_len = msg->len;
Harald Welte08d91a52009-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 Welteda783762009-02-18 03:29:53 +0000570
571 msg->trx = lchan->ts->trx;
572
573 return abis_rsl_sendmsg(msg);
574}
575
Harald Welte115d1032009-08-10 11:43:22 +0200576/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-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)19ef62a2009-12-27 18:16:36 +0100589 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200590
591 return abis_rsl_sendmsg(msg);
592}
593
Holger Hans Peter Freyther4b4dd102010-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 Freyther44752d92010-06-08 11:53:33 +0800605 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800606}
607
Harald Welte115d1032009-08-10 11:43:22 +0200608/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800609static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte52b1f982008-12-23 20:25:15 +0000610{
611 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800612 struct msgb *msg;
Harald Welte52b1f982008-12-23 20:25:15 +0000613
Holger Hans Peter Freyther4b4dd102010-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 Welte52b1f982008-12-23 20:25:15 +0000621 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
622 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000623 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000624
Harald Welte8470bf22008-12-25 23:28:35 +0000625 msg->lchan = lchan;
626 msg->trx = lchan->ts->trx;
627
Holger Hans Peter Freyther4b4dd102010-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 Freyther44752d92010-06-08 11:53:33 +0800636 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-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 Welte2d5b6382008-12-27 19:46:06 +0000642
Harald Welte115d1032009-08-10 11:43:22 +0200643 /* BTS will respond by RF CHAN REL ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000644 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000645}
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;
Harald Welte8470bf22008-12-25 23:28:35 +0000651 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000652
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);
Harald Welte255539c2008-12-28 02:26:27 +0000658 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000659 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
660
Harald Welte8470bf22008-12-25 23:28:35 +0000661 msg->trx = bts->c0;
662
663 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000664}
665
Holger Freyther7448a532009-01-04 20:18:23 +0000666int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
667 struct gsm_subscriber *subscr)
668{
Holger Freytherca362a62009-01-04 21:05:01 +0000669#if 0
Holger Freyther7448a532009-01-04 20:18:23 +0000670 u_int8_t mi[128];
671 unsigned int mi_len;
672 u_int8_t paging_group;
Holger Freytherca362a62009-01-04 21:05:01 +0000673#endif
Holger Freyther7448a532009-01-04 20:18:23 +0000674
675 return -1;
676}
677
Harald Welte52b1f982008-12-23 20:25:15 +0000678int 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
Harald Welte702d8702008-12-26 20:25:35 +0000695/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000696int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
697{
Harald Welte8470bf22008-12-25 23:28:35 +0000698 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000699 struct abis_rsl_dchan_hdr *dh;
Harald Welte362322e2009-02-15 14:36:38 +0000700 u_int8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000701
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
Harald Welte362322e2009-02-15 14:36:38 +0000706 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 }
Harald Welte52b1f982008-12-23 20:25:15 +0000716
Harald Welte8470bf22008-12-25 23:28:35 +0000717 msg->trx = bts->c0;
718
719 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000720}
721
Harald Welte67fa91b2009-08-10 09:51:40 +0200722/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200723int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-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 Welte3c456d02009-08-10 11:26:14 +0200730 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte67fa91b2009-08-10 09:51:40 +0200731 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte31c48932009-08-10 10:07:33 +0200732 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200733
Harald Welte5b8ed432009-12-24 12:20:20 +0100734 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100735 gsm_lchan_name(lchan), *(u_int8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200736
737 msg->trx = lchan->ts->trx;
738
Harald Welte67fa91b2009-08-10 09:51:40 +0200739 return abis_rsl_sendmsg(msg);
740}
741
742
Harald Welte8470bf22008-12-25 23:28:35 +0000743/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000744/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000745int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000746{
Harald Welte8470bf22008-12-25 23:28:35 +0000747 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100748 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000749 return -EINVAL;
750 }
Harald Welte52b1f982008-12-23 20:25:15 +0000751
Harald Welte3c9c5f92010-03-04 10:33:10 +0100752 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, lchan2chan_nr(msg->lchan),
753 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000754
Harald Welte8470bf22008-12-25 23:28:35 +0000755 msg->trx = msg->lchan->ts->trx;
756
757 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000758}
759
Harald Welteedcc5272009-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 Welte3c9c5f92010-03-04 10:33:10 +0100764 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200765
Harald Welte3c9c5f92010-03-04 10:33:10 +0100766 msg = rsl_rll_simple(RSL_MT_EST_REQ, lchan2chan_nr(lchan),
767 link_id, 0);
Harald Welteedcc5272009-08-09 13:47:35 +0200768 msg->trx = lchan->ts->trx;
769
770 return abis_rsl_sendmsg(msg);
771}
772
Harald Welted2dc1de2009-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 Freyther4f5848d2010-06-08 11:57:45 +0800778int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason)
Harald Welted2dc1de2009-08-08 13:15:07 +0200779{
Harald Welted2dc1de2009-08-08 13:15:07 +0200780
Harald Welte3c9c5f92010-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 Freyther4f5848d2010-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 Welted2dc1de2009-08-08 13:15:07 +0200787
Harald Welte8e93b792009-12-29 10:44:17 +0100788 /* FIXME: start some timer in case we don't receive a REL ACK ? */
789
Harald Welted2dc1de2009-08-08 13:15:07 +0200790 msg->trx = lchan->ts->trx;
791
792 return abis_rsl_sendmsg(msg);
793}
794
Holger Hans Peter Freyther74419492010-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 Welte702d8702008-12-26 20:25:35 +0000801/* 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 */
Harald Welte4b634542008-12-27 01:55:51 +0000808 if (rslh->ie_chan != RSL_IE_CHAN_NR)
809 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100810
Harald Welte8e93b792009-12-29 10:44:17 +0100811 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-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 Freyther74419492010-04-10 00:12:31 +0200815 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100816
Holger Hans Peter Freyther5ba05f42010-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 Welted011e8b2009-11-29 22:45:52 +0100824 dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
825
Harald Welte4b634542008-12-27 01:55:51 +0000826 return 0;
827}
Harald Welte702d8702008-12-26 20:25:35 +0000828
Harald Welte4b634542008-12-27 01:55:51 +0000829/* Chapter 8.4.3: Channel Activate NACK */
830static int rsl_rx_chan_act_nack(struct msgb *msg)
831{
Harald Welte6dab0552009-05-01 17:21:37 +0000832 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
833 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000834
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100835 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100836 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100837
Harald Welte6dab0552009-05-01 17:21:37 +0000838 /* BTS has rejected channel activation ?!? */
839 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000840 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000841
842 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-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 Welte8830e072009-07-28 17:58:09 +0200846 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100847 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200848 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100849 } else
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200850 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200851
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100852 LOGPC(DRSL, LOGL_ERROR, "\n");
853
Harald Welted011e8b2009-11-29 22:45:52 +0100854 dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
855
Harald Welte3073a9f2009-08-09 19:50:08 +0200856 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000857 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000858}
859
Harald Welte7f93cea2009-02-23 00:02:59 +0000860/* 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 Welteb1d4c8e2009-12-17 23:10:46 +0100866 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100867 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100868 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000869
870 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
871
Harald Welte8830e072009-07-28 17:58:09 +0200872 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100873 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200874 TLVP_LEN(&tp, RSL_IE_CAUSE));
875
Harald Welte (local)fc057502009-12-26 22:33:09 +0100876 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000877 /* FIXME: only free it after channel release ACK */
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +0200878 counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800879 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte7f93cea2009-02-23 00:02:59 +0000880}
881
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100882static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
883 const char *prefix)
884{
Harald Welte6739dfb2009-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 Welte3c7dc6e2009-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 Welte6739dfb2009-12-16 16:52:07 +0100894 int i;
895
Harald Welte3c7dc6e2009-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 Welte6739dfb2009-12-16 16:52:07 +0100907 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-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 Welte479015b2009-12-19 18:33:05 +0100923 if (mr->num_cell == 7)
924 return;
Harald Welte6739dfb2009-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 Welte303e5e02009-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 Welte6739dfb2009-12-16 16:52:07 +0100929 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100930}
931
Harald Welte440fed02009-05-01 18:43:47 +0000932static 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 Welted12b0fd2009-12-15 21:36:05 +0100936 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100937 u_int8_t len;
938 const u_int8_t *val;
939 int rc;
Harald Welte440fed02009-05-01 18:43:47 +0000940
Harald Welteb8bfc562009-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 Welte8e93b792009-12-29 10:44:17 +0100943 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +0800944 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +0100945 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +0100946 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +0100947 }
Harald Welteb8bfc562009-12-21 13:27:11 +0100948
Harald Welted12b0fd2009-12-15 21:36:05 +0100949 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +0100950 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +0100951
Harald Welte440fed02009-05-01 18:43:47 +0000952 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
953
Harald Welte3c7dc6e2009-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 Welted12b0fd2009-12-15 21:36:05 +0100960 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-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 Welted12b0fd2009-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 Welte440fed02009-05-01 18:43:47 +0000971 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100972
Harald Welted12b0fd2009-12-15 21:36:05 +0100973 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100974
975 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +0000976 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +0100977 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100978 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
979
Harald Weltefe9af262009-06-20 18:44:35 +0200980 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100981 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-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 Welte3c7dc6e2009-11-29 19:07:28 +0100984 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +0100985 mr->flags |= MEAS_REP_F_FPC;
986 mr->ms_l1.ta = val[1];
Harald Weltefe9af262009-06-20 18:44:35 +0200987 }
Harald Weltef7c43522009-06-09 20:24:21 +0000988 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherddd918f2009-10-22 15:43:55 +0200989 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +0100990 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100991 if (rc < 0)
992 return rc;
993 }
994
Harald Welted12b0fd2009-12-15 21:36:05 +0100995 print_meas_rep(mr);
Harald Welte60d68f12009-06-05 20:07:43 +0000996
Harald Welted12b0fd2009-12-15 21:36:05 +0100997 dispatch_signal(SS_LCHAN, S_LCHAN_MEAS_REP, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +0100998
Harald Welte75d34a82009-05-23 06:11:13 +0000999 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001000}
1001
Harald Welted011e8b2009-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)19ef62a2009-12-27 18:16:36 +01001008 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-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 Welte52b1f982008-12-23 20:25:15 +00001023static int abis_rsl_rx_dchan(struct msgb *msg)
1024{
Harald Welte8470bf22008-12-25 23:28:35 +00001025 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1026 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001027 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +00001028
Harald Welte8470bf22008-12-25 23:28:35 +00001029 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001030 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001031
Harald Welte8470bf22008-12-25 23:28:35 +00001032 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001033 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001034 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001035 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001036 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001037 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001038 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001039 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001040 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001041 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001042 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001043 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001044 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001045 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001046 case RSL_MT_HANDO_DET:
1047 rc = rsl_rx_hando_det(msg);
1048 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001049 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001050 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", ts_name);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001051 if (msg->lchan->state != LCHAN_S_REL_REQ && msg->lchan->state != LCHAN_S_REL_ERR)
Harald Welte1887f9d2009-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 Freytherf30c0dc2010-05-31 21:33:15 +08001055 bsc_del_timer(&msg->lchan->T3111);
Holger Hans Peter Freyther4b4dd102010-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 Welte2d5b6382008-12-27 19:46:06 +00001059 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001060 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001061 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001062 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001063 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001064 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001065 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001066 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001067 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001068 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001069 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001070 break;
1071 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001072 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001073 break;
1074 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001075 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001076 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001077 break;
1078 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001079 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001080 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001081 case RSL_MT_PHY_CONTEXT_CONF:
1082 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001083 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 Welte5b8ed432009-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 Welte52b1f982008-12-23 20:25:15 +00001091 break;
1092 default:
Harald Welte5b8ed432009-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 Welte52b1f982008-12-23 20:25:15 +00001095 return -EINVAL;
1096 }
Harald Weltef325eb42009-02-19 17:07:39 +00001097
Harald Welte8470bf22008-12-25 23:28:35 +00001098 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001099}
1100
Harald Welte702d8702008-12-26 20:25:35 +00001101static int rsl_rx_error_rep(struct msgb *msg)
1102{
1103 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001104 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001105
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001106 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
Harald Welte8830e072009-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 Welte5b8ed432009-12-24 12:20:20 +01001111 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001112 TLVP_LEN(&tp, RSL_IE_CAUSE));
1113
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001114 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001115
1116 return 0;
1117}
1118
Harald Welte52b1f982008-12-23 20:25:15 +00001119static int abis_rsl_rx_trx(struct msgb *msg)
1120{
Harald Welte702d8702008-12-26 20:25:35 +00001121 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001122 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001123
1124 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001125 case RSL_MT_ERROR_REPORT:
1126 rc = rsl_rx_error_rep(msg);
1127 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001128 case RSL_MT_RF_RES_IND:
1129 /* interference on idle channels of TRX */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001130 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001131 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001132 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001133 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001134 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
1135 gsm_trx_name(msg->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001136 break;
1137 default:
Harald Welte (local)d48f4eb2009-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 Welte52b1f982008-12-23 20:25:15 +00001140 return -EINVAL;
1141 }
Harald Welte8470bf22008-12-25 23:28:35 +00001142 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001143}
1144
Harald Welteb7e81162009-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 Freyther4b4dd102010-05-31 21:38:24 +08001150 rsl_rf_chan_release(lchan, 1);
Harald Welteb7e81162009-08-10 00:26:10 +02001151}
1152
Holger Hans Peter Freytherf30c0dc2010-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 Freyther4b4dd102010-05-31 21:38:24 +08001158 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001159}
1160
laforgecfa4a012010-06-21 12:08:52 +02001161#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1162
Harald Welte8470bf22008-12-25 23:28:35 +00001163/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001164static int rsl_rx_chan_rqd(struct msgb *msg)
1165{
Harald Welte702d8702008-12-26 20:25:35 +00001166 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001167 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1168 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001169 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001170 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001171 struct gsm_lchan *lchan;
1172 u_int8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001173 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001174
Harald Welte52b1f982008-12-23 20:25:15 +00001175 u_int16_t arfcn;
1176 u_int8_t ts_number, subch;
1177
Harald Welte8470bf22008-12-25 23:28:35 +00001178 /* 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 Freyther78891072010-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 Welte2cbe0922008-12-29 04:09:31 +00001193
Harald Welteffa55a42009-12-22 19:07:32 +01001194 counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001195
Holger Hans Peter Freyther457c2a82010-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 Welte8470bf22008-12-25 23:28:35 +00001202 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001203 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001204 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001205 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001206 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Harald Welteffa55a42009-12-22 19:07:32 +01001207 counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte8470bf22008-12-25 23:28:35 +00001208 /* FIXME: send some kind of reject ?!? */
1209 return -ENOMEM;
1210 }
1211
Harald Welte8e93b792009-12-29 10:44:17 +01001212 if (lchan->state != LCHAN_S_NONE)
1213 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001214 "in state %s\n", gsm_lchan_name(lchan),
1215 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001216 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001217
Holger Hans Peter Freyther5ba05f42010-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 Welte8470bf22008-12-25 23:28:35 +00001229 ts_number = lchan->ts->nr;
1230 arfcn = lchan->ts->trx->arfcn;
1231 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001232
Harald Welte08d91a52009-08-30 15:37:11 +09001233 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001234 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001235 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001236 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001237 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001238
1239 /* FIXME: Start another timer or assume the BTS sends a ACK/NACK? */
Harald Welte8d77b952009-12-17 00:31:10 +01001240 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001241
Holger Hans Peter Freyther5ba05f42010-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 Welte52b1f982008-12-23 20:25:15 +00001255 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001256 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001257 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-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 Weltea39b0f22010-06-14 22:26:10 +02001262
Harald Welte8470bf22008-12-25 23:28:35 +00001263 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-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 Weltea39b0f22010-06-14 22:26:10 +02001266 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001267 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001268 } else {
laforge09108bf2010-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 Weltea39b0f22010-06-14 22:26:10 +02001271 }
Harald Weltea1d39a22010-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 Welte52b1f982008-12-23 20:25:15 +00001274
Harald Welteb7e81162009-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 Freytherc4d88ad2009-11-21 21:18:38 +01001278 bsc_schedule_timer(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001279
Harald Welte52b1f982008-12-23 20:25:15 +00001280 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001281 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (u_int8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001282}
1283
Harald Welteea280442009-02-02 22:29:56 +00001284/* 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;
Holger Freyther8c563cf2009-02-03 20:08:51 +00001289 u_int16_t rach_slot_count = -1;
1290 u_int16_t rach_busy_count = -1;
1291 u_int16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001292
1293 switch (rslh->data[0]) {
1294 case RSL_IE_PAGING_LOAD:
1295 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Harald Welte38e9c822010-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 }
Holger Freyther392209c2009-02-10 00:06:19 +00001300 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001301 break;
1302 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001303 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 }
Harald Welteea280442009-02-02 22:29:56 +00001308 break;
1309 default:
1310 break;
1311 }
1312
1313 return 0;
1314}
1315
Harald Welte52b1f982008-12-23 20:25:15 +00001316static int abis_rsl_rx_cchan(struct msgb *msg)
1317{
Harald Welteea280442009-02-02 22:29:56 +00001318 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001319 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001320
Harald Welte8470bf22008-12-25 23:28:35 +00001321 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1322
1323 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001324 case RSL_MT_CHAN_RQD:
1325 /* MS has requested a channel on the RACH */
1326 rc = rsl_rx_chan_rqd(msg);
1327 break;
Harald Welteea280442009-02-02 22:29:56 +00001328 case RSL_MT_CCCH_LOAD_IND:
1329 /* current load on the CCCH */
1330 rc = rsl_rx_ccch_load(msg);
1331 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001332 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 Welteb1d4c8e2009-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 Welte52b1f982008-12-23 20:25:15 +00001338 break;
1339 default:
Harald Welteb1d4c8e2009-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 Welte52b1f982008-12-23 20:25:15 +00001342 return -EINVAL;
1343 }
Harald Welte8470bf22008-12-25 23:28:35 +00001344
1345 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001346}
1347
Harald Welte4b634542008-12-27 01:55:51 +00001348static 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)9538efc2009-12-26 23:55:00 +01001353 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001354 gsm_lchan_name(msg->lchan),
Harald Weltee95daf12010-03-25 12:13:02 +08001355 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteedcc5272009-08-09 13:47:35 +02001356
1357 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001358
Holger Hans Peter Freyther3ba36d52010-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 Freyther4b4dd102010-05-31 21:38:24 +08001361 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001362 }
Harald Welte81543bc2009-07-04 09:40:05 +02001363
Harald Welte4b634542008-12-27 01:55:51 +00001364 return 0;
1365}
Harald Weltef325eb42009-02-19 17:07:39 +00001366
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001367static void rsl_handle_release(struct gsm_lchan *lchan)
1368{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001369 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001370 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001371
1372 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001373 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-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 Freytherd7fd3062010-04-08 22:47:44 +02001384
1385
Holger Hans Peter Freytherf30c0dc2010-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 Freytherdbc5fae2010-04-08 22:39:34 +02001391}
1392
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001393/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001394 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);
Harald Weltef325eb42009-02-19 17:07:39 +00001402 int rc = 0;
1403 char *ts_name;
Harald Welte (local)daef6062009-08-14 11:41:12 +02001404 u_int8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001405
1406 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001407 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001408 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001409
1410 switch (rllh->c.msg_type) {
1411 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001412 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001413 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001414 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)daef6062009-08-14 11:41:12 +02001417 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001418 }
Harald Welte52b1f982008-12-23 20:25:15 +00001419 break;
1420 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001421 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001422 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001423 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welteb7e81162009-08-10 00:26:10 +02001424 bsc_del_timer(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001425 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001426 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)daef6062009-08-14 11:41:12 +02001429 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001430 }
Harald Welte52b1f982008-12-23 20:25:15 +00001431 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001432 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001433 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001434 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001435 rll_indication(msg->lchan, rllh->link_id,
1436 BSC_RLLR_IND_EST_CONF);
1437 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001438 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001439 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001440 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001441 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001442 rll_indication(msg->lchan, rllh->link_id,
1443 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001444 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001445 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte2d5b6382008-12-27 19:46:06 +00001446 break;
1447 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-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 Welte602f2b82009-08-04 02:50:21 +02001450 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001451 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001452 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001453 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte4b634542008-12-27 01:55:51 +00001454 break;
1455 case RSL_MT_ERROR_IND:
1456 rc = rsl_rx_rll_err_ind(msg);
1457 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001458 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001459 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1460 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001461 break;
1462 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001463 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1464 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001465 }
Harald Welte8470bf22008-12-25 23:28:35 +00001466 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001467}
1468
Harald Welte0603c9d2009-12-02 01:58:23 +05301469static u_int8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001470{
Harald Welte0603c9d2009-12-02 01:58:23 +05301471 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001472 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-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 Weltef4e79f22009-07-28 18:11:56 +02001481 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-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 Weltef4e79f22009-07-28 18:11:56 +02001489 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-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 Weltef4e79f22009-07-28 18:11:56 +02001500 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001501 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301502 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001503 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001504}
1505
Sylvain Munautb54dda42009-12-20 22:06:40 +01001506static u_int8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
1507{
Holger Hans Peter Freyther8cc59032010-11-14 21:09:08 +01001508 struct gsm_network *net = lchan->ts->trx->bts->network;
1509
1510 /* allow to hardcode the rtp payload */
1511 if (net->hardcoded_rtp_payload != 0)
1512 return net->hardcoded_rtp_payload;
1513
Sylvain Munautb54dda42009-12-20 22:06:40 +01001514 switch (lchan->tch_mode) {
1515 case GSM48_CMODE_SPEECH_V1:
1516 switch (lchan->type) {
1517 case GSM_LCHAN_TCH_F:
1518 return RTP_PT_GSM_FULL;
1519 case GSM_LCHAN_TCH_H:
1520 return RTP_PT_GSM_HALF;
1521 default:
1522 break;
1523 }
1524 case GSM48_CMODE_SPEECH_EFR:
1525 switch (lchan->type) {
1526 case GSM_LCHAN_TCH_F:
1527 return RTP_PT_GSM_EFR;
1528 /* there's no half-rate EFR */
1529 default:
1530 break;
1531 }
1532 case GSM48_CMODE_SPEECH_AMR:
1533 switch (lchan->type) {
1534 case GSM_LCHAN_TCH_F:
1535 return RTP_PT_AMR_FULL;
1536 case GSM_LCHAN_TCH_H:
1537 return RTP_PT_AMR_HALF;
1538 default:
1539 break;
1540 }
1541 default:
1542 break;
1543 }
1544 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1545 "tch_mode == 0x%02x\n & lchan_type == %d",
1546 lchan->tch_mode, lchan->type);
1547 return 0;
1548}
1549
Harald Welte75099262009-02-16 21:12:08 +00001550/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001551static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1552{
1553 struct in_addr ip;
1554 u_int16_t port, conn_id;
1555
1556 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
1557 ip.s_addr = *((u_int32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
1558 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1559 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1560 }
1561
1562 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
1563 port = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
1564 port = ntohs(port);
1565 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1566 lchan->abis_ip.bound_port = port;
1567 }
1568
1569 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
1570 conn_id = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
1571 conn_id = ntohs(conn_id);
1572 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1573 lchan->abis_ip.conn_id = conn_id;
1574 }
1575
1576 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1577 lchan->abis_ip.rtp_payload2 =
1578 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1579 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1580 lchan->abis_ip.rtp_payload2);
1581 }
1582
1583 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1584 lchan->abis_ip.speech_mode =
1585 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1586 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1587 lchan->abis_ip.speech_mode);
1588 }
1589
1590 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
1591 ip.s_addr = *((u_int32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
1592 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1593 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1594 }
1595
1596 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
1597 port = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
1598 port = ntohs(port);
1599 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1600 lchan->abis_ip.connect_port = port;
1601 }
1602}
1603
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001604int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001605{
1606 struct msgb *msg = rsl_msgb_alloc();
1607 struct abis_rsl_dchan_hdr *dh;
1608
1609 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001610 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001611 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1612 dh->chan_nr = lchan2chan_nr(lchan);
1613
Harald Weltef4e79f22009-07-28 18:11:56 +02001614 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001615 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001616 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001617 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001618 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001619
Sylvain Munautb54dda42009-12-20 22:06:40 +01001620 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1621 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1622 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001623
Harald Welte75099262009-02-16 21:12:08 +00001624 msg->trx = lchan->ts->trx;
1625
1626 return abis_rsl_sendmsg(msg);
1627}
1628
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001629int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Welte5e3d91b2009-12-19 16:42:06 +01001630 u_int8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001631{
1632 struct msgb *msg = rsl_msgb_alloc();
1633 struct abis_rsl_dchan_hdr *dh;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001634 u_int32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001635 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001636
1637 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001638 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001639 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1640 dh->chan_nr = lchan2chan_nr(lchan);
1641
Harald Welte5e3d91b2009-12-19 16:42:06 +01001642 /* we need to store these now as MDCX_ACK does not return them :( */
1643 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1644 lchan->abis_ip.connect_port = port;
1645 lchan->abis_ip.connect_ip = ip;
1646
Harald Welte58ca5b72009-07-29 12:12:18 +02001647 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001648 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001649 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001650
Harald Weltef4e79f22009-07-28 18:11:56 +02001651 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001652 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1653 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1654 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1655 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001656
Harald Welte5e3d91b2009-12-19 16:42:06 +01001657 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1658 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
1659 att_ip = (u_int32_t *) msgb_put(msg, sizeof(ip));
1660 *att_ip = ia.s_addr;
1661 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1662 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001663 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001664 if (rtp_payload2)
1665 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1666
Harald Welte75099262009-02-16 21:12:08 +00001667 msg->trx = lchan->ts->trx;
1668
1669 return abis_rsl_sendmsg(msg);
1670}
1671
Harald Weltea72273e2009-12-20 16:51:09 +01001672/* tell BTS to connect RTP stream to our local RTP socket */
1673int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1674{
1675 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1676 int rc;
1677
1678 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1679 ntohs(rs->rtp.sin_local.sin_port),
1680 /* FIXME: use RTP payload of bound socket, not BTS*/
1681 lchan->abis_ip.rtp_payload2);
1682
1683 return rc;
1684}
1685
Harald Welte4563eab2010-03-28 14:42:09 +08001686int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001687{
1688 struct msgb *msg = rsl_msgb_alloc();
1689 struct abis_rsl_dchan_hdr *dh;
Harald Welte4563eab2010-03-28 14:42:09 +08001690 u_int8_t msg_type;
1691
1692 if (act)
1693 msg_type = RSL_MT_IPAC_PDCH_ACT;
1694 else
1695 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001696
1697 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001698 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001699 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1700 dh->chan_nr = lchan2chan_nr(lchan);
1701
Harald Welte4563eab2010-03-28 14:42:09 +08001702 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_lchan_name(lchan),
1703 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001704
1705 msg->trx = lchan->ts->trx;
1706
1707 return abis_rsl_sendmsg(msg);
1708}
1709
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001710static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001711{
1712 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1713 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301714 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001715
1716 /* the BTS has acknowledged a local bind, it now tells us the IP
1717 * address and port number to which it has bound the given logical
1718 * channel */
1719
1720 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1721 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1722 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001723 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001724 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001725 return -EINVAL;
1726 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001727
Harald Welte5e3d91b2009-12-19 16:42:06 +01001728 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001729
1730 /* in case we don't use direct BTS-to-BTS RTP */
1731 if (!ipacc_rtp_direct) {
1732 int rc;
1733 /* the BTS has successfully bound a TCH to a local ip/port,
1734 * which means we can connect our UDP socket to it */
1735 if (lchan->abis_ip.rtp_socket) {
1736 rtp_socket_free(lchan->abis_ip.rtp_socket);
1737 lchan->abis_ip.rtp_socket = NULL;
1738 }
1739
1740 lchan->abis_ip.rtp_socket = rtp_socket_create();
1741 if (!lchan->abis_ip.rtp_socket)
1742 goto out_err;
1743
1744 rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
1745 lchan->abis_ip.bound_ip,
1746 lchan->abis_ip.bound_port);
1747 if (rc < 0)
1748 goto out_err;
1749 }
1750
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001751 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001752
Harald Welte75099262009-02-16 21:12:08 +00001753 return 0;
Harald Welte17f5bf62009-12-20 15:42:44 +01001754out_err:
1755 return -EIO;
Harald Welte75099262009-02-16 21:12:08 +00001756}
1757
Harald Welte5e3d91b2009-12-19 16:42:06 +01001758static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1759{
1760 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1761 struct tlv_parsed tv;
1762 struct gsm_lchan *lchan = msg->lchan;
1763
1764 /* the BTS has acknowledged a remote connect request and
1765 * it now tells us the IP address and port number to which it has
1766 * connected the given logical channel */
1767
1768 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1769 ipac_parse_rtp(lchan, &tv);
1770 dispatch_signal(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
1771
1772 return 0;
1773}
1774
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001775static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001776{
1777 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1778 struct tlv_parsed tv;
Harald Welte17f5bf62009-12-20 15:42:44 +01001779 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001780
1781 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001782
Harald Welte8830e072009-07-28 17:58:09 +02001783 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001784 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001785 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001786
Harald Welte17f5bf62009-12-20 15:42:44 +01001787 /* the BTS tells us a RTP stream has been disconnected */
1788 if (lchan->abis_ip.rtp_socket) {
1789 rtp_socket_free(lchan->abis_ip.rtp_socket);
1790 lchan->abis_ip.rtp_socket = NULL;
1791 }
1792
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001793 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001794
Harald Welte75099262009-02-16 21:12:08 +00001795 return 0;
1796}
1797
1798static int abis_rsl_rx_ipacc(struct msgb *msg)
1799{
1800 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001801 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001802 int rc = 0;
1803
1804 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001805 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001806
1807 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001808 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001809 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001810 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001811 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001812 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001813 /* somehow the BTS was unable to bind the lchan to its local
1814 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001815 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001816 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001817 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001818 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001819 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001820 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001821 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001822 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001823 /* somehow the BTS was unable to connect the lchan to a remote
1824 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001825 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001826 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001827 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001828 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001829 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001830 break;
1831 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001832 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001833 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001834 break;
1835 }
Harald Welte6dab0552009-05-01 17:21:37 +00001836 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001837
1838 return rc;
1839}
1840
1841
Harald Welte52b1f982008-12-23 20:25:15 +00001842/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001843int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001844{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001845 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00001846 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001847
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001848 if (!msg) {
1849 DEBUGP(DRSL, "Empty RSL msg?..\n");
1850 return -1;
1851 }
1852
1853 if (msgb_l2len(msg) < sizeof(*rslh)) {
1854 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
1855 return -1;
1856 }
1857
1858 rslh = msgb_l2(msg);
1859
Harald Welte52b1f982008-12-23 20:25:15 +00001860 switch (rslh->msg_discr & 0xfe) {
1861 case ABIS_RSL_MDISC_RLL:
1862 rc = abis_rsl_rx_rll(msg);
1863 break;
1864 case ABIS_RSL_MDISC_DED_CHAN:
1865 rc = abis_rsl_rx_dchan(msg);
1866 break;
1867 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001868 rc = abis_rsl_rx_cchan(msg);
1869 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001870 case ABIS_RSL_MDISC_TRX:
1871 rc = abis_rsl_rx_trx(msg);
1872 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001873 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001874 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00001875 rslh->msg_discr);
1876 break;
Harald Welte75099262009-02-16 21:12:08 +00001877 case ABIS_RSL_MDISC_IPACCESS:
1878 rc = abis_rsl_rx_ipacc(msg);
1879 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001880 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001881 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1882 "0x%02x\n", rslh->msg_discr);
Harald Welte52b1f982008-12-23 20:25:15 +00001883 return -EINVAL;
1884 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001885 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001886 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001887}
Holger Freyther3b72a892009-02-04 00:31:39 +00001888
Holger Freyther3b72a892009-02-04 00:31:39 +00001889/* From Table 10.5.33 of GSM 04.08 */
1890int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1891{
Harald Weltea43f7892009-12-01 18:04:30 +05301892 if (bts->si_common.chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1893 return MAX(1, (3 - bts->si_common.chan_desc.bs_ag_blks_res))
1894 * (bts->si_common.chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001895 } else {
Harald Weltea43f7892009-12-01 18:04:30 +05301896 return (9 - bts->si_common.chan_desc.bs_ag_blks_res)
1897 * (bts->si_common.chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001898 }
1899}
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08001900
1901int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1902 uint8_t cb_command, const uint8_t *data, int len)
1903{
1904 struct abis_rsl_dchan_hdr *dh;
1905 struct msgb *cb_cmd;
1906
1907 cb_cmd = rsl_msgb_alloc();
1908 if (!cb_cmd)
1909 return -1;
1910
1911 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1912 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
1913 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
1914
1915 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
1916 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
1917
1918 cb_cmd->trx = bts->c0;
1919
1920 return abis_rsl_sendmsg(cb_cmd);
1921}