blob: ad11c73623134504de71d49deaa80a6214d76368 [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
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010054static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
55 struct gsm_meas_rep *resp)
56{
57 struct lchan_signal_data sig;
58 sig.lchan = lchan;
59 sig.mr = resp;
60 dispatch_signal(SS_LCHAN, sig_no, &sig);
61}
62
Harald Welte52b1f982008-12-23 20:25:15 +000063static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
64{
65 /* mask off the transparent bit ? */
66 msg_type &= 0xfe;
67
Harald Welte8470bf22008-12-25 23:28:35 +000068 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000069 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000070 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000071 if (msg_type >= 0x19 && msg_type <= 0x22)
72 return ABIS_RSL_MDISC_TRX;
73 else
74 return ABIS_RSL_MDISC_COM_CHAN;
75 }
Harald Welte2d5b6382008-12-27 19:46:06 +000076 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000077 return ABIS_RSL_MDISC_DED_CHAN;
78
79 return ABIS_RSL_MDISC_LOC;
80}
81
82static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
83 u_int8_t msg_type)
84{
85 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
86 dh->c.msg_type = msg_type;
87 dh->ie_chan = RSL_IE_CHAN_NR;
88}
89
Harald Welte8470bf22008-12-25 23:28:35 +000090/* determine logical channel based on TRX and channel number IE */
91struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
92{
93 struct gsm_lchan *lchan;
94 u_int8_t ts_nr = chan_nr & 0x07;
95 u_int8_t cbits = chan_nr >> 3;
96 u_int8_t lch_idx;
97 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
98
99 if (cbits == 0x01) {
100 lch_idx = 0; /* TCH/F */
Harald Weltea1499d02009-10-24 10:25:50 +0200101 if (ts->pchan != GSM_PCHAN_TCH_F &&
102 ts->pchan != GSM_PCHAN_PDCH &&
103 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100104 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000105 chan_nr, ts->pchan);
106 } else if ((cbits & 0x1e) == 0x02) {
107 lch_idx = cbits & 0x1; /* TCH/H */
108 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100109 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000110 chan_nr, ts->pchan);
111 } else if ((cbits & 0x1c) == 0x04) {
112 lch_idx = cbits & 0x3; /* SDCCH/4 */
113 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100114 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000115 chan_nr, ts->pchan);
116 } else if ((cbits & 0x18) == 0x08) {
117 lch_idx = cbits & 0x7; /* SDCCH/8 */
118 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100119 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000120 chan_nr, ts->pchan);
121 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
122 lch_idx = 0;
123 if (ts->pchan != GSM_PCHAN_CCCH &&
124 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100125 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000126 chan_nr, ts->pchan);
127 /* FIXME: we should not return first sdcch4 !!! */
128 } else {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100129 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000130 return NULL;
131 }
132
133 lchan = &ts->lchan[lch_idx];
Harald Weltedc5062b2010-03-26 21:28:59 +0800134 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800135 if (lchan->conn)
136 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000137
138 return lchan;
139}
140
Holger Hans Peter Freythere81a6102009-10-22 11:47:45 +0200141/* See Table 10.5.25 of GSM04.08 */
Harald Welte53cd7ac2010-12-23 12:59:52 +0100142static u_int8_t ts2chan_nr(const struct gsm_bts_trx_ts *ts, uint8_t lchan_nr)
Harald Welte8470bf22008-12-25 23:28:35 +0000143{
Harald Welte8470bf22008-12-25 23:28:35 +0000144 u_int8_t cbits, chan_nr;
145
146 switch (ts->pchan) {
147 case GSM_PCHAN_TCH_F:
Harald Weltea1499d02009-10-24 10:25:50 +0200148 case GSM_PCHAN_PDCH:
149 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte8470bf22008-12-25 23:28:35 +0000150 cbits = 0x01;
151 break;
152 case GSM_PCHAN_TCH_H:
153 cbits = 0x02;
Harald Welte53cd7ac2010-12-23 12:59:52 +0100154 cbits += lchan_nr;
Harald Welte8470bf22008-12-25 23:28:35 +0000155 break;
156 case GSM_PCHAN_CCCH_SDCCH4:
157 cbits = 0x04;
Harald Welte53cd7ac2010-12-23 12:59:52 +0100158 cbits += lchan_nr;
Harald Welte8470bf22008-12-25 23:28:35 +0000159 break;
160 case GSM_PCHAN_SDCCH8_SACCH8C:
161 cbits = 0x08;
Harald Welte53cd7ac2010-12-23 12:59:52 +0100162 cbits += lchan_nr;
Harald Welte8470bf22008-12-25 23:28:35 +0000163 break;
164 default:
165 case GSM_PCHAN_CCCH:
166 cbits = 0x10;
167 break;
168 }
169
170 chan_nr = (cbits << 3) | (ts->nr & 0x7);
171
172 return chan_nr;
173}
174
Harald Welte53cd7ac2010-12-23 12:59:52 +0100175u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan)
176{
177 return ts2chan_nr(lchan->ts, lchan->nr);
178}
179
Harald Welte52b1f982008-12-23 20:25:15 +0000180/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
181u_int64_t str_to_imsi(const char *imsi_str)
182{
183 u_int64_t ret;
184
185 ret = strtoull(imsi_str, NULL, 10);
186
187 return ret;
188}
189
190/* Table 5 Clause 7 TS 05.02 */
191unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
192{
193 if (!bs_ccch_sdcch_comb)
194 return 9 - bs_ag_blks_res;
195 else
196 return 3 - bs_ag_blks_res;
197}
198
199/* Chapter 6.5.2 of TS 05.02 */
200unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
201 unsigned int n_pag_blocks)
202{
203 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
204}
205
206/* Chapter 6.5.2 of TS 05.02 */
207unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
208 int n_pag_blocks)
209{
210 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
211}
212
Harald Welte8470bf22008-12-25 23:28:35 +0000213static struct msgb *rsl_msgb_alloc(void)
214{
Harald Welte966636f2009-06-26 19:39:35 +0200215 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
216 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000217}
218
Harald Welte362322e2009-02-15 14:36:38 +0000219#define MACBLOCK_SIZE 23
220static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
221{
222 memcpy(out, in, len);
223
224 if (len < MACBLOCK_SIZE)
225 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
226}
227
Harald Welte08d91a52009-08-30 15:37:11 +0900228/* Chapter 9.3.7: Encryption Information */
229static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
230{
231 *out++ = lchan->encr.alg_id & 0xff;
232 if (lchan->encr.key_len)
233 memcpy(out, lchan->encr.key, lchan->encr.key_len);
234 return lchan->encr.key_len + 1;
235}
236
Harald Welte5b8ed432009-12-24 12:20:20 +0100237static void print_rsl_cause(int lvl, const u_int8_t *cause_v, u_int8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200238{
Harald Welte7f93cea2009-02-23 00:02:59 +0000239 int i;
240
Harald Welte5b8ed432009-12-24 12:20:20 +0100241 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200242 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200243 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100244 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000245}
246
Harald Welte52b1f982008-12-23 20:25:15 +0000247/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Harald Weltee79769b2009-02-07 00:48:17 +0000248int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000249 const u_int8_t *data, int len)
250{
251 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000252 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000253
254 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
255 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
256 dh->chan_nr = RSL_CHAN_BCCH;
257
258 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
259 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
260
Harald Weltee79769b2009-02-07 00:48:17 +0000261 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000262
263 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000264}
265
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200266int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000267 const u_int8_t *data, int len)
268{
269 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000270 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000271
272 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
273 ch->msg_discr = ABIS_RSL_MDISC_TRX;
274 ch->msg_type = RSL_MT_SACCH_FILL;
275
276 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000277 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000278
Harald Weltee79769b2009-02-07 00:48:17 +0000279 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000280
281 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000282}
283
Harald Weltefcd24452009-06-20 18:15:19 +0200284int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
285{
286 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200287 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200288 u_int8_t chan_nr = lchan2chan_nr(lchan);
289
290 db = abs(db);
291 if (db > 30)
292 return -EINVAL;
293
Harald Welteeab33352009-06-27 03:09:08 +0200294 msg = rsl_msgb_alloc();
295
Harald Weltefcd24452009-06-20 18:15:19 +0200296 lchan->bs_power = db/2;
297 if (fpc)
298 lchan->bs_power |= 0x10;
299
300 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
301 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
302 dh->chan_nr = chan_nr;
303
304 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
305
306 msg->trx = lchan->ts->trx;
307
308 return abis_rsl_sendmsg(msg);
309}
310
Harald Weltefcd24452009-06-20 18:15:19 +0200311int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
312{
313 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200314 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200315 u_int8_t chan_nr = lchan2chan_nr(lchan);
316 int ctl_lvl;
317
Harald Welte66b6a8d2009-08-09 14:45:18 +0200318 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200319 if (ctl_lvl < 0)
320 return ctl_lvl;
321
Harald Welteeab33352009-06-27 03:09:08 +0200322 msg = rsl_msgb_alloc();
323
Harald Weltefcd24452009-06-20 18:15:19 +0200324 lchan->ms_power = ctl_lvl;
325
326 if (fpc)
327 lchan->ms_power |= 0x20;
328
329 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
330 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
331 dh->chan_nr = chan_nr;
332
333 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
334
335 msg->trx = lchan->ts->trx;
336
337 return abis_rsl_sendmsg(msg);
338}
339
Harald Welte9943c5b2009-07-29 15:41:29 +0200340static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
341 struct gsm_lchan *lchan)
342{
343 memset(cm, 0, sizeof(cm));
344
345 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800346 if (lchan->ts->trx->bts->network->dtx_enabled)
347 cm->dtx_dtu = 0x03;
348 else
349 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200350
351 /* set TCH Speech/Data */
352 cm->spd_ind = lchan->rsl_cmode;
353
Harald Welte1a79d362009-11-27 08:55:16 +0100354 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
355 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100356 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100357 "but tch_mode != signalling\n");
358
Harald Welte9943c5b2009-07-29 15:41:29 +0200359 switch (lchan->type) {
360 case GSM_LCHAN_SDCCH:
361 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
362 break;
363 case GSM_LCHAN_TCH_F:
364 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
365 break;
366 case GSM_LCHAN_TCH_H:
367 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
368 break;
369 case GSM_LCHAN_NONE:
370 case GSM_LCHAN_UNKNOWN:
371 default:
372 return -EINVAL;
373 }
374
375 switch (lchan->tch_mode) {
376 case GSM48_CMODE_SIGN:
377 cm->chan_rate = 0;
378 break;
379 case GSM48_CMODE_SPEECH_V1:
380 cm->chan_rate = RSL_CMOD_SP_GSM1;
381 break;
382 case GSM48_CMODE_SPEECH_EFR:
383 cm->chan_rate = RSL_CMOD_SP_GSM2;
384 break;
385 case GSM48_CMODE_SPEECH_AMR:
386 cm->chan_rate = RSL_CMOD_SP_GSM3;
387 break;
388 case GSM48_CMODE_DATA_14k5:
389 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
390 break;
391 case GSM48_CMODE_DATA_12k0:
392 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
393 break;
394 case GSM48_CMODE_DATA_6k0:
395 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
396 break;
397 default:
398 return -EINVAL;
399 }
400
401 return 0;
402}
403
Harald Welte52b1f982008-12-23 20:25:15 +0000404/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000405#if 0
Harald Weltee79769b2009-02-07 00:48:17 +0000406int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
Harald Welte52b1f982008-12-23 20:25:15 +0000407 u_int8_t act_type,
408 struct rsl_ie_chan_mode *chan_mode,
409 struct rsl_ie_chan_ident *chan_ident,
410 u_int8_t bs_power, u_int8_t ms_power,
411 u_int8_t ta)
412{
413 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000414 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000415
416 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
417 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
418 dh->chan_nr = chan_nr;
419
420 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
421 /* For compatibility with Phase 1 */
422 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
423 (u_int8_t *) chan_mode);
424 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Harald Welte702d8702008-12-26 20:25:35 +0000425 (u_int8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000426#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000427 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
428 (u_int8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000429#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000430 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000431 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
432 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
433
Harald Weltee79769b2009-02-07 00:48:17 +0000434 msg->trx = trx;
435
Harald Welte8470bf22008-12-25 23:28:35 +0000436 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000437}
Harald Welteddab3c72009-02-28 13:19:15 +0000438#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000439
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200440int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte8d77b952009-12-17 00:31:10 +0100441 u_int8_t ta, u_int8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000442{
443 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200444 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200445 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200446 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000447
448 u_int8_t chan_nr = lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000449 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200450 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000451
Harald Welte9943c5b2009-07-29 15:41:29 +0200452 rc = channel_mode_from_lchan(&cm, lchan);
453 if (rc < 0)
454 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000455
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800456 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200457 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000458
Harald Welteeab33352009-06-27 03:09:08 +0200459 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000460 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
461 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
462 dh->chan_nr = chan_nr;
463
464 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000465 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
466 (u_int8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800467
468 /*
469 * The Channel Identification is needed for Phase1 phones
470 * and it contains the GSM48 Channel Description and the
471 * Mobile Allocation. The GSM 08.58 asks for the Mobile
472 * Allocation to have a length of zero. We are using the
473 * msgb_l3len to calculate the length of both messages.
474 */
laforge694a5cf2010-06-20 21:38:19 +0200475 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200476 len = msgb_put(msg, 1);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800477 msgb_tlv_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800478
479 if (lchan->ts->hopping.enabled)
480 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
481 lchan->ts->hopping.ma_data);
482 else
483 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800484
485 /* update the calculated size */
486 msg->l3h = len + 1;
487 *len = msgb_l3len(msg);
488
Harald Welte08d91a52009-08-30 15:37:11 +0900489 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
490 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
491 rc = build_encr_info(encr_info, lchan);
492 if (rc > 0)
493 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
494 }
495
Harald Welte8d77b952009-12-17 00:31:10 +0100496 switch (act_type) {
497 case RSL_ACT_INTER_ASYNC:
498 case RSL_ACT_INTER_SYNC:
499 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
500 break;
501 default:
502 break;
503 }
504
Harald Welted4c9bf32009-02-15 16:56:18 +0000505 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
506 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000507 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
508
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100509 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
510 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
511 (u_int8_t *) &lchan->mr_conf);
512
Harald Weltee79769b2009-02-07 00:48:17 +0000513 msg->trx = lchan->ts->trx;
514
Harald Welte4b634542008-12-27 01:55:51 +0000515 return abis_rsl_sendmsg(msg);
516}
517
Harald Welte470abb72009-07-29 11:38:15 +0200518/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000519int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
520{
521 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200522 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200523 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000524
525 u_int8_t chan_nr = lchan2chan_nr(lchan);
526 struct rsl_ie_chan_mode cm;
527
Harald Welte9943c5b2009-07-29 15:41:29 +0200528 rc = channel_mode_from_lchan(&cm, lchan);
529 if (rc < 0)
530 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000531
Harald Welteeab33352009-06-27 03:09:08 +0200532 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000533 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
534 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
535 dh->chan_nr = chan_nr;
536
537 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
538 (u_int8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900539
540 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
541 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
542 rc = build_encr_info(encr_info, lchan);
543 if (rc > 0)
544 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
545 }
546
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100547 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
548 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
549 (u_int8_t *) &lchan->mr_conf);
550 }
551
Harald Welte08d91a52009-08-30 15:37:11 +0900552 msg->trx = lchan->ts->trx;
553
554 return abis_rsl_sendmsg(msg);
555}
556
557/* Chapter 8.4.6: Send the encryption command with given L3 info */
558int rsl_encryption_cmd(struct msgb *msg)
559{
560 struct abis_rsl_dchan_hdr *dh;
561 struct gsm_lchan *lchan = msg->lchan;
562 u_int8_t chan_nr = lchan2chan_nr(lchan);
563 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut82aa6842009-09-27 11:13:18 +0200564 u_int8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900565 int rc;
566
567 /* First push the L3 IE tag and length */
568 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
569
570 /* then the link identifier (SAPI0, main sign link) */
571 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
572
573 /* then encryption information */
574 rc = build_encr_info(encr_info, lchan);
575 if (rc <= 0)
576 return rc;
577 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
578
579 /* and finally the DCHAN header */
580 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
581 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
582 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000583
584 msg->trx = lchan->ts->trx;
585
586 return abis_rsl_sendmsg(msg);
587}
588
Harald Welte115d1032009-08-10 11:43:22 +0200589/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200590int rsl_deact_sacch(struct gsm_lchan *lchan)
591{
592 struct abis_rsl_dchan_hdr *dh;
593 struct msgb *msg = rsl_msgb_alloc();
594
595 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
596 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
597 dh->chan_nr = lchan2chan_nr(lchan);
598
599 msg->lchan = lchan;
600 msg->trx = lchan->ts->trx;
601
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100602 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200603
604 return abis_rsl_sendmsg(msg);
605}
606
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800607static void error_timeout_cb(void *data)
608{
609 struct gsm_lchan *lchan = data;
610 if (lchan->state != LCHAN_S_REL_ERR) {
611 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
612 gsm_lchan_name(lchan), lchan->state);
613 return;
614 }
615
616 /* go back to the none state */
617 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800618 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800619}
620
Harald Welte115d1032009-08-10 11:43:22 +0200621/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800622static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte52b1f982008-12-23 20:25:15 +0000623{
624 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800625 struct msgb *msg;
Harald Welte52b1f982008-12-23 20:25:15 +0000626
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800627 if (lchan->state == LCHAN_S_REL_ERR) {
628 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
629 gsm_lchan_name(lchan));
630 return -1;
631 }
632
633 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000634 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
635 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000636 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000637
Harald Welte8470bf22008-12-25 23:28:35 +0000638 msg->lchan = lchan;
639 msg->trx = lchan->ts->trx;
640
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800641 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
642
643 if (error) {
644 /*
645 * the nanoBTS sends RLL release indications after the channel release. This can
646 * be a problem when we have reassigned the channel to someone else and then can
647 * not figure out who used this channel.
648 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800649 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800650 lchan->error_timer.data = lchan;
651 lchan->error_timer.cb = error_timeout_cb;
652 bsc_schedule_timer(&lchan->error_timer,
653 msg->trx->bts->network->T3111 + 2, 0);
654 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000655
Harald Welte115d1032009-08-10 11:43:22 +0200656 /* BTS will respond by RF CHAN REL ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000657 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000658}
659
660int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
661 u_int8_t *ms_ident, u_int8_t chan_needed)
662{
663 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000664 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000665
666 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
667 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
668 dh->chan_nr = RSL_CHAN_PCH_AGCH;
669
670 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000671 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000672 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
673
Harald Welte8470bf22008-12-25 23:28:35 +0000674 msg->trx = bts->c0;
675
676 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000677}
678
679int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
680{
681 int i, len = strlen(str_in);
682
683 for (i = 0; i < len; i++) {
684 int num = str_in[i] - 0x30;
685 if (num < 0 || num > 9)
686 return -1;
687 if (i % 2 == 0)
688 bcd_out[i/2] = num;
689 else
690 bcd_out[i/2] |= (num << 4);
691 }
692
693 return 0;
694}
695
Harald Welte702d8702008-12-26 20:25:35 +0000696/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000697int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
698{
Harald Welte8470bf22008-12-25 23:28:35 +0000699 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000700 struct abis_rsl_dchan_hdr *dh;
Harald Welte362322e2009-02-15 14:36:38 +0000701 u_int8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000702
703 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
704 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
705 dh->chan_nr = RSL_CHAN_PCH_AGCH;
706
Harald Welte362322e2009-02-15 14:36:38 +0000707 switch (bts->type) {
708 case GSM_BTS_TYPE_BS11:
709 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
710 break;
711 default:
712 /* If phase 2, construct a FULL_IMM_ASS_INFO */
713 pad_macblock(buf, val, len);
714 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
715 break;
716 }
Harald Welte52b1f982008-12-23 20:25:15 +0000717
Harald Welte8470bf22008-12-25 23:28:35 +0000718 msg->trx = bts->c0;
719
720 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000721}
722
Harald Welte67fa91b2009-08-10 09:51:40 +0200723/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200724int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200725{
726 struct msgb *msg = rsl_msgb_alloc();
727 struct abis_rsl_dchan_hdr *dh;
728
729 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
730 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200731 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte67fa91b2009-08-10 09:51:40 +0200732 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte31c48932009-08-10 10:07:33 +0200733 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200734
Harald Welte5b8ed432009-12-24 12:20:20 +0100735 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100736 gsm_lchan_name(lchan), *(u_int8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200737
738 msg->trx = lchan->ts->trx;
739
Harald Welte67fa91b2009-08-10 09:51:40 +0200740 return abis_rsl_sendmsg(msg);
741}
742
743
Harald Welte8470bf22008-12-25 23:28:35 +0000744/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000745/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000746int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000747{
Harald Welte8470bf22008-12-25 23:28:35 +0000748 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100749 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000750 return -EINVAL;
751 }
Harald Welte52b1f982008-12-23 20:25:15 +0000752
Harald Welte3c9c5f92010-03-04 10:33:10 +0100753 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, lchan2chan_nr(msg->lchan),
754 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000755
Harald Welte8470bf22008-12-25 23:28:35 +0000756 msg->trx = msg->lchan->ts->trx;
757
758 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000759}
760
Harald Welteedcc5272009-08-09 13:47:35 +0200761/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
762/* Chapter 8.3.1 */
763int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
764{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100765 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200766
Harald Welte3c9c5f92010-03-04 10:33:10 +0100767 msg = rsl_rll_simple(RSL_MT_EST_REQ, lchan2chan_nr(lchan),
768 link_id, 0);
Harald Welteedcc5272009-08-09 13:47:35 +0200769 msg->trx = lchan->ts->trx;
770
771 return abis_rsl_sendmsg(msg);
772}
773
Harald Welted2dc1de2009-08-08 13:15:07 +0200774/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
775 This is what higher layers should call. The BTS then responds with
776 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
777 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
778 lchan_free() */
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800779int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason)
Harald Welted2dc1de2009-08-08 13:15:07 +0200780{
Harald Welted2dc1de2009-08-08 13:15:07 +0200781
Harald Welte3c9c5f92010-03-04 10:33:10 +0100782 struct msgb *msg;
783
784 msg = rsl_rll_simple(RSL_MT_REL_REQ, lchan2chan_nr(lchan),
785 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800786 /* 0 is normal release, 1 is local end */
787 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
Harald Welted2dc1de2009-08-08 13:15:07 +0200788
Harald Welte8e93b792009-12-29 10:44:17 +0100789 /* FIXME: start some timer in case we don't receive a REL ACK ? */
790
Harald Welted2dc1de2009-08-08 13:15:07 +0200791 msg->trx = lchan->ts->trx;
792
793 return abis_rsl_sendmsg(msg);
794}
795
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200796int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
797{
798 lchan->state = state;
799 return 0;
800}
801
Harald Welte702d8702008-12-26 20:25:35 +0000802/* Chapter 8.4.2: Channel Activate Acknowledge */
803static int rsl_rx_chan_act_ack(struct msgb *msg)
804{
805 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
806
807 /* BTS has confirmed channel activation, we now need
808 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000809 if (rslh->ie_chan != RSL_IE_CHAN_NR)
810 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100811
Harald Welte8e93b792009-12-29 10:44:17 +0100812 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100813 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
814 gsm_lchan_name(msg->lchan),
815 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200816 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100817
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800818 if (msg->lchan->rqd_ref) {
819 rsl_send_imm_assignment(msg->lchan);
820 talloc_free(msg->lchan->rqd_ref);
821 msg->lchan->rqd_ref = NULL;
822 msg->lchan->rqd_ta = 0;
823 }
824
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100825 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100826
Harald Welte4b634542008-12-27 01:55:51 +0000827 return 0;
828}
Harald Welte702d8702008-12-26 20:25:35 +0000829
Harald Welte4b634542008-12-27 01:55:51 +0000830/* Chapter 8.4.3: Channel Activate NACK */
831static int rsl_rx_chan_act_nack(struct msgb *msg)
832{
Harald Welte6dab0552009-05-01 17:21:37 +0000833 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
834 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000835
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100836 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100837 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100838
Harald Welte6dab0552009-05-01 17:21:37 +0000839 /* BTS has rejected channel activation ?!? */
840 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000841 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000842
843 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100844 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
845 const u_int8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
846 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200847 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100848 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200849 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100850 } else
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200851 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200852
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100853 LOGPC(DRSL, LOGL_ERROR, "\n");
854
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100855 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100856
Harald Welte3073a9f2009-08-09 19:50:08 +0200857 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000858 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000859}
860
Harald Welte7f93cea2009-02-23 00:02:59 +0000861/* Chapter 8.4.4: Connection Failure Indication */
862static int rsl_rx_conn_fail(struct msgb *msg)
863{
864 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
865 struct tlv_parsed tp;
866
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100867 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100868 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100869 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000870
871 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
872
Harald Welte8830e072009-07-28 17:58:09 +0200873 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100874 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200875 TLVP_LEN(&tp, RSL_IE_CAUSE));
876
Harald Welte (local)fc057502009-12-26 22:33:09 +0100877 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000878 /* FIXME: only free it after channel release ACK */
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +0200879 counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800880 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte7f93cea2009-02-23 00:02:59 +0000881}
882
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100883static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
884 const char *prefix)
885{
Harald Welte6739dfb2009-12-16 16:52:07 +0100886 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
887 prefix, rxlev2dbm(mru->full.rx_lev),
888 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100889 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
890 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
891}
892
893static void print_meas_rep(struct gsm_meas_rep *mr)
894{
Harald Welte6739dfb2009-12-16 16:52:07 +0100895 int i;
896
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100897 DEBUGP(DMEAS, "MEASUREMENT RESULT NR=%d ", mr->nr);
898
899 if (mr->flags & MEAS_REP_F_DL_DTX)
900 DEBUGPC(DMEAS, "DTXd ");
901
902 print_meas_rep_uni(&mr->ul, "ul");
903 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
904 if (mr->flags & MEAS_REP_F_MS_TO)
905 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
906
907 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +0100908 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100909 DEBUGPC(DMEAS, "L1_FPC=%u ",
910 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
911 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
912 }
913
914 if (mr->flags & MEAS_REP_F_UL_DTX)
915 DEBUGPC(DMEAS, "DTXu ");
916 if (mr->flags & MEAS_REP_F_BA1)
917 DEBUGPC(DMEAS, "BA1 ");
918 if (!(mr->flags & MEAS_REP_F_DL_VALID))
919 DEBUGPC(DMEAS, "NOT VALID ");
920 else
921 print_meas_rep_uni(&mr->dl, "dl");
922
923 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +0100924 if (mr->num_cell == 7)
925 return;
Harald Welte6739dfb2009-12-16 16:52:07 +0100926 for (i = 0; i < mr->num_cell; i++) {
927 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +0100928 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
929 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +0100930 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100931}
932
Harald Welte440fed02009-05-01 18:43:47 +0000933static int rsl_rx_meas_res(struct msgb *msg)
934{
935 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
936 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +0100937 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100938 u_int8_t len;
939 const u_int8_t *val;
940 int rc;
Harald Welte440fed02009-05-01 18:43:47 +0000941
Harald Welteb8bfc562009-12-21 13:27:11 +0100942 /* check if this channel is actually active */
943 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +0100944 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +0800945 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +0100946 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +0100947 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +0100948 }
Harald Welteb8bfc562009-12-21 13:27:11 +0100949
Harald Welted12b0fd2009-12-15 21:36:05 +0100950 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +0100951 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +0100952
Harald Welte440fed02009-05-01 18:43:47 +0000953 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
954
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100955 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
956 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
957 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
958 return -EIO;
959
960 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +0100961 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100962
963 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
964 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
965 if (len >= 3) {
966 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +0100967 mr->flags |= MEAS_REP_F_DL_DTX;
968 mr->ul.full.rx_lev = val[0] & 0x3f;
969 mr->ul.sub.rx_lev = val[1] & 0x3f;
970 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
971 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +0000972 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100973
Harald Welted12b0fd2009-12-15 21:36:05 +0100974 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100975
976 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +0000977 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +0100978 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100979 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
980
Harald Weltefe9af262009-06-20 18:44:35 +0200981 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100982 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +0100983 mr->flags |= MEAS_REP_F_MS_L1;
984 mr->ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100985 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +0100986 mr->flags |= MEAS_REP_F_FPC;
987 mr->ms_l1.ta = val[1];
Harald Weltefe9af262009-06-20 18:44:35 +0200988 }
Harald Weltef7c43522009-06-09 20:24:21 +0000989 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherddd918f2009-10-22 15:43:55 +0200990 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +0100991 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100992 if (rc < 0)
993 return rc;
994 }
995
Harald Welted12b0fd2009-12-15 21:36:05 +0100996 print_meas_rep(mr);
Harald Welte60d68f12009-06-05 20:07:43 +0000997
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100998 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +0100999
Harald Welte75d34a82009-05-23 06:11:13 +00001000 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001001}
1002
Harald Welted011e8b2009-11-29 22:45:52 +01001003/* Chapter 8.4.7 */
1004static int rsl_rx_hando_det(struct msgb *msg)
1005{
1006 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1007 struct tlv_parsed tp;
1008
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001009 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001010
1011 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1012
1013 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1014 DEBUGPC(DRSL, "access delay = %u\n",
1015 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1016 else
1017 DEBUGPC(DRSL, "\n");
1018
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001019 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001020
1021 return 0;
1022}
1023
Harald Welte52b1f982008-12-23 20:25:15 +00001024static int abis_rsl_rx_dchan(struct msgb *msg)
1025{
Harald Welte8470bf22008-12-25 23:28:35 +00001026 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1027 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001028 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +00001029
Harald Welte8470bf22008-12-25 23:28:35 +00001030 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001031 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001032
Harald Welte8470bf22008-12-25 23:28:35 +00001033 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001034 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001035 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001036 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001037 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001038 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001039 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001040 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001041 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001042 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001043 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001044 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001045 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001046 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001047 case RSL_MT_HANDO_DET:
1048 rc = rsl_rx_hando_det(msg);
1049 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001050 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001051 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", ts_name);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001052 if (msg->lchan->state != LCHAN_S_REL_REQ && msg->lchan->state != LCHAN_S_REL_ERR)
Harald Welte1887f9d2009-12-29 10:52:38 +01001053 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
1054 gsm_lchan_name(msg->lchan),
1055 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001056 bsc_del_timer(&msg->lchan->T3111);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001057 /* we have an error timer pending to release that */
1058 if (msg->lchan->state != LCHAN_S_REL_ERR)
1059 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte2d5b6382008-12-27 19:46:06 +00001060 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001061 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001062 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001063 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001064 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001065 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001066 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001067 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001068 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001069 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001070 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001071 break;
1072 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001073 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001074 break;
1075 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001076 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001077 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001078 break;
1079 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001080 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001081 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001082 case RSL_MT_PHY_CONTEXT_CONF:
1083 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001084 case RSL_MT_TALKER_DET:
1085 case RSL_MT_LISTENER_DET:
1086 case RSL_MT_REMOTE_CODEC_CONF_REP:
1087 case RSL_MT_MR_CODEC_MOD_ACK:
1088 case RSL_MT_MR_CODEC_MOD_NACK:
1089 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001090 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1091 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001092 break;
1093 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001094 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1095 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001096 return -EINVAL;
1097 }
Harald Weltef325eb42009-02-19 17:07:39 +00001098
Harald Welte8470bf22008-12-25 23:28:35 +00001099 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001100}
1101
Harald Welte702d8702008-12-26 20:25:35 +00001102static int rsl_rx_error_rep(struct msgb *msg)
1103{
1104 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001105 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001106
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001107 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001108
1109 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1110
1111 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001112 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001113 TLVP_LEN(&tp, RSL_IE_CAUSE));
1114
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001115 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001116
1117 return 0;
1118}
1119
Harald Welte52b1f982008-12-23 20:25:15 +00001120static int abis_rsl_rx_trx(struct msgb *msg)
1121{
Harald Welte702d8702008-12-26 20:25:35 +00001122 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001123 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001124
1125 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001126 case RSL_MT_ERROR_REPORT:
1127 rc = rsl_rx_error_rep(msg);
1128 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001129 case RSL_MT_RF_RES_IND:
1130 /* interference on idle channels of TRX */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001131 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001132 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001133 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001134 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001135 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
1136 gsm_trx_name(msg->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001137 break;
1138 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001139 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
1140 "type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001141 return -EINVAL;
1142 }
Harald Welte8470bf22008-12-25 23:28:35 +00001143 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001144}
1145
Harald Welteb7e81162009-08-10 00:26:10 +02001146/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1147static void t3101_expired(void *data)
1148{
1149 struct gsm_lchan *lchan = data;
1150
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001151 rsl_rf_chan_release(lchan, 1);
Harald Welteb7e81162009-08-10 00:26:10 +02001152}
1153
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001154/* If T3111 expires, we will send the RF Channel Request */
1155static void t3111_expired(void *data)
1156{
1157 struct gsm_lchan *lchan = data;
1158
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001159 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001160}
1161
laforgecfa4a012010-06-21 12:08:52 +02001162#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1163
Harald Welte2862dca2010-12-23 14:39:29 +01001164/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1165static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1166 unsigned int num_req_refs,
1167 struct gsm48_req_ref *rqd_refs,
1168 uint8_t wait_ind)
1169{
1170 uint8_t buf[GSM_MACBLOCK_LEN];
1171 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1172
1173 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1174 memset(iar, 0, sizeof(*iar));
1175 iar->proto_discr = GSM48_PDISC_RR;
1176 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1177 iar->page_mode = GSM48_PM_SAME;
1178
1179 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1180 iar->wait_ind1 = wait_ind;
1181
1182 if (num_req_refs >= 2)
1183 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1184 else
1185 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1186 iar->wait_ind2 = wait_ind;
1187
1188 if (num_req_refs >= 3)
1189 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1190 else
1191 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1192 iar->wait_ind3 = wait_ind;
1193
1194 if (num_req_refs >= 4)
1195 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1196 else
1197 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1198 iar->wait_ind4 = wait_ind;
1199
1200 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1201}
1202
Harald Welte8470bf22008-12-25 23:28:35 +00001203/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001204static int rsl_rx_chan_rqd(struct msgb *msg)
1205{
Harald Welte702d8702008-12-26 20:25:35 +00001206 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001207 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1208 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001209 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001210 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001211 struct gsm_lchan *lchan;
1212 u_int8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001213 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001214
Harald Welte52b1f982008-12-23 20:25:15 +00001215 u_int16_t arfcn;
1216 u_int8_t ts_number, subch;
1217
Harald Welte8470bf22008-12-25 23:28:35 +00001218 /* parse request reference to be used in immediate assign */
1219 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1220 return -EINVAL;
1221
1222 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1223
1224 /* parse access delay and use as TA */
1225 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1226 return -EINVAL;
1227 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1228
1229 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1230 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001231 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1232 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001233
Harald Welteffa55a42009-12-22 19:07:32 +01001234 counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001235
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001236 /*
1237 * We want LOCATION UPDATES to succeed and will assign a TCH
1238 * if we have no SDCCH available.
1239 */
1240 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1241
Harald Welte8470bf22008-12-25 23:28:35 +00001242 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001243 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001244 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001245 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001246 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Harald Welteffa55a42009-12-22 19:07:32 +01001247 counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001248 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1249 if (bts->network->T3122)
1250 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001251 return -ENOMEM;
1252 }
1253
Harald Welte8e93b792009-12-29 10:44:17 +01001254 if (lchan->state != LCHAN_S_NONE)
1255 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001256 "in state %s\n", gsm_lchan_name(lchan),
1257 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001258 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001259
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001260 /* save the RACH data as we need it after the CHAN ACT ACK */
1261 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1262 if (!lchan->rqd_ref) {
1263 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1264 lchan_free(lchan);
1265 return -ENOMEM;
1266 }
1267
1268 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1269 lchan->rqd_ta = rqd_ta;
1270
Harald Welte8470bf22008-12-25 23:28:35 +00001271 ts_number = lchan->ts->nr;
1272 arfcn = lchan->ts->trx->arfcn;
1273 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001274
Harald Welte08d91a52009-08-30 15:37:11 +09001275 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001276 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001277 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001278 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001279 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001280
1281 /* FIXME: Start another timer or assume the BTS sends a ACK/NACK? */
Harald Welte8d77b952009-12-17 00:31:10 +01001282 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001283
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001284 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1285 "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
1286 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1287 rqd_ref->ra);
1288 return 0;
1289}
1290
1291static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1292{
1293 struct gsm_bts *bts = lchan->ts->trx->bts;
1294 u_int8_t buf[GSM_MACBLOCK_LEN];
1295 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1296
Harald Welte52b1f982008-12-23 20:25:15 +00001297 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001298 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001299 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001300 ia->proto_discr = GSM48_PDISC_RR;
1301 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1302 ia->page_mode = GSM48_PM_SAME;
1303 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001304
Harald Welte8470bf22008-12-25 23:28:35 +00001305 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001306 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1307 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001308 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001309 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001310 } else {
laforge09108bf2010-06-20 15:18:46 +02001311 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1312 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001313 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001314 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1315 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001316
Harald Welteb7e81162009-08-10 00:26:10 +02001317 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1318 lchan->T3101.cb = t3101_expired;
1319 lchan->T3101.data = lchan;
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001320 bsc_schedule_timer(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001321
Harald Welte52b1f982008-12-23 20:25:15 +00001322 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001323 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (u_int8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001324}
1325
Harald Welteea280442009-02-02 22:29:56 +00001326/* MS has requested a channel on the RACH */
1327static int rsl_rx_ccch_load(struct msgb *msg)
1328{
1329 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1330 u_int16_t pg_buf_space;
Holger Freyther8c563cf2009-02-03 20:08:51 +00001331 u_int16_t rach_slot_count = -1;
1332 u_int16_t rach_busy_count = -1;
1333 u_int16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001334
1335 switch (rslh->data[0]) {
1336 case RSL_IE_PAGING_LOAD:
1337 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Harald Welte38e9c822010-04-19 10:24:07 +02001338 if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
1339 /* paging load below configured threshold, use 50 as default */
1340 pg_buf_space = 50;
1341 }
Holger Freyther392209c2009-02-10 00:06:19 +00001342 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001343 break;
1344 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001345 if (msg->data_len >= 7) {
1346 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1347 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1348 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1349 }
Harald Welteea280442009-02-02 22:29:56 +00001350 break;
1351 default:
1352 break;
1353 }
1354
1355 return 0;
1356}
1357
Harald Welte52b1f982008-12-23 20:25:15 +00001358static int abis_rsl_rx_cchan(struct msgb *msg)
1359{
Harald Welteea280442009-02-02 22:29:56 +00001360 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001361 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001362
Harald Welte8470bf22008-12-25 23:28:35 +00001363 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1364
1365 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001366 case RSL_MT_CHAN_RQD:
1367 /* MS has requested a channel on the RACH */
1368 rc = rsl_rx_chan_rqd(msg);
1369 break;
Harald Welteea280442009-02-02 22:29:56 +00001370 case RSL_MT_CCCH_LOAD_IND:
1371 /* current load on the CCCH */
1372 rc = rsl_rx_ccch_load(msg);
1373 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001374 case RSL_MT_DELETE_IND:
1375 /* CCCH overloaded, IMM_ASSIGN was dropped */
1376 case RSL_MT_CBCH_LOAD_IND:
1377 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001378 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1379 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001380 break;
1381 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001382 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1383 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001384 return -EINVAL;
1385 }
Harald Welte8470bf22008-12-25 23:28:35 +00001386
1387 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001388}
1389
Harald Welte4b634542008-12-27 01:55:51 +00001390static int rsl_rx_rll_err_ind(struct msgb *msg)
1391{
1392 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1393 u_int8_t *rlm_cause = rllh->data;
1394
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001395 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001396 gsm_lchan_name(msg->lchan),
Harald Weltee95daf12010-03-25 12:13:02 +08001397 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteedcc5272009-08-09 13:47:35 +02001398
1399 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001400
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001401 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
1402 counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001403 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001404 }
Harald Welte81543bc2009-07-04 09:40:05 +02001405
Harald Welte4b634542008-12-27 01:55:51 +00001406 return 0;
1407}
Harald Weltef325eb42009-02-19 17:07:39 +00001408
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001409static void rsl_handle_release(struct gsm_lchan *lchan)
1410{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001411 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001412 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001413
1414 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001415 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001416 return;
1417
1418 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1419 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1420 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001421 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001422 gsm_lchan_name(lchan), sapi);
1423 return;
1424 }
1425
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001426
1427
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001428 /* wait a bit to send the RF Channel Release */
1429 lchan->T3111.cb = t3111_expired;
1430 lchan->T3111.data = lchan;
1431 bts = lchan->ts->trx->bts;
1432 bsc_schedule_timer(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001433}
1434
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001435/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001436 0x02, 0x06,
1437 0x01, 0x20,
1438 0x02, 0x00,
1439 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1440
1441static int abis_rsl_rx_rll(struct msgb *msg)
1442{
1443 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001444 int rc = 0;
1445 char *ts_name;
Harald Welte (local)daef6062009-08-14 11:41:12 +02001446 u_int8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001447
1448 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001449 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001450 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001451
1452 switch (rllh->c.msg_type) {
1453 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001454 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001455 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001456 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1457 rllh->data[0] == RSL_IE_L3_INFO) {
1458 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001459 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001460 }
Harald Welte52b1f982008-12-23 20:25:15 +00001461 break;
1462 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001463 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001464 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001465 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welteb7e81162009-08-10 00:26:10 +02001466 bsc_del_timer(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001467 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001468 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1469 rllh->data[0] == RSL_IE_L3_INFO) {
1470 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001471 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001472 }
Harald Welte52b1f982008-12-23 20:25:15 +00001473 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001474 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001475 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001476 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001477 rll_indication(msg->lchan, rllh->link_id,
1478 BSC_RLLR_IND_EST_CONF);
1479 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001480 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001481 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001482 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001483 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001484 rll_indication(msg->lchan, rllh->link_id,
1485 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001486 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001487 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte2d5b6382008-12-27 19:46:06 +00001488 break;
1489 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001490 /* BTS informs us of having received UA from MS,
1491 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001492 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001493 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001494 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001495 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte4b634542008-12-27 01:55:51 +00001496 break;
1497 case RSL_MT_ERROR_IND:
1498 rc = rsl_rx_rll_err_ind(msg);
1499 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001500 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001501 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1502 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001503 break;
1504 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001505 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1506 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001507 }
Harald Welte8470bf22008-12-25 23:28:35 +00001508 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001509}
1510
Harald Welte0603c9d2009-12-02 01:58:23 +05301511static u_int8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001512{
Harald Welte0603c9d2009-12-02 01:58:23 +05301513 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001514 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301515 switch (lchan->type) {
1516 case GSM_LCHAN_TCH_F:
1517 return 0x00;
1518 case GSM_LCHAN_TCH_H:
1519 return 0x03;
1520 default:
1521 break;
1522 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001523 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301524 switch (lchan->type) {
1525 case GSM_LCHAN_TCH_F:
1526 return 0x01;
1527 /* there's no half-rate EFR */
1528 default:
1529 break;
1530 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001531 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301532 switch (lchan->type) {
1533 case GSM_LCHAN_TCH_F:
1534 return 0x02;
1535 case GSM_LCHAN_TCH_H:
1536 return 0x05;
1537 default:
1538 break;
1539 }
1540 default:
1541 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001542 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001543 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301544 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001545 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001546}
1547
Sylvain Munautb54dda42009-12-20 22:06:40 +01001548static u_int8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
1549{
Holger Hans Peter Freyther8cc59032010-11-14 21:09:08 +01001550 struct gsm_network *net = lchan->ts->trx->bts->network;
1551
1552 /* allow to hardcode the rtp payload */
1553 if (net->hardcoded_rtp_payload != 0)
1554 return net->hardcoded_rtp_payload;
1555
Sylvain Munautb54dda42009-12-20 22:06:40 +01001556 switch (lchan->tch_mode) {
1557 case GSM48_CMODE_SPEECH_V1:
1558 switch (lchan->type) {
1559 case GSM_LCHAN_TCH_F:
1560 return RTP_PT_GSM_FULL;
1561 case GSM_LCHAN_TCH_H:
1562 return RTP_PT_GSM_HALF;
1563 default:
1564 break;
1565 }
1566 case GSM48_CMODE_SPEECH_EFR:
1567 switch (lchan->type) {
1568 case GSM_LCHAN_TCH_F:
1569 return RTP_PT_GSM_EFR;
1570 /* there's no half-rate EFR */
1571 default:
1572 break;
1573 }
1574 case GSM48_CMODE_SPEECH_AMR:
1575 switch (lchan->type) {
1576 case GSM_LCHAN_TCH_F:
1577 return RTP_PT_AMR_FULL;
1578 case GSM_LCHAN_TCH_H:
1579 return RTP_PT_AMR_HALF;
1580 default:
1581 break;
1582 }
1583 default:
1584 break;
1585 }
1586 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1587 "tch_mode == 0x%02x\n & lchan_type == %d",
1588 lchan->tch_mode, lchan->type);
1589 return 0;
1590}
1591
Harald Welte75099262009-02-16 21:12:08 +00001592/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001593static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1594{
1595 struct in_addr ip;
1596 u_int16_t port, conn_id;
1597
1598 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
1599 ip.s_addr = *((u_int32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
1600 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1601 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1602 }
1603
1604 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
1605 port = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
1606 port = ntohs(port);
1607 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1608 lchan->abis_ip.bound_port = port;
1609 }
1610
1611 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
1612 conn_id = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
1613 conn_id = ntohs(conn_id);
1614 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1615 lchan->abis_ip.conn_id = conn_id;
1616 }
1617
1618 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1619 lchan->abis_ip.rtp_payload2 =
1620 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1621 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1622 lchan->abis_ip.rtp_payload2);
1623 }
1624
1625 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1626 lchan->abis_ip.speech_mode =
1627 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1628 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1629 lchan->abis_ip.speech_mode);
1630 }
1631
1632 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
1633 ip.s_addr = *((u_int32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
1634 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1635 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1636 }
1637
1638 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
1639 port = *((u_int16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
1640 port = ntohs(port);
1641 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1642 lchan->abis_ip.connect_port = port;
1643 }
1644}
1645
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001646int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001647{
1648 struct msgb *msg = rsl_msgb_alloc();
1649 struct abis_rsl_dchan_hdr *dh;
1650
1651 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001652 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001653 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1654 dh->chan_nr = lchan2chan_nr(lchan);
1655
Harald Weltef4e79f22009-07-28 18:11:56 +02001656 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001657 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001658 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001659 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001660 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001661
Sylvain Munautb54dda42009-12-20 22:06:40 +01001662 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1663 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1664 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001665
Harald Welte75099262009-02-16 21:12:08 +00001666 msg->trx = lchan->ts->trx;
1667
1668 return abis_rsl_sendmsg(msg);
1669}
1670
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001671int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Welte5e3d91b2009-12-19 16:42:06 +01001672 u_int8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001673{
1674 struct msgb *msg = rsl_msgb_alloc();
1675 struct abis_rsl_dchan_hdr *dh;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001676 u_int32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001677 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001678
1679 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001680 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001681 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1682 dh->chan_nr = lchan2chan_nr(lchan);
1683
Harald Welte5e3d91b2009-12-19 16:42:06 +01001684 /* we need to store these now as MDCX_ACK does not return them :( */
1685 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1686 lchan->abis_ip.connect_port = port;
1687 lchan->abis_ip.connect_ip = ip;
1688
Harald Welte58ca5b72009-07-29 12:12:18 +02001689 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001690 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001691 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001692
Harald Weltef4e79f22009-07-28 18:11:56 +02001693 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001694 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1695 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1696 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1697 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001698
Harald Welte5e3d91b2009-12-19 16:42:06 +01001699 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1700 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
1701 att_ip = (u_int32_t *) msgb_put(msg, sizeof(ip));
1702 *att_ip = ia.s_addr;
1703 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1704 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001705 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001706 if (rtp_payload2)
1707 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1708
Harald Welte75099262009-02-16 21:12:08 +00001709 msg->trx = lchan->ts->trx;
1710
1711 return abis_rsl_sendmsg(msg);
1712}
1713
Harald Weltea72273e2009-12-20 16:51:09 +01001714/* tell BTS to connect RTP stream to our local RTP socket */
1715int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1716{
1717 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1718 int rc;
1719
1720 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1721 ntohs(rs->rtp.sin_local.sin_port),
1722 /* FIXME: use RTP payload of bound socket, not BTS*/
1723 lchan->abis_ip.rtp_payload2);
1724
1725 return rc;
1726}
1727
Harald Welte53cd7ac2010-12-23 12:59:52 +01001728int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001729{
1730 struct msgb *msg = rsl_msgb_alloc();
1731 struct abis_rsl_dchan_hdr *dh;
Harald Welte4563eab2010-03-28 14:42:09 +08001732 u_int8_t msg_type;
1733
1734 if (act)
1735 msg_type = RSL_MT_IPAC_PDCH_ACT;
1736 else
1737 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001738
1739 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001740 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001741 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte53cd7ac2010-12-23 12:59:52 +01001742 dh->chan_nr = ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001743
Harald Welte53cd7ac2010-12-23 12:59:52 +01001744 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001745 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001746
Harald Welte53cd7ac2010-12-23 12:59:52 +01001747 msg->trx = ts->trx;
Harald Welte9c880c92009-10-24 10:29:22 +02001748
1749 return abis_rsl_sendmsg(msg);
1750}
1751
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001752static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001753{
1754 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1755 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301756 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001757
1758 /* the BTS has acknowledged a local bind, it now tells us the IP
1759 * address and port number to which it has bound the given logical
1760 * channel */
1761
1762 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1763 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1764 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001765 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001766 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001767 return -EINVAL;
1768 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001769
Harald Welte5e3d91b2009-12-19 16:42:06 +01001770 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001771
1772 /* in case we don't use direct BTS-to-BTS RTP */
1773 if (!ipacc_rtp_direct) {
1774 int rc;
1775 /* the BTS has successfully bound a TCH to a local ip/port,
1776 * which means we can connect our UDP socket to it */
1777 if (lchan->abis_ip.rtp_socket) {
1778 rtp_socket_free(lchan->abis_ip.rtp_socket);
1779 lchan->abis_ip.rtp_socket = NULL;
1780 }
1781
1782 lchan->abis_ip.rtp_socket = rtp_socket_create();
1783 if (!lchan->abis_ip.rtp_socket)
1784 goto out_err;
1785
1786 rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
1787 lchan->abis_ip.bound_ip,
1788 lchan->abis_ip.bound_port);
1789 if (rc < 0)
1790 goto out_err;
1791 }
1792
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001793 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001794
Harald Welte75099262009-02-16 21:12:08 +00001795 return 0;
Harald Welte17f5bf62009-12-20 15:42:44 +01001796out_err:
1797 return -EIO;
Harald Welte75099262009-02-16 21:12:08 +00001798}
1799
Harald Welte5e3d91b2009-12-19 16:42:06 +01001800static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1801{
1802 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1803 struct tlv_parsed tv;
1804 struct gsm_lchan *lchan = msg->lchan;
1805
1806 /* the BTS has acknowledged a remote connect request and
1807 * it now tells us the IP address and port number to which it has
1808 * connected the given logical channel */
1809
1810 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1811 ipac_parse_rtp(lchan, &tv);
1812 dispatch_signal(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
1813
1814 return 0;
1815}
1816
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001817static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001818{
1819 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1820 struct tlv_parsed tv;
Harald Welte17f5bf62009-12-20 15:42:44 +01001821 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001822
1823 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001824
Harald Welte8830e072009-07-28 17:58:09 +02001825 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001826 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001827 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001828
Harald Welte17f5bf62009-12-20 15:42:44 +01001829 /* the BTS tells us a RTP stream has been disconnected */
1830 if (lchan->abis_ip.rtp_socket) {
1831 rtp_socket_free(lchan->abis_ip.rtp_socket);
1832 lchan->abis_ip.rtp_socket = NULL;
1833 }
1834
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001835 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001836
Harald Welte75099262009-02-16 21:12:08 +00001837 return 0;
1838}
1839
1840static int abis_rsl_rx_ipacc(struct msgb *msg)
1841{
1842 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001843 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001844 int rc = 0;
1845
1846 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001847 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001848
1849 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001850 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001851 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001852 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001853 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001854 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001855 /* somehow the BTS was unable to bind the lchan to its local
1856 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001857 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001858 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001859 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001860 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001861 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001862 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001863 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001864 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001865 /* somehow the BTS was unable to connect the lchan to a remote
1866 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001867 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001868 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001869 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001870 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001871 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001872 break;
1873 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001874 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001875 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001876 break;
1877 }
Harald Welte6dab0552009-05-01 17:21:37 +00001878 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001879
1880 return rc;
1881}
1882
1883
Harald Welte52b1f982008-12-23 20:25:15 +00001884/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001885int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001886{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001887 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00001888 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001889
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001890 if (!msg) {
1891 DEBUGP(DRSL, "Empty RSL msg?..\n");
1892 return -1;
1893 }
1894
1895 if (msgb_l2len(msg) < sizeof(*rslh)) {
1896 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
1897 return -1;
1898 }
1899
1900 rslh = msgb_l2(msg);
1901
Harald Welte52b1f982008-12-23 20:25:15 +00001902 switch (rslh->msg_discr & 0xfe) {
1903 case ABIS_RSL_MDISC_RLL:
1904 rc = abis_rsl_rx_rll(msg);
1905 break;
1906 case ABIS_RSL_MDISC_DED_CHAN:
1907 rc = abis_rsl_rx_dchan(msg);
1908 break;
1909 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001910 rc = abis_rsl_rx_cchan(msg);
1911 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001912 case ABIS_RSL_MDISC_TRX:
1913 rc = abis_rsl_rx_trx(msg);
1914 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001915 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001916 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00001917 rslh->msg_discr);
1918 break;
Harald Welte75099262009-02-16 21:12:08 +00001919 case ABIS_RSL_MDISC_IPACCESS:
1920 rc = abis_rsl_rx_ipacc(msg);
1921 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001922 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001923 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1924 "0x%02x\n", rslh->msg_discr);
Harald Welte52b1f982008-12-23 20:25:15 +00001925 return -EINVAL;
1926 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001927 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001928 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001929}
Holger Freyther3b72a892009-02-04 00:31:39 +00001930
Holger Freyther3b72a892009-02-04 00:31:39 +00001931/* From Table 10.5.33 of GSM 04.08 */
1932int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1933{
Harald Weltea43f7892009-12-01 18:04:30 +05301934 if (bts->si_common.chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1935 return MAX(1, (3 - bts->si_common.chan_desc.bs_ag_blks_res))
1936 * (bts->si_common.chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001937 } else {
Harald Weltea43f7892009-12-01 18:04:30 +05301938 return (9 - bts->si_common.chan_desc.bs_ag_blks_res)
1939 * (bts->si_common.chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001940 }
1941}
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08001942
1943int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1944 uint8_t cb_command, const uint8_t *data, int len)
1945{
1946 struct abis_rsl_dchan_hdr *dh;
1947 struct msgb *cb_cmd;
1948
1949 cb_cmd = rsl_msgb_alloc();
1950 if (!cb_cmd)
1951 return -1;
1952
1953 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1954 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
1955 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
1956
1957 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
1958 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
1959
1960 cb_cmd->trx = bts->c0;
1961
1962 return abis_rsl_sendmsg(cb_cmd);
1963}