blob: fc56862833de1c13a8b6eb275d5a80186bacd860 [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>
Max3d94aca2016-05-11 12:45:13 +020038#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include <osmocom/gsm/protocol/gsm_08_58.h>
Harald Welte59b04682009-06-10 05:40:52 +080040#include <openbsc/paging.h>
41#include <openbsc/signal.h>
Harald Weltec20bd1d2009-11-29 19:07:28 +010042#include <openbsc/meas_rep.h>
Harald Welte50517742009-12-20 15:42:44 +010043#include <openbsc/rtp_proxy.h>
Pablo Neira Ayuso42e41df2011-08-17 22:44:07 +020044#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010045#include <osmocom/gsm/rsl.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010046#include <osmocom/core/talloc.h>
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080047
Harald Welte59b04682009-06-10 05:40:52 +080048#define RSL_ALLOC_SIZE 1024
49#define RSL_ALLOC_HEADROOM 128
50
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +010051enum sacch_deact {
52 SACCH_NONE,
53 SACCH_DEACTIVATE,
54};
55
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080056static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020057static void error_timeout_cb(void *data);
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080058
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010059static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
60 struct gsm_meas_rep *resp)
61{
62 struct lchan_signal_data sig;
63 sig.lchan = lchan;
64 sig.mr = resp;
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +020065 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010066}
67
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010068static void do_lchan_free(struct gsm_lchan *lchan)
69{
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020070 /* We start the error timer to make the channel available again */
71 if (lchan->state == LCHAN_S_REL_ERR) {
72 lchan->error_timer.data = lchan;
73 lchan->error_timer.cb = error_timeout_cb;
74 osmo_timer_schedule(&lchan->error_timer,
75 lchan->ts->trx->bts->network->T3111 + 2, 0);
76 } else {
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010077 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020078 }
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010079 lchan_free(lchan);
80}
81
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020082static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080083{
84 /* mask off the transparent bit ? */
85 msg_type &= 0xfe;
86
87 if ((msg_type & 0xf0) == 0x00)
88 return ABIS_RSL_MDISC_RLL;
89 if ((msg_type & 0xf0) == 0x10) {
90 if (msg_type >= 0x19 && msg_type <= 0x22)
91 return ABIS_RSL_MDISC_TRX;
92 else
93 return ABIS_RSL_MDISC_COM_CHAN;
94 }
95 if ((msg_type & 0xe0) == 0x20)
96 return ABIS_RSL_MDISC_DED_CHAN;
97
98 return ABIS_RSL_MDISC_LOC;
99}
100
101static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200102 uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +0800103{
104 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
105 dh->c.msg_type = msg_type;
106 dh->ie_chan = RSL_IE_CHAN_NR;
107}
108
Harald Welte59b04682009-06-10 05:40:52 +0800109/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200110struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte59b04682009-06-10 05:40:52 +0800111{
112 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200113 uint8_t ts_nr = chan_nr & 0x07;
114 uint8_t cbits = chan_nr >> 3;
115 uint8_t lch_idx;
Harald Welte59b04682009-06-10 05:40:52 +0800116 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
117
118 if (cbits == 0x01) {
119 lch_idx = 0; /* TCH/F */
Harald Welte37884ed2009-10-24 10:25:50 +0200120 if (ts->pchan != GSM_PCHAN_TCH_F &&
121 ts->pchan != GSM_PCHAN_PDCH &&
122 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100123 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800124 chan_nr, ts->pchan);
125 } else if ((cbits & 0x1e) == 0x02) {
126 lch_idx = cbits & 0x1; /* TCH/H */
127 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100128 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800129 chan_nr, ts->pchan);
130 } else if ((cbits & 0x1c) == 0x04) {
131 lch_idx = cbits & 0x3; /* SDCCH/4 */
Harald Weltebf4ba722014-12-28 15:00:45 +0100132 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
133 ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100134 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800135 chan_nr, ts->pchan);
136 } else if ((cbits & 0x18) == 0x08) {
137 lch_idx = cbits & 0x7; /* SDCCH/8 */
Harald Weltebf4ba722014-12-28 15:00:45 +0100138 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C &&
139 ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100140 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800141 chan_nr, ts->pchan);
142 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
143 lch_idx = 0;
144 if (ts->pchan != GSM_PCHAN_CCCH &&
Harald Weltebf4ba722014-12-28 15:00:45 +0100145 ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
146 ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100147 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800148 chan_nr, ts->pchan);
149 /* FIXME: we should not return first sdcch4 !!! */
150 } else {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100151 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800152 return NULL;
153 }
154
155 lchan = &ts->lchan[lch_idx];
Harald Welte51d2a592010-03-26 21:28:59 +0800156 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800157 if (lchan->conn)
158 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800159
160 return lchan;
161}
162
Harald Welte59b04682009-06-10 05:40:52 +0800163/* 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 +0200164uint64_t str_to_imsi(const char *imsi_str)
Harald Welte59b04682009-06-10 05:40:52 +0800165{
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200166 uint64_t ret;
Harald Welte59b04682009-06-10 05:40:52 +0800167
168 ret = strtoull(imsi_str, NULL, 10);
169
170 return ret;
171}
172
Harald Welte59b04682009-06-10 05:40:52 +0800173static struct msgb *rsl_msgb_alloc(void)
174{
Harald Welte9cfc9352009-06-26 19:39:35 +0200175 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
176 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800177}
178
179#define MACBLOCK_SIZE 23
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200180static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800181{
182 memcpy(out, in, len);
183
184 if (len < MACBLOCK_SIZE)
185 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
186}
187
Harald Welted2dd9de2009-08-30 15:37:11 +0900188/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200189static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welted2dd9de2009-08-30 15:37:11 +0900190{
191 *out++ = lchan->encr.alg_id & 0xff;
192 if (lchan->encr.key_len)
193 memcpy(out, lchan->encr.key, lchan->encr.key_len);
194 return lchan->encr.key_len + 1;
195}
196
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200197static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200198{
Harald Welte59b04682009-06-10 05:40:52 +0800199 int i;
200
Harald Weltede4477a2009-12-24 12:20:20 +0100201 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200202 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200203 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100204 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800205}
206
Harald Welte32951ea2011-08-10 23:26:33 +0200207static void lchan_act_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 activation. Marked as broken.\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200213 gsm_lchan_name(lchan));
214
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100215 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann2731e732011-08-11 04:44:12 +0200216 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200217}
218
219static void lchan_deact_tmr_cb(void *data)
220{
221 struct gsm_lchan *lchan = data;
222
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200223 LOGP(DRSL, LOGL_ERROR,
224 "%s Timeout during deactivation! Marked as broken.\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200225 gsm_lchan_name(lchan));
226
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100227 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200228 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200229}
230
231
Harald Welte59b04682009-06-10 05:40:52 +0800232/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200233int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
234 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800235{
236 struct abis_rsl_dchan_hdr *dh;
237 struct msgb *msg = rsl_msgb_alloc();
238
239 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
240 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
241 dh->chan_nr = RSL_CHAN_BCCH;
242
243 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
244 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
245
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200246 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800247
248 return abis_rsl_sendmsg(msg);
249}
250
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200251int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
252 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800253{
254 struct abis_rsl_common_hdr *ch;
255 struct msgb *msg = rsl_msgb_alloc();
256
257 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
258 ch->msg_discr = ABIS_RSL_MDISC_TRX;
259 ch->msg_type = RSL_MT_SACCH_FILL;
260
261 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
262 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
263
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200264 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800265
266 return abis_rsl_sendmsg(msg);
267}
268
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200269int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
270 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100271{
272 struct abis_rsl_dchan_hdr *dh;
273 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200274 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100275
276 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
277 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
278 dh->chan_nr = chan_nr;
279
280 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
281 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
282
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200283 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte10b7d8f2011-01-13 23:16:03 +0100284
285 return abis_rsl_sendmsg(msg);
286}
287
Harald Welte91afe4c2009-06-20 18:15:19 +0200288int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
289{
290 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200291 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200292 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200293
294 db = abs(db);
295 if (db > 30)
296 return -EINVAL;
297
Harald Welteed831842009-06-27 03:09:08 +0200298 msg = rsl_msgb_alloc();
299
Harald Welte91afe4c2009-06-20 18:15:19 +0200300 lchan->bs_power = db/2;
301 if (fpc)
302 lchan->bs_power |= 0x10;
303
304 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
305 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
306 dh->chan_nr = chan_nr;
307
308 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
309
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200310 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200311
312 return abis_rsl_sendmsg(msg);
313}
314
Harald Welte91afe4c2009-06-20 18:15:19 +0200315int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
316{
317 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200318 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200319 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200320 int ctl_lvl;
321
Harald Weltec4dcda02009-08-09 14:45:18 +0200322 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200323 if (ctl_lvl < 0)
324 return ctl_lvl;
325
Harald Welteed831842009-06-27 03:09:08 +0200326 msg = rsl_msgb_alloc();
327
Harald Welte91afe4c2009-06-20 18:15:19 +0200328 lchan->ms_power = ctl_lvl;
329
330 if (fpc)
331 lchan->ms_power |= 0x20;
332
333 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
334 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
335 dh->chan_nr = chan_nr;
336
337 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
338
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200339 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200340
341 return abis_rsl_sendmsg(msg);
342}
343
Harald Welte39274f42009-07-29 15:41:29 +0200344static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
345 struct gsm_lchan *lchan)
346{
Holger Hans Peter Freytherfad73652013-03-09 17:50:10 +0100347 memset(cm, 0, sizeof(*cm));
Harald Welte39274f42009-07-29 15:41:29 +0200348
349 /* FIXME: what to do with data calls ? */
Max3d94aca2016-05-11 12:45:13 +0200350 cm->dtx_dtu = 0;
351 if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
352 cm->dtx_dtu |= RSL_CMOD_DTXu;
353 if (lchan->ts->trx->bts->dtxd)
354 cm->dtx_dtu |= RSL_CMOD_DTXd;
Harald Welte39274f42009-07-29 15:41:29 +0200355
356 /* set TCH Speech/Data */
357 cm->spd_ind = lchan->rsl_cmode;
358
Harald Welte951e3512009-11-27 08:55:16 +0100359 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
360 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100361 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100362 "but tch_mode != signalling\n");
363
Harald Welte39274f42009-07-29 15:41:29 +0200364 switch (lchan->type) {
365 case GSM_LCHAN_SDCCH:
366 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
367 break;
368 case GSM_LCHAN_TCH_F:
369 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
370 break;
371 case GSM_LCHAN_TCH_H:
372 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
373 break;
374 case GSM_LCHAN_NONE:
375 case GSM_LCHAN_UNKNOWN:
376 default:
377 return -EINVAL;
378 }
379
380 switch (lchan->tch_mode) {
381 case GSM48_CMODE_SIGN:
382 cm->chan_rate = 0;
383 break;
384 case GSM48_CMODE_SPEECH_V1:
385 cm->chan_rate = RSL_CMOD_SP_GSM1;
386 break;
387 case GSM48_CMODE_SPEECH_EFR:
388 cm->chan_rate = RSL_CMOD_SP_GSM2;
389 break;
390 case GSM48_CMODE_SPEECH_AMR:
391 cm->chan_rate = RSL_CMOD_SP_GSM3;
392 break;
393 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200394 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200395 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200396 switch (lchan->csd_mode) {
397 case LCHAN_CSD_M_NT:
398 /* non-transparent CSD with RLP */
399 switch (lchan->tch_mode) {
400 case GSM48_CMODE_DATA_14k5:
401 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
402 break;
403 case GSM48_CMODE_DATA_12k0:
404 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
405 break;
406 case GSM48_CMODE_DATA_6k0:
407 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
408 break;
409 default:
410 return -EINVAL;
411 }
412 break;
413 /* transparent data services below */
414 case LCHAN_CSD_M_T_1200_75:
415 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
416 break;
417 case LCHAN_CSD_M_T_600:
418 cm->chan_rate = RSL_CMOD_CSD_T_600;
419 break;
420 case LCHAN_CSD_M_T_1200:
421 cm->chan_rate = RSL_CMOD_CSD_T_1200;
422 break;
423 case LCHAN_CSD_M_T_2400:
424 cm->chan_rate = RSL_CMOD_CSD_T_2400;
425 break;
426 case LCHAN_CSD_M_T_9600:
427 cm->chan_rate = RSL_CMOD_CSD_T_9600;
428 break;
429 case LCHAN_CSD_M_T_14400:
430 cm->chan_rate = RSL_CMOD_CSD_T_14400;
431 break;
432 case LCHAN_CSD_M_T_29000:
433 cm->chan_rate = RSL_CMOD_CSD_T_29000;
434 break;
435 case LCHAN_CSD_M_T_32000:
436 cm->chan_rate = RSL_CMOD_CSD_T_32000;
437 break;
438 default:
439 return -EINVAL;
440 }
Harald Welte39274f42009-07-29 15:41:29 +0200441 default:
442 return -EINVAL;
443 }
444
445 return 0;
446}
447
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200448static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
449{
450 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
451 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
452 lchan->mr_bts_lv + 1);
453}
454
Harald Welte59b04682009-06-10 05:40:52 +0800455/* Chapter 8.4.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200456int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200457 uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800458{
459 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200460 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200461 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200462 uint8_t *len;
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200463 uint8_t ta;
Harald Welte59b04682009-06-10 05:40:52 +0800464
Harald Weltee6d51f92011-06-25 10:02:33 +0200465 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800466 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200467 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800468
Harald Welte39274f42009-07-29 15:41:29 +0200469 rc = channel_mode_from_lchan(&cm, lchan);
470 if (rc < 0)
471 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800472
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200473 /* if channel is in PDCH mode, deactivate PDCH first */
474 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +0200475 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200476 /* store activation type and handover reference */
477 lchan->dyn_pdch.act_type = act_type;
478 lchan->dyn_pdch.ho_ref = ho_ref;
479 return rsl_ipacc_pdch_activate(lchan->ts, 0);
480 }
481
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200482 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
483
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200484 ta = lchan->rqd_ta;
485
486 /* BS11 requires TA shifted by 2 bits */
487 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
488 ta <<= 2;
489
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800490 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200491 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800492
Harald Welteed831842009-06-27 03:09:08 +0200493 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800494 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
495 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
496 dh->chan_nr = chan_nr;
497
498 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800499 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200500 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800501
502 /*
503 * The Channel Identification is needed for Phase1 phones
504 * and it contains the GSM48 Channel Description and the
505 * Mobile Allocation. The GSM 08.58 asks for the Mobile
506 * Allocation to have a length of zero. We are using the
507 * msgb_l3len to calculate the length of both messages.
508 */
laforgef723cf02010-06-20 21:38:19 +0200509 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200510 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200511 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800512
513 if (lchan->ts->hopping.enabled)
514 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
515 lchan->ts->hopping.ma_data);
516 else
517 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800518
519 /* update the calculated size */
520 msg->l3h = len + 1;
521 *len = msgb_l3len(msg);
522
Harald Welted2dd9de2009-08-30 15:37:11 +0900523 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200524 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900525 rc = build_encr_info(encr_info, lchan);
526 if (rc > 0)
527 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
528 }
529
Harald Welteb90d7bd2009-12-17 00:31:10 +0100530 switch (act_type) {
531 case RSL_ACT_INTER_ASYNC:
532 case RSL_ACT_INTER_SYNC:
533 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
534 break;
535 default:
536 break;
537 }
538
Harald Welte59b04682009-06-10 05:40:52 +0800539 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
540 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
541 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200542 mr_config_for_bts(lchan, msg);
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 Freytherae27c1b2015-08-20 19:32:46 +0200578 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100579
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200580 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900581
582 return abis_rsl_sendmsg(msg);
583}
584
585/* Chapter 8.4.6: Send the encryption command with given L3 info */
586int rsl_encryption_cmd(struct msgb *msg)
587{
588 struct abis_rsl_dchan_hdr *dh;
589 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200590 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200591 uint8_t encr_info[MAX_A5_KEY_LEN+2];
592 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900593 int rc;
594
595 /* First push the L3 IE tag and length */
596 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
597
598 /* then the link identifier (SAPI0, main sign link) */
599 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
600
601 /* then encryption information */
602 rc = build_encr_info(encr_info, lchan);
603 if (rc <= 0)
604 return rc;
605 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
606
607 /* and finally the DCHAN header */
608 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
609 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
610 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800611
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200612 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800613
614 return abis_rsl_sendmsg(msg);
615}
616
Harald Welte85a163c2009-08-10 11:43:22 +0200617/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200618int rsl_deact_sacch(struct gsm_lchan *lchan)
619{
620 struct abis_rsl_dchan_hdr *dh;
621 struct msgb *msg = rsl_msgb_alloc();
622
623 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
624 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200625 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200626
627 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200628 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200629
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100630 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200631
632 return abis_rsl_sendmsg(msg);
633}
634
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800635static void error_timeout_cb(void *data)
636{
637 struct gsm_lchan *lchan = data;
638 if (lchan->state != LCHAN_S_REL_ERR) {
639 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
640 gsm_lchan_name(lchan), lchan->state);
641 return;
642 }
643
644 /* go back to the none state */
Harald Weltefddaba52012-11-13 04:26:22 +0100645 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800646 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800647}
648
Harald Welte08011e22011-03-04 13:41:31 +0100649static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
650
Harald Welte85a163c2009-08-10 11:43:22 +0200651/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100652static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
653 enum sacch_deact deact_sacch)
Harald Welte59b04682009-06-10 05:40:52 +0800654{
655 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800656 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100657 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800658
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100659 /* Stop timers that should lead to a channel release */
660 osmo_timer_del(&lchan->T3109);
661
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800662 if (lchan->state == LCHAN_S_REL_ERR) {
663 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
664 gsm_lchan_name(lchan));
665 return -1;
666 }
667
668 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800669 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
670 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200671 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800672
673 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200674 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800675
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800676 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
677
678 if (error) {
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100679 /*
680 * FIXME: GSM 04.08 gives us two options for the abnormal
681 * chanel release. This can be either like in the non-existent
682 * sub-lcuase 3.5.1 or for the main signalling link deactivate
683 * the SACCH, start timer T3109 and consider the channel as
684 * released.
685 *
686 * This code is doing the later for all raido links and not
687 * only the main link. Right now all SAPIs are released on the
688 * local end, the SACCH will be de-activated and right now the
689 * T3111 will be started. First T3109 should be started and then
690 * the T3111.
691 *
692 * TODO: Move this out of the function.
693 */
694
695 /*
696 * sacch de-activate and "local end release"
697 */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100698 if (deact_sacch == SACCH_DEACTIVATE)
699 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100700 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
701
702 /*
703 * TODO: start T3109 now.
704 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800705 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800706 }
Harald Welte59b04682009-06-10 05:40:52 +0800707
Harald Welte32951ea2011-08-10 23:26:33 +0200708 /* Start another timer or assume the BTS sends a ACK/NACK? */
709 lchan->act_timer.cb = lchan_deact_tmr_cb;
710 lchan->act_timer.data = lchan;
711 osmo_timer_schedule(&lchan->act_timer, 4, 0);
712
Harald Welte08011e22011-03-04 13:41:31 +0100713 rc = abis_rsl_sendmsg(msg);
714
Harald Welte85a163c2009-08-10 11:43:22 +0200715 /* BTS will respond by RF CHAN REL ACK */
Harald Welte08011e22011-03-04 13:41:31 +0100716 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800717}
718
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +0200719/*
720 * Special handling for channel releases in the error case.
721 */
722static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
723{
724 if (lchan->state != LCHAN_S_ACTIVE)
725 return 0;
726 return rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
727}
728
Harald Welte9773f6c2011-01-14 14:16:16 +0100729static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
730{
731
732 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
733
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100734 /* Stop all pending timers */
Harald Welte32951ea2011-08-10 23:26:33 +0200735 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100736 osmo_timer_del(&lchan->T3111);
Harald Welte32951ea2011-08-10 23:26:33 +0200737
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200738 /*
739 * The BTS didn't respond within the timeout to our channel
740 * release request and we have marked the channel as broken.
741 * Now we do receive an ACK and let's be conservative. If it
742 * is a sysmoBTS we know that only one RF Channel Release ACK
743 * will be sent. So let's "repair" the channel.
744 */
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200745 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200746 int do_free = is_sysmobts_v2(lchan->ts->trx->bts);
747 LOGP(DRSL, LOGL_NOTICE,
748 "%s CHAN REL ACK for broken channel. %s.\n",
749 gsm_lchan_name(lchan),
750 do_free ? "Releasing it" : "Keeping it broken");
751 if (do_free)
752 do_lchan_free(lchan);
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200753 return 0;
754 }
755
Harald Welte9773f6c2011-01-14 14:16:16 +0100756 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
757 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
758 gsm_lchan_name(lchan),
759 gsm_lchans_name(lchan->state));
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200760
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200761 do_lchan_free(lchan);
762
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200763 /* Put PDCH channel back into PDCH mode first */
764 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH)
765 return rsl_ipacc_pdch_activate(lchan->ts, 1);
766
Harald Welte9773f6c2011-01-14 14:16:16 +0100767 return 0;
768}
769
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200770int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
771 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800772{
773 struct abis_rsl_dchan_hdr *dh;
774 struct msgb *msg = rsl_msgb_alloc();
775
776 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
777 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
778 dh->chan_nr = RSL_CHAN_PCH_AGCH;
779
780 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
781 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
782 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
783
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200784 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800785
786 return abis_rsl_sendmsg(msg);
787}
788
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200789int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800790{
791 int i, len = strlen(str_in);
792
793 for (i = 0; i < len; i++) {
794 int num = str_in[i] - 0x30;
795 if (num < 0 || num > 9)
796 return -1;
797 if (i % 2 == 0)
798 bcd_out[i/2] = num;
799 else
800 bcd_out[i/2] |= (num << 4);
801 }
802
803 return 0;
804}
805
806/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200807int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800808{
809 struct msgb *msg = rsl_msgb_alloc();
810 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200811 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800812
813 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
814 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
815 dh->chan_nr = RSL_CHAN_PCH_AGCH;
816
817 switch (bts->type) {
818 case GSM_BTS_TYPE_BS11:
819 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
820 break;
821 default:
822 /* If phase 2, construct a FULL_IMM_ASS_INFO */
823 pad_macblock(buf, val, len);
824 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
825 break;
826 }
827
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200828 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800829
830 return abis_rsl_sendmsg(msg);
831}
832
Harald Welte4684e632009-08-10 09:51:40 +0200833/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200834int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200835{
836 struct msgb *msg = rsl_msgb_alloc();
837 struct abis_rsl_dchan_hdr *dh;
838
839 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
840 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200841 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200842 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200843 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200844
Harald Weltede4477a2009-12-24 12:20:20 +0100845 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200846 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200847
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200848 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +0200849
Harald Welte4684e632009-08-10 09:51:40 +0200850 return abis_rsl_sendmsg(msg);
851}
852
853
Harald Welte59b04682009-06-10 05:40:52 +0800854/* Send "DATA REQUEST" message with given L3 Info payload */
855/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200856int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800857{
Harald Welte59b04682009-06-10 05:40:52 +0800858 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100859 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800860 return -EINVAL;
861 }
862
Harald Weltee6d51f92011-06-25 10:02:33 +0200863 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100864 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800865
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200866 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800867
868 return abis_rsl_sendmsg(msg);
869}
870
Harald Welteed9a5ab2009-08-09 13:47:35 +0200871/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
872/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200873int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200874{
Harald Weltea22d36b2010-03-04 10:33:10 +0100875 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200876
Harald Weltee6d51f92011-06-25 10:02:33 +0200877 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100878 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200879 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200880
Harald Welte17091bd2012-04-26 19:42:19 +0200881 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
882 gsm_lchan_name(lchan), link_id);
883
Harald Welteed9a5ab2009-08-09 13:47:35 +0200884 return abis_rsl_sendmsg(msg);
885}
886
Andreas Eversbergac27b952013-12-05 13:25:06 +0100887static void rsl_handle_release(struct gsm_lchan *lchan);
888
889/* Special work handler to handle missing RSL_MT_REL_CONF message from
890 * Nokia InSite BTS */
891static void lchan_rel_work_cb(void *data)
892{
893 struct gsm_lchan *lchan = data;
894 int sapi;
895
896 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
897 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
898 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
899 }
900 rsl_handle_release(lchan);
901}
902
Harald Welte0f2e3c12009-08-08 13:15:07 +0200903/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
904 This is what higher layers should call. The BTS then responds with
905 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
906 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
907 lchan_free() */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100908int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
909 enum rsl_rel_mode release_mode)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200910{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200911
Harald Weltea22d36b2010-03-04 10:33:10 +0100912 struct msgb *msg;
913
Harald Weltee6d51f92011-06-25 10:02:33 +0200914 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100915 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800916 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100917 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200918
Harald Weltec88a4432009-12-29 10:44:17 +0100919 /* FIXME: start some timer in case we don't receive a REL ACK ? */
920
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200921 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200922
Harald Welte17091bd2012-04-26 19:42:19 +0200923 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100924 gsm_lchan_name(lchan), link_id, release_mode);
Harald Welte17091bd2012-04-26 19:42:19 +0200925
Andreas Eversbergac27b952013-12-05 13:25:06 +0100926 abis_rsl_sendmsg(msg);
927
928 /* Do not wait for Nokia BTS to send the confirm. */
929 if (is_nokia_bts(lchan->ts->trx->bts)
930 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
931 && release_mode == RSL_REL_LOCAL_END) {
932 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
933 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
934 lchan->rel_work.cb = lchan_rel_work_cb;
935 lchan->rel_work.data = lchan;
936 osmo_timer_schedule(&lchan->rel_work, 0, 0);
937 }
938
939 return 0;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200940}
941
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100942int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
943{
944 lchan->state = LCHAN_S_BROKEN;
945 lchan->broken_reason = reason;
946 return 0;
947}
948
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200949int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
950{
951 lchan->state = state;
952 return 0;
953}
954
Harald Welte59b04682009-06-10 05:40:52 +0800955/* Chapter 8.4.2: Channel Activate Acknowledge */
956static int rsl_rx_chan_act_ack(struct msgb *msg)
957{
958 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
959
960 /* BTS has confirmed channel activation, we now need
961 * to assign the activated channel to the MS */
962 if (rslh->ie_chan != RSL_IE_CHAN_NR)
963 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100964
Harald Welte32951ea2011-08-10 23:26:33 +0200965 osmo_timer_del(&msg->lchan->act_timer);
966
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200967 if (msg->lchan->state == LCHAN_S_BROKEN) {
968 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel.\n",
969 gsm_lchan_name(msg->lchan));
970 return 0;
971 }
972
Harald Weltec88a4432009-12-29 10:44:17 +0100973 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100974 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
975 gsm_lchan_name(msg->lchan),
976 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200977 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100978
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800979 if (msg->lchan->rqd_ref) {
980 rsl_send_imm_assignment(msg->lchan);
981 talloc_free(msg->lchan->rqd_ref);
982 msg->lchan->rqd_ref = NULL;
983 msg->lchan->rqd_ta = 0;
984 }
985
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100986 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100987
Harald Welte59b04682009-06-10 05:40:52 +0800988 return 0;
989}
990
991/* Chapter 8.4.3: Channel Activate NACK */
992static int rsl_rx_chan_act_nack(struct msgb *msg)
993{
994 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
995 struct tlv_parsed tp;
996
Harald Welte32951ea2011-08-10 23:26:33 +0200997 osmo_timer_del(&msg->lchan->act_timer);
998
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200999 if (msg->lchan->state == LCHAN_S_BROKEN) {
1000 LOGP(DRSL, LOGL_ERROR,
1001 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
1002 gsm_lchan_name(msg->lchan));
1003 return -1;
1004 }
1005
Daniel Willmann9e9d44c2011-08-11 04:54:23 +02001006 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001007 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001008
Harald Welte59b04682009-06-10 05:40:52 +08001009 /* BTS has rejected channel activation ?!? */
1010 if (dh->ie_chan != RSL_IE_CHAN_NR)
1011 return -EINVAL;
1012
1013 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001014 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001015 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001016 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +02001017 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +01001018 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001019 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1020 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1021 } else
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001022 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann245ee032011-08-11 04:47:11 +02001023
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001024 } else {
1025 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1026 }
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001027
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001028 LOGPC(DRSL, LOGL_ERROR, "\n");
1029
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001030 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte59b04682009-06-10 05:40:52 +08001031 return 0;
1032}
1033
1034/* Chapter 8.4.4: Connection Failure Indication */
1035static int rsl_rx_conn_fail(struct msgb *msg)
1036{
1037 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1038 struct tlv_parsed tp;
1039
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001040 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1041 gsm_lchan_name(msg->lchan),
1042 gsm_lchans_name(msg->lchan->state));
1043
Harald Welte59b04682009-06-10 05:40:52 +08001044 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1045
Harald Weltef1a168d2009-07-28 17:58:09 +02001046 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001047 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001048 TLVP_LEN(&tp, RSL_IE_CAUSE));
1049
Harald Welte (local)4bd76642009-12-26 22:33:09 +01001050 LOGPC(DRSL, LOGL_NOTICE, "\n");
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001051 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001052 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001053}
1054
Harald Weltec20bd1d2009-11-29 19:07:28 +01001055static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1056 const char *prefix)
1057{
Harald Welte0e4fa782009-12-16 16:52:07 +01001058 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1059 prefix, rxlev2dbm(mru->full.rx_lev),
1060 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +01001061 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1062 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1063}
1064
Harald Welte50290cc2012-07-02 17:12:08 +02001065static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +01001066{
Harald Welte0e4fa782009-12-16 16:52:07 +01001067 int i;
Harald Welte50290cc2012-07-02 17:12:08 +02001068 char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +01001069
Harald Welteb764f1c2015-12-28 14:04:36 +01001070 if (lchan && lchan->conn)
Harald Welte50290cc2012-07-02 17:12:08 +02001071 name = subscr_name(lchan->conn->subscr);
1072
1073 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001074
1075 if (mr->flags & MEAS_REP_F_DL_DTX)
1076 DEBUGPC(DMEAS, "DTXd ");
1077
1078 print_meas_rep_uni(&mr->ul, "ul");
1079 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1080 if (mr->flags & MEAS_REP_F_MS_TO)
1081 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1082
1083 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +01001084 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001085 DEBUGPC(DMEAS, "L1_FPC=%u ",
1086 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1087 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1088 }
1089
1090 if (mr->flags & MEAS_REP_F_UL_DTX)
1091 DEBUGPC(DMEAS, "DTXu ");
1092 if (mr->flags & MEAS_REP_F_BA1)
1093 DEBUGPC(DMEAS, "BA1 ");
1094 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1095 DEBUGPC(DMEAS, "NOT VALID ");
1096 else
1097 print_meas_rep_uni(&mr->dl, "dl");
1098
1099 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +01001100 if (mr->num_cell == 7)
1101 return;
Harald Welte0e4fa782009-12-16 16:52:07 +01001102 for (i = 0; i < mr->num_cell; i++) {
1103 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +01001104 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1105 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001106 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001107}
1108
Harald Welte59b04682009-06-10 05:40:52 +08001109static int rsl_rx_meas_res(struct msgb *msg)
1110{
1111 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1112 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001113 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001114 uint8_t len;
1115 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001116 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001117
Harald Welte4baa9c52009-12-21 13:27:11 +01001118 /* check if this channel is actually active */
1119 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001120 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001121 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001122 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001123 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001124 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001125
Harald Weltef9476812009-12-15 21:36:05 +01001126 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001127 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001128
Harald Welte59b04682009-06-10 05:40:52 +08001129 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1130
Harald Weltec20bd1d2009-11-29 19:07:28 +01001131 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1132 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1133 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1134 return -EIO;
1135
1136 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001137 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001138
1139 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1140 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1141 if (len >= 3) {
1142 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001143 mr->flags |= MEAS_REP_F_DL_DTX;
1144 mr->ul.full.rx_lev = val[0] & 0x3f;
1145 mr->ul.sub.rx_lev = val[1] & 0x3f;
1146 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1147 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001148 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001149
Harald Weltef9476812009-12-15 21:36:05 +01001150 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001151
1152 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +08001153 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +01001154 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +01001155 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1156
Harald Weltea1467eb2009-06-20 18:44:35 +02001157 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001158 struct e1inp_sign_link *sign_link = msg->dst;
1159
Harald Weltec20bd1d2009-11-29 19:07:28 +01001160 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001161 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001162 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001163 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001164 mr->flags |= MEAS_REP_F_FPC;
1165 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001166 /* BS11 and Nokia reports TA shifted by 2 bits */
1167 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1168 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001169 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001170 }
Harald Welte59b04682009-06-10 05:40:52 +08001171 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001172 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001173 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001174 if (rc < 0)
1175 return rc;
1176 }
1177
Harald Welte50290cc2012-07-02 17:12:08 +02001178 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001179
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001180 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001181
Harald Welte59b04682009-06-10 05:40:52 +08001182 return 0;
1183}
1184
Harald Welte6720a432009-11-29 22:45:52 +01001185/* Chapter 8.4.7 */
1186static int rsl_rx_hando_det(struct msgb *msg)
1187{
1188 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1189 struct tlv_parsed tp;
1190
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001191 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001192
1193 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1194
1195 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1196 DEBUGPC(DRSL, "access delay = %u\n",
1197 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1198 else
1199 DEBUGPC(DRSL, "\n");
1200
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001201 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001202
1203 return 0;
1204}
1205
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001206static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1207{
1208 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001209
1210 OSMO_ASSERT(lchan);
1211
1212 ts = lchan->ts;
1213 OSMO_ASSERT(ts);
1214 OSMO_ASSERT(ts->trx);
1215 OSMO_ASSERT(ts->trx->bts);
1216
1217 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
1218 LOGP(DRSL, LOGL_ERROR, "(bts %u, trx %u, ts %u, pchan %s)"
1219 " Rx PDCH %s ACK for channel that is no TCH/F_PDCH\n",
1220 ts->trx->bts->nr, ts->trx->nr, ts->nr,
1221 gsm_pchan_name(ts->pchan),
1222 pdch_act? "ACT" : "DEACT");
1223 return false;
1224 }
1225
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +02001226 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001227 LOGP(DRSL, LOGL_ERROR, "(bts %u, trx %u, ts %u, pchan %s)"
1228 " Rx PDCH %s ACK in unexpected state: %s\n",
1229 ts->trx->bts->nr, ts->trx->nr, ts->nr,
1230 gsm_pchan_name(ts->pchan),
1231 pdch_act? "ACT" : "DEACT",
1232 gsm_lchans_name(lchan->state));
1233 return false;
1234 }
1235 return true;
1236}
1237
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001238static int rsl_rx_pdch_act_ack(struct msgb *msg)
1239{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001240 if (!lchan_may_change_pdch(msg->lchan, true))
1241 return -EINVAL;
1242
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001243 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001244 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001245
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001246 return 0;
1247}
1248
1249static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1250{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001251 if (!lchan_may_change_pdch(msg->lchan, false))
1252 return -EINVAL;
1253
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001254 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001255 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001256
1257 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn_pdch.act_type,
1258 msg->lchan->dyn_pdch.ho_ref);
1259
1260 return 0;
1261}
1262
Harald Welte59b04682009-06-10 05:40:52 +08001263static int abis_rsl_rx_dchan(struct msgb *msg)
1264{
1265 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1266 int rc = 0;
1267 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001268 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001269
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001270 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001271 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001272
Harald Welte59b04682009-06-10 05:40:52 +08001273 switch (rslh->c.msg_type) {
1274 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001275 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001276 rc = rsl_rx_chan_act_ack(msg);
1277 break;
1278 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001279 rc = rsl_rx_chan_act_nack(msg);
1280 break;
1281 case RSL_MT_CONN_FAIL:
1282 rc = rsl_rx_conn_fail(msg);
1283 break;
1284 case RSL_MT_MEAS_RES:
1285 rc = rsl_rx_meas_res(msg);
1286 break;
Harald Welte6720a432009-11-29 22:45:52 +01001287 case RSL_MT_HANDO_DET:
1288 rc = rsl_rx_hando_det(msg);
1289 break;
Harald Welte59b04682009-06-10 05:40:52 +08001290 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001291 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001292 break;
1293 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001294 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001295 break;
1296 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001297 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001298 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001299 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr6b272302016-05-31 17:51:41 +02001300 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001301 rc = rsl_rx_pdch_act_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001302 break;
1303 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001304 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001305 break;
1306 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001307 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001308 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001309 break;
1310 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001311 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001312 break;
Harald Welte59b04682009-06-10 05:40:52 +08001313 case RSL_MT_PHY_CONTEXT_CONF:
1314 case RSL_MT_PREPROC_MEAS_RES:
1315 case RSL_MT_TALKER_DET:
1316 case RSL_MT_LISTENER_DET:
1317 case RSL_MT_REMOTE_CODEC_CONF_REP:
1318 case RSL_MT_MR_CODEC_MOD_ACK:
1319 case RSL_MT_MR_CODEC_MOD_NACK:
1320 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001321 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1322 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001323 break;
1324 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001325 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1326 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001327 return -EINVAL;
1328 }
1329
1330 return rc;
1331}
1332
1333static int rsl_rx_error_rep(struct msgb *msg)
1334{
1335 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001336 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001337 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001338
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001339 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001340
1341 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1342
1343 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001344 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001345 TLVP_LEN(&tp, RSL_IE_CAUSE));
1346
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001347 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001348
1349 return 0;
1350}
1351
1352static int abis_rsl_rx_trx(struct msgb *msg)
1353{
1354 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001355 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001356 int rc = 0;
1357
1358 switch (rslh->msg_type) {
1359 case RSL_MT_ERROR_REPORT:
1360 rc = rsl_rx_error_rep(msg);
1361 break;
1362 case RSL_MT_RF_RES_IND:
1363 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001364 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001365 break;
1366 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001367 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001368 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001369 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001370 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001371 case 0x42: /* Nokia specific: SI End ACK */
1372 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1373 break;
1374 case 0x43: /* Nokia specific: SI End NACK */
1375 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1376 break;
Harald Welte59b04682009-06-10 05:40:52 +08001377 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001378 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001379 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001380 return -EINVAL;
1381 }
1382 return rc;
1383}
1384
Harald Welte427dbc42009-08-10 00:26:10 +02001385/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1386static void t3101_expired(void *data)
1387{
1388 struct gsm_lchan *lchan = data;
1389
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001390 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welte427dbc42009-08-10 00:26:10 +02001391}
1392
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001393/* If T3111 expires, we will send the RF Channel Request */
1394static void t3111_expired(void *data)
1395{
1396 struct gsm_lchan *lchan = data;
1397
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001398 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1399}
1400
1401/* If T3109 expires the MS has not send a UA/UM do the error release */
1402static void t3109_expired(void *data)
1403{
1404 struct gsm_lchan *lchan = data;
1405
1406 LOGP(DRSL, LOGL_ERROR,
1407 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1408 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001409}
1410
Harald Weltea00fdd72010-12-23 14:39:29 +01001411/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1412static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1413 unsigned int num_req_refs,
1414 struct gsm48_req_ref *rqd_refs,
1415 uint8_t wait_ind)
1416{
1417 uint8_t buf[GSM_MACBLOCK_LEN];
1418 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1419
1420 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1421 memset(iar, 0, sizeof(*iar));
1422 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001423 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Weltea00fdd72010-12-23 14:39:29 +01001424 iar->page_mode = GSM48_PM_SAME;
1425
1426 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1427 iar->wait_ind1 = wait_ind;
1428
1429 if (num_req_refs >= 2)
1430 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1431 else
1432 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1433 iar->wait_ind2 = wait_ind;
1434
1435 if (num_req_refs >= 3)
1436 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1437 else
1438 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1439 iar->wait_ind3 = wait_ind;
1440
1441 if (num_req_refs >= 4)
1442 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1443 else
1444 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1445 iar->wait_ind4 = wait_ind;
1446
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001447 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1448 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1449
1450 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Weltea00fdd72010-12-23 14:39:29 +01001451}
1452
Harald Welte59b04682009-06-10 05:40:52 +08001453/* MS has requested a channel on the RACH */
1454static int rsl_rx_chan_rqd(struct msgb *msg)
1455{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001456 struct e1inp_sign_link *sign_link = msg->dst;
1457 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001458 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1459 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001460 enum gsm_chan_t lctype;
1461 enum gsm_chreq_reason_t chreq_reason;
1462 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001463 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001464 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001465
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001466 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001467 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001468
1469 /* parse request reference to be used in immediate assign */
1470 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1471 return -EINVAL;
1472
1473 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1474
1475 /* parse access delay and use as TA */
1476 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1477 return -EINVAL;
1478 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1479
1480 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1481 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001482 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1483 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001484
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001485 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001486
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001487 /*
1488 * We want LOCATION UPDATES to succeed and will assign a TCH
1489 * if we have no SDCCH available.
1490 */
1491 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1492
Harald Welte59b04682009-06-10 05:40:52 +08001493 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001494 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001495 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001496 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001497 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001498 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001499 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1500 if (bts->network->T3122)
1501 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Weltecf7c90c2012-11-13 04:46:03 +01001502 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001503 }
1504
Harald Weltec88a4432009-12-29 10:44:17 +01001505 if (lchan->state != LCHAN_S_NONE)
1506 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001507 "in state %s\n", gsm_lchan_name(lchan),
1508 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001509
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001510 /* save the RACH data as we need it after the CHAN ACT ACK */
1511 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1512 if (!lchan->rqd_ref) {
1513 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1514 lchan_free(lchan);
1515 return -ENOMEM;
1516 }
1517
1518 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1519 lchan->rqd_ta = rqd_ta;
1520
Harald Welte59b04682009-06-10 05:40:52 +08001521 arfcn = lchan->ts->trx->arfcn;
1522 subch = lchan->nr;
1523
Harald Welted2dd9de2009-08-30 15:37:11 +09001524 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001525 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001526 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001527 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001528 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001529
Harald Welte32951ea2011-08-10 23:26:33 +02001530 /* Start another timer or assume the BTS sends a ACK/NACK? */
1531 lchan->act_timer.cb = lchan_act_tmr_cb;
1532 lchan->act_timer.data = lchan;
1533 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1534
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001535 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1536 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1537 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1538 rqd_ref->ra, rqd_ta);
1539
Andreas Eversberg3ca9af32013-10-11 12:55:35 +02001540 rsl_chan_activate_lchan(lchan, 0x00, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001541
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001542 return 0;
1543}
1544
1545static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1546{
1547 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001548 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001549 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1550
Harald Welte59b04682009-06-10 05:40:52 +08001551 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001552 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001553 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001554 ia->proto_discr = GSM48_PDISC_RR;
1555 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1556 ia->page_mode = GSM48_PM_SAME;
1557 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001558
Harald Welte59b04682009-06-10 05:40:52 +08001559 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001560 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1561 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001562 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001563 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001564 } else {
laforgee06d5982010-06-20 15:18:46 +02001565 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1566 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001567 }
Harald Welte07f32182010-06-28 18:41:27 +02001568 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1569 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001570
Harald Welte427dbc42009-08-10 00:26:10 +02001571 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1572 lchan->T3101.cb = t3101_expired;
1573 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001574 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001575
1576 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001577 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001578}
1579
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001580/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001581static int rsl_rx_ccch_load(struct msgb *msg)
1582{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001583 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001584 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001585 struct ccch_signal_data sd;
1586
1587 sd.bts = sign_link->trx->bts;
1588 sd.rach_slot_count = -1;
1589 sd.rach_busy_count = -1;
1590 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001591
1592 switch (rslh->data[0]) {
1593 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001594 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1595 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001596 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001597 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001598 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001599 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1600 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001601 break;
1602 case RSL_IE_RACH_LOAD:
1603 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001604 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1605 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1606 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1607 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001608 }
1609 break;
1610 default:
1611 break;
1612 }
1613
1614 return 0;
1615}
1616
1617static int abis_rsl_rx_cchan(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_dchan_hdr *rslh = msgb_l2(msg);
1621 int rc = 0;
1622
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001623 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001624
1625 switch (rslh->c.msg_type) {
1626 case RSL_MT_CHAN_RQD:
1627 /* MS has requested a channel on the RACH */
1628 rc = rsl_rx_chan_rqd(msg);
1629 break;
1630 case RSL_MT_CCCH_LOAD_IND:
1631 /* current load on the CCCH */
1632 rc = rsl_rx_ccch_load(msg);
1633 break;
1634 case RSL_MT_DELETE_IND:
1635 /* CCCH overloaded, IMM_ASSIGN was dropped */
1636 case RSL_MT_CBCH_LOAD_IND:
1637 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001638 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1639 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001640 break;
1641 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001642 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1643 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001644 return -EINVAL;
1645 }
1646
1647 return rc;
1648}
1649
1650static int rsl_rx_rll_err_ind(struct msgb *msg)
1651{
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001652 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001653 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001654 uint8_t rlm_cause;
Harald Welte59b04682009-06-10 05:40:52 +08001655
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001656 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1657 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1658 LOGP(DRLL, LOGL_ERROR,
1659 "%s ERROR INDICATION without mandantory cause.\n",
1660 gsm_lchan_name(msg->lchan));
1661 return -1;
1662 }
1663
1664 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001665 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001666 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001667 rsl_rlm_cause_name(rlm_cause),
1668 gsm_lchans_name(msg->lchan->state));
1669
Harald Welteed9a5ab2009-08-09 13:47:35 +02001670 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001671
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001672 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001673 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001674 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001675 }
Harald Welte692f5852009-07-04 09:40:05 +02001676
Harald Welte59b04682009-06-10 05:40:52 +08001677 return 0;
1678}
1679
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001680static void rsl_handle_release(struct gsm_lchan *lchan)
1681{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001682 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001683 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001684
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +01001685 /*
1686 * Maybe only one link/SAPI was releasd or the error handling
1687 * was activated. Just return now and let the other code handle
1688 * it.
1689 */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001690 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001691 return;
1692
1693 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1694 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1695 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001696 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001697 gsm_lchan_name(lchan), sapi);
1698 return;
1699 }
1700
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001701
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001702 /* Stop T3109 and wait for T3111 before re-using the channel */
1703 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001704 lchan->T3111.cb = t3111_expired;
1705 lchan->T3111.data = lchan;
1706 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001707 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001708}
1709
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001710/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001711 0x02, 0x06,
1712 0x01, 0x20,
1713 0x02, 0x00,
1714 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1715
1716static int abis_rsl_rx_rll(struct msgb *msg)
1717{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001718 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001719 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1720 int rc = 0;
1721 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001722 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001723
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001724 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001725 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001726 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001727
1728 switch (rllh->c.msg_type) {
1729 case RSL_MT_DATA_IND:
1730 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001731 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001732 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1733 rllh->data[0] == RSL_IE_L3_INFO) {
1734 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001735 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001736 }
1737 break;
1738 case RSL_MT_EST_IND:
1739 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001740 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001741 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001742 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001743 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001744 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1745 rllh->data[0] == RSL_IE_L3_INFO) {
1746 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001747 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001748 }
1749 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001750 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001751 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001752 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001753 rll_indication(msg->lchan, rllh->link_id,
1754 BSC_RLLR_IND_EST_CONF);
1755 break;
Harald Welte59b04682009-06-10 05:40:52 +08001756 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001757 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001758 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001759 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001760 rll_indication(msg->lchan, rllh->link_id,
1761 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001762 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001763 break;
1764 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001765 /* BTS informs us of having received UA from MS,
1766 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001767 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001768 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001769 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001770 break;
1771 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001772 rc = rsl_rx_rll_err_ind(msg);
1773 break;
1774 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001775 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1776 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001777 break;
1778 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001779 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1780 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001781 }
Harald Welte59b04682009-06-10 05:40:52 +08001782 return rc;
1783}
1784
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001785static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001786{
Harald Welteb284b472009-12-02 01:58:23 +05301787 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001788 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301789 switch (lchan->type) {
1790 case GSM_LCHAN_TCH_F:
1791 return 0x00;
1792 case GSM_LCHAN_TCH_H:
1793 return 0x03;
1794 default:
1795 break;
1796 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001797 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001798 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301799 switch (lchan->type) {
1800 case GSM_LCHAN_TCH_F:
1801 return 0x01;
1802 /* there's no half-rate EFR */
1803 default:
1804 break;
1805 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001806 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001807 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301808 switch (lchan->type) {
1809 case GSM_LCHAN_TCH_F:
1810 return 0x02;
1811 case GSM_LCHAN_TCH_H:
1812 return 0x05;
1813 default:
1814 break;
1815 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001816 break;
Harald Welteb284b472009-12-02 01:58:23 +05301817 default:
1818 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001819 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001820 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301821 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001822 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001823}
1824
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001825static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001826{
1827 switch (lchan->tch_mode) {
1828 case GSM48_CMODE_SPEECH_V1:
1829 switch (lchan->type) {
1830 case GSM_LCHAN_TCH_F:
1831 return RTP_PT_GSM_FULL;
1832 case GSM_LCHAN_TCH_H:
1833 return RTP_PT_GSM_HALF;
1834 default:
1835 break;
1836 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001837 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001838 case GSM48_CMODE_SPEECH_EFR:
1839 switch (lchan->type) {
1840 case GSM_LCHAN_TCH_F:
1841 return RTP_PT_GSM_EFR;
1842 /* there's no half-rate EFR */
1843 default:
1844 break;
1845 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001846 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001847 case GSM48_CMODE_SPEECH_AMR:
1848 switch (lchan->type) {
1849 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01001850 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02001851 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001852 default:
1853 break;
1854 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001855 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001856 default:
1857 break;
1858 }
1859 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1860 "tch_mode == 0x%02x\n & lchan_type == %d",
1861 lchan->tch_mode, lchan->type);
1862 return 0;
1863}
1864
Harald Welte59b04682009-06-10 05:40:52 +08001865/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001866static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1867{
1868 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001869 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001870
1871 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001872 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01001873 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1874 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1875 }
1876
1877 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001878 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01001879 port = ntohs(port);
1880 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1881 lchan->abis_ip.bound_port = port;
1882 }
1883
1884 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001885 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Weltebffa4992009-12-19 16:42:06 +01001886 conn_id = ntohs(conn_id);
1887 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1888 lchan->abis_ip.conn_id = conn_id;
1889 }
1890
1891 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1892 lchan->abis_ip.rtp_payload2 =
1893 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1894 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1895 lchan->abis_ip.rtp_payload2);
1896 }
1897
1898 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1899 lchan->abis_ip.speech_mode =
1900 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1901 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1902 lchan->abis_ip.speech_mode);
1903 }
1904
1905 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001906 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01001907 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1908 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1909 }
1910
1911 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001912 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01001913 port = ntohs(port);
1914 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1915 lchan->abis_ip.connect_port = port;
1916 }
1917}
1918
Harald Welte9a696d72013-02-03 12:06:58 +01001919/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1920 * \param[in] lchan Logical Channel for which we issue CRCX
1921 */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001922int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001923{
1924 struct msgb *msg = rsl_msgb_alloc();
1925 struct abis_rsl_dchan_hdr *dh;
1926
1927 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001928 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001929 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001930 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001931
Harald Welte98d79f92009-07-28 18:11:56 +02001932 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001933 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001934 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001935 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001936 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001937
Sylvain Munaut1338a552009-12-20 22:06:40 +01001938 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1939 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1940 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001941
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001942 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001943
1944 return abis_rsl_sendmsg(msg);
1945}
1946
Harald Welte9a696d72013-02-03 12:06:58 +01001947/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1948 * \param[in] lchan Logical Channel for which we issue MDCX
1949 * \param[in] ip Remote (MGW) IP address for RTP
1950 * \param[in] port Remote (MGW) UDP port number for RTP
1951 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1952 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001953int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1954 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001955{
1956 struct msgb *msg = rsl_msgb_alloc();
1957 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001958 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001959 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001960
1961 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001962 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001963 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001964 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001965
Harald Weltebffa4992009-12-19 16:42:06 +01001966 /* we need to store these now as MDCX_ACK does not return them :( */
1967 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1968 lchan->abis_ip.connect_port = port;
1969 lchan->abis_ip.connect_ip = ip;
1970
Harald Weltefb4a9e92009-07-29 12:12:18 +02001971 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001972 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001973 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001974
Harald Welte98d79f92009-07-28 18:11:56 +02001975 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001976 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1977 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1978 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1979 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001980
Harald Weltebffa4992009-12-19 16:42:06 +01001981 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1982 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001983 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001984 *att_ip = ia.s_addr;
1985 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1986 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001987 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001988 if (rtp_payload2)
1989 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001990
1991 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001992
1993 return abis_rsl_sendmsg(msg);
1994}
1995
Harald Welte9947d9f2009-12-20 16:51:09 +01001996/* tell BTS to connect RTP stream to our local RTP socket */
1997int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1998{
1999 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
2000 int rc;
2001
2002 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
2003 ntohs(rs->rtp.sin_local.sin_port),
2004 /* FIXME: use RTP payload of bound socket, not BTS*/
2005 lchan->abis_ip.rtp_payload2);
2006
2007 return rc;
2008}
2009
Harald Welte6f40df02010-12-23 12:59:52 +01002010int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02002011{
2012 struct msgb *msg = rsl_msgb_alloc();
2013 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002014 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08002015
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002016 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2017 LOGP(DRSL, LOGL_ERROR,
2018 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2019 gsm_ts_name(ts),
2020 act ? "ACT" : "DEACT",
2021 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2022 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2023 return -EINVAL;
2024 }
2025
2026 if (act){
Harald Welte2b361522010-03-28 14:42:09 +08002027 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002028 ts->flags |= TS_F_PDCH_ACT_PENDING;
2029 } else {
Harald Welte2b361522010-03-28 14:42:09 +08002030 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002031 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2032 }
2033 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welteaed946e2009-10-24 10:29:22 +02002034
2035 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08002036 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02002037 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02002038 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02002039
Neels Hofmeyr6b272302016-05-31 17:51:41 +02002040 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08002041 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02002042
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002043 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02002044
2045 return abis_rsl_sendmsg(msg);
2046}
2047
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002048static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002049{
2050 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2051 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05302052 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08002053
2054 /* the BTS has acknowledged a local bind, it now tells us the IP
2055 * address and port number to which it has bound the given logical
2056 * channel */
2057
2058 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2059 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2060 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02002061 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002062 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08002063 return -EINVAL;
2064 }
Harald Welte50517742009-12-20 15:42:44 +01002065
Harald Weltebffa4992009-12-19 16:42:06 +01002066 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01002067
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002068 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002069
2070 return 0;
2071}
2072
Harald Weltebffa4992009-12-19 16:42:06 +01002073static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2074{
2075 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2076 struct tlv_parsed tv;
2077 struct gsm_lchan *lchan = msg->lchan;
2078
2079 /* the BTS has acknowledged a remote connect request and
2080 * it now tells us the IP address and port number to which it has
2081 * connected the given logical channel */
2082
2083 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2084 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002085 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01002086
2087 return 0;
2088}
2089
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002090static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002091{
2092 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2093 struct tlv_parsed tv;
2094
2095 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08002096
Harald Weltef1a168d2009-07-28 17:58:09 +02002097 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01002098 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02002099 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08002100
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002101 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02002102
Harald Welte59b04682009-06-10 05:40:52 +08002103 return 0;
2104}
2105
2106static int abis_rsl_rx_ipacc(struct msgb *msg)
2107{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002108 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08002109 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01002110 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08002111 int rc = 0;
2112
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002113 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01002114 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002115
2116 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002117 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01002118 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002119 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002120 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002121 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002122 /* somehow the BTS was unable to bind the lchan to its local
2123 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01002124 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002125 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002126 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08002127 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01002128 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01002129 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002130 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002131 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002132 /* somehow the BTS was unable to connect the lchan to a remote
2133 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01002134 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002135 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002136 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01002137 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002138 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002139 break;
2140 default:
Harald Weltede4477a2009-12-24 12:20:20 +01002141 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002142 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002143 break;
2144 }
2145 DEBUGPC(DRSL, "\n");
2146
2147 return rc;
2148}
2149
2150
2151/* Entry-point where L2 RSL from BTS enters */
2152int abis_rsl_rcvmsg(struct msgb *msg)
2153{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002154 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08002155 int rc = 0;
2156
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002157 if (!msg) {
2158 DEBUGP(DRSL, "Empty RSL msg?..\n");
2159 return -1;
2160 }
2161
2162 if (msgb_l2len(msg) < sizeof(*rslh)) {
2163 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02002164 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002165 return -1;
2166 }
2167
2168 rslh = msgb_l2(msg);
2169
Harald Welte59b04682009-06-10 05:40:52 +08002170 switch (rslh->msg_discr & 0xfe) {
2171 case ABIS_RSL_MDISC_RLL:
2172 rc = abis_rsl_rx_rll(msg);
2173 break;
2174 case ABIS_RSL_MDISC_DED_CHAN:
2175 rc = abis_rsl_rx_dchan(msg);
2176 break;
2177 case ABIS_RSL_MDISC_COM_CHAN:
2178 rc = abis_rsl_rx_cchan(msg);
2179 break;
2180 case ABIS_RSL_MDISC_TRX:
2181 rc = abis_rsl_rx_trx(msg);
2182 break;
2183 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002184 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08002185 rslh->msg_discr);
2186 break;
2187 case ABIS_RSL_MDISC_IPACCESS:
2188 rc = abis_rsl_rx_ipacc(msg);
2189 break;
2190 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002191 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2192 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02002193 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08002194 }
2195 msgb_free(msg);
2196 return rc;
2197}
2198
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002199int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Weltebf4ba722014-12-28 15:00:45 +01002200 struct rsl_ie_cb_cmd_type cb_command,
2201 const uint8_t *data, int len)
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002202{
2203 struct abis_rsl_dchan_hdr *dh;
2204 struct msgb *cb_cmd;
2205
2206 cb_cmd = rsl_msgb_alloc();
2207 if (!cb_cmd)
2208 return -1;
2209
Harald Weltebf4ba722014-12-28 15:00:45 +01002210 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002211 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Weltebf4ba722014-12-28 15:00:45 +01002212 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2213 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002214
Harald Weltebf4ba722014-12-28 15:00:45 +01002215 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002216 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2217
Harald Weltebf4ba722014-12-28 15:00:45 +01002218 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002219
2220 return abis_rsl_sendmsg(cb_cmd);
2221}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002222
2223int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2224{
2225 struct abis_rsl_common_hdr *ch;
2226 struct msgb *msg = rsl_msgb_alloc();
2227
2228 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2229 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2230 ch->msg_type = 0x40; /* Nokia SI Begin */
2231
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002232 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002233
2234 return abis_rsl_sendmsg(msg);
2235}
2236
2237int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2238{
2239 struct abis_rsl_common_hdr *ch;
2240 struct msgb *msg = rsl_msgb_alloc();
2241
2242 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2243 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2244 ch->msg_type = 0x41; /* Nokia SI End */
2245
2246 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2247
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002248 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002249
2250 return abis_rsl_sendmsg(msg);
2251}
2252
2253int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2254{
2255 struct abis_rsl_common_hdr *ch;
2256 struct msgb *msg = rsl_msgb_alloc();
2257
2258 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2259 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2260 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2261
2262 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2263 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2264
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002265 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002266
2267 return abis_rsl_sendmsg(msg);
2268}
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01002269
2270/**
2271 * Release all allocated SAPIs starting from @param start and
2272 * release them with the given release mode. Once the release
2273 * confirmation arrives it will be attempted to release the
2274 * the RF channel.
2275 */
2276int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2277 enum rsl_rel_mode release_mode)
2278{
2279 int no_sapi = 1;
2280 int sapi;
2281
2282 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2283 uint8_t link_id;
2284 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2285 continue;
2286
2287 link_id = sapi;
2288 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2289 link_id |= 0x40;
2290 rsl_release_request(lchan, link_id, release_mode);
2291 no_sapi = 0;
2292 }
2293
2294 return no_sapi;
2295}
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002296
2297int rsl_start_t3109(struct gsm_lchan *lchan)
2298{
2299 struct gsm_bts *bts = lchan->ts->trx->bts;
2300
2301 /* Disabled, mostly legacy code */
2302 if (bts->network->T3109 == 0)
2303 return -1;
2304
2305 lchan->T3109.cb = t3109_expired;
2306 lchan->T3109.data = lchan;
2307 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2308 return 0;
2309}
Holger Hans Peter Freytherc63cb862012-12-25 23:45:14 +01002310
2311/**
2312 * \brief directly RF Channel Release the lchan
2313 *
2314 * When no SAPI was allocated, directly release the logical channel. This
2315 * should only be called from chan_alloc.c on channel release handling. In
2316 * case no SAPI was established the RF Channel can be directly released,
2317 */
2318int rsl_direct_rf_release(struct gsm_lchan *lchan)
2319{
2320 int i;
2321 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2322 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2323 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2324 gsm_lchan_name(lchan), i);
2325 return -1;
2326 }
2327 }
2328
2329 /* Now release it */
2330 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2331}