blob: 8a326def9997fa7b38ad8c9af3a57a7d5c2add26 [file] [log] [blame]
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte59b04682009-06-10 05:40:52 +08002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Weltea22d36b2010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte59b04682009-06-10 05:40:52 +08005 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
Harald Welte0e3e88e2011-01-01 15:25:50 +01009 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
Harald Welte59b04682009-06-10 05:40:52 +080011 * (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
Harald Welte0e3e88e2011-01-01 15:25:50 +010016 * GNU Affero General Public License for more details.
Harald Welte59b04682009-06-10 05:40:52 +080017 *
Harald Welte0e3e88e2011-01-01 15:25:50 +010018 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte59b04682009-06-10 05:40:52 +080020 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <errno.h>
Harald Welte59b04682009-06-10 05:40:52 +080026#include <netinet/in.h>
27#include <arpa/inet.h>
28
29#include <openbsc/gsm_data.h>
30#include <openbsc/gsm_04_08.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010031#include <osmocom/gsm/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080032#include <openbsc/abis_rsl.h>
33#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020034#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080035#include <openbsc/debug.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010036#include <osmocom/gsm/tlv.h>
Harald Welte59b04682009-06-10 05:40:52 +080037#include <openbsc/paging.h>
38#include <openbsc/signal.h>
Harald Weltec20bd1d2009-11-29 19:07:28 +010039#include <openbsc/meas_rep.h>
Harald Welte50517742009-12-20 15:42:44 +010040#include <openbsc/rtp_proxy.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010041#include <osmocom/gsm/rsl.h>
Harald Welte59b04682009-06-10 05:40:52 +080042
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010043#include <osmocom/core/talloc.h>
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080044
Harald Welte59b04682009-06-10 05:40:52 +080045#define RSL_ALLOC_SIZE 1024
46#define RSL_ALLOC_HEADROOM 128
47
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080048static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
49
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010050static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
51 struct gsm_meas_rep *resp)
52{
53 struct lchan_signal_data sig;
54 sig.lchan = lchan;
55 sig.mr = resp;
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +020056 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010057}
58
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020059static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080060{
61 /* mask off the transparent bit ? */
62 msg_type &= 0xfe;
63
64 if ((msg_type & 0xf0) == 0x00)
65 return ABIS_RSL_MDISC_RLL;
66 if ((msg_type & 0xf0) == 0x10) {
67 if (msg_type >= 0x19 && msg_type <= 0x22)
68 return ABIS_RSL_MDISC_TRX;
69 else
70 return ABIS_RSL_MDISC_COM_CHAN;
71 }
72 if ((msg_type & 0xe0) == 0x20)
73 return ABIS_RSL_MDISC_DED_CHAN;
74
75 return ABIS_RSL_MDISC_LOC;
76}
77
78static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020079 uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080080{
81 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
82 dh->c.msg_type = msg_type;
83 dh->ie_chan = RSL_IE_CHAN_NR;
84}
85
Harald Welte59b04682009-06-10 05:40:52 +080086/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020087struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte59b04682009-06-10 05:40:52 +080088{
89 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020090 uint8_t ts_nr = chan_nr & 0x07;
91 uint8_t cbits = chan_nr >> 3;
92 uint8_t lch_idx;
Harald Welte59b04682009-06-10 05:40:52 +080093 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
94
95 if (cbits == 0x01) {
96 lch_idx = 0; /* TCH/F */
Harald Welte37884ed2009-10-24 10:25:50 +020097 if (ts->pchan != GSM_PCHAN_TCH_F &&
98 ts->pchan != GSM_PCHAN_PDCH &&
99 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100100 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800101 chan_nr, ts->pchan);
102 } else if ((cbits & 0x1e) == 0x02) {
103 lch_idx = cbits & 0x1; /* TCH/H */
104 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100105 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800106 chan_nr, ts->pchan);
107 } else if ((cbits & 0x1c) == 0x04) {
108 lch_idx = cbits & 0x3; /* SDCCH/4 */
109 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100110 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800111 chan_nr, ts->pchan);
112 } else if ((cbits & 0x18) == 0x08) {
113 lch_idx = cbits & 0x7; /* SDCCH/8 */
114 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100115 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800116 chan_nr, ts->pchan);
117 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
118 lch_idx = 0;
119 if (ts->pchan != GSM_PCHAN_CCCH &&
120 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100121 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800122 chan_nr, ts->pchan);
123 /* FIXME: we should not return first sdcch4 !!! */
124 } else {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100125 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800126 return NULL;
127 }
128
129 lchan = &ts->lchan[lch_idx];
Harald Welte51d2a592010-03-26 21:28:59 +0800130 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800131 if (lchan->conn)
132 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800133
134 return lchan;
135}
136
Harald Welte59b04682009-06-10 05:40:52 +0800137/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200138uint64_t str_to_imsi(const char *imsi_str)
Harald Welte59b04682009-06-10 05:40:52 +0800139{
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200140 uint64_t ret;
Harald Welte59b04682009-06-10 05:40:52 +0800141
142 ret = strtoull(imsi_str, NULL, 10);
143
144 return ret;
145}
146
Harald Welte59b04682009-06-10 05:40:52 +0800147static struct msgb *rsl_msgb_alloc(void)
148{
Harald Welte9cfc9352009-06-26 19:39:35 +0200149 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
150 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800151}
152
153#define MACBLOCK_SIZE 23
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200154static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800155{
156 memcpy(out, in, len);
157
158 if (len < MACBLOCK_SIZE)
159 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
160}
161
Harald Welted2dd9de2009-08-30 15:37:11 +0900162/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200163static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welted2dd9de2009-08-30 15:37:11 +0900164{
165 *out++ = lchan->encr.alg_id & 0xff;
166 if (lchan->encr.key_len)
167 memcpy(out, lchan->encr.key, lchan->encr.key_len);
168 return lchan->encr.key_len + 1;
169}
170
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200171static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200172{
Harald Welte59b04682009-06-10 05:40:52 +0800173 int i;
174
Harald Weltede4477a2009-12-24 12:20:20 +0100175 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200176 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200177 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100178 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800179}
180
Harald Welte32951ea2011-08-10 23:26:33 +0200181static void lchan_act_tmr_cb(void *data)
182{
183 struct gsm_lchan *lchan = data;
184
185 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during activation!\n",
186 gsm_lchan_name(lchan));
187
188 lchan->state = LCHAN_S_NONE;
189}
190
191static void lchan_deact_tmr_cb(void *data)
192{
193 struct gsm_lchan *lchan = data;
194
195 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during deactivation!\n",
196 gsm_lchan_name(lchan));
197
198 lchan->state = LCHAN_S_NONE;
199}
200
201
Harald Welte59b04682009-06-10 05:40:52 +0800202/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200203int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
204 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800205{
206 struct abis_rsl_dchan_hdr *dh;
207 struct msgb *msg = rsl_msgb_alloc();
208
209 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
210 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
211 dh->chan_nr = RSL_CHAN_BCCH;
212
213 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
214 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
215
216 msg->trx = trx;
217
218 return abis_rsl_sendmsg(msg);
219}
220
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200221int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
222 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800223{
224 struct abis_rsl_common_hdr *ch;
225 struct msgb *msg = rsl_msgb_alloc();
226
227 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
228 ch->msg_discr = ABIS_RSL_MDISC_TRX;
229 ch->msg_type = RSL_MT_SACCH_FILL;
230
231 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
232 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
233
234 msg->trx = trx;
235
236 return abis_rsl_sendmsg(msg);
237}
238
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200239int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
240 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100241{
242 struct abis_rsl_dchan_hdr *dh;
243 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200244 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100245
246 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
247 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
248 dh->chan_nr = chan_nr;
249
250 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
251 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
252
253 msg->trx = lchan->ts->trx;
254
255 return abis_rsl_sendmsg(msg);
256}
257
Harald Welte91afe4c2009-06-20 18:15:19 +0200258int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
259{
260 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200261 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200262 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200263
264 db = abs(db);
265 if (db > 30)
266 return -EINVAL;
267
Harald Welteed831842009-06-27 03:09:08 +0200268 msg = rsl_msgb_alloc();
269
Harald Welte91afe4c2009-06-20 18:15:19 +0200270 lchan->bs_power = db/2;
271 if (fpc)
272 lchan->bs_power |= 0x10;
273
274 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
275 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
276 dh->chan_nr = chan_nr;
277
278 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
279
280 msg->trx = lchan->ts->trx;
281
282 return abis_rsl_sendmsg(msg);
283}
284
Harald Welte91afe4c2009-06-20 18:15:19 +0200285int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
286{
287 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200288 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200289 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200290 int ctl_lvl;
291
Harald Weltec4dcda02009-08-09 14:45:18 +0200292 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200293 if (ctl_lvl < 0)
294 return ctl_lvl;
295
Harald Welteed831842009-06-27 03:09:08 +0200296 msg = rsl_msgb_alloc();
297
Harald Welte91afe4c2009-06-20 18:15:19 +0200298 lchan->ms_power = ctl_lvl;
299
300 if (fpc)
301 lchan->ms_power |= 0x20;
302
303 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
304 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
305 dh->chan_nr = chan_nr;
306
307 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
308
309 msg->trx = lchan->ts->trx;
310
311 return abis_rsl_sendmsg(msg);
312}
313
Harald Welte39274f42009-07-29 15:41:29 +0200314static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
315 struct gsm_lchan *lchan)
316{
317 memset(cm, 0, sizeof(cm));
318
319 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther21d63ff2010-09-06 09:25:48 +0800320 if (lchan->ts->trx->bts->network->dtx_enabled)
321 cm->dtx_dtu = 0x03;
322 else
323 cm->dtx_dtu = 0x00;
Harald Welte39274f42009-07-29 15:41:29 +0200324
325 /* set TCH Speech/Data */
326 cm->spd_ind = lchan->rsl_cmode;
327
Harald Welte951e3512009-11-27 08:55:16 +0100328 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
329 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100330 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100331 "but tch_mode != signalling\n");
332
Harald Welte39274f42009-07-29 15:41:29 +0200333 switch (lchan->type) {
334 case GSM_LCHAN_SDCCH:
335 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
336 break;
337 case GSM_LCHAN_TCH_F:
338 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
339 break;
340 case GSM_LCHAN_TCH_H:
341 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
342 break;
343 case GSM_LCHAN_NONE:
344 case GSM_LCHAN_UNKNOWN:
345 default:
346 return -EINVAL;
347 }
348
349 switch (lchan->tch_mode) {
350 case GSM48_CMODE_SIGN:
351 cm->chan_rate = 0;
352 break;
353 case GSM48_CMODE_SPEECH_V1:
354 cm->chan_rate = RSL_CMOD_SP_GSM1;
355 break;
356 case GSM48_CMODE_SPEECH_EFR:
357 cm->chan_rate = RSL_CMOD_SP_GSM2;
358 break;
359 case GSM48_CMODE_SPEECH_AMR:
360 cm->chan_rate = RSL_CMOD_SP_GSM3;
361 break;
362 case GSM48_CMODE_DATA_14k5:
363 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
364 break;
365 case GSM48_CMODE_DATA_12k0:
366 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
367 break;
368 case GSM48_CMODE_DATA_6k0:
369 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
370 break;
371 default:
372 return -EINVAL;
373 }
374
375 return 0;
376}
377
Harald Welte59b04682009-06-10 05:40:52 +0800378/* Chapter 8.4.1 */
379#if 0
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200380int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
381 uint8_t act_type,
Harald Welte59b04682009-06-10 05:40:52 +0800382 struct rsl_ie_chan_mode *chan_mode,
383 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200384 uint8_t bs_power, uint8_t ms_power,
385 uint8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800386{
387 struct abis_rsl_dchan_hdr *dh;
388 struct msgb *msg = rsl_msgb_alloc();
389
390 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
391 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
392 dh->chan_nr = chan_nr;
393
394 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
395 /* For compatibility with Phase 1 */
396 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200397 (uint8_t *) chan_mode);
Harald Welte59b04682009-06-10 05:40:52 +0800398 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200399 (uint8_t *) chan_ident);
Harald Welte59b04682009-06-10 05:40:52 +0800400#if 0
401 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200402 (uint8_t *) &encr_info);
Harald Welte59b04682009-06-10 05:40:52 +0800403#endif
404 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
405 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
406 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
407
408 msg->trx = trx;
409
410 return abis_rsl_sendmsg(msg);
411}
412#endif
413
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200414int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
415 uint8_t ta, uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800416{
417 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200418 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200419 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200420 uint8_t *len;
Harald Welte59b04682009-06-10 05:40:52 +0800421
Harald Weltee6d51f92011-06-25 10:02:33 +0200422 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800423 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200424 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800425
Harald Welte39274f42009-07-29 15:41:29 +0200426 rc = channel_mode_from_lchan(&cm, lchan);
427 if (rc < 0)
428 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800429
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800430 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200431 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800432
Harald Welteed831842009-06-27 03:09:08 +0200433 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800434 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
435 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
436 dh->chan_nr = chan_nr;
437
438 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800439 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200440 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800441
442 /*
443 * The Channel Identification is needed for Phase1 phones
444 * and it contains the GSM48 Channel Description and the
445 * Mobile Allocation. The GSM 08.58 asks for the Mobile
446 * Allocation to have a length of zero. We are using the
447 * msgb_l3len to calculate the length of both messages.
448 */
laforgef723cf02010-06-20 21:38:19 +0200449 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200450 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200451 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800452
453 if (lchan->ts->hopping.enabled)
454 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
455 lchan->ts->hopping.ma_data);
456 else
457 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800458
459 /* update the calculated size */
460 msg->l3h = len + 1;
461 *len = msgb_l3len(msg);
462
Harald Welted2dd9de2009-08-30 15:37:11 +0900463 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200464 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900465 rc = build_encr_info(encr_info, lchan);
466 if (rc > 0)
467 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
468 }
469
Harald Welteb90d7bd2009-12-17 00:31:10 +0100470 switch (act_type) {
471 case RSL_ACT_INTER_ASYNC:
472 case RSL_ACT_INTER_SYNC:
473 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
474 break;
475 default:
476 break;
477 }
478
Harald Welte59b04682009-06-10 05:40:52 +0800479 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
480 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
481 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
482
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100483 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
484 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200485 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100486
Harald Welte59b04682009-06-10 05:40:52 +0800487 msg->trx = lchan->ts->trx;
488
489 return abis_rsl_sendmsg(msg);
490}
491
Harald Welte8e770492009-07-29 11:38:15 +0200492/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800493int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
494{
495 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200496 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200497 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800498
Harald Weltee6d51f92011-06-25 10:02:33 +0200499 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800500 struct rsl_ie_chan_mode cm;
501
Harald Welte39274f42009-07-29 15:41:29 +0200502 rc = channel_mode_from_lchan(&cm, lchan);
503 if (rc < 0)
504 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800505
Harald Welteed831842009-06-27 03:09:08 +0200506 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800507 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
508 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
509 dh->chan_nr = chan_nr;
510
511 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200512 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900513
514 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200515 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900516 rc = build_encr_info(encr_info, lchan);
517 if (rc > 0)
518 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
519 }
520
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100521 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
522 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200523 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100524 }
525
Harald Welted2dd9de2009-08-30 15:37:11 +0900526 msg->trx = lchan->ts->trx;
527
528 return abis_rsl_sendmsg(msg);
529}
530
531/* Chapter 8.4.6: Send the encryption command with given L3 info */
532int rsl_encryption_cmd(struct msgb *msg)
533{
534 struct abis_rsl_dchan_hdr *dh;
535 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200536 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200537 uint8_t encr_info[MAX_A5_KEY_LEN+2];
538 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900539 int rc;
540
541 /* First push the L3 IE tag and length */
542 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
543
544 /* then the link identifier (SAPI0, main sign link) */
545 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
546
547 /* then encryption information */
548 rc = build_encr_info(encr_info, lchan);
549 if (rc <= 0)
550 return rc;
551 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
552
553 /* and finally the DCHAN header */
554 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
555 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
556 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800557
558 msg->trx = lchan->ts->trx;
559
560 return abis_rsl_sendmsg(msg);
561}
562
Harald Welte85a163c2009-08-10 11:43:22 +0200563/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200564int rsl_deact_sacch(struct gsm_lchan *lchan)
565{
566 struct abis_rsl_dchan_hdr *dh;
567 struct msgb *msg = rsl_msgb_alloc();
568
569 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
570 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200571 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200572
573 msg->lchan = lchan;
574 msg->trx = lchan->ts->trx;
575
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100576 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200577
578 return abis_rsl_sendmsg(msg);
579}
580
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800581static void error_timeout_cb(void *data)
582{
583 struct gsm_lchan *lchan = data;
584 if (lchan->state != LCHAN_S_REL_ERR) {
585 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
586 gsm_lchan_name(lchan), lchan->state);
587 return;
588 }
589
590 /* go back to the none state */
591 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800592 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800593}
594
Harald Welte08011e22011-03-04 13:41:31 +0100595static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
596
Harald Welte85a163c2009-08-10 11:43:22 +0200597/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800598static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte59b04682009-06-10 05:40:52 +0800599{
600 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800601 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100602 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800603
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800604 if (lchan->state == LCHAN_S_REL_ERR) {
605 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
606 gsm_lchan_name(lchan));
607 return -1;
608 }
609
610 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800611 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
612 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200613 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800614
615 msg->lchan = lchan;
616 msg->trx = lchan->ts->trx;
617
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800618 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
619
620 if (error) {
621 /*
622 * the nanoBTS sends RLL release indications after the channel release. This can
623 * be a problem when we have reassigned the channel to someone else and then can
624 * not figure out who used this channel.
625 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800626 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800627 lchan->error_timer.data = lchan;
628 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +0200629 osmo_timer_schedule(&lchan->error_timer,
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800630 msg->trx->bts->network->T3111 + 2, 0);
631 }
Harald Welte59b04682009-06-10 05:40:52 +0800632
Harald Welte32951ea2011-08-10 23:26:33 +0200633 /* Start another timer or assume the BTS sends a ACK/NACK? */
634 lchan->act_timer.cb = lchan_deact_tmr_cb;
635 lchan->act_timer.data = lchan;
636 osmo_timer_schedule(&lchan->act_timer, 4, 0);
637
Harald Welte08011e22011-03-04 13:41:31 +0100638 rc = abis_rsl_sendmsg(msg);
639
Harald Welte85a163c2009-08-10 11:43:22 +0200640 /* BTS will respond by RF CHAN REL ACK */
Harald Welte6bddd822011-01-14 23:18:59 +0100641#ifdef HSL_SR_1_0
Harald Welte08011e22011-03-04 13:41:31 +0100642 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
643 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
644 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte6bddd822011-01-14 23:18:59 +0100645#endif
Harald Welte08011e22011-03-04 13:41:31 +0100646
647 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800648}
649
Harald Welte9773f6c2011-01-14 14:16:16 +0100650static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
651{
652
653 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
654
Harald Welte32951ea2011-08-10 23:26:33 +0200655 osmo_timer_del(&lchan->act_timer);
656
Harald Welte9773f6c2011-01-14 14:16:16 +0100657 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
658 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
659 gsm_lchan_name(lchan),
660 gsm_lchans_name(lchan->state));
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +0200661 osmo_timer_del(&lchan->T3111);
Harald Welte9773f6c2011-01-14 14:16:16 +0100662 /* we have an error timer pending to release that */
663 if (lchan->state != LCHAN_S_REL_ERR)
664 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
665 lchan_free(lchan);
666
667 return 0;
668}
669
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200670int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
671 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800672{
673 struct abis_rsl_dchan_hdr *dh;
674 struct msgb *msg = rsl_msgb_alloc();
675
676 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
677 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
678 dh->chan_nr = RSL_CHAN_PCH_AGCH;
679
680 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
681 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
682 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
683
684 msg->trx = bts->c0;
685
686 return abis_rsl_sendmsg(msg);
687}
688
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200689int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800690{
691 int i, len = strlen(str_in);
692
693 for (i = 0; i < len; i++) {
694 int num = str_in[i] - 0x30;
695 if (num < 0 || num > 9)
696 return -1;
697 if (i % 2 == 0)
698 bcd_out[i/2] = num;
699 else
700 bcd_out[i/2] |= (num << 4);
701 }
702
703 return 0;
704}
705
706/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200707int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800708{
709 struct msgb *msg = rsl_msgb_alloc();
710 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200711 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800712
713 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
714 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
715 dh->chan_nr = RSL_CHAN_PCH_AGCH;
716
717 switch (bts->type) {
718 case GSM_BTS_TYPE_BS11:
719 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
720 break;
721 default:
722 /* If phase 2, construct a FULL_IMM_ASS_INFO */
723 pad_macblock(buf, val, len);
724 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
725 break;
726 }
727
728 msg->trx = bts->c0;
729
730 return abis_rsl_sendmsg(msg);
731}
732
Harald Welte4684e632009-08-10 09:51:40 +0200733/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200734int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200735{
736 struct msgb *msg = rsl_msgb_alloc();
737 struct abis_rsl_dchan_hdr *dh;
738
739 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
740 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200741 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200742 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200743 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200744
Harald Weltede4477a2009-12-24 12:20:20 +0100745 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200746 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200747
748 msg->trx = lchan->ts->trx;
749
Harald Welte4684e632009-08-10 09:51:40 +0200750 return abis_rsl_sendmsg(msg);
751}
752
753
Harald Welte59b04682009-06-10 05:40:52 +0800754/* Send "DATA REQUEST" message with given L3 Info payload */
755/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200756int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800757{
Harald Welte59b04682009-06-10 05:40:52 +0800758 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100759 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800760 return -EINVAL;
761 }
762
Harald Weltee6d51f92011-06-25 10:02:33 +0200763 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100764 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800765
766 msg->trx = msg->lchan->ts->trx;
767
768 return abis_rsl_sendmsg(msg);
769}
770
Harald Welteed9a5ab2009-08-09 13:47:35 +0200771/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
772/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200773int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200774{
Harald Weltea22d36b2010-03-04 10:33:10 +0100775 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200776
Harald Weltee6d51f92011-06-25 10:02:33 +0200777 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100778 link_id, 0);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200779 msg->trx = lchan->ts->trx;
780
781 return abis_rsl_sendmsg(msg);
782}
783
Harald Welte0f2e3c12009-08-08 13:15:07 +0200784/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
785 This is what higher layers should call. The BTS then responds with
786 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
787 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
788 lchan_free() */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200789int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200790{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200791
Harald Weltea22d36b2010-03-04 10:33:10 +0100792 struct msgb *msg;
793
Harald Weltee6d51f92011-06-25 10:02:33 +0200794 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100795 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800796 /* 0 is normal release, 1 is local end */
797 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200798
Harald Weltec88a4432009-12-29 10:44:17 +0100799 /* FIXME: start some timer in case we don't receive a REL ACK ? */
800
Harald Welte0f2e3c12009-08-08 13:15:07 +0200801 msg->trx = lchan->ts->trx;
802
803 return abis_rsl_sendmsg(msg);
804}
805
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200806int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
807{
808 lchan->state = state;
809 return 0;
810}
811
Harald Welte59b04682009-06-10 05:40:52 +0800812/* Chapter 8.4.2: Channel Activate Acknowledge */
813static int rsl_rx_chan_act_ack(struct msgb *msg)
814{
815 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
816
817 /* BTS has confirmed channel activation, we now need
818 * to assign the activated channel to the MS */
819 if (rslh->ie_chan != RSL_IE_CHAN_NR)
820 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100821
Harald Welte32951ea2011-08-10 23:26:33 +0200822 osmo_timer_del(&msg->lchan->act_timer);
823
Harald Weltec88a4432009-12-29 10:44:17 +0100824 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100825 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
826 gsm_lchan_name(msg->lchan),
827 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200828 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100829
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800830 if (msg->lchan->rqd_ref) {
831 rsl_send_imm_assignment(msg->lchan);
832 talloc_free(msg->lchan->rqd_ref);
833 msg->lchan->rqd_ref = NULL;
834 msg->lchan->rqd_ta = 0;
835 }
836
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100837 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100838
Harald Welte59b04682009-06-10 05:40:52 +0800839 return 0;
840}
841
842/* Chapter 8.4.3: Channel Activate NACK */
843static int rsl_rx_chan_act_nack(struct msgb *msg)
844{
845 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
846 struct tlv_parsed tp;
847
Harald Welte32951ea2011-08-10 23:26:33 +0200848 osmo_timer_del(&msg->lchan->act_timer);
849
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100850 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100851 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100852
Harald Welte59b04682009-06-10 05:40:52 +0800853 /* BTS has rejected channel activation ?!? */
854 if (dh->ie_chan != RSL_IE_CHAN_NR)
855 return -EINVAL;
856
857 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100858 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200859 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100860 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +0200861 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100862 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200863 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100864 } else
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200865 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200866
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100867 LOGPC(DRSL, LOGL_ERROR, "\n");
868
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100869 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100870
Harald Weltecddb9802009-08-09 19:50:08 +0200871 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800872 return 0;
873}
874
875/* Chapter 8.4.4: Connection Failure Indication */
876static int rsl_rx_conn_fail(struct msgb *msg)
877{
878 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
879 struct tlv_parsed tp;
880
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100881 /* FIXME: print which channel */
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100882 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100883 gsm_lchan_name(msg->lchan));
Harald Welte59b04682009-06-10 05:40:52 +0800884
885 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
886
Harald Weltef1a168d2009-07-28 17:58:09 +0200887 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +0100888 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +0200889 TLVP_LEN(&tp, RSL_IE_CAUSE));
890
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100891 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800892 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +0200893 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800894 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800895}
896
Harald Weltec20bd1d2009-11-29 19:07:28 +0100897static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
898 const char *prefix)
899{
Harald Welte0e4fa782009-12-16 16:52:07 +0100900 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
901 prefix, rxlev2dbm(mru->full.rx_lev),
902 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +0100903 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
904 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
905}
906
907static void print_meas_rep(struct gsm_meas_rep *mr)
908{
Harald Welte0e4fa782009-12-16 16:52:07 +0100909 int i;
910
Harald Weltec20bd1d2009-11-29 19:07:28 +0100911 DEBUGP(DMEAS, "MEASUREMENT RESULT NR=%d ", mr->nr);
912
913 if (mr->flags & MEAS_REP_F_DL_DTX)
914 DEBUGPC(DMEAS, "DTXd ");
915
916 print_meas_rep_uni(&mr->ul, "ul");
917 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
918 if (mr->flags & MEAS_REP_F_MS_TO)
919 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
920
921 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +0100922 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100923 DEBUGPC(DMEAS, "L1_FPC=%u ",
924 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
925 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
926 }
927
928 if (mr->flags & MEAS_REP_F_UL_DTX)
929 DEBUGPC(DMEAS, "DTXu ");
930 if (mr->flags & MEAS_REP_F_BA1)
931 DEBUGPC(DMEAS, "BA1 ");
932 if (!(mr->flags & MEAS_REP_F_DL_VALID))
933 DEBUGPC(DMEAS, "NOT VALID ");
934 else
935 print_meas_rep_uni(&mr->dl, "dl");
936
937 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +0100938 if (mr->num_cell == 7)
939 return;
Harald Welte0e4fa782009-12-16 16:52:07 +0100940 for (i = 0; i < mr->num_cell; i++) {
941 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +0100942 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
943 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +0100944 }
Harald Weltec20bd1d2009-11-29 19:07:28 +0100945}
946
Harald Welte59b04682009-06-10 05:40:52 +0800947static int rsl_rx_meas_res(struct msgb *msg)
948{
949 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
950 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +0100951 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200952 uint8_t len;
953 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +0100954 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800955
Harald Welte4baa9c52009-12-21 13:27:11 +0100956 /* check if this channel is actually active */
957 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +0100958 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +0800959 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +0100960 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +0100961 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +0100962 }
Harald Welte4baa9c52009-12-21 13:27:11 +0100963
Harald Weltef9476812009-12-15 21:36:05 +0100964 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +0100965 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +0100966
Harald Welte59b04682009-06-10 05:40:52 +0800967 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
968
Harald Weltec20bd1d2009-11-29 19:07:28 +0100969 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
970 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
971 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
972 return -EIO;
973
974 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +0100975 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100976
977 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
978 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
979 if (len >= 3) {
980 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +0100981 mr->flags |= MEAS_REP_F_DL_DTX;
982 mr->ul.full.rx_lev = val[0] & 0x3f;
983 mr->ul.sub.rx_lev = val[1] & 0x3f;
984 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
985 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +0800986 }
Harald Weltec20bd1d2009-11-29 19:07:28 +0100987
Harald Weltef9476812009-12-15 21:36:05 +0100988 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100989
990 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +0800991 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +0100992 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +0100993 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
994
Harald Weltea1467eb2009-06-20 18:44:35 +0200995 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Weltec20bd1d2009-11-29 19:07:28 +0100996 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +0100997 mr->flags |= MEAS_REP_F_MS_L1;
998 mr->ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100999 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001000 mr->flags |= MEAS_REP_F_FPC;
1001 mr->ms_l1.ta = val[1];
Harald Weltea1467eb2009-06-20 18:44:35 +02001002 }
Harald Welte59b04682009-06-10 05:40:52 +08001003 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001004 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001005 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001006 if (rc < 0)
1007 return rc;
1008 }
1009
Harald Weltef9476812009-12-15 21:36:05 +01001010 print_meas_rep(mr);
Harald Welte59b04682009-06-10 05:40:52 +08001011
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001012 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001013
Harald Welte59b04682009-06-10 05:40:52 +08001014 return 0;
1015}
1016
Harald Welte6720a432009-11-29 22:45:52 +01001017/* Chapter 8.4.7 */
1018static int rsl_rx_hando_det(struct msgb *msg)
1019{
1020 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1021 struct tlv_parsed tp;
1022
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001023 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001024
1025 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1026
1027 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1028 DEBUGPC(DRSL, "access delay = %u\n",
1029 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1030 else
1031 DEBUGPC(DRSL, "\n");
1032
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001033 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001034
1035 return 0;
1036}
1037
Harald Welte59b04682009-06-10 05:40:52 +08001038static int abis_rsl_rx_dchan(struct msgb *msg)
1039{
1040 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1041 int rc = 0;
1042 char *ts_name;
1043
1044 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001045 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001046
Harald Welte59b04682009-06-10 05:40:52 +08001047 switch (rslh->c.msg_type) {
1048 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001049 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001050 rc = rsl_rx_chan_act_ack(msg);
1051 break;
1052 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001053 rc = rsl_rx_chan_act_nack(msg);
1054 break;
1055 case RSL_MT_CONN_FAIL:
1056 rc = rsl_rx_conn_fail(msg);
1057 break;
1058 case RSL_MT_MEAS_RES:
1059 rc = rsl_rx_meas_res(msg);
1060 break;
Harald Welte6720a432009-11-29 22:45:52 +01001061 case RSL_MT_HANDO_DET:
1062 rc = rsl_rx_hando_det(msg);
1063 break;
Harald Welte59b04682009-06-10 05:40:52 +08001064 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001065 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001066 break;
1067 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001068 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001069 break;
1070 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001071 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001072 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001073 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001074 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001075 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001076 break;
1077 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001078 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001079 break;
1080 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001081 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001082 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001083 break;
1084 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001085 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001086 break;
Harald Welte59b04682009-06-10 05:40:52 +08001087 case RSL_MT_PHY_CONTEXT_CONF:
1088 case RSL_MT_PREPROC_MEAS_RES:
1089 case RSL_MT_TALKER_DET:
1090 case RSL_MT_LISTENER_DET:
1091 case RSL_MT_REMOTE_CODEC_CONF_REP:
1092 case RSL_MT_MR_CODEC_MOD_ACK:
1093 case RSL_MT_MR_CODEC_MOD_NACK:
1094 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001095 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1096 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001097 break;
1098 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001099 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1100 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001101 return -EINVAL;
1102 }
1103
1104 return rc;
1105}
1106
1107static int rsl_rx_error_rep(struct msgb *msg)
1108{
1109 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001110 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001111
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001112 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001113
1114 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1115
1116 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001117 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001118 TLVP_LEN(&tp, RSL_IE_CAUSE));
1119
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001120 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001121
1122 return 0;
1123}
1124
1125static int abis_rsl_rx_trx(struct msgb *msg)
1126{
1127 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1128 int rc = 0;
1129
1130 switch (rslh->msg_type) {
1131 case RSL_MT_ERROR_REPORT:
1132 rc = rsl_rx_error_rep(msg);
1133 break;
1134 case RSL_MT_RF_RES_IND:
1135 /* interference on idle channels of TRX */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001136 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001137 break;
1138 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001139 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001140 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
1141 gsm_trx_name(msg->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001142 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001143 case 0x42: /* Nokia specific: SI End ACK */
1144 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1145 break;
1146 case 0x43: /* Nokia specific: SI End NACK */
1147 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1148 break;
Harald Welte59b04682009-06-10 05:40:52 +08001149 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001150 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
1151 "type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001152 return -EINVAL;
1153 }
1154 return rc;
1155}
1156
Harald Welte427dbc42009-08-10 00:26:10 +02001157/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1158static void t3101_expired(void *data)
1159{
1160 struct gsm_lchan *lchan = data;
1161
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001162 rsl_rf_chan_release(lchan, 1);
Harald Welte427dbc42009-08-10 00:26:10 +02001163}
1164
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001165/* If T3111 expires, we will send the RF Channel Request */
1166static void t3111_expired(void *data)
1167{
1168 struct gsm_lchan *lchan = data;
1169
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001170 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001171}
1172
laforge50312e82010-06-21 12:08:52 +02001173#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1174
Harald Weltea00fdd72010-12-23 14:39:29 +01001175/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1176static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1177 unsigned int num_req_refs,
1178 struct gsm48_req_ref *rqd_refs,
1179 uint8_t wait_ind)
1180{
1181 uint8_t buf[GSM_MACBLOCK_LEN];
1182 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1183
1184 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1185 memset(iar, 0, sizeof(*iar));
1186 iar->proto_discr = GSM48_PDISC_RR;
1187 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1188 iar->page_mode = GSM48_PM_SAME;
1189
1190 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1191 iar->wait_ind1 = wait_ind;
1192
1193 if (num_req_refs >= 2)
1194 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1195 else
1196 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1197 iar->wait_ind2 = wait_ind;
1198
1199 if (num_req_refs >= 3)
1200 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1201 else
1202 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1203 iar->wait_ind3 = wait_ind;
1204
1205 if (num_req_refs >= 4)
1206 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1207 else
1208 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1209 iar->wait_ind4 = wait_ind;
1210
1211 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1212}
1213
Harald Welte59b04682009-06-10 05:40:52 +08001214/* MS has requested a channel on the RACH */
1215static int rsl_rx_chan_rqd(struct msgb *msg)
1216{
1217 struct gsm_bts *bts = msg->trx->bts;
1218 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1219 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001220 enum gsm_chan_t lctype;
1221 enum gsm_chreq_reason_t chreq_reason;
1222 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001223 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001224 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001225
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001226 uint16_t arfcn;
1227 uint8_t ts_number, subch;
Harald Welte59b04682009-06-10 05:40:52 +08001228
1229 /* parse request reference to be used in immediate assign */
1230 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1231 return -EINVAL;
1232
1233 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1234
1235 /* parse access delay and use as TA */
1236 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1237 return -EINVAL;
1238 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1239
1240 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1241 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001242 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1243 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001244
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001245 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001246
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001247 /*
1248 * We want LOCATION UPDATES to succeed and will assign a TCH
1249 * if we have no SDCCH available.
1250 */
1251 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1252
Harald Welte59b04682009-06-10 05:40:52 +08001253 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001254 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001255 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001256 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001257 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001258 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001259 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1260 if (bts->network->T3122)
1261 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte59b04682009-06-10 05:40:52 +08001262 return -ENOMEM;
1263 }
1264
Harald Weltec88a4432009-12-29 10:44:17 +01001265 if (lchan->state != LCHAN_S_NONE)
1266 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001267 "in state %s\n", gsm_lchan_name(lchan),
1268 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +02001269 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001270
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001271 /* save the RACH data as we need it after the CHAN ACT ACK */
1272 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1273 if (!lchan->rqd_ref) {
1274 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1275 lchan_free(lchan);
1276 return -ENOMEM;
1277 }
1278
1279 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1280 lchan->rqd_ta = rqd_ta;
1281
Harald Welte59b04682009-06-10 05:40:52 +08001282 ts_number = lchan->ts->nr;
1283 arfcn = lchan->ts->trx->arfcn;
1284 subch = lchan->nr;
1285
Harald Welted2dd9de2009-08-30 15:37:11 +09001286 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001287 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001288 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001289 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001290 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001291
Harald Welte32951ea2011-08-10 23:26:33 +02001292 /* Start another timer or assume the BTS sends a ACK/NACK? */
1293 lchan->act_timer.cb = lchan_act_tmr_cb;
1294 lchan->act_timer.data = lchan;
1295 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1296
Harald Welteb90d7bd2009-12-17 00:31:10 +01001297 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001298
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001299 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1300 "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
1301 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1302 rqd_ref->ra);
1303 return 0;
1304}
1305
1306static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1307{
1308 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001309 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001310 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1311
Harald Welte59b04682009-06-10 05:40:52 +08001312 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001313 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001314 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001315 ia->proto_discr = GSM48_PDISC_RR;
1316 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1317 ia->page_mode = GSM48_PM_SAME;
1318 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001319
Harald Welte59b04682009-06-10 05:40:52 +08001320 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001321 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1322 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001323 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001324 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001325 } else {
laforgee06d5982010-06-20 15:18:46 +02001326 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1327 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001328 }
Harald Welte07f32182010-06-28 18:41:27 +02001329 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1330 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001331
Harald Welte427dbc42009-08-10 00:26:10 +02001332 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1333 lchan->T3101.cb = t3101_expired;
1334 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001335 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001336
1337 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001338 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001339}
1340
1341/* MS has requested a channel on the RACH */
1342static int rsl_rx_ccch_load(struct msgb *msg)
1343{
1344 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001345 uint16_t pg_buf_space;
1346 uint16_t rach_slot_count = -1;
1347 uint16_t rach_busy_count = -1;
1348 uint16_t rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001349
1350 switch (rslh->data[0]) {
1351 case RSL_IE_PAGING_LOAD:
1352 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Harald Welte008a4922010-04-19 10:24:07 +02001353 if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
1354 /* paging load below configured threshold, use 50 as default */
1355 pg_buf_space = 50;
1356 }
Harald Welte59b04682009-06-10 05:40:52 +08001357 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1358 break;
1359 case RSL_IE_RACH_LOAD:
1360 if (msg->data_len >= 7) {
1361 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1362 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1363 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1364 }
1365 break;
1366 default:
1367 break;
1368 }
1369
1370 return 0;
1371}
1372
1373static int abis_rsl_rx_cchan(struct msgb *msg)
1374{
1375 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1376 int rc = 0;
1377
1378 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1379
1380 switch (rslh->c.msg_type) {
1381 case RSL_MT_CHAN_RQD:
1382 /* MS has requested a channel on the RACH */
1383 rc = rsl_rx_chan_rqd(msg);
1384 break;
1385 case RSL_MT_CCCH_LOAD_IND:
1386 /* current load on the CCCH */
1387 rc = rsl_rx_ccch_load(msg);
1388 break;
1389 case RSL_MT_DELETE_IND:
1390 /* CCCH overloaded, IMM_ASSIGN was dropped */
1391 case RSL_MT_CBCH_LOAD_IND:
1392 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001393 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1394 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001395 break;
1396 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001397 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1398 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001399 return -EINVAL;
1400 }
1401
1402 return rc;
1403}
1404
1405static int rsl_rx_rll_err_ind(struct msgb *msg)
1406{
1407 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001408 uint8_t *rlm_cause = rllh->data;
Harald Welte59b04682009-06-10 05:40:52 +08001409
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001410 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001411 gsm_lchan_name(msg->lchan),
Harald Welteb30935e2010-03-25 12:13:02 +08001412 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteed9a5ab2009-08-09 13:47:35 +02001413
1414 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001415
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001416 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001417 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001418 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001419 }
Harald Welte692f5852009-07-04 09:40:05 +02001420
Harald Welte59b04682009-06-10 05:40:52 +08001421 return 0;
1422}
1423
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001424static void rsl_handle_release(struct gsm_lchan *lchan)
1425{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001426 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001427 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001428
1429 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001430 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001431 return;
1432
1433 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1434 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1435 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001436 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001437 gsm_lchan_name(lchan), sapi);
1438 return;
1439 }
1440
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001441
1442
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001443 /* wait a bit to send the RF Channel Release */
1444 lchan->T3111.cb = t3111_expired;
1445 lchan->T3111.data = lchan;
1446 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001447 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001448}
1449
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001450/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001451 0x02, 0x06,
1452 0x01, 0x20,
1453 0x02, 0x00,
1454 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1455
1456static int abis_rsl_rx_rll(struct msgb *msg)
1457{
1458 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1459 int rc = 0;
1460 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001461 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001462
1463 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001464 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001465 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001466
1467 switch (rllh->c.msg_type) {
1468 case RSL_MT_DATA_IND:
1469 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001470 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001471 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1472 rllh->data[0] == RSL_IE_L3_INFO) {
1473 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001474 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001475 }
1476 break;
1477 case RSL_MT_EST_IND:
1478 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001479 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001480 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001481 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001482 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001483 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1484 rllh->data[0] == RSL_IE_L3_INFO) {
1485 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001486 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001487 }
1488 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001489 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001490 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001491 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001492 rll_indication(msg->lchan, rllh->link_id,
1493 BSC_RLLR_IND_EST_CONF);
1494 break;
Harald Welte59b04682009-06-10 05:40:52 +08001495 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001496 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001497 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001498 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001499 rll_indication(msg->lchan, rllh->link_id,
1500 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001501 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001502 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001503 break;
1504 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001505 /* BTS informs us of having received UA from MS,
1506 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001507 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001508 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001509 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001510 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001511 break;
1512 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001513 rc = rsl_rx_rll_err_ind(msg);
1514 break;
1515 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001516 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1517 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001518 break;
1519 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001520 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1521 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001522 }
Harald Welte59b04682009-06-10 05:40:52 +08001523 return rc;
1524}
1525
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001526static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001527{
Harald Welteb284b472009-12-02 01:58:23 +05301528 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001529 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301530 switch (lchan->type) {
1531 case GSM_LCHAN_TCH_F:
1532 return 0x00;
1533 case GSM_LCHAN_TCH_H:
1534 return 0x03;
1535 default:
1536 break;
1537 }
Harald Welte98d79f92009-07-28 18:11:56 +02001538 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301539 switch (lchan->type) {
1540 case GSM_LCHAN_TCH_F:
1541 return 0x01;
1542 /* there's no half-rate EFR */
1543 default:
1544 break;
1545 }
Harald Welte98d79f92009-07-28 18:11:56 +02001546 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301547 switch (lchan->type) {
1548 case GSM_LCHAN_TCH_F:
1549 return 0x02;
1550 case GSM_LCHAN_TCH_H:
1551 return 0x05;
1552 default:
1553 break;
1554 }
1555 default:
1556 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001557 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001558 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301559 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001560 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001561}
1562
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001563static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001564{
Holger Hans Peter Freyther6651b692010-11-14 21:09:08 +01001565 struct gsm_network *net = lchan->ts->trx->bts->network;
1566
1567 /* allow to hardcode the rtp payload */
1568 if (net->hardcoded_rtp_payload != 0)
1569 return net->hardcoded_rtp_payload;
1570
Sylvain Munaut1338a552009-12-20 22:06:40 +01001571 switch (lchan->tch_mode) {
1572 case GSM48_CMODE_SPEECH_V1:
1573 switch (lchan->type) {
1574 case GSM_LCHAN_TCH_F:
1575 return RTP_PT_GSM_FULL;
1576 case GSM_LCHAN_TCH_H:
1577 return RTP_PT_GSM_HALF;
1578 default:
1579 break;
1580 }
1581 case GSM48_CMODE_SPEECH_EFR:
1582 switch (lchan->type) {
1583 case GSM_LCHAN_TCH_F:
1584 return RTP_PT_GSM_EFR;
1585 /* there's no half-rate EFR */
1586 default:
1587 break;
1588 }
1589 case GSM48_CMODE_SPEECH_AMR:
1590 switch (lchan->type) {
1591 case GSM_LCHAN_TCH_F:
1592 return RTP_PT_AMR_FULL;
1593 case GSM_LCHAN_TCH_H:
1594 return RTP_PT_AMR_HALF;
1595 default:
1596 break;
1597 }
1598 default:
1599 break;
1600 }
1601 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1602 "tch_mode == 0x%02x\n & lchan_type == %d",
1603 lchan->tch_mode, lchan->type);
1604 return 0;
1605}
1606
Harald Welte59b04682009-06-10 05:40:52 +08001607/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001608static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1609{
1610 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001611 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001612
1613 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001614 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001615 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1616 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1617 }
1618
1619 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001620 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001621 port = ntohs(port);
1622 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1623 lchan->abis_ip.bound_port = port;
1624 }
1625
1626 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001627 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Weltebffa4992009-12-19 16:42:06 +01001628 conn_id = ntohs(conn_id);
1629 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1630 lchan->abis_ip.conn_id = conn_id;
1631 }
1632
1633 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1634 lchan->abis_ip.rtp_payload2 =
1635 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1636 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1637 lchan->abis_ip.rtp_payload2);
1638 }
1639
1640 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1641 lchan->abis_ip.speech_mode =
1642 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1643 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1644 lchan->abis_ip.speech_mode);
1645 }
1646
1647 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001648 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001649 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1650 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1651 }
1652
1653 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001654 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001655 port = ntohs(port);
1656 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1657 lchan->abis_ip.connect_port = port;
1658 }
1659}
1660
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001661int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001662{
1663 struct msgb *msg = rsl_msgb_alloc();
1664 struct abis_rsl_dchan_hdr *dh;
1665
1666 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001667 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001668 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001669 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001670
Harald Welte98d79f92009-07-28 18:11:56 +02001671 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001672 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001673 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001674 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001675 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001676
Sylvain Munaut1338a552009-12-20 22:06:40 +01001677 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1678 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1679 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001680
Harald Welte59b04682009-06-10 05:40:52 +08001681 msg->trx = lchan->ts->trx;
1682
1683 return abis_rsl_sendmsg(msg);
1684}
1685
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001686int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1687 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001688{
1689 struct msgb *msg = rsl_msgb_alloc();
1690 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001691 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001692 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001693
1694 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001695 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001696 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001697 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001698
Harald Weltebffa4992009-12-19 16:42:06 +01001699 /* we need to store these now as MDCX_ACK does not return them :( */
1700 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1701 lchan->abis_ip.connect_port = port;
1702 lchan->abis_ip.connect_ip = ip;
1703
Harald Weltefb4a9e92009-07-29 12:12:18 +02001704 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001705 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001706 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001707
Harald Welte98d79f92009-07-28 18:11:56 +02001708 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001709 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1710 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1711 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1712 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001713
Harald Weltebffa4992009-12-19 16:42:06 +01001714 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1715 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001716 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001717 *att_ip = ia.s_addr;
1718 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1719 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001720 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001721 if (rtp_payload2)
1722 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1723
Harald Welte59b04682009-06-10 05:40:52 +08001724 msg->trx = lchan->ts->trx;
1725
1726 return abis_rsl_sendmsg(msg);
1727}
1728
Harald Welte9947d9f2009-12-20 16:51:09 +01001729/* tell BTS to connect RTP stream to our local RTP socket */
1730int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1731{
1732 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1733 int rc;
1734
1735 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1736 ntohs(rs->rtp.sin_local.sin_port),
1737 /* FIXME: use RTP payload of bound socket, not BTS*/
1738 lchan->abis_ip.rtp_payload2);
1739
1740 return rc;
1741}
1742
Harald Welte6f40df02010-12-23 12:59:52 +01001743int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02001744{
1745 struct msgb *msg = rsl_msgb_alloc();
1746 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001747 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08001748
1749 if (act)
1750 msg_type = RSL_MT_IPAC_PDCH_ACT;
1751 else
1752 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welteaed946e2009-10-24 10:29:22 +02001753
1754 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08001755 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02001756 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02001757 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02001758
Harald Welte6f40df02010-12-23 12:59:52 +01001759 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08001760 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02001761
Harald Welte6f40df02010-12-23 12:59:52 +01001762 msg->trx = ts->trx;
Harald Welteaed946e2009-10-24 10:29:22 +02001763
1764 return abis_rsl_sendmsg(msg);
1765}
1766
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001767static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001768{
1769 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1770 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05301771 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001772
1773 /* the BTS has acknowledged a local bind, it now tells us the IP
1774 * address and port number to which it has bound the given logical
1775 * channel */
1776
1777 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1778 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1779 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001780 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001781 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08001782 return -EINVAL;
1783 }
Harald Welte50517742009-12-20 15:42:44 +01001784
Harald Weltebffa4992009-12-19 16:42:06 +01001785 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01001786
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001787 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001788
1789 return 0;
1790}
1791
Harald Weltebffa4992009-12-19 16:42:06 +01001792static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1793{
1794 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1795 struct tlv_parsed tv;
1796 struct gsm_lchan *lchan = msg->lchan;
1797
1798 /* the BTS has acknowledged a remote connect request and
1799 * it now tells us the IP address and port number to which it has
1800 * connected the given logical channel */
1801
1802 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1803 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001804 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001805
1806 return 0;
1807}
1808
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001809static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001810{
1811 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1812 struct tlv_parsed tv;
1813
1814 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001815
Harald Weltef1a168d2009-07-28 17:58:09 +02001816 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001817 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001818 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001819
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001820 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001821
Harald Welte59b04682009-06-10 05:40:52 +08001822 return 0;
1823}
1824
1825static int abis_rsl_rx_ipacc(struct msgb *msg)
1826{
1827 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01001828 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08001829 int rc = 0;
1830
1831 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001832 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001833
1834 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001835 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001836 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001837 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001838 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001839 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001840 /* somehow the BTS was unable to bind the lchan to its local
1841 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01001842 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001843 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001844 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001845 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01001846 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01001847 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001848 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001849 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001850 /* somehow the BTS was unable to connect the lchan to a remote
1851 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01001852 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001853 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001854 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01001855 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001856 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001857 break;
1858 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001859 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001860 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001861 break;
1862 }
1863 DEBUGPC(DRSL, "\n");
1864
1865 return rc;
1866}
1867
1868
1869/* Entry-point where L2 RSL from BTS enters */
1870int abis_rsl_rcvmsg(struct msgb *msg)
1871{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001872 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08001873 int rc = 0;
1874
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001875 if (!msg) {
1876 DEBUGP(DRSL, "Empty RSL msg?..\n");
1877 return -1;
1878 }
1879
1880 if (msgb_l2len(msg) < sizeof(*rslh)) {
1881 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
1882 return -1;
1883 }
1884
1885 rslh = msgb_l2(msg);
1886
Harald Welte59b04682009-06-10 05:40:52 +08001887 switch (rslh->msg_discr & 0xfe) {
1888 case ABIS_RSL_MDISC_RLL:
1889 rc = abis_rsl_rx_rll(msg);
1890 break;
1891 case ABIS_RSL_MDISC_DED_CHAN:
1892 rc = abis_rsl_rx_dchan(msg);
1893 break;
1894 case ABIS_RSL_MDISC_COM_CHAN:
1895 rc = abis_rsl_rx_cchan(msg);
1896 break;
1897 case ABIS_RSL_MDISC_TRX:
1898 rc = abis_rsl_rx_trx(msg);
1899 break;
1900 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001901 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001902 rslh->msg_discr);
1903 break;
1904 case ABIS_RSL_MDISC_IPACCESS:
1905 rc = abis_rsl_rx_ipacc(msg);
1906 break;
1907 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001908 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1909 "0x%02x\n", rslh->msg_discr);
Harald Welte59b04682009-06-10 05:40:52 +08001910 return -EINVAL;
1911 }
1912 msgb_free(msg);
1913 return rc;
1914}
1915
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08001916int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1917 uint8_t cb_command, const uint8_t *data, int len)
1918{
1919 struct abis_rsl_dchan_hdr *dh;
1920 struct msgb *cb_cmd;
1921
1922 cb_cmd = rsl_msgb_alloc();
1923 if (!cb_cmd)
1924 return -1;
1925
1926 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1927 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
1928 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
1929
1930 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
1931 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
1932
1933 cb_cmd->trx = bts->c0;
1934
1935 return abis_rsl_sendmsg(cb_cmd);
1936}
Dieter Spaar49c843e2011-07-28 00:01:50 +02001937
1938int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
1939{
1940 struct abis_rsl_common_hdr *ch;
1941 struct msgb *msg = rsl_msgb_alloc();
1942
1943 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
1944 ch->msg_discr = ABIS_RSL_MDISC_TRX;
1945 ch->msg_type = 0x40; /* Nokia SI Begin */
1946
1947 msg->trx = trx;
1948
1949 return abis_rsl_sendmsg(msg);
1950}
1951
1952int rsl_nokia_si_end(struct gsm_bts_trx *trx)
1953{
1954 struct abis_rsl_common_hdr *ch;
1955 struct msgb *msg = rsl_msgb_alloc();
1956
1957 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
1958 ch->msg_discr = ABIS_RSL_MDISC_TRX;
1959 ch->msg_type = 0x41; /* Nokia SI End */
1960
1961 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
1962
1963 msg->trx = trx;
1964
1965 return abis_rsl_sendmsg(msg);
1966}
1967
1968int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
1969{
1970 struct abis_rsl_common_hdr *ch;
1971 struct msgb *msg = rsl_msgb_alloc();
1972
1973 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
1974 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1975 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
1976
1977 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
1978 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
1979
1980 msg->trx = trx;
1981
1982 return abis_rsl_sendmsg(msg);
1983}