blob: 7aae590fc71ec568b79ea48d1cebc2569c162d49 [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 Freytherbd5f21f2013-05-01 18:44:04 +0200199 LOGP(DRSL, LOGL_ERROR,
200 "%s Timeout during activation. Marked as broken.\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200201 gsm_lchan_name(lchan));
202
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200203 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
Daniel Willmann2731e732011-08-11 04:44:12 +0200204 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200205}
206
207static void lchan_deact_tmr_cb(void *data)
208{
209 struct gsm_lchan *lchan = data;
210
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200211 LOGP(DRSL, LOGL_ERROR,
212 "%s Timeout during deactivation! Marked as broken.\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200213 gsm_lchan_name(lchan));
214
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200215 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
216 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200217}
218
219
Harald Welte59b04682009-06-10 05:40:52 +0800220/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200221int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
222 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800223{
224 struct abis_rsl_dchan_hdr *dh;
225 struct msgb *msg = rsl_msgb_alloc();
226
227 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
228 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
229 dh->chan_nr = RSL_CHAN_BCCH;
230
231 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
232 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
233
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200234 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800235
236 return abis_rsl_sendmsg(msg);
237}
238
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200239int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
240 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800241{
242 struct abis_rsl_common_hdr *ch;
243 struct msgb *msg = rsl_msgb_alloc();
244
245 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
246 ch->msg_discr = ABIS_RSL_MDISC_TRX;
247 ch->msg_type = RSL_MT_SACCH_FILL;
248
249 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
250 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
251
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200252 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800253
254 return abis_rsl_sendmsg(msg);
255}
256
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200257int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
258 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100259{
260 struct abis_rsl_dchan_hdr *dh;
261 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200262 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100263
264 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
265 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
266 dh->chan_nr = chan_nr;
267
268 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
269 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
270
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200271 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte10b7d8f2011-01-13 23:16:03 +0100272
273 return abis_rsl_sendmsg(msg);
274}
275
Harald Welte91afe4c2009-06-20 18:15:19 +0200276int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
277{
278 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200279 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200280 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200281
282 db = abs(db);
283 if (db > 30)
284 return -EINVAL;
285
Harald Welteed831842009-06-27 03:09:08 +0200286 msg = rsl_msgb_alloc();
287
Harald Welte91afe4c2009-06-20 18:15:19 +0200288 lchan->bs_power = db/2;
289 if (fpc)
290 lchan->bs_power |= 0x10;
291
292 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
293 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
294 dh->chan_nr = chan_nr;
295
296 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
297
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200298 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200299
300 return abis_rsl_sendmsg(msg);
301}
302
Harald Welte91afe4c2009-06-20 18:15:19 +0200303int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
304{
305 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200306 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200307 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200308 int ctl_lvl;
309
Harald Weltec4dcda02009-08-09 14:45:18 +0200310 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200311 if (ctl_lvl < 0)
312 return ctl_lvl;
313
Harald Welteed831842009-06-27 03:09:08 +0200314 msg = rsl_msgb_alloc();
315
Harald Welte91afe4c2009-06-20 18:15:19 +0200316 lchan->ms_power = ctl_lvl;
317
318 if (fpc)
319 lchan->ms_power |= 0x20;
320
321 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
322 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
323 dh->chan_nr = chan_nr;
324
325 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
326
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200327 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200328
329 return abis_rsl_sendmsg(msg);
330}
331
Harald Welte39274f42009-07-29 15:41:29 +0200332static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
333 struct gsm_lchan *lchan)
334{
Holger Hans Peter Freytherfad73652013-03-09 17:50:10 +0100335 memset(cm, 0, sizeof(*cm));
Harald Welte39274f42009-07-29 15:41:29 +0200336
337 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther21d63ff2010-09-06 09:25:48 +0800338 if (lchan->ts->trx->bts->network->dtx_enabled)
339 cm->dtx_dtu = 0x03;
340 else
341 cm->dtx_dtu = 0x00;
Harald Welte39274f42009-07-29 15:41:29 +0200342
343 /* set TCH Speech/Data */
344 cm->spd_ind = lchan->rsl_cmode;
345
Harald Welte951e3512009-11-27 08:55:16 +0100346 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
347 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100348 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100349 "but tch_mode != signalling\n");
350
Harald Welte39274f42009-07-29 15:41:29 +0200351 switch (lchan->type) {
352 case GSM_LCHAN_SDCCH:
353 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
354 break;
355 case GSM_LCHAN_TCH_F:
356 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
357 break;
358 case GSM_LCHAN_TCH_H:
359 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
360 break;
361 case GSM_LCHAN_NONE:
362 case GSM_LCHAN_UNKNOWN:
363 default:
364 return -EINVAL;
365 }
366
367 switch (lchan->tch_mode) {
368 case GSM48_CMODE_SIGN:
369 cm->chan_rate = 0;
370 break;
371 case GSM48_CMODE_SPEECH_V1:
372 cm->chan_rate = RSL_CMOD_SP_GSM1;
373 break;
374 case GSM48_CMODE_SPEECH_EFR:
375 cm->chan_rate = RSL_CMOD_SP_GSM2;
376 break;
377 case GSM48_CMODE_SPEECH_AMR:
378 cm->chan_rate = RSL_CMOD_SP_GSM3;
379 break;
380 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200381 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200382 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200383 switch (lchan->csd_mode) {
384 case LCHAN_CSD_M_NT:
385 /* non-transparent CSD with RLP */
386 switch (lchan->tch_mode) {
387 case GSM48_CMODE_DATA_14k5:
388 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
389 break;
390 case GSM48_CMODE_DATA_12k0:
391 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
392 break;
393 case GSM48_CMODE_DATA_6k0:
394 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
395 break;
396 default:
397 return -EINVAL;
398 }
399 break;
400 /* transparent data services below */
401 case LCHAN_CSD_M_T_1200_75:
402 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
403 break;
404 case LCHAN_CSD_M_T_600:
405 cm->chan_rate = RSL_CMOD_CSD_T_600;
406 break;
407 case LCHAN_CSD_M_T_1200:
408 cm->chan_rate = RSL_CMOD_CSD_T_1200;
409 break;
410 case LCHAN_CSD_M_T_2400:
411 cm->chan_rate = RSL_CMOD_CSD_T_2400;
412 break;
413 case LCHAN_CSD_M_T_9600:
414 cm->chan_rate = RSL_CMOD_CSD_T_9600;
415 break;
416 case LCHAN_CSD_M_T_14400:
417 cm->chan_rate = RSL_CMOD_CSD_T_14400;
418 break;
419 case LCHAN_CSD_M_T_29000:
420 cm->chan_rate = RSL_CMOD_CSD_T_29000;
421 break;
422 case LCHAN_CSD_M_T_32000:
423 cm->chan_rate = RSL_CMOD_CSD_T_32000;
424 break;
425 default:
426 return -EINVAL;
427 }
Harald Welte39274f42009-07-29 15:41:29 +0200428 default:
429 return -EINVAL;
430 }
431
432 return 0;
433}
434
Harald Welte59b04682009-06-10 05:40:52 +0800435/* Chapter 8.4.1 */
436#if 0
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200437int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
438 uint8_t act_type,
Harald Welte59b04682009-06-10 05:40:52 +0800439 struct rsl_ie_chan_mode *chan_mode,
440 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200441 uint8_t bs_power, uint8_t ms_power,
442 uint8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800443{
444 struct abis_rsl_dchan_hdr *dh;
445 struct msgb *msg = rsl_msgb_alloc();
446
447 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
448 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
449 dh->chan_nr = chan_nr;
450
451 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
452 /* For compatibility with Phase 1 */
453 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200454 (uint8_t *) chan_mode);
Harald Welte59b04682009-06-10 05:40:52 +0800455 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200456 (uint8_t *) chan_ident);
Harald Welte59b04682009-06-10 05:40:52 +0800457#if 0
458 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200459 (uint8_t *) &encr_info);
Harald Welte59b04682009-06-10 05:40:52 +0800460#endif
461 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
462 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
463 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
464
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200465 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800466
467 return abis_rsl_sendmsg(msg);
468}
469#endif
470
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200471int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
472 uint8_t ta, uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800473{
474 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200475 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200476 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200477 uint8_t *len;
Harald Welte59b04682009-06-10 05:40:52 +0800478
Harald Weltee6d51f92011-06-25 10:02:33 +0200479 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800480 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200481 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800482
Harald Welte39274f42009-07-29 15:41:29 +0200483 rc = channel_mode_from_lchan(&cm, lchan);
484 if (rc < 0)
485 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800486
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800487 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200488 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800489
Harald Welteed831842009-06-27 03:09:08 +0200490 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800491 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
492 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
493 dh->chan_nr = chan_nr;
494
495 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800496 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200497 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800498
499 /*
500 * The Channel Identification is needed for Phase1 phones
501 * and it contains the GSM48 Channel Description and the
502 * Mobile Allocation. The GSM 08.58 asks for the Mobile
503 * Allocation to have a length of zero. We are using the
504 * msgb_l3len to calculate the length of both messages.
505 */
laforgef723cf02010-06-20 21:38:19 +0200506 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200507 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200508 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800509
510 if (lchan->ts->hopping.enabled)
511 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
512 lchan->ts->hopping.ma_data);
513 else
514 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800515
516 /* update the calculated size */
517 msg->l3h = len + 1;
518 *len = msgb_l3len(msg);
519
Harald Welted2dd9de2009-08-30 15:37:11 +0900520 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200521 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900522 rc = build_encr_info(encr_info, lchan);
523 if (rc > 0)
524 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
525 }
526
Harald Welteb90d7bd2009-12-17 00:31:10 +0100527 switch (act_type) {
528 case RSL_ACT_INTER_ASYNC:
529 case RSL_ACT_INTER_SYNC:
530 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
531 break;
532 default:
533 break;
534 }
535
Harald Welte59b04682009-06-10 05:40:52 +0800536 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
537 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
538 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
539
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100540 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
541 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200542 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100543
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200544 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800545
546 return abis_rsl_sendmsg(msg);
547}
548
Harald Welte8e770492009-07-29 11:38:15 +0200549/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800550int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
551{
552 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200553 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200554 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800555
Harald Weltee6d51f92011-06-25 10:02:33 +0200556 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800557 struct rsl_ie_chan_mode cm;
558
Harald Welte39274f42009-07-29 15:41:29 +0200559 rc = channel_mode_from_lchan(&cm, lchan);
560 if (rc < 0)
561 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800562
Harald Welteed831842009-06-27 03:09:08 +0200563 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800564 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
565 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
566 dh->chan_nr = chan_nr;
567
568 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200569 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900570
571 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200572 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900573 rc = build_encr_info(encr_info, lchan);
574 if (rc > 0)
575 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
576 }
577
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100578 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
579 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200580 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100581 }
582
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200583 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900584
585 return abis_rsl_sendmsg(msg);
586}
587
588/* Chapter 8.4.6: Send the encryption command with given L3 info */
589int rsl_encryption_cmd(struct msgb *msg)
590{
591 struct abis_rsl_dchan_hdr *dh;
592 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200593 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200594 uint8_t encr_info[MAX_A5_KEY_LEN+2];
595 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900596 int rc;
597
598 /* First push the L3 IE tag and length */
599 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
600
601 /* then the link identifier (SAPI0, main sign link) */
602 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
603
604 /* then encryption information */
605 rc = build_encr_info(encr_info, lchan);
606 if (rc <= 0)
607 return rc;
608 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
609
610 /* and finally the DCHAN header */
611 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
612 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
613 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800614
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200615 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800616
617 return abis_rsl_sendmsg(msg);
618}
619
Harald Welte85a163c2009-08-10 11:43:22 +0200620/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200621int rsl_deact_sacch(struct gsm_lchan *lchan)
622{
623 struct abis_rsl_dchan_hdr *dh;
624 struct msgb *msg = rsl_msgb_alloc();
625
626 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
627 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200628 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200629
630 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200631 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200632
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100633 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200634
635 return abis_rsl_sendmsg(msg);
636}
637
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800638static void error_timeout_cb(void *data)
639{
640 struct gsm_lchan *lchan = data;
641 if (lchan->state != LCHAN_S_REL_ERR) {
642 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
643 gsm_lchan_name(lchan), lchan->state);
644 return;
645 }
646
647 /* go back to the none state */
648 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800649 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800650}
651
Harald Welte08011e22011-03-04 13:41:31 +0100652static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
653
Harald Welte85a163c2009-08-10 11:43:22 +0200654/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100655static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
656 enum sacch_deact deact_sacch)
Harald Welte59b04682009-06-10 05:40:52 +0800657{
658 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800659 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100660 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800661
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100662 /* Stop timers that should lead to a channel release */
663 osmo_timer_del(&lchan->T3109);
664
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800665 if (lchan->state == LCHAN_S_REL_ERR) {
666 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
667 gsm_lchan_name(lchan));
668 return -1;
669 }
670
671 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800672 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
673 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200674 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800675
676 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200677 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800678
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800679 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
680
681 if (error) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200682 struct e1inp_sign_link *sign_link = msg->dst;
683
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100684 /*
685 * FIXME: GSM 04.08 gives us two options for the abnormal
686 * chanel release. This can be either like in the non-existent
687 * sub-lcuase 3.5.1 or for the main signalling link deactivate
688 * the SACCH, start timer T3109 and consider the channel as
689 * released.
690 *
691 * This code is doing the later for all raido links and not
692 * only the main link. Right now all SAPIs are released on the
693 * local end, the SACCH will be de-activated and right now the
694 * T3111 will be started. First T3109 should be started and then
695 * the T3111.
696 *
697 * TODO: Move this out of the function.
698 */
699
700 /*
701 * sacch de-activate and "local end release"
702 */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100703 if (deact_sacch == SACCH_DEACTIVATE)
704 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100705 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
706
707 /*
708 * TODO: start T3109 now.
709 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800710 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800711 lchan->error_timer.data = lchan;
712 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +0200713 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200714 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800715 }
Harald Welte59b04682009-06-10 05:40:52 +0800716
Harald Welte32951ea2011-08-10 23:26:33 +0200717 /* Start another timer or assume the BTS sends a ACK/NACK? */
718 lchan->act_timer.cb = lchan_deact_tmr_cb;
719 lchan->act_timer.data = lchan;
720 osmo_timer_schedule(&lchan->act_timer, 4, 0);
721
Harald Welte08011e22011-03-04 13:41:31 +0100722 rc = abis_rsl_sendmsg(msg);
723
Harald Welte85a163c2009-08-10 11:43:22 +0200724 /* BTS will respond by RF CHAN REL ACK */
Harald Welte6bddd822011-01-14 23:18:59 +0100725#ifdef HSL_SR_1_0
Harald Welte08011e22011-03-04 13:41:31 +0100726 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
727 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
728 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte6bddd822011-01-14 23:18:59 +0100729#endif
Harald Welte08011e22011-03-04 13:41:31 +0100730
731 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800732}
733
Harald Welte9773f6c2011-01-14 14:16:16 +0100734static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
735{
736
737 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
738
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100739 /* Stop all pending timers */
Harald Welte32951ea2011-08-10 23:26:33 +0200740 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100741 osmo_timer_del(&lchan->T3111);
Harald Welte32951ea2011-08-10 23:26:33 +0200742
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200743 if (lchan->state == LCHAN_S_BROKEN) {
744 /* we are leaving this channel broken for now */
745 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK for broken channel.\n",
746 gsm_lchan_name(lchan));
747 return 0;
748 }
749
Harald Welte9773f6c2011-01-14 14:16:16 +0100750 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
751 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
752 gsm_lchan_name(lchan),
753 gsm_lchans_name(lchan->state));
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100754 do_lchan_free(lchan);
Harald Welte9773f6c2011-01-14 14:16:16 +0100755
756 return 0;
757}
758
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200759int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
760 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800761{
762 struct abis_rsl_dchan_hdr *dh;
763 struct msgb *msg = rsl_msgb_alloc();
764
765 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
766 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
767 dh->chan_nr = RSL_CHAN_PCH_AGCH;
768
769 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
770 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
771 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
772
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200773 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800774
775 return abis_rsl_sendmsg(msg);
776}
777
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200778int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800779{
780 int i, len = strlen(str_in);
781
782 for (i = 0; i < len; i++) {
783 int num = str_in[i] - 0x30;
784 if (num < 0 || num > 9)
785 return -1;
786 if (i % 2 == 0)
787 bcd_out[i/2] = num;
788 else
789 bcd_out[i/2] |= (num << 4);
790 }
791
792 return 0;
793}
794
795/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200796int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800797{
798 struct msgb *msg = rsl_msgb_alloc();
799 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200800 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800801
802 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
803 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
804 dh->chan_nr = RSL_CHAN_PCH_AGCH;
805
806 switch (bts->type) {
807 case GSM_BTS_TYPE_BS11:
808 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
809 break;
810 default:
811 /* If phase 2, construct a FULL_IMM_ASS_INFO */
812 pad_macblock(buf, val, len);
813 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
814 break;
815 }
816
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200817 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800818
819 return abis_rsl_sendmsg(msg);
820}
821
Harald Welte4684e632009-08-10 09:51:40 +0200822/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200823int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200824{
825 struct msgb *msg = rsl_msgb_alloc();
826 struct abis_rsl_dchan_hdr *dh;
827
828 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
829 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200830 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200831 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200832 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200833
Harald Weltede4477a2009-12-24 12:20:20 +0100834 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200835 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200836
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200837 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +0200838
Harald Welte4684e632009-08-10 09:51:40 +0200839 return abis_rsl_sendmsg(msg);
840}
841
842
Harald Welte59b04682009-06-10 05:40:52 +0800843/* Send "DATA REQUEST" message with given L3 Info payload */
844/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200845int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800846{
Harald Welte59b04682009-06-10 05:40:52 +0800847 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100848 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800849 return -EINVAL;
850 }
851
Harald Weltee6d51f92011-06-25 10:02:33 +0200852 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100853 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800854
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200855 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800856
857 return abis_rsl_sendmsg(msg);
858}
859
Harald Welteed9a5ab2009-08-09 13:47:35 +0200860/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
861/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200862int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200863{
Harald Weltea22d36b2010-03-04 10:33:10 +0100864 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200865
Harald Weltee6d51f92011-06-25 10:02:33 +0200866 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100867 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200868 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200869
Harald Welte17091bd2012-04-26 19:42:19 +0200870 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
871 gsm_lchan_name(lchan), link_id);
872
Harald Welteed9a5ab2009-08-09 13:47:35 +0200873 return abis_rsl_sendmsg(msg);
874}
875
Harald Welte0f2e3c12009-08-08 13:15:07 +0200876/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
877 This is what higher layers should call. The BTS then responds with
878 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
879 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
880 lchan_free() */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100881int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
882 enum rsl_rel_mode release_mode)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200883{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200884
Harald Weltea22d36b2010-03-04 10:33:10 +0100885 struct msgb *msg;
886
Harald Weltee6d51f92011-06-25 10:02:33 +0200887 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100888 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800889 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100890 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200891
Harald Weltec88a4432009-12-29 10:44:17 +0100892 /* FIXME: start some timer in case we don't receive a REL ACK ? */
893
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200894 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200895
Harald Welte17091bd2012-04-26 19:42:19 +0200896 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100897 gsm_lchan_name(lchan), link_id, release_mode);
Harald Welte17091bd2012-04-26 19:42:19 +0200898
Harald Welte0f2e3c12009-08-08 13:15:07 +0200899 return abis_rsl_sendmsg(msg);
900}
901
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200902int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
903{
904 lchan->state = state;
905 return 0;
906}
907
Harald Welte59b04682009-06-10 05:40:52 +0800908/* Chapter 8.4.2: Channel Activate Acknowledge */
909static int rsl_rx_chan_act_ack(struct msgb *msg)
910{
911 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
912
913 /* BTS has confirmed channel activation, we now need
914 * to assign the activated channel to the MS */
915 if (rslh->ie_chan != RSL_IE_CHAN_NR)
916 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100917
Harald Welte32951ea2011-08-10 23:26:33 +0200918 osmo_timer_del(&msg->lchan->act_timer);
919
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200920 if (msg->lchan->state == LCHAN_S_BROKEN) {
921 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel.\n",
922 gsm_lchan_name(msg->lchan));
923 return 0;
924 }
925
Harald Weltec88a4432009-12-29 10:44:17 +0100926 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100927 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
928 gsm_lchan_name(msg->lchan),
929 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200930 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100931
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800932 if (msg->lchan->rqd_ref) {
933 rsl_send_imm_assignment(msg->lchan);
934 talloc_free(msg->lchan->rqd_ref);
935 msg->lchan->rqd_ref = NULL;
936 msg->lchan->rqd_ta = 0;
937 }
938
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100939 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100940
Harald Welte59b04682009-06-10 05:40:52 +0800941 return 0;
942}
943
944/* Chapter 8.4.3: Channel Activate NACK */
945static int rsl_rx_chan_act_nack(struct msgb *msg)
946{
947 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
948 struct tlv_parsed tp;
949
Harald Welte32951ea2011-08-10 23:26:33 +0200950 osmo_timer_del(&msg->lchan->act_timer);
951
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200952 if (msg->lchan->state == LCHAN_S_BROKEN) {
953 LOGP(DRSL, LOGL_ERROR,
954 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
955 gsm_lchan_name(msg->lchan));
956 return -1;
957 }
958
Daniel Willmann9e9d44c2011-08-11 04:54:23 +0200959 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100960 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100961
Harald Welte59b04682009-06-10 05:40:52 +0800962 /* BTS has rejected channel activation ?!? */
963 if (dh->ie_chan != RSL_IE_CHAN_NR)
964 return -EINVAL;
965
966 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100967 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200968 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100969 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +0200970 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +0100971 msg->lchan->error_cause = *cause;
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100972 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +0100973 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Daniel Willmann245ee032011-08-11 04:47:11 +0200974 else
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100975 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann245ee032011-08-11 04:47:11 +0200976
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100977 } else
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +0100978 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200979
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100980 LOGPC(DRSL, LOGL_ERROR, "\n");
981
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100982 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte59b04682009-06-10 05:40:52 +0800983 return 0;
984}
985
986/* Chapter 8.4.4: Connection Failure Indication */
987static int rsl_rx_conn_fail(struct msgb *msg)
988{
989 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
990 struct tlv_parsed tp;
991
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100992 /* FIXME: print which channel */
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100993 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100994 gsm_lchan_name(msg->lchan));
Harald Welte59b04682009-06-10 05:40:52 +0800995
996 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
997
Harald Weltef1a168d2009-07-28 17:58:09 +0200998 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +0100999 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001000 TLVP_LEN(&tp, RSL_IE_CAUSE));
1001
Harald Welte (local)4bd76642009-12-26 22:33:09 +01001002 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001003 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001004 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001005 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Harald Welte59b04682009-06-10 05:40:52 +08001006}
1007
Harald Weltec20bd1d2009-11-29 19:07:28 +01001008static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1009 const char *prefix)
1010{
Harald Welte0e4fa782009-12-16 16:52:07 +01001011 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1012 prefix, rxlev2dbm(mru->full.rx_lev),
1013 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +01001014 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1015 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1016}
1017
Harald Welte50290cc2012-07-02 17:12:08 +02001018static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +01001019{
Harald Welte0e4fa782009-12-16 16:52:07 +01001020 int i;
Harald Welte50290cc2012-07-02 17:12:08 +02001021 char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +01001022
Harald Welte50290cc2012-07-02 17:12:08 +02001023 if (lchan && lchan->conn && lchan->conn->subscr)
1024 name = subscr_name(lchan->conn->subscr);
1025
1026 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001027
1028 if (mr->flags & MEAS_REP_F_DL_DTX)
1029 DEBUGPC(DMEAS, "DTXd ");
1030
1031 print_meas_rep_uni(&mr->ul, "ul");
1032 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1033 if (mr->flags & MEAS_REP_F_MS_TO)
1034 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1035
1036 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +01001037 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001038 DEBUGPC(DMEAS, "L1_FPC=%u ",
1039 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1040 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1041 }
1042
1043 if (mr->flags & MEAS_REP_F_UL_DTX)
1044 DEBUGPC(DMEAS, "DTXu ");
1045 if (mr->flags & MEAS_REP_F_BA1)
1046 DEBUGPC(DMEAS, "BA1 ");
1047 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1048 DEBUGPC(DMEAS, "NOT VALID ");
1049 else
1050 print_meas_rep_uni(&mr->dl, "dl");
1051
1052 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +01001053 if (mr->num_cell == 7)
1054 return;
Harald Welte0e4fa782009-12-16 16:52:07 +01001055 for (i = 0; i < mr->num_cell; i++) {
1056 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +01001057 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1058 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001059 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001060}
1061
Harald Welte59b04682009-06-10 05:40:52 +08001062static int rsl_rx_meas_res(struct msgb *msg)
1063{
1064 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1065 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001066 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001067 uint8_t len;
1068 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001069 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001070
Harald Welte4baa9c52009-12-21 13:27:11 +01001071 /* check if this channel is actually active */
1072 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001073 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001074 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001075 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001076 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001077 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001078
Harald Weltef9476812009-12-15 21:36:05 +01001079 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001080 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001081
Harald Welte59b04682009-06-10 05:40:52 +08001082 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1083
Harald Weltec20bd1d2009-11-29 19:07:28 +01001084 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1085 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1086 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1087 return -EIO;
1088
1089 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001090 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001091
1092 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1093 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1094 if (len >= 3) {
1095 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001096 mr->flags |= MEAS_REP_F_DL_DTX;
1097 mr->ul.full.rx_lev = val[0] & 0x3f;
1098 mr->ul.sub.rx_lev = val[1] & 0x3f;
1099 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1100 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001101 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001102
Harald Weltef9476812009-12-15 21:36:05 +01001103 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001104
1105 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +08001106 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +01001107 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +01001108 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1109
Harald Weltea1467eb2009-06-20 18:44:35 +02001110 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001111 struct e1inp_sign_link *sign_link = msg->dst;
1112
Harald Weltec20bd1d2009-11-29 19:07:28 +01001113 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001114 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001115 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001116 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001117 mr->flags |= MEAS_REP_F_FPC;
1118 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001119 /* BS11 and Nokia reports TA shifted by 2 bits */
1120 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1121 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001122 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001123 }
Harald Welte59b04682009-06-10 05:40:52 +08001124 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001125 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001126 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001127 if (rc < 0)
1128 return rc;
1129 }
1130
Harald Welte50290cc2012-07-02 17:12:08 +02001131 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001132
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001133 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001134
Harald Welte59b04682009-06-10 05:40:52 +08001135 return 0;
1136}
1137
Harald Welte6720a432009-11-29 22:45:52 +01001138/* Chapter 8.4.7 */
1139static int rsl_rx_hando_det(struct msgb *msg)
1140{
1141 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1142 struct tlv_parsed tp;
1143
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001144 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001145
1146 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1147
1148 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1149 DEBUGPC(DRSL, "access delay = %u\n",
1150 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1151 else
1152 DEBUGPC(DRSL, "\n");
1153
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001154 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001155
1156 return 0;
1157}
1158
Harald Welte59b04682009-06-10 05:40:52 +08001159static int abis_rsl_rx_dchan(struct msgb *msg)
1160{
1161 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1162 int rc = 0;
1163 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001164 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001165
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001166 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001167 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001168
Harald Welte59b04682009-06-10 05:40:52 +08001169 switch (rslh->c.msg_type) {
1170 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001171 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001172 rc = rsl_rx_chan_act_ack(msg);
1173 break;
1174 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001175 rc = rsl_rx_chan_act_nack(msg);
1176 break;
1177 case RSL_MT_CONN_FAIL:
1178 rc = rsl_rx_conn_fail(msg);
1179 break;
1180 case RSL_MT_MEAS_RES:
1181 rc = rsl_rx_meas_res(msg);
1182 break;
Harald Welte6720a432009-11-29 22:45:52 +01001183 case RSL_MT_HANDO_DET:
1184 rc = rsl_rx_hando_det(msg);
1185 break;
Harald Welte59b04682009-06-10 05:40:52 +08001186 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001187 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001188 break;
1189 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001190 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001191 break;
1192 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001193 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001194 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001195 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001196 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001197 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001198 break;
1199 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001200 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001201 break;
1202 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001203 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001204 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001205 break;
1206 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001207 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001208 break;
Harald Welte59b04682009-06-10 05:40:52 +08001209 case RSL_MT_PHY_CONTEXT_CONF:
1210 case RSL_MT_PREPROC_MEAS_RES:
1211 case RSL_MT_TALKER_DET:
1212 case RSL_MT_LISTENER_DET:
1213 case RSL_MT_REMOTE_CODEC_CONF_REP:
1214 case RSL_MT_MR_CODEC_MOD_ACK:
1215 case RSL_MT_MR_CODEC_MOD_NACK:
1216 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001217 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1218 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001219 break;
1220 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001221 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1222 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001223 return -EINVAL;
1224 }
1225
1226 return rc;
1227}
1228
1229static int rsl_rx_error_rep(struct msgb *msg)
1230{
1231 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001232 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001233 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001234
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001235 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001236
1237 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1238
1239 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001240 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001241 TLVP_LEN(&tp, RSL_IE_CAUSE));
1242
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001243 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001244
1245 return 0;
1246}
1247
1248static int abis_rsl_rx_trx(struct msgb *msg)
1249{
1250 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001251 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001252 int rc = 0;
1253
1254 switch (rslh->msg_type) {
1255 case RSL_MT_ERROR_REPORT:
1256 rc = rsl_rx_error_rep(msg);
1257 break;
1258 case RSL_MT_RF_RES_IND:
1259 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001260 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001261 break;
1262 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001263 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001264 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001265 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001266 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001267 case 0x42: /* Nokia specific: SI End ACK */
1268 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1269 break;
1270 case 0x43: /* Nokia specific: SI End NACK */
1271 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1272 break;
Harald Welte59b04682009-06-10 05:40:52 +08001273 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001274 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001275 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001276 return -EINVAL;
1277 }
1278 return rc;
1279}
1280
Harald Welte427dbc42009-08-10 00:26:10 +02001281/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1282static void t3101_expired(void *data)
1283{
1284 struct gsm_lchan *lchan = data;
1285
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001286 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welte427dbc42009-08-10 00:26:10 +02001287}
1288
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001289/* If T3111 expires, we will send the RF Channel Request */
1290static void t3111_expired(void *data)
1291{
1292 struct gsm_lchan *lchan = data;
1293
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001294 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1295}
1296
1297/* If T3109 expires the MS has not send a UA/UM do the error release */
1298static void t3109_expired(void *data)
1299{
1300 struct gsm_lchan *lchan = data;
1301
1302 LOGP(DRSL, LOGL_ERROR,
1303 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1304 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001305}
1306
laforge50312e82010-06-21 12:08:52 +02001307#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1308
Harald Weltea00fdd72010-12-23 14:39:29 +01001309/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1310static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1311 unsigned int num_req_refs,
1312 struct gsm48_req_ref *rqd_refs,
1313 uint8_t wait_ind)
1314{
1315 uint8_t buf[GSM_MACBLOCK_LEN];
1316 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1317
1318 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1319 memset(iar, 0, sizeof(*iar));
1320 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001321 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Weltea00fdd72010-12-23 14:39:29 +01001322 iar->page_mode = GSM48_PM_SAME;
1323
1324 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1325 iar->wait_ind1 = wait_ind;
1326
1327 if (num_req_refs >= 2)
1328 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1329 else
1330 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1331 iar->wait_ind2 = wait_ind;
1332
1333 if (num_req_refs >= 3)
1334 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1335 else
1336 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1337 iar->wait_ind3 = wait_ind;
1338
1339 if (num_req_refs >= 4)
1340 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1341 else
1342 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1343 iar->wait_ind4 = wait_ind;
1344
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001345 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1346 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1347
1348 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Weltea00fdd72010-12-23 14:39:29 +01001349}
1350
Harald Welte59b04682009-06-10 05:40:52 +08001351/* MS has requested a channel on the RACH */
1352static int rsl_rx_chan_rqd(struct msgb *msg)
1353{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001354 struct e1inp_sign_link *sign_link = msg->dst;
1355 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001356 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1357 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001358 enum gsm_chan_t lctype;
1359 enum gsm_chreq_reason_t chreq_reason;
1360 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001361 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001362 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001363
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001364 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001365 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001366
1367 /* parse request reference to be used in immediate assign */
1368 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1369 return -EINVAL;
1370
1371 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1372
1373 /* parse access delay and use as TA */
1374 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1375 return -EINVAL;
1376 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1377
1378 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1379 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001380 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1381 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001382
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001383 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001384
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001385 /*
1386 * We want LOCATION UPDATES to succeed and will assign a TCH
1387 * if we have no SDCCH available.
1388 */
1389 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1390
Harald Welte59b04682009-06-10 05:40:52 +08001391 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001392 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001393 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001394 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001395 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001396 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001397 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1398 if (bts->network->T3122)
1399 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte59b04682009-06-10 05:40:52 +08001400 return -ENOMEM;
1401 }
1402
Harald Weltec88a4432009-12-29 10:44:17 +01001403 if (lchan->state != LCHAN_S_NONE)
1404 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001405 "in state %s\n", gsm_lchan_name(lchan),
1406 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001407
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001408 /* save the RACH data as we need it after the CHAN ACT ACK */
1409 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1410 if (!lchan->rqd_ref) {
1411 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1412 lchan_free(lchan);
1413 return -ENOMEM;
1414 }
1415
Holger Hans Peter Freyther161cec12011-12-29 23:33:04 +01001416 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001417 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1418 lchan->rqd_ta = rqd_ta;
1419
Harald Welte59b04682009-06-10 05:40:52 +08001420 arfcn = lchan->ts->trx->arfcn;
1421 subch = lchan->nr;
1422
Harald Welted2dd9de2009-08-30 15:37:11 +09001423 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001424 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001425 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001426 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001427 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001428
Harald Welte32951ea2011-08-10 23:26:33 +02001429 /* Start another timer or assume the BTS sends a ACK/NACK? */
1430 lchan->act_timer.cb = lchan_act_tmr_cb;
1431 lchan->act_timer.data = lchan;
1432 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1433
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001434 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1435 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1436 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1437 rqd_ref->ra, rqd_ta);
1438
1439 /* BS11 requires TA shifted by 2 bits */
1440 if (bts->type == GSM_BTS_TYPE_BS11)
1441 rqd_ta <<= 2;
Harald Welteb90d7bd2009-12-17 00:31:10 +01001442 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001443
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001444 return 0;
1445}
1446
1447static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1448{
1449 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001450 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001451 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1452
Harald Welte59b04682009-06-10 05:40:52 +08001453 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001454 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001455 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001456 ia->proto_discr = GSM48_PDISC_RR;
1457 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1458 ia->page_mode = GSM48_PM_SAME;
1459 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001460
Harald Welte59b04682009-06-10 05:40:52 +08001461 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001462 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1463 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001464 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001465 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001466 } else {
laforgee06d5982010-06-20 15:18:46 +02001467 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1468 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001469 }
Harald Welte07f32182010-06-28 18:41:27 +02001470 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1471 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001472
Harald Welte427dbc42009-08-10 00:26:10 +02001473 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1474 lchan->T3101.cb = t3101_expired;
1475 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001476 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001477
1478 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001479 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001480}
1481
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001482/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001483static int rsl_rx_ccch_load(struct msgb *msg)
1484{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001485 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001486 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001487 struct ccch_signal_data sd;
1488
1489 sd.bts = sign_link->trx->bts;
1490 sd.rach_slot_count = -1;
1491 sd.rach_busy_count = -1;
1492 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001493
1494 switch (rslh->data[0]) {
1495 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001496 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1497 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001498 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001499 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001500 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001501 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1502 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001503 break;
1504 case RSL_IE_RACH_LOAD:
1505 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001506 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1507 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1508 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1509 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001510 }
1511 break;
1512 default:
1513 break;
1514 }
1515
1516 return 0;
1517}
1518
1519static int abis_rsl_rx_cchan(struct msgb *msg)
1520{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001521 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001522 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1523 int rc = 0;
1524
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001525 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001526
1527 switch (rslh->c.msg_type) {
1528 case RSL_MT_CHAN_RQD:
1529 /* MS has requested a channel on the RACH */
1530 rc = rsl_rx_chan_rqd(msg);
1531 break;
1532 case RSL_MT_CCCH_LOAD_IND:
1533 /* current load on the CCCH */
1534 rc = rsl_rx_ccch_load(msg);
1535 break;
1536 case RSL_MT_DELETE_IND:
1537 /* CCCH overloaded, IMM_ASSIGN was dropped */
1538 case RSL_MT_CBCH_LOAD_IND:
1539 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001540 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1541 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001542 break;
1543 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001544 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1545 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001546 return -EINVAL;
1547 }
1548
1549 return rc;
1550}
1551
1552static int rsl_rx_rll_err_ind(struct msgb *msg)
1553{
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001554 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001555 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001556 uint8_t rlm_cause;
Harald Welte59b04682009-06-10 05:40:52 +08001557
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001558 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1559 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1560 LOGP(DRLL, LOGL_ERROR,
1561 "%s ERROR INDICATION without mandantory cause.\n",
1562 gsm_lchan_name(msg->lchan));
1563 return -1;
1564 }
1565
1566 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001567 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001568 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001569 rsl_rlm_cause_name(rlm_cause));
Harald Welteed9a5ab2009-08-09 13:47:35 +02001570
1571 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001572
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001573 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001574 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001575 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001576 }
Harald Welte692f5852009-07-04 09:40:05 +02001577
Harald Welte59b04682009-06-10 05:40:52 +08001578 return 0;
1579}
1580
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001581static void rsl_handle_release(struct gsm_lchan *lchan)
1582{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001583 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001584 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001585
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +01001586 /*
1587 * Maybe only one link/SAPI was releasd or the error handling
1588 * was activated. Just return now and let the other code handle
1589 * it.
1590 */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001591 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001592 return;
1593
1594 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1595 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1596 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001597 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001598 gsm_lchan_name(lchan), sapi);
1599 return;
1600 }
1601
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001602
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001603 /* Stop T3109 and wait for T3111 before re-using the channel */
1604 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001605 lchan->T3111.cb = t3111_expired;
1606 lchan->T3111.data = lchan;
1607 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001608 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001609}
1610
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001611/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001612 0x02, 0x06,
1613 0x01, 0x20,
1614 0x02, 0x00,
1615 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1616
1617static int abis_rsl_rx_rll(struct msgb *msg)
1618{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001619 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001620 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1621 int rc = 0;
1622 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001623 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001624
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001625 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001626 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001627 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001628
1629 switch (rllh->c.msg_type) {
1630 case RSL_MT_DATA_IND:
1631 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001632 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001633 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1634 rllh->data[0] == RSL_IE_L3_INFO) {
1635 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001636 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001637 }
1638 break;
1639 case RSL_MT_EST_IND:
1640 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001641 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001642 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001643 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001644 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001645 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1646 rllh->data[0] == RSL_IE_L3_INFO) {
1647 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001648 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001649 }
1650 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001651 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001652 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001653 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001654 rll_indication(msg->lchan, rllh->link_id,
1655 BSC_RLLR_IND_EST_CONF);
1656 break;
Harald Welte59b04682009-06-10 05:40:52 +08001657 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001658 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001659 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001660 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001661 rll_indication(msg->lchan, rllh->link_id,
1662 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001663 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001664 break;
1665 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001666 /* BTS informs us of having received UA from MS,
1667 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001668 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001669 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001670 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001671 break;
1672 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001673 rc = rsl_rx_rll_err_ind(msg);
1674 break;
1675 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001676 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1677 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001678 break;
1679 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001680 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1681 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001682 }
Harald Welte59b04682009-06-10 05:40:52 +08001683 return rc;
1684}
1685
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001686static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001687{
Harald Welteb284b472009-12-02 01:58:23 +05301688 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001689 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301690 switch (lchan->type) {
1691 case GSM_LCHAN_TCH_F:
1692 return 0x00;
1693 case GSM_LCHAN_TCH_H:
1694 return 0x03;
1695 default:
1696 break;
1697 }
Harald Welte98d79f92009-07-28 18:11:56 +02001698 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301699 switch (lchan->type) {
1700 case GSM_LCHAN_TCH_F:
1701 return 0x01;
1702 /* there's no half-rate EFR */
1703 default:
1704 break;
1705 }
Harald Welte98d79f92009-07-28 18:11:56 +02001706 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301707 switch (lchan->type) {
1708 case GSM_LCHAN_TCH_F:
1709 return 0x02;
1710 case GSM_LCHAN_TCH_H:
1711 return 0x05;
1712 default:
1713 break;
1714 }
1715 default:
1716 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001717 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001718 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301719 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001720 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001721}
1722
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001723static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001724{
1725 switch (lchan->tch_mode) {
1726 case GSM48_CMODE_SPEECH_V1:
1727 switch (lchan->type) {
1728 case GSM_LCHAN_TCH_F:
1729 return RTP_PT_GSM_FULL;
1730 case GSM_LCHAN_TCH_H:
1731 return RTP_PT_GSM_HALF;
1732 default:
1733 break;
1734 }
1735 case GSM48_CMODE_SPEECH_EFR:
1736 switch (lchan->type) {
1737 case GSM_LCHAN_TCH_F:
1738 return RTP_PT_GSM_EFR;
1739 /* there's no half-rate EFR */
1740 default:
1741 break;
1742 }
1743 case GSM48_CMODE_SPEECH_AMR:
1744 switch (lchan->type) {
1745 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01001746 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02001747 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001748 default:
1749 break;
1750 }
1751 default:
1752 break;
1753 }
1754 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1755 "tch_mode == 0x%02x\n & lchan_type == %d",
1756 lchan->tch_mode, lchan->type);
1757 return 0;
1758}
1759
Harald Welte59b04682009-06-10 05:40:52 +08001760/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001761static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1762{
1763 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001764 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001765
1766 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001767 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001768 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1769 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1770 }
1771
1772 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001773 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001774 port = ntohs(port);
1775 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1776 lchan->abis_ip.bound_port = port;
1777 }
1778
1779 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001780 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Weltebffa4992009-12-19 16:42:06 +01001781 conn_id = ntohs(conn_id);
1782 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1783 lchan->abis_ip.conn_id = conn_id;
1784 }
1785
1786 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1787 lchan->abis_ip.rtp_payload2 =
1788 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1789 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1790 lchan->abis_ip.rtp_payload2);
1791 }
1792
1793 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1794 lchan->abis_ip.speech_mode =
1795 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1796 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1797 lchan->abis_ip.speech_mode);
1798 }
1799
1800 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001801 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001802 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1803 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1804 }
1805
1806 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001807 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001808 port = ntohs(port);
1809 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1810 lchan->abis_ip.connect_port = port;
1811 }
1812}
1813
Harald Welte9a696d72013-02-03 12:06:58 +01001814/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1815 * \param[in] lchan Logical Channel for which we issue CRCX
1816 */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001817int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001818{
1819 struct msgb *msg = rsl_msgb_alloc();
1820 struct abis_rsl_dchan_hdr *dh;
1821
1822 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001823 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001824 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001825 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001826
Harald Welte98d79f92009-07-28 18:11:56 +02001827 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001828 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001829 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001830 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001831 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001832
Sylvain Munaut1338a552009-12-20 22:06:40 +01001833 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1834 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1835 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001836
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001837 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001838
1839 return abis_rsl_sendmsg(msg);
1840}
1841
Harald Welte9a696d72013-02-03 12:06:58 +01001842/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1843 * \param[in] lchan Logical Channel for which we issue MDCX
1844 * \param[in] ip Remote (MGW) IP address for RTP
1845 * \param[in] port Remote (MGW) UDP port number for RTP
1846 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1847 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001848int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1849 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001850{
1851 struct msgb *msg = rsl_msgb_alloc();
1852 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001853 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001854 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001855
1856 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001857 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001858 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001859 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001860
Harald Weltebffa4992009-12-19 16:42:06 +01001861 /* we need to store these now as MDCX_ACK does not return them :( */
1862 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1863 lchan->abis_ip.connect_port = port;
1864 lchan->abis_ip.connect_ip = ip;
1865
Harald Weltefb4a9e92009-07-29 12:12:18 +02001866 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001867 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001868 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001869
Harald Welte98d79f92009-07-28 18:11:56 +02001870 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001871 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1872 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1873 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1874 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001875
Harald Weltebffa4992009-12-19 16:42:06 +01001876 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1877 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001878 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001879 *att_ip = ia.s_addr;
1880 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1881 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001882 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001883 if (rtp_payload2)
1884 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001885
1886 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001887
1888 return abis_rsl_sendmsg(msg);
1889}
1890
Harald Welte9947d9f2009-12-20 16:51:09 +01001891/* tell BTS to connect RTP stream to our local RTP socket */
1892int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1893{
1894 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1895 int rc;
1896
1897 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1898 ntohs(rs->rtp.sin_local.sin_port),
1899 /* FIXME: use RTP payload of bound socket, not BTS*/
1900 lchan->abis_ip.rtp_payload2);
1901
1902 return rc;
1903}
1904
Harald Welte6f40df02010-12-23 12:59:52 +01001905int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02001906{
1907 struct msgb *msg = rsl_msgb_alloc();
1908 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001909 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08001910
1911 if (act)
1912 msg_type = RSL_MT_IPAC_PDCH_ACT;
1913 else
1914 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welteaed946e2009-10-24 10:29:22 +02001915
1916 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08001917 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02001918 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02001919 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02001920
Harald Welte6f40df02010-12-23 12:59:52 +01001921 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08001922 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02001923
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001924 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02001925
1926 return abis_rsl_sendmsg(msg);
1927}
1928
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001929static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001930{
1931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1932 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05301933 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001934
1935 /* the BTS has acknowledged a local bind, it now tells us the IP
1936 * address and port number to which it has bound the given logical
1937 * channel */
1938
1939 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1940 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1941 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001942 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001943 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08001944 return -EINVAL;
1945 }
Harald Welte50517742009-12-20 15:42:44 +01001946
Harald Weltebffa4992009-12-19 16:42:06 +01001947 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01001948
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001949 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001950
1951 return 0;
1952}
1953
Harald Weltebffa4992009-12-19 16:42:06 +01001954static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1955{
1956 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1957 struct tlv_parsed tv;
1958 struct gsm_lchan *lchan = msg->lchan;
1959
1960 /* the BTS has acknowledged a remote connect request and
1961 * it now tells us the IP address and port number to which it has
1962 * connected the given logical channel */
1963
1964 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1965 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001966 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001967
1968 return 0;
1969}
1970
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001971static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001972{
1973 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1974 struct tlv_parsed tv;
1975
1976 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001977
Harald Weltef1a168d2009-07-28 17:58:09 +02001978 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001979 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001980 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001981
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001982 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001983
Harald Welte59b04682009-06-10 05:40:52 +08001984 return 0;
1985}
1986
1987static int abis_rsl_rx_ipacc(struct msgb *msg)
1988{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001989 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001990 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01001991 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08001992 int rc = 0;
1993
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001994 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001995 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001996
1997 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001998 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001999 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002000 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002001 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002002 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002003 /* somehow the BTS was unable to bind the lchan to its local
2004 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01002005 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002006 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002007 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08002008 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01002009 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01002010 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002011 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002012 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002013 /* somehow the BTS was unable to connect the lchan to a remote
2014 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01002015 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002016 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002017 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01002018 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002019 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002020 break;
2021 default:
Harald Weltede4477a2009-12-24 12:20:20 +01002022 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002023 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002024 break;
2025 }
2026 DEBUGPC(DRSL, "\n");
2027
2028 return rc;
2029}
2030
2031
2032/* Entry-point where L2 RSL from BTS enters */
2033int abis_rsl_rcvmsg(struct msgb *msg)
2034{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002035 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08002036 int rc = 0;
2037
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002038 if (!msg) {
2039 DEBUGP(DRSL, "Empty RSL msg?..\n");
2040 return -1;
2041 }
2042
2043 if (msgb_l2len(msg) < sizeof(*rslh)) {
2044 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02002045 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002046 return -1;
2047 }
2048
2049 rslh = msgb_l2(msg);
2050
Harald Welte59b04682009-06-10 05:40:52 +08002051 switch (rslh->msg_discr & 0xfe) {
2052 case ABIS_RSL_MDISC_RLL:
2053 rc = abis_rsl_rx_rll(msg);
2054 break;
2055 case ABIS_RSL_MDISC_DED_CHAN:
2056 rc = abis_rsl_rx_dchan(msg);
2057 break;
2058 case ABIS_RSL_MDISC_COM_CHAN:
2059 rc = abis_rsl_rx_cchan(msg);
2060 break;
2061 case ABIS_RSL_MDISC_TRX:
2062 rc = abis_rsl_rx_trx(msg);
2063 break;
2064 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002065 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08002066 rslh->msg_discr);
2067 break;
2068 case ABIS_RSL_MDISC_IPACCESS:
2069 rc = abis_rsl_rx_ipacc(msg);
2070 break;
2071 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002072 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2073 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02002074 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08002075 }
2076 msgb_free(msg);
2077 return rc;
2078}
2079
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002080int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
2081 uint8_t cb_command, const uint8_t *data, int len)
2082{
2083 struct abis_rsl_dchan_hdr *dh;
2084 struct msgb *cb_cmd;
2085
2086 cb_cmd = rsl_msgb_alloc();
2087 if (!cb_cmd)
2088 return -1;
2089
2090 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
2091 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2092 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2093
2094 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2095 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2096
2097 cb_cmd->trx = bts->c0;
2098
2099 return abis_rsl_sendmsg(cb_cmd);
2100}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002101
2102int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2103{
2104 struct abis_rsl_common_hdr *ch;
2105 struct msgb *msg = rsl_msgb_alloc();
2106
2107 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2108 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2109 ch->msg_type = 0x40; /* Nokia SI Begin */
2110
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002111 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002112
2113 return abis_rsl_sendmsg(msg);
2114}
2115
2116int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2117{
2118 struct abis_rsl_common_hdr *ch;
2119 struct msgb *msg = rsl_msgb_alloc();
2120
2121 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2122 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2123 ch->msg_type = 0x41; /* Nokia SI End */
2124
2125 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2126
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002127 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002128
2129 return abis_rsl_sendmsg(msg);
2130}
2131
2132int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2133{
2134 struct abis_rsl_common_hdr *ch;
2135 struct msgb *msg = rsl_msgb_alloc();
2136
2137 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2138 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2139 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2140
2141 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2142 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2143
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002144 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002145
2146 return abis_rsl_sendmsg(msg);
2147}
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01002148
2149/**
2150 * Release all allocated SAPIs starting from @param start and
2151 * release them with the given release mode. Once the release
2152 * confirmation arrives it will be attempted to release the
2153 * the RF channel.
2154 */
2155int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2156 enum rsl_rel_mode release_mode)
2157{
2158 int no_sapi = 1;
2159 int sapi;
2160
2161 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2162 uint8_t link_id;
2163 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2164 continue;
2165
2166 link_id = sapi;
2167 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2168 link_id |= 0x40;
2169 rsl_release_request(lchan, link_id, release_mode);
2170 no_sapi = 0;
2171 }
2172
2173 return no_sapi;
2174}
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002175
2176int rsl_start_t3109(struct gsm_lchan *lchan)
2177{
2178 struct gsm_bts *bts = lchan->ts->trx->bts;
2179
2180 /* Disabled, mostly legacy code */
2181 if (bts->network->T3109 == 0)
2182 return -1;
2183
2184 lchan->T3109.cb = t3109_expired;
2185 lchan->T3109.data = lchan;
2186 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2187 return 0;
2188}
Holger Hans Peter Freytherc63cb862012-12-25 23:45:14 +01002189
2190/**
2191 * \brief directly RF Channel Release the lchan
2192 *
2193 * When no SAPI was allocated, directly release the logical channel. This
2194 * should only be called from chan_alloc.c on channel release handling. In
2195 * case no SAPI was established the RF Channel can be directly released,
2196 */
2197int rsl_direct_rf_release(struct gsm_lchan *lchan)
2198{
2199 int i;
2200 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2201 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2202 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2203 gsm_lchan_name(lchan), i);
2204 return -1;
2205 }
2206 }
2207
2208 /* Now release it */
2209 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2210}