blob: 12f68e9b450345fc56ba5042d21b2afbc199bef4 [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>
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte59b04682009-06-10 05:40:52 +08006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte0e3e88e2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte59b04682009-06-10 05:40:52 +080012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte0e3e88e2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte59b04682009-06-10 05:40:52 +080018 *
Harald Welte0e3e88e2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte59b04682009-06-10 05:40:52 +080021 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
Harald Welte59b04682009-06-10 05:40:52 +080027#include <netinet/in.h>
28#include <arpa/inet.h>
29
30#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080036#include <openbsc/debug.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Harald Welte59b04682009-06-10 05:40:52 +080038#include <openbsc/paging.h>
39#include <openbsc/signal.h>
Harald Weltec20bd1d2009-11-29 19:07:28 +010040#include <openbsc/meas_rep.h>
Harald Welte50517742009-12-20 15:42:44 +010041#include <openbsc/rtp_proxy.h>
Pablo Neira Ayuso42e41df2011-08-17 22:44:07 +020042#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010043#include <osmocom/gsm/rsl.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010044#include <osmocom/core/talloc.h>
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080045
Harald Welte59b04682009-06-10 05:40:52 +080046#define RSL_ALLOC_SIZE 1024
47#define RSL_ALLOC_HEADROOM 128
48
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +010049enum sacch_deact {
50 SACCH_NONE,
51 SACCH_DEACTIVATE,
52};
53
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080054static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
55
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010056static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
57 struct gsm_meas_rep *resp)
58{
59 struct lchan_signal_data sig;
60 sig.lchan = lchan;
61 sig.mr = resp;
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +020062 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010063}
64
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010065static void do_lchan_free(struct gsm_lchan *lchan)
66{
67 /* we have an error timer pending to release that */
68 if (lchan->state != LCHAN_S_REL_ERR)
69 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
70 lchan_free(lchan);
71}
72
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020073static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080074{
75 /* mask off the transparent bit ? */
76 msg_type &= 0xfe;
77
78 if ((msg_type & 0xf0) == 0x00)
79 return ABIS_RSL_MDISC_RLL;
80 if ((msg_type & 0xf0) == 0x10) {
81 if (msg_type >= 0x19 && msg_type <= 0x22)
82 return ABIS_RSL_MDISC_TRX;
83 else
84 return ABIS_RSL_MDISC_COM_CHAN;
85 }
86 if ((msg_type & 0xe0) == 0x20)
87 return ABIS_RSL_MDISC_DED_CHAN;
88
89 return ABIS_RSL_MDISC_LOC;
90}
91
92static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020093 uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080094{
95 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
96 dh->c.msg_type = msg_type;
97 dh->ie_chan = RSL_IE_CHAN_NR;
98}
99
Harald Welte59b04682009-06-10 05:40:52 +0800100/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200101struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte59b04682009-06-10 05:40:52 +0800102{
103 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200104 uint8_t ts_nr = chan_nr & 0x07;
105 uint8_t cbits = chan_nr >> 3;
106 uint8_t lch_idx;
Harald Welte59b04682009-06-10 05:40:52 +0800107 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
108
109 if (cbits == 0x01) {
110 lch_idx = 0; /* TCH/F */
Harald Welte37884ed2009-10-24 10:25:50 +0200111 if (ts->pchan != GSM_PCHAN_TCH_F &&
112 ts->pchan != GSM_PCHAN_PDCH &&
113 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100114 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800115 chan_nr, ts->pchan);
116 } else if ((cbits & 0x1e) == 0x02) {
117 lch_idx = cbits & 0x1; /* TCH/H */
118 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100119 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800120 chan_nr, ts->pchan);
121 } else if ((cbits & 0x1c) == 0x04) {
122 lch_idx = cbits & 0x3; /* SDCCH/4 */
123 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100124 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800125 chan_nr, ts->pchan);
126 } else if ((cbits & 0x18) == 0x08) {
127 lch_idx = cbits & 0x7; /* SDCCH/8 */
128 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100129 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800130 chan_nr, ts->pchan);
131 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
132 lch_idx = 0;
133 if (ts->pchan != GSM_PCHAN_CCCH &&
134 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100135 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800136 chan_nr, ts->pchan);
137 /* FIXME: we should not return first sdcch4 !!! */
138 } else {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100139 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800140 return NULL;
141 }
142
143 lchan = &ts->lchan[lch_idx];
Harald Welte51d2a592010-03-26 21:28:59 +0800144 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800145 if (lchan->conn)
146 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800147
148 return lchan;
149}
150
Harald Welte59b04682009-06-10 05:40:52 +0800151/* 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 +0200152uint64_t str_to_imsi(const char *imsi_str)
Harald Welte59b04682009-06-10 05:40:52 +0800153{
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200154 uint64_t ret;
Harald Welte59b04682009-06-10 05:40:52 +0800155
156 ret = strtoull(imsi_str, NULL, 10);
157
158 return ret;
159}
160
Harald Welte59b04682009-06-10 05:40:52 +0800161static struct msgb *rsl_msgb_alloc(void)
162{
Harald Welte9cfc9352009-06-26 19:39:35 +0200163 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
164 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800165}
166
167#define MACBLOCK_SIZE 23
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200168static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800169{
170 memcpy(out, in, len);
171
172 if (len < MACBLOCK_SIZE)
173 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
174}
175
Harald Welted2dd9de2009-08-30 15:37:11 +0900176/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200177static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welted2dd9de2009-08-30 15:37:11 +0900178{
179 *out++ = lchan->encr.alg_id & 0xff;
180 if (lchan->encr.key_len)
181 memcpy(out, lchan->encr.key, lchan->encr.key_len);
182 return lchan->encr.key_len + 1;
183}
184
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200185static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200186{
Harald Welte59b04682009-06-10 05:40:52 +0800187 int i;
188
Harald Weltede4477a2009-12-24 12:20:20 +0100189 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200190 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200191 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100192 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800193}
194
Harald Welte32951ea2011-08-10 23:26:33 +0200195static void lchan_act_tmr_cb(void *data)
196{
197 struct gsm_lchan *lchan = data;
198
Holger Hans Peter Freytherb050e3e2012-12-06 19:00:35 +0100199 LOGP(DRSL, LOGL_ERROR, "%s Timeout during activation!\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200200 gsm_lchan_name(lchan));
201
Daniel Willmann2731e732011-08-11 04:44:12 +0200202 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
203 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200204}
205
206static void lchan_deact_tmr_cb(void *data)
207{
208 struct gsm_lchan *lchan = data;
209
Holger Hans Peter Freytherb050e3e2012-12-06 19:00:35 +0100210 LOGP(DRSL, LOGL_ERROR, "%s Timeout during deactivation!\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200211 gsm_lchan_name(lchan));
212
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100213 do_lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200214}
215
216
Harald Welte59b04682009-06-10 05:40:52 +0800217/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200218int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
219 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800220{
221 struct abis_rsl_dchan_hdr *dh;
222 struct msgb *msg = rsl_msgb_alloc();
223
224 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
225 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
226 dh->chan_nr = RSL_CHAN_BCCH;
227
228 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
229 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
230
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200231 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800232
233 return abis_rsl_sendmsg(msg);
234}
235
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200236int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
237 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800238{
239 struct abis_rsl_common_hdr *ch;
240 struct msgb *msg = rsl_msgb_alloc();
241
242 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
243 ch->msg_discr = ABIS_RSL_MDISC_TRX;
244 ch->msg_type = RSL_MT_SACCH_FILL;
245
246 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
247 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
248
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200249 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800250
251 return abis_rsl_sendmsg(msg);
252}
253
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200254int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
255 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100256{
257 struct abis_rsl_dchan_hdr *dh;
258 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200259 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100260
261 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
262 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
263 dh->chan_nr = chan_nr;
264
265 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
266 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
267
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200268 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte10b7d8f2011-01-13 23:16:03 +0100269
270 return abis_rsl_sendmsg(msg);
271}
272
Harald Welte91afe4c2009-06-20 18:15:19 +0200273int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
274{
275 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200276 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200277 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200278
279 db = abs(db);
280 if (db > 30)
281 return -EINVAL;
282
Harald Welteed831842009-06-27 03:09:08 +0200283 msg = rsl_msgb_alloc();
284
Harald Welte91afe4c2009-06-20 18:15:19 +0200285 lchan->bs_power = db/2;
286 if (fpc)
287 lchan->bs_power |= 0x10;
288
289 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
290 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
291 dh->chan_nr = chan_nr;
292
293 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
294
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200295 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200296
297 return abis_rsl_sendmsg(msg);
298}
299
Harald Welte91afe4c2009-06-20 18:15:19 +0200300int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
301{
302 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200303 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200304 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200305 int ctl_lvl;
306
Harald Weltec4dcda02009-08-09 14:45:18 +0200307 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200308 if (ctl_lvl < 0)
309 return ctl_lvl;
310
Harald Welteed831842009-06-27 03:09:08 +0200311 msg = rsl_msgb_alloc();
312
Harald Welte91afe4c2009-06-20 18:15:19 +0200313 lchan->ms_power = ctl_lvl;
314
315 if (fpc)
316 lchan->ms_power |= 0x20;
317
318 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
319 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
320 dh->chan_nr = chan_nr;
321
322 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
323
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200324 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200325
326 return abis_rsl_sendmsg(msg);
327}
328
Harald Welte39274f42009-07-29 15:41:29 +0200329static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
330 struct gsm_lchan *lchan)
331{
332 memset(cm, 0, sizeof(cm));
333
334 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther21d63ff2010-09-06 09:25:48 +0800335 if (lchan->ts->trx->bts->network->dtx_enabled)
336 cm->dtx_dtu = 0x03;
337 else
338 cm->dtx_dtu = 0x00;
Harald Welte39274f42009-07-29 15:41:29 +0200339
340 /* set TCH Speech/Data */
341 cm->spd_ind = lchan->rsl_cmode;
342
Harald Welte951e3512009-11-27 08:55:16 +0100343 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
344 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100345 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100346 "but tch_mode != signalling\n");
347
Harald Welte39274f42009-07-29 15:41:29 +0200348 switch (lchan->type) {
349 case GSM_LCHAN_SDCCH:
350 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
351 break;
352 case GSM_LCHAN_TCH_F:
353 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
354 break;
355 case GSM_LCHAN_TCH_H:
356 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
357 break;
358 case GSM_LCHAN_NONE:
359 case GSM_LCHAN_UNKNOWN:
360 default:
361 return -EINVAL;
362 }
363
364 switch (lchan->tch_mode) {
365 case GSM48_CMODE_SIGN:
366 cm->chan_rate = 0;
367 break;
368 case GSM48_CMODE_SPEECH_V1:
369 cm->chan_rate = RSL_CMOD_SP_GSM1;
370 break;
371 case GSM48_CMODE_SPEECH_EFR:
372 cm->chan_rate = RSL_CMOD_SP_GSM2;
373 break;
374 case GSM48_CMODE_SPEECH_AMR:
375 cm->chan_rate = RSL_CMOD_SP_GSM3;
376 break;
377 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200378 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200379 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200380 switch (lchan->csd_mode) {
381 case LCHAN_CSD_M_NT:
382 /* non-transparent CSD with RLP */
383 switch (lchan->tch_mode) {
384 case GSM48_CMODE_DATA_14k5:
385 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
386 break;
387 case GSM48_CMODE_DATA_12k0:
388 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
389 break;
390 case GSM48_CMODE_DATA_6k0:
391 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
392 break;
393 default:
394 return -EINVAL;
395 }
396 break;
397 /* transparent data services below */
398 case LCHAN_CSD_M_T_1200_75:
399 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
400 break;
401 case LCHAN_CSD_M_T_600:
402 cm->chan_rate = RSL_CMOD_CSD_T_600;
403 break;
404 case LCHAN_CSD_M_T_1200:
405 cm->chan_rate = RSL_CMOD_CSD_T_1200;
406 break;
407 case LCHAN_CSD_M_T_2400:
408 cm->chan_rate = RSL_CMOD_CSD_T_2400;
409 break;
410 case LCHAN_CSD_M_T_9600:
411 cm->chan_rate = RSL_CMOD_CSD_T_9600;
412 break;
413 case LCHAN_CSD_M_T_14400:
414 cm->chan_rate = RSL_CMOD_CSD_T_14400;
415 break;
416 case LCHAN_CSD_M_T_29000:
417 cm->chan_rate = RSL_CMOD_CSD_T_29000;
418 break;
419 case LCHAN_CSD_M_T_32000:
420 cm->chan_rate = RSL_CMOD_CSD_T_32000;
421 break;
422 default:
423 return -EINVAL;
424 }
Harald Welte39274f42009-07-29 15:41:29 +0200425 default:
426 return -EINVAL;
427 }
428
429 return 0;
430}
431
Harald Welte59b04682009-06-10 05:40:52 +0800432/* Chapter 8.4.1 */
433#if 0
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200434int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
435 uint8_t act_type,
Harald Welte59b04682009-06-10 05:40:52 +0800436 struct rsl_ie_chan_mode *chan_mode,
437 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200438 uint8_t bs_power, uint8_t ms_power,
439 uint8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800440{
441 struct abis_rsl_dchan_hdr *dh;
442 struct msgb *msg = rsl_msgb_alloc();
443
444 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
445 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
446 dh->chan_nr = chan_nr;
447
448 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
449 /* For compatibility with Phase 1 */
450 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200451 (uint8_t *) chan_mode);
Harald Welte59b04682009-06-10 05:40:52 +0800452 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200453 (uint8_t *) chan_ident);
Harald Welte59b04682009-06-10 05:40:52 +0800454#if 0
455 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200456 (uint8_t *) &encr_info);
Harald Welte59b04682009-06-10 05:40:52 +0800457#endif
458 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
459 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
460 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
461
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200462 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800463
464 return abis_rsl_sendmsg(msg);
465}
466#endif
467
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200468int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
469 uint8_t ta, uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800470{
471 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200472 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200473 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200474 uint8_t *len;
Harald Welte59b04682009-06-10 05:40:52 +0800475
Harald Weltee6d51f92011-06-25 10:02:33 +0200476 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800477 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200478 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800479
Harald Welte39274f42009-07-29 15:41:29 +0200480 rc = channel_mode_from_lchan(&cm, lchan);
481 if (rc < 0)
482 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800483
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800484 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200485 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800486
Harald Welteed831842009-06-27 03:09:08 +0200487 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800488 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
489 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
490 dh->chan_nr = chan_nr;
491
492 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800493 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200494 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800495
496 /*
497 * The Channel Identification is needed for Phase1 phones
498 * and it contains the GSM48 Channel Description and the
499 * Mobile Allocation. The GSM 08.58 asks for the Mobile
500 * Allocation to have a length of zero. We are using the
501 * msgb_l3len to calculate the length of both messages.
502 */
laforgef723cf02010-06-20 21:38:19 +0200503 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200504 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200505 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800506
507 if (lchan->ts->hopping.enabled)
508 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
509 lchan->ts->hopping.ma_data);
510 else
511 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800512
513 /* update the calculated size */
514 msg->l3h = len + 1;
515 *len = msgb_l3len(msg);
516
Harald Welted2dd9de2009-08-30 15:37:11 +0900517 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200518 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900519 rc = build_encr_info(encr_info, lchan);
520 if (rc > 0)
521 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
522 }
523
Harald Welteb90d7bd2009-12-17 00:31:10 +0100524 switch (act_type) {
525 case RSL_ACT_INTER_ASYNC:
526 case RSL_ACT_INTER_SYNC:
527 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
528 break;
529 default:
530 break;
531 }
532
Harald Welte59b04682009-06-10 05:40:52 +0800533 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
534 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
535 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
536
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100537 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
538 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200539 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100540
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200541 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800542
543 return abis_rsl_sendmsg(msg);
544}
545
Harald Welte8e770492009-07-29 11:38:15 +0200546/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800547int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
548{
549 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200550 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200551 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800552
Harald Weltee6d51f92011-06-25 10:02:33 +0200553 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800554 struct rsl_ie_chan_mode cm;
555
Harald Welte39274f42009-07-29 15:41:29 +0200556 rc = channel_mode_from_lchan(&cm, lchan);
557 if (rc < 0)
558 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800559
Harald Welteed831842009-06-27 03:09:08 +0200560 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800561 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
562 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
563 dh->chan_nr = chan_nr;
564
565 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200566 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900567
568 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200569 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900570 rc = build_encr_info(encr_info, lchan);
571 if (rc > 0)
572 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
573 }
574
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100575 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
576 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200577 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100578 }
579
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200580 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900581
582 return abis_rsl_sendmsg(msg);
583}
584
585/* Chapter 8.4.6: Send the encryption command with given L3 info */
586int rsl_encryption_cmd(struct msgb *msg)
587{
588 struct abis_rsl_dchan_hdr *dh;
589 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200590 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200591 uint8_t encr_info[MAX_A5_KEY_LEN+2];
592 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900593 int rc;
594
595 /* First push the L3 IE tag and length */
596 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
597
598 /* then the link identifier (SAPI0, main sign link) */
599 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
600
601 /* then encryption information */
602 rc = build_encr_info(encr_info, lchan);
603 if (rc <= 0)
604 return rc;
605 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
606
607 /* and finally the DCHAN header */
608 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
609 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
610 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800611
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200612 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800613
614 return abis_rsl_sendmsg(msg);
615}
616
Harald Welte85a163c2009-08-10 11:43:22 +0200617/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200618int rsl_deact_sacch(struct gsm_lchan *lchan)
619{
620 struct abis_rsl_dchan_hdr *dh;
621 struct msgb *msg = rsl_msgb_alloc();
622
623 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
624 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200625 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200626
627 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200628 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200629
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100630 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200631
632 return abis_rsl_sendmsg(msg);
633}
634
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800635static void error_timeout_cb(void *data)
636{
637 struct gsm_lchan *lchan = data;
638 if (lchan->state != LCHAN_S_REL_ERR) {
639 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
640 gsm_lchan_name(lchan), lchan->state);
641 return;
642 }
643
644 /* go back to the none state */
645 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800646 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800647}
648
Harald Welte08011e22011-03-04 13:41:31 +0100649static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
650
Harald Welte85a163c2009-08-10 11:43:22 +0200651/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100652static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
653 enum sacch_deact deact_sacch)
Harald Welte59b04682009-06-10 05:40:52 +0800654{
655 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800656 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100657 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800658
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100659 /* Stop timers that should lead to a channel release */
660 osmo_timer_del(&lchan->T3109);
661
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800662 if (lchan->state == LCHAN_S_REL_ERR) {
663 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
664 gsm_lchan_name(lchan));
665 return -1;
666 }
667
668 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800669 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
670 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200671 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800672
673 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200674 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800675
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800676 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
677
678 if (error) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200679 struct e1inp_sign_link *sign_link = msg->dst;
680
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100681 /*
682 * FIXME: GSM 04.08 gives us two options for the abnormal
683 * chanel release. This can be either like in the non-existent
684 * sub-lcuase 3.5.1 or for the main signalling link deactivate
685 * the SACCH, start timer T3109 and consider the channel as
686 * released.
687 *
688 * This code is doing the later for all raido links and not
689 * only the main link. Right now all SAPIs are released on the
690 * local end, the SACCH will be de-activated and right now the
691 * T3111 will be started. First T3109 should be started and then
692 * the T3111.
693 *
694 * TODO: Move this out of the function.
695 */
696
697 /*
698 * sacch de-activate and "local end release"
699 */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100700 if (deact_sacch == SACCH_DEACTIVATE)
701 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100702 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
703
704 /*
705 * TODO: start T3109 now.
706 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800707 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800708 lchan->error_timer.data = lchan;
709 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +0200710 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200711 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800712 }
Harald Welte59b04682009-06-10 05:40:52 +0800713
Harald Welte32951ea2011-08-10 23:26:33 +0200714 /* Start another timer or assume the BTS sends a ACK/NACK? */
715 lchan->act_timer.cb = lchan_deact_tmr_cb;
716 lchan->act_timer.data = lchan;
717 osmo_timer_schedule(&lchan->act_timer, 4, 0);
718
Harald Welte08011e22011-03-04 13:41:31 +0100719 rc = abis_rsl_sendmsg(msg);
720
Harald Welte85a163c2009-08-10 11:43:22 +0200721 /* BTS will respond by RF CHAN REL ACK */
Harald Welte6bddd822011-01-14 23:18:59 +0100722#ifdef HSL_SR_1_0
Harald Welte08011e22011-03-04 13:41:31 +0100723 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
724 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
725 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte6bddd822011-01-14 23:18:59 +0100726#endif
Harald Welte08011e22011-03-04 13:41:31 +0100727
728 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800729}
730
Harald Welte9773f6c2011-01-14 14:16:16 +0100731static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
732{
733
734 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
735
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100736 /* Stop all pending timers */
Harald Welte32951ea2011-08-10 23:26:33 +0200737 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100738 osmo_timer_del(&lchan->T3111);
Harald Welte32951ea2011-08-10 23:26:33 +0200739
Harald Welte9773f6c2011-01-14 14:16:16 +0100740 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
741 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
742 gsm_lchan_name(lchan),
743 gsm_lchans_name(lchan->state));
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100744 do_lchan_free(lchan);
Harald Welte9773f6c2011-01-14 14:16:16 +0100745
746 return 0;
747}
748
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200749int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
750 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800751{
752 struct abis_rsl_dchan_hdr *dh;
753 struct msgb *msg = rsl_msgb_alloc();
754
755 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
756 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
757 dh->chan_nr = RSL_CHAN_PCH_AGCH;
758
759 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
760 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
761 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
762
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200763 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800764
765 return abis_rsl_sendmsg(msg);
766}
767
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200768int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800769{
770 int i, len = strlen(str_in);
771
772 for (i = 0; i < len; i++) {
773 int num = str_in[i] - 0x30;
774 if (num < 0 || num > 9)
775 return -1;
776 if (i % 2 == 0)
777 bcd_out[i/2] = num;
778 else
779 bcd_out[i/2] |= (num << 4);
780 }
781
782 return 0;
783}
784
785/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200786int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800787{
788 struct msgb *msg = rsl_msgb_alloc();
789 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200790 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800791
792 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
793 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
794 dh->chan_nr = RSL_CHAN_PCH_AGCH;
795
796 switch (bts->type) {
797 case GSM_BTS_TYPE_BS11:
798 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
799 break;
800 default:
801 /* If phase 2, construct a FULL_IMM_ASS_INFO */
802 pad_macblock(buf, val, len);
803 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
804 break;
805 }
806
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200807 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800808
809 return abis_rsl_sendmsg(msg);
810}
811
Harald Welte4684e632009-08-10 09:51:40 +0200812/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200813int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200814{
815 struct msgb *msg = rsl_msgb_alloc();
816 struct abis_rsl_dchan_hdr *dh;
817
818 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
819 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200820 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200821 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200822 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200823
Harald Weltede4477a2009-12-24 12:20:20 +0100824 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200825 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200826
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200827 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +0200828
Harald Welte4684e632009-08-10 09:51:40 +0200829 return abis_rsl_sendmsg(msg);
830}
831
832
Harald Welte59b04682009-06-10 05:40:52 +0800833/* Send "DATA REQUEST" message with given L3 Info payload */
834/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200835int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800836{
Harald Welte59b04682009-06-10 05:40:52 +0800837 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100838 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800839 return -EINVAL;
840 }
841
Harald Weltee6d51f92011-06-25 10:02:33 +0200842 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100843 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800844
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200845 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800846
847 return abis_rsl_sendmsg(msg);
848}
849
Harald Welteed9a5ab2009-08-09 13:47:35 +0200850/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
851/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200852int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200853{
Harald Weltea22d36b2010-03-04 10:33:10 +0100854 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200855
Harald Weltee6d51f92011-06-25 10:02:33 +0200856 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100857 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200858 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200859
Harald Welte17091bd2012-04-26 19:42:19 +0200860 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
861 gsm_lchan_name(lchan), link_id);
862
Harald Welteed9a5ab2009-08-09 13:47:35 +0200863 return abis_rsl_sendmsg(msg);
864}
865
Harald Welte0f2e3c12009-08-08 13:15:07 +0200866/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
867 This is what higher layers should call. The BTS then responds with
868 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
869 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
870 lchan_free() */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100871int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
872 enum rsl_rel_mode release_mode)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200873{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200874
Harald Weltea22d36b2010-03-04 10:33:10 +0100875 struct msgb *msg;
876
Harald Weltee6d51f92011-06-25 10:02:33 +0200877 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100878 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800879 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100880 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200881
Harald Weltec88a4432009-12-29 10:44:17 +0100882 /* FIXME: start some timer in case we don't receive a REL ACK ? */
883
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200884 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200885
Harald Welte17091bd2012-04-26 19:42:19 +0200886 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100887 gsm_lchan_name(lchan), link_id, release_mode);
Harald Welte17091bd2012-04-26 19:42:19 +0200888
Harald Welte0f2e3c12009-08-08 13:15:07 +0200889 return abis_rsl_sendmsg(msg);
890}
891
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200892int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
893{
894 lchan->state = state;
895 return 0;
896}
897
Harald Welte59b04682009-06-10 05:40:52 +0800898/* Chapter 8.4.2: Channel Activate Acknowledge */
899static int rsl_rx_chan_act_ack(struct msgb *msg)
900{
901 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
902
903 /* BTS has confirmed channel activation, we now need
904 * to assign the activated channel to the MS */
905 if (rslh->ie_chan != RSL_IE_CHAN_NR)
906 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100907
Harald Welte32951ea2011-08-10 23:26:33 +0200908 osmo_timer_del(&msg->lchan->act_timer);
909
Harald Weltec88a4432009-12-29 10:44:17 +0100910 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100911 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
912 gsm_lchan_name(msg->lchan),
913 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200914 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100915
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800916 if (msg->lchan->rqd_ref) {
917 rsl_send_imm_assignment(msg->lchan);
918 talloc_free(msg->lchan->rqd_ref);
919 msg->lchan->rqd_ref = NULL;
920 msg->lchan->rqd_ta = 0;
921 }
922
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100923 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100924
Harald Welte59b04682009-06-10 05:40:52 +0800925 return 0;
926}
927
928/* Chapter 8.4.3: Channel Activate NACK */
929static int rsl_rx_chan_act_nack(struct msgb *msg)
930{
931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
932 struct tlv_parsed tp;
933
Harald Welte32951ea2011-08-10 23:26:33 +0200934 osmo_timer_del(&msg->lchan->act_timer);
935
Daniel Willmann9e9d44c2011-08-11 04:54:23 +0200936 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100937 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100938
Harald Welte59b04682009-06-10 05:40:52 +0800939 /* BTS has rejected channel activation ?!? */
940 if (dh->ie_chan != RSL_IE_CHAN_NR)
941 return -EINVAL;
942
943 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100944 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200945 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100946 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +0200947 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +0100948 msg->lchan->error_cause = *cause;
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100949 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +0100950 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Daniel Willmann245ee032011-08-11 04:47:11 +0200951 else
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100952 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann245ee032011-08-11 04:47:11 +0200953
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100954 } else
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +0100955 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200956
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100957 LOGPC(DRSL, LOGL_ERROR, "\n");
958
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100959 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte59b04682009-06-10 05:40:52 +0800960 return 0;
961}
962
963/* Chapter 8.4.4: Connection Failure Indication */
964static int rsl_rx_conn_fail(struct msgb *msg)
965{
966 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
967 struct tlv_parsed tp;
968
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100969 /* FIXME: print which channel */
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100970 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100971 gsm_lchan_name(msg->lchan));
Harald Welte59b04682009-06-10 05:40:52 +0800972
973 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
974
Harald Weltef1a168d2009-07-28 17:58:09 +0200975 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +0100976 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +0200977 TLVP_LEN(&tp, RSL_IE_CAUSE));
978
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100979 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800980 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +0200981 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100982 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Harald Welte59b04682009-06-10 05:40:52 +0800983}
984
Harald Weltec20bd1d2009-11-29 19:07:28 +0100985static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
986 const char *prefix)
987{
Harald Welte0e4fa782009-12-16 16:52:07 +0100988 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
989 prefix, rxlev2dbm(mru->full.rx_lev),
990 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +0100991 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
992 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
993}
994
Harald Welte50290cc2012-07-02 17:12:08 +0200995static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +0100996{
Harald Welte0e4fa782009-12-16 16:52:07 +0100997 int i;
Harald Welte50290cc2012-07-02 17:12:08 +0200998 char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +0100999
Harald Welte50290cc2012-07-02 17:12:08 +02001000 if (lchan && lchan->conn && lchan->conn->subscr)
1001 name = subscr_name(lchan->conn->subscr);
1002
1003 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001004
1005 if (mr->flags & MEAS_REP_F_DL_DTX)
1006 DEBUGPC(DMEAS, "DTXd ");
1007
1008 print_meas_rep_uni(&mr->ul, "ul");
1009 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1010 if (mr->flags & MEAS_REP_F_MS_TO)
1011 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1012
1013 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +01001014 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001015 DEBUGPC(DMEAS, "L1_FPC=%u ",
1016 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1017 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1018 }
1019
1020 if (mr->flags & MEAS_REP_F_UL_DTX)
1021 DEBUGPC(DMEAS, "DTXu ");
1022 if (mr->flags & MEAS_REP_F_BA1)
1023 DEBUGPC(DMEAS, "BA1 ");
1024 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1025 DEBUGPC(DMEAS, "NOT VALID ");
1026 else
1027 print_meas_rep_uni(&mr->dl, "dl");
1028
1029 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +01001030 if (mr->num_cell == 7)
1031 return;
Harald Welte0e4fa782009-12-16 16:52:07 +01001032 for (i = 0; i < mr->num_cell; i++) {
1033 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +01001034 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1035 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001036 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001037}
1038
Harald Welte59b04682009-06-10 05:40:52 +08001039static int rsl_rx_meas_res(struct msgb *msg)
1040{
1041 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1042 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001043 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001044 uint8_t len;
1045 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001046 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001047
Harald Welte4baa9c52009-12-21 13:27:11 +01001048 /* check if this channel is actually active */
1049 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001050 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001051 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001052 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001053 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001054 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001055
Harald Weltef9476812009-12-15 21:36:05 +01001056 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001057 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001058
Harald Welte59b04682009-06-10 05:40:52 +08001059 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1060
Harald Weltec20bd1d2009-11-29 19:07:28 +01001061 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1062 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1063 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1064 return -EIO;
1065
1066 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001067 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001068
1069 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1070 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1071 if (len >= 3) {
1072 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001073 mr->flags |= MEAS_REP_F_DL_DTX;
1074 mr->ul.full.rx_lev = val[0] & 0x3f;
1075 mr->ul.sub.rx_lev = val[1] & 0x3f;
1076 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1077 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001078 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001079
Harald Weltef9476812009-12-15 21:36:05 +01001080 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001081
1082 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +08001083 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +01001084 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +01001085 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1086
Harald Weltea1467eb2009-06-20 18:44:35 +02001087 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001088 struct e1inp_sign_link *sign_link = msg->dst;
1089
Harald Weltec20bd1d2009-11-29 19:07:28 +01001090 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001091 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001092 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001093 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001094 mr->flags |= MEAS_REP_F_FPC;
1095 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001096 /* BS11 and Nokia reports TA shifted by 2 bits */
1097 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1098 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001099 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001100 }
Harald Welte59b04682009-06-10 05:40:52 +08001101 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001102 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001103 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001104 if (rc < 0)
1105 return rc;
1106 }
1107
Harald Welte50290cc2012-07-02 17:12:08 +02001108 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001109
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001110 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001111
Harald Welte59b04682009-06-10 05:40:52 +08001112 return 0;
1113}
1114
Harald Welte6720a432009-11-29 22:45:52 +01001115/* Chapter 8.4.7 */
1116static int rsl_rx_hando_det(struct msgb *msg)
1117{
1118 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1119 struct tlv_parsed tp;
1120
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001121 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001122
1123 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1124
1125 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1126 DEBUGPC(DRSL, "access delay = %u\n",
1127 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1128 else
1129 DEBUGPC(DRSL, "\n");
1130
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001131 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001132
1133 return 0;
1134}
1135
Harald Welte59b04682009-06-10 05:40:52 +08001136static int abis_rsl_rx_dchan(struct msgb *msg)
1137{
1138 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1139 int rc = 0;
1140 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001141 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001142
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001143 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001144 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001145
Harald Welte59b04682009-06-10 05:40:52 +08001146 switch (rslh->c.msg_type) {
1147 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001148 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001149 rc = rsl_rx_chan_act_ack(msg);
1150 break;
1151 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001152 rc = rsl_rx_chan_act_nack(msg);
1153 break;
1154 case RSL_MT_CONN_FAIL:
1155 rc = rsl_rx_conn_fail(msg);
1156 break;
1157 case RSL_MT_MEAS_RES:
1158 rc = rsl_rx_meas_res(msg);
1159 break;
Harald Welte6720a432009-11-29 22:45:52 +01001160 case RSL_MT_HANDO_DET:
1161 rc = rsl_rx_hando_det(msg);
1162 break;
Harald Welte59b04682009-06-10 05:40:52 +08001163 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001164 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001165 break;
1166 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001167 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001168 break;
1169 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001170 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001171 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001172 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001173 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001174 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001175 break;
1176 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001177 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001178 break;
1179 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001180 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001181 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001182 break;
1183 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001184 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001185 break;
Harald Welte59b04682009-06-10 05:40:52 +08001186 case RSL_MT_PHY_CONTEXT_CONF:
1187 case RSL_MT_PREPROC_MEAS_RES:
1188 case RSL_MT_TALKER_DET:
1189 case RSL_MT_LISTENER_DET:
1190 case RSL_MT_REMOTE_CODEC_CONF_REP:
1191 case RSL_MT_MR_CODEC_MOD_ACK:
1192 case RSL_MT_MR_CODEC_MOD_NACK:
1193 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001194 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1195 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001196 break;
1197 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001198 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1199 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001200 return -EINVAL;
1201 }
1202
1203 return rc;
1204}
1205
1206static int rsl_rx_error_rep(struct msgb *msg)
1207{
1208 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001209 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001210 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001211
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001212 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001213
1214 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1215
1216 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001217 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001218 TLVP_LEN(&tp, RSL_IE_CAUSE));
1219
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001220 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001221
1222 return 0;
1223}
1224
1225static int abis_rsl_rx_trx(struct msgb *msg)
1226{
1227 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001228 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001229 int rc = 0;
1230
1231 switch (rslh->msg_type) {
1232 case RSL_MT_ERROR_REPORT:
1233 rc = rsl_rx_error_rep(msg);
1234 break;
1235 case RSL_MT_RF_RES_IND:
1236 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001237 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001238 break;
1239 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001240 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001241 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001242 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001243 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001244 case 0x42: /* Nokia specific: SI End ACK */
1245 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1246 break;
1247 case 0x43: /* Nokia specific: SI End NACK */
1248 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1249 break;
Harald Welte59b04682009-06-10 05:40:52 +08001250 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001251 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001252 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001253 return -EINVAL;
1254 }
1255 return rc;
1256}
1257
Harald Welte427dbc42009-08-10 00:26:10 +02001258/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1259static void t3101_expired(void *data)
1260{
1261 struct gsm_lchan *lchan = data;
1262
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001263 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welte427dbc42009-08-10 00:26:10 +02001264}
1265
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001266/* If T3111 expires, we will send the RF Channel Request */
1267static void t3111_expired(void *data)
1268{
1269 struct gsm_lchan *lchan = data;
1270
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001271 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1272}
1273
1274/* If T3109 expires the MS has not send a UA/UM do the error release */
1275static void t3109_expired(void *data)
1276{
1277 struct gsm_lchan *lchan = data;
1278
1279 LOGP(DRSL, LOGL_ERROR,
1280 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1281 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001282}
1283
laforge50312e82010-06-21 12:08:52 +02001284#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1285
Harald Weltea00fdd72010-12-23 14:39:29 +01001286/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1287static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1288 unsigned int num_req_refs,
1289 struct gsm48_req_ref *rqd_refs,
1290 uint8_t wait_ind)
1291{
1292 uint8_t buf[GSM_MACBLOCK_LEN];
1293 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1294
1295 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1296 memset(iar, 0, sizeof(*iar));
1297 iar->proto_discr = GSM48_PDISC_RR;
1298 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1299 iar->page_mode = GSM48_PM_SAME;
1300
1301 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1302 iar->wait_ind1 = wait_ind;
1303
1304 if (num_req_refs >= 2)
1305 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1306 else
1307 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1308 iar->wait_ind2 = wait_ind;
1309
1310 if (num_req_refs >= 3)
1311 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1312 else
1313 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1314 iar->wait_ind3 = wait_ind;
1315
1316 if (num_req_refs >= 4)
1317 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1318 else
1319 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1320 iar->wait_ind4 = wait_ind;
1321
1322 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1323}
1324
Harald Welte59b04682009-06-10 05:40:52 +08001325/* MS has requested a channel on the RACH */
1326static int rsl_rx_chan_rqd(struct msgb *msg)
1327{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001328 struct e1inp_sign_link *sign_link = msg->dst;
1329 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001330 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1331 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001332 enum gsm_chan_t lctype;
1333 enum gsm_chreq_reason_t chreq_reason;
1334 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001335 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001336 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001337
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001338 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001339 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001340
1341 /* parse request reference to be used in immediate assign */
1342 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1343 return -EINVAL;
1344
1345 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1346
1347 /* parse access delay and use as TA */
1348 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1349 return -EINVAL;
1350 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1351
1352 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1353 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001354 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1355 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001356
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001357 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001358
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001359 /*
1360 * We want LOCATION UPDATES to succeed and will assign a TCH
1361 * if we have no SDCCH available.
1362 */
1363 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1364
Harald Welte59b04682009-06-10 05:40:52 +08001365 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001366 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001367 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001368 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001369 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001370 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001371 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1372 if (bts->network->T3122)
1373 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte59b04682009-06-10 05:40:52 +08001374 return -ENOMEM;
1375 }
1376
Harald Weltec88a4432009-12-29 10:44:17 +01001377 if (lchan->state != LCHAN_S_NONE)
1378 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001379 "in state %s\n", gsm_lchan_name(lchan),
1380 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001381
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001382 /* save the RACH data as we need it after the CHAN ACT ACK */
1383 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1384 if (!lchan->rqd_ref) {
1385 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1386 lchan_free(lchan);
1387 return -ENOMEM;
1388 }
1389
Holger Hans Peter Freyther161cec12011-12-29 23:33:04 +01001390 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001391 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1392 lchan->rqd_ta = rqd_ta;
1393
Harald Welte59b04682009-06-10 05:40:52 +08001394 arfcn = lchan->ts->trx->arfcn;
1395 subch = lchan->nr;
1396
Harald Welted2dd9de2009-08-30 15:37:11 +09001397 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001398 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001399 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001400 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001401 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001402
Harald Welte32951ea2011-08-10 23:26:33 +02001403 /* Start another timer or assume the BTS sends a ACK/NACK? */
1404 lchan->act_timer.cb = lchan_act_tmr_cb;
1405 lchan->act_timer.data = lchan;
1406 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1407
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001408 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1409 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1410 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1411 rqd_ref->ra, rqd_ta);
1412
1413 /* BS11 requires TA shifted by 2 bits */
1414 if (bts->type == GSM_BTS_TYPE_BS11)
1415 rqd_ta <<= 2;
Harald Welteb90d7bd2009-12-17 00:31:10 +01001416 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001417
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001418 return 0;
1419}
1420
1421static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1422{
1423 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001424 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001425 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1426
Harald Welte59b04682009-06-10 05:40:52 +08001427 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001428 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001429 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001430 ia->proto_discr = GSM48_PDISC_RR;
1431 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1432 ia->page_mode = GSM48_PM_SAME;
1433 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001434
Harald Welte59b04682009-06-10 05:40:52 +08001435 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001436 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1437 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001438 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001439 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001440 } else {
laforgee06d5982010-06-20 15:18:46 +02001441 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1442 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001443 }
Harald Welte07f32182010-06-28 18:41:27 +02001444 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1445 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001446
Harald Welte427dbc42009-08-10 00:26:10 +02001447 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1448 lchan->T3101.cb = t3101_expired;
1449 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001450 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001451
1452 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001453 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001454}
1455
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001456/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001457static int rsl_rx_ccch_load(struct msgb *msg)
1458{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001459 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001460 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001461 struct ccch_signal_data sd;
1462
1463 sd.bts = sign_link->trx->bts;
1464 sd.rach_slot_count = -1;
1465 sd.rach_busy_count = -1;
1466 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001467
1468 switch (rslh->data[0]) {
1469 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001470 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1471 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001472 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001473 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001474 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001475 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1476 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001477 break;
1478 case RSL_IE_RACH_LOAD:
1479 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001480 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1481 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1482 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1483 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001484 }
1485 break;
1486 default:
1487 break;
1488 }
1489
1490 return 0;
1491}
1492
1493static int abis_rsl_rx_cchan(struct msgb *msg)
1494{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001495 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001496 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1497 int rc = 0;
1498
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001499 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001500
1501 switch (rslh->c.msg_type) {
1502 case RSL_MT_CHAN_RQD:
1503 /* MS has requested a channel on the RACH */
1504 rc = rsl_rx_chan_rqd(msg);
1505 break;
1506 case RSL_MT_CCCH_LOAD_IND:
1507 /* current load on the CCCH */
1508 rc = rsl_rx_ccch_load(msg);
1509 break;
1510 case RSL_MT_DELETE_IND:
1511 /* CCCH overloaded, IMM_ASSIGN was dropped */
1512 case RSL_MT_CBCH_LOAD_IND:
1513 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001514 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1515 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001516 break;
1517 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001518 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1519 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001520 return -EINVAL;
1521 }
1522
1523 return rc;
1524}
1525
1526static int rsl_rx_rll_err_ind(struct msgb *msg)
1527{
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001528 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001529 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001530 uint8_t rlm_cause;
Harald Welte59b04682009-06-10 05:40:52 +08001531
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001532 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1533 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1534 LOGP(DRLL, LOGL_ERROR,
1535 "%s ERROR INDICATION without mandantory cause.\n",
1536 gsm_lchan_name(msg->lchan));
1537 return -1;
1538 }
1539
1540 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001541 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001542 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001543 rsl_rlm_cause_name(rlm_cause));
Harald Welteed9a5ab2009-08-09 13:47:35 +02001544
1545 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001546
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001547 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001548 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001549 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001550 }
Harald Welte692f5852009-07-04 09:40:05 +02001551
Harald Welte59b04682009-06-10 05:40:52 +08001552 return 0;
1553}
1554
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001555static void rsl_handle_release(struct gsm_lchan *lchan)
1556{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001557 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001558 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001559
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +01001560 /*
1561 * Maybe only one link/SAPI was releasd or the error handling
1562 * was activated. Just return now and let the other code handle
1563 * it.
1564 */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001565 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001566 return;
1567
1568 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1569 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1570 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001571 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001572 gsm_lchan_name(lchan), sapi);
1573 return;
1574 }
1575
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001576
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001577 /* Stop T3109 and wait for T3111 before re-using the channel */
1578 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001579 lchan->T3111.cb = t3111_expired;
1580 lchan->T3111.data = lchan;
1581 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001582 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001583}
1584
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001585/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001586 0x02, 0x06,
1587 0x01, 0x20,
1588 0x02, 0x00,
1589 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1590
1591static int abis_rsl_rx_rll(struct msgb *msg)
1592{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001593 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001594 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1595 int rc = 0;
1596 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001597 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001598
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001599 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001600 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001601 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001602
1603 switch (rllh->c.msg_type) {
1604 case RSL_MT_DATA_IND:
1605 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001606 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001607 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1608 rllh->data[0] == RSL_IE_L3_INFO) {
1609 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001610 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001611 }
1612 break;
1613 case RSL_MT_EST_IND:
1614 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001615 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001616 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001617 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001618 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001619 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1620 rllh->data[0] == RSL_IE_L3_INFO) {
1621 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001622 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001623 }
1624 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001625 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001626 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001627 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001628 rll_indication(msg->lchan, rllh->link_id,
1629 BSC_RLLR_IND_EST_CONF);
1630 break;
Harald Welte59b04682009-06-10 05:40:52 +08001631 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001632 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001633 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001634 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001635 rll_indication(msg->lchan, rllh->link_id,
1636 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001637 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001638 break;
1639 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001640 /* BTS informs us of having received UA from MS,
1641 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001642 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001643 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001644 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001645 break;
1646 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001647 rc = rsl_rx_rll_err_ind(msg);
1648 break;
1649 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001650 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1651 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001652 break;
1653 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001654 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1655 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001656 }
Harald Welte59b04682009-06-10 05:40:52 +08001657 return rc;
1658}
1659
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001660static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001661{
Harald Welteb284b472009-12-02 01:58:23 +05301662 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001663 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301664 switch (lchan->type) {
1665 case GSM_LCHAN_TCH_F:
1666 return 0x00;
1667 case GSM_LCHAN_TCH_H:
1668 return 0x03;
1669 default:
1670 break;
1671 }
Harald Welte98d79f92009-07-28 18:11:56 +02001672 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301673 switch (lchan->type) {
1674 case GSM_LCHAN_TCH_F:
1675 return 0x01;
1676 /* there's no half-rate EFR */
1677 default:
1678 break;
1679 }
Harald Welte98d79f92009-07-28 18:11:56 +02001680 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301681 switch (lchan->type) {
1682 case GSM_LCHAN_TCH_F:
1683 return 0x02;
1684 case GSM_LCHAN_TCH_H:
1685 return 0x05;
1686 default:
1687 break;
1688 }
1689 default:
1690 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001691 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001692 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301693 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001694 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001695}
1696
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001697static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001698{
1699 switch (lchan->tch_mode) {
1700 case GSM48_CMODE_SPEECH_V1:
1701 switch (lchan->type) {
1702 case GSM_LCHAN_TCH_F:
1703 return RTP_PT_GSM_FULL;
1704 case GSM_LCHAN_TCH_H:
1705 return RTP_PT_GSM_HALF;
1706 default:
1707 break;
1708 }
1709 case GSM48_CMODE_SPEECH_EFR:
1710 switch (lchan->type) {
1711 case GSM_LCHAN_TCH_F:
1712 return RTP_PT_GSM_EFR;
1713 /* there's no half-rate EFR */
1714 default:
1715 break;
1716 }
1717 case GSM48_CMODE_SPEECH_AMR:
1718 switch (lchan->type) {
1719 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01001720 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02001721 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001722 default:
1723 break;
1724 }
1725 default:
1726 break;
1727 }
1728 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1729 "tch_mode == 0x%02x\n & lchan_type == %d",
1730 lchan->tch_mode, lchan->type);
1731 return 0;
1732}
1733
Harald Welte59b04682009-06-10 05:40:52 +08001734/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001735static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1736{
1737 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001738 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001739
1740 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001741 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001742 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1743 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1744 }
1745
1746 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001747 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001748 port = ntohs(port);
1749 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1750 lchan->abis_ip.bound_port = port;
1751 }
1752
1753 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001754 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Weltebffa4992009-12-19 16:42:06 +01001755 conn_id = ntohs(conn_id);
1756 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1757 lchan->abis_ip.conn_id = conn_id;
1758 }
1759
1760 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1761 lchan->abis_ip.rtp_payload2 =
1762 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1763 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1764 lchan->abis_ip.rtp_payload2);
1765 }
1766
1767 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1768 lchan->abis_ip.speech_mode =
1769 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1770 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1771 lchan->abis_ip.speech_mode);
1772 }
1773
1774 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001775 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001776 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1777 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1778 }
1779
1780 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001781 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001782 port = ntohs(port);
1783 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1784 lchan->abis_ip.connect_port = port;
1785 }
1786}
1787
Harald Welte9a696d72013-02-03 12:06:58 +01001788/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1789 * \param[in] lchan Logical Channel for which we issue CRCX
1790 */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001791int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001792{
1793 struct msgb *msg = rsl_msgb_alloc();
1794 struct abis_rsl_dchan_hdr *dh;
1795
1796 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001797 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001798 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001799 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001800
Harald Welte98d79f92009-07-28 18:11:56 +02001801 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001802 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001803 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001804 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001805 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001806
Sylvain Munaut1338a552009-12-20 22:06:40 +01001807 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1808 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1809 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001810
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001811 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001812
1813 return abis_rsl_sendmsg(msg);
1814}
1815
Harald Welte9a696d72013-02-03 12:06:58 +01001816/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1817 * \param[in] lchan Logical Channel for which we issue MDCX
1818 * \param[in] ip Remote (MGW) IP address for RTP
1819 * \param[in] port Remote (MGW) UDP port number for RTP
1820 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1821 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001822int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1823 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001824{
1825 struct msgb *msg = rsl_msgb_alloc();
1826 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001827 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001828 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001829
1830 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001831 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001832 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001833 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001834
Harald Weltebffa4992009-12-19 16:42:06 +01001835 /* we need to store these now as MDCX_ACK does not return them :( */
1836 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1837 lchan->abis_ip.connect_port = port;
1838 lchan->abis_ip.connect_ip = ip;
1839
Harald Weltefb4a9e92009-07-29 12:12:18 +02001840 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001841 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001842 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001843
Harald Welte98d79f92009-07-28 18:11:56 +02001844 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001845 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1846 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1847 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1848 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001849
Harald Weltebffa4992009-12-19 16:42:06 +01001850 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1851 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001852 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001853 *att_ip = ia.s_addr;
1854 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1855 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001856 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001857 if (rtp_payload2)
1858 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001859
1860 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001861
1862 return abis_rsl_sendmsg(msg);
1863}
1864
Harald Welte9947d9f2009-12-20 16:51:09 +01001865/* tell BTS to connect RTP stream to our local RTP socket */
1866int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1867{
1868 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1869 int rc;
1870
1871 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1872 ntohs(rs->rtp.sin_local.sin_port),
1873 /* FIXME: use RTP payload of bound socket, not BTS*/
1874 lchan->abis_ip.rtp_payload2);
1875
1876 return rc;
1877}
1878
Harald Welte6f40df02010-12-23 12:59:52 +01001879int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02001880{
1881 struct msgb *msg = rsl_msgb_alloc();
1882 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001883 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08001884
1885 if (act)
1886 msg_type = RSL_MT_IPAC_PDCH_ACT;
1887 else
1888 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welteaed946e2009-10-24 10:29:22 +02001889
1890 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08001891 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02001892 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02001893 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02001894
Harald Welte6f40df02010-12-23 12:59:52 +01001895 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08001896 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02001897
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001898 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02001899
1900 return abis_rsl_sendmsg(msg);
1901}
1902
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001903static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001904{
1905 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1906 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05301907 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001908
1909 /* the BTS has acknowledged a local bind, it now tells us the IP
1910 * address and port number to which it has bound the given logical
1911 * channel */
1912
1913 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1914 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1915 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001916 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001917 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08001918 return -EINVAL;
1919 }
Harald Welte50517742009-12-20 15:42:44 +01001920
Harald Weltebffa4992009-12-19 16:42:06 +01001921 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01001922
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001923 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001924
1925 return 0;
1926}
1927
Harald Weltebffa4992009-12-19 16:42:06 +01001928static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1929{
1930 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1931 struct tlv_parsed tv;
1932 struct gsm_lchan *lchan = msg->lchan;
1933
1934 /* the BTS has acknowledged a remote connect request and
1935 * it now tells us the IP address and port number to which it has
1936 * connected the given logical channel */
1937
1938 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1939 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001940 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001941
1942 return 0;
1943}
1944
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001945static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001946{
1947 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1948 struct tlv_parsed tv;
1949
1950 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001951
Harald Weltef1a168d2009-07-28 17:58:09 +02001952 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001953 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001954 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001955
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001956 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001957
Harald Welte59b04682009-06-10 05:40:52 +08001958 return 0;
1959}
1960
1961static int abis_rsl_rx_ipacc(struct msgb *msg)
1962{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001963 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001964 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01001965 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08001966 int rc = 0;
1967
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001968 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001969 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001970
1971 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001972 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001973 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001974 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001975 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001976 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001977 /* somehow the BTS was unable to bind the lchan to its local
1978 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01001979 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001980 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001981 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001982 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01001983 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01001984 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001985 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001986 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001987 /* somehow the BTS was unable to connect the lchan to a remote
1988 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01001989 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001990 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001991 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01001992 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001993 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001994 break;
1995 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001996 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001997 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001998 break;
1999 }
2000 DEBUGPC(DRSL, "\n");
2001
2002 return rc;
2003}
2004
2005
2006/* Entry-point where L2 RSL from BTS enters */
2007int abis_rsl_rcvmsg(struct msgb *msg)
2008{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002009 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08002010 int rc = 0;
2011
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002012 if (!msg) {
2013 DEBUGP(DRSL, "Empty RSL msg?..\n");
2014 return -1;
2015 }
2016
2017 if (msgb_l2len(msg) < sizeof(*rslh)) {
2018 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02002019 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002020 return -1;
2021 }
2022
2023 rslh = msgb_l2(msg);
2024
Harald Welte59b04682009-06-10 05:40:52 +08002025 switch (rslh->msg_discr & 0xfe) {
2026 case ABIS_RSL_MDISC_RLL:
2027 rc = abis_rsl_rx_rll(msg);
2028 break;
2029 case ABIS_RSL_MDISC_DED_CHAN:
2030 rc = abis_rsl_rx_dchan(msg);
2031 break;
2032 case ABIS_RSL_MDISC_COM_CHAN:
2033 rc = abis_rsl_rx_cchan(msg);
2034 break;
2035 case ABIS_RSL_MDISC_TRX:
2036 rc = abis_rsl_rx_trx(msg);
2037 break;
2038 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002039 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08002040 rslh->msg_discr);
2041 break;
2042 case ABIS_RSL_MDISC_IPACCESS:
2043 rc = abis_rsl_rx_ipacc(msg);
2044 break;
2045 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002046 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2047 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02002048 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08002049 }
2050 msgb_free(msg);
2051 return rc;
2052}
2053
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002054int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
2055 uint8_t cb_command, const uint8_t *data, int len)
2056{
2057 struct abis_rsl_dchan_hdr *dh;
2058 struct msgb *cb_cmd;
2059
2060 cb_cmd = rsl_msgb_alloc();
2061 if (!cb_cmd)
2062 return -1;
2063
2064 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
2065 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2066 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2067
2068 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2069 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2070
2071 cb_cmd->trx = bts->c0;
2072
2073 return abis_rsl_sendmsg(cb_cmd);
2074}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002075
2076int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2077{
2078 struct abis_rsl_common_hdr *ch;
2079 struct msgb *msg = rsl_msgb_alloc();
2080
2081 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2082 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2083 ch->msg_type = 0x40; /* Nokia SI Begin */
2084
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002085 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002086
2087 return abis_rsl_sendmsg(msg);
2088}
2089
2090int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2091{
2092 struct abis_rsl_common_hdr *ch;
2093 struct msgb *msg = rsl_msgb_alloc();
2094
2095 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2096 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2097 ch->msg_type = 0x41; /* Nokia SI End */
2098
2099 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2100
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002101 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002102
2103 return abis_rsl_sendmsg(msg);
2104}
2105
2106int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2107{
2108 struct abis_rsl_common_hdr *ch;
2109 struct msgb *msg = rsl_msgb_alloc();
2110
2111 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2112 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2113 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2114
2115 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2116 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2117
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002118 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002119
2120 return abis_rsl_sendmsg(msg);
2121}
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01002122
2123/**
2124 * Release all allocated SAPIs starting from @param start and
2125 * release them with the given release mode. Once the release
2126 * confirmation arrives it will be attempted to release the
2127 * the RF channel.
2128 */
2129int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2130 enum rsl_rel_mode release_mode)
2131{
2132 int no_sapi = 1;
2133 int sapi;
2134
2135 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2136 uint8_t link_id;
2137 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2138 continue;
2139
2140 link_id = sapi;
2141 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2142 link_id |= 0x40;
2143 rsl_release_request(lchan, link_id, release_mode);
2144 no_sapi = 0;
2145 }
2146
2147 return no_sapi;
2148}
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002149
2150int rsl_start_t3109(struct gsm_lchan *lchan)
2151{
2152 struct gsm_bts *bts = lchan->ts->trx->bts;
2153
2154 /* Disabled, mostly legacy code */
2155 if (bts->network->T3109 == 0)
2156 return -1;
2157
2158 lchan->T3109.cb = t3109_expired;
2159 lchan->T3109.data = lchan;
2160 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2161 return 0;
2162}
Holger Hans Peter Freytherc63cb862012-12-25 23:45:14 +01002163
2164/**
2165 * \brief directly RF Channel Release the lchan
2166 *
2167 * When no SAPI was allocated, directly release the logical channel. This
2168 * should only be called from chan_alloc.c on channel release handling. In
2169 * case no SAPI was established the RF Channel can be directly released,
2170 */
2171int rsl_direct_rf_release(struct gsm_lchan *lchan)
2172{
2173 int i;
2174 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2175 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2176 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2177 gsm_lchan_name(lchan), i);
2178 return -1;
2179 }
2180 }
2181
2182 /* Now release it */
2183 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2184}