blob: 20dd2b5ca9bcca2bb065982e53baa492f07199cf [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>
Max2c7690a2017-04-20 13:07:58 +020044#include <openbsc/gsm_subscriber.h>
Pablo Neira Ayuso42e41df2011-08-17 22:44:07 +020045#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010046#include <osmocom/gsm/rsl.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010047#include <osmocom/core/talloc.h>
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080048
Harald Welte59b04682009-06-10 05:40:52 +080049#define RSL_ALLOC_SIZE 1024
50#define RSL_ALLOC_HEADROOM 128
51
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +010052enum sacch_deact {
53 SACCH_NONE,
54 SACCH_DEACTIVATE,
55};
56
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080057static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020058static void error_timeout_cb(void *data);
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +020059static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts);
60static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +020061static void dyn_ts_switchover_complete(struct gsm_lchan *lchan);
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080062
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010063static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
64 struct gsm_meas_rep *resp)
65{
66 struct lchan_signal_data sig;
67 sig.lchan = lchan;
68 sig.mr = resp;
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +020069 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010070}
71
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010072static void do_lchan_free(struct gsm_lchan *lchan)
73{
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020074 /* We start the error timer to make the channel available again */
75 if (lchan->state == LCHAN_S_REL_ERR) {
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +020076 osmo_timer_setup(&lchan->error_timer, error_timeout_cb, lchan);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020077 osmo_timer_schedule(&lchan->error_timer,
78 lchan->ts->trx->bts->network->T3111 + 2, 0);
79 } else {
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010080 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020081 }
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010082 lchan_free(lchan);
83}
84
Alexander Couzens4f598fc2016-08-23 06:27:19 +020085static void count_codecs(struct gsm_bts *bts, struct gsm_lchan *lchan)
86{
87 OSMO_ASSERT(bts);
88
89 if (lchan->type == GSM_LCHAN_TCH_H) {
90 switch (lchan->tch_mode) {
91 case GSM48_CMODE_SPEECH_AMR:
92 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_H]);
93 break;
94 case GSM48_CMODE_SPEECH_V1:
95 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_HR]);
96 break;
97 default:
98 break;
99 }
100 } else if (lchan->type == GSM_LCHAN_TCH_F) {
101 switch (lchan->tch_mode) {
102 case GSM48_CMODE_SPEECH_AMR:
103 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_F]);
104 break;
105 case GSM48_CMODE_SPEECH_V1:
106 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_FR]);
107 break;
108 case GSM48_CMODE_SPEECH_EFR:
109 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_EFR]);
110 break;
111 default:
112 break;
113 }
Alexander Couzens4f598fc2016-08-23 06:27:19 +0200114 }
115}
116
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200117static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +0800118{
119 /* mask off the transparent bit ? */
120 msg_type &= 0xfe;
121
122 if ((msg_type & 0xf0) == 0x00)
123 return ABIS_RSL_MDISC_RLL;
124 if ((msg_type & 0xf0) == 0x10) {
125 if (msg_type >= 0x19 && msg_type <= 0x22)
126 return ABIS_RSL_MDISC_TRX;
127 else
128 return ABIS_RSL_MDISC_COM_CHAN;
129 }
130 if ((msg_type & 0xe0) == 0x20)
131 return ABIS_RSL_MDISC_DED_CHAN;
132
133 return ABIS_RSL_MDISC_LOC;
134}
135
136static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200137 uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +0800138{
139 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
140 dh->c.msg_type = msg_type;
141 dh->ie_chan = RSL_IE_CHAN_NR;
142}
143
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200144/* call rsl_lchan_lookup and set the log context */
Neels Hofmeyr0781eb02016-08-23 01:22:58 +0200145static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
146 const char *log_name)
Harald Welte59b04682009-06-10 05:40:52 +0800147{
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200148 int rc;
149 struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc);
Harald Welte59b04682009-06-10 05:40:52 +0800150
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200151 if (!lchan) {
Neels Hofmeyr0781eb02016-08-23 01:22:58 +0200152 LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n",
153 log_name, chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800154 return NULL;
155 }
156
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200157 if (rc < 0)
Neels Hofmeyr0781eb02016-08-23 01:22:58 +0200158 LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n",
159 gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr);
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200160
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800161 if (lchan->conn)
Neels Hofmeyrcf0136d2017-02-23 18:00:51 +0100162 log_set_context(LOG_CTX_VLR_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800163
164 return lchan;
165}
166
Harald Welte59b04682009-06-10 05:40:52 +0800167/* 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 +0200168uint64_t str_to_imsi(const char *imsi_str)
Harald Welte59b04682009-06-10 05:40:52 +0800169{
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200170 uint64_t ret;
Harald Welte59b04682009-06-10 05:40:52 +0800171
172 ret = strtoull(imsi_str, NULL, 10);
173
174 return ret;
175}
176
Harald Welte59b04682009-06-10 05:40:52 +0800177static struct msgb *rsl_msgb_alloc(void)
178{
Harald Welte9cfc9352009-06-26 19:39:35 +0200179 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
180 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800181}
182
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200183static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800184{
185 memcpy(out, in, len);
186
Max6b238392017-02-09 19:23:38 +0100187 if (len < GSM_MACBLOCK_LEN)
188 memset(out+len, 0x2b, GSM_MACBLOCK_LEN - len);
Harald Welte59b04682009-06-10 05:40:52 +0800189}
190
Harald Welted2dd9de2009-08-30 15:37:11 +0900191/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200192static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welted2dd9de2009-08-30 15:37:11 +0900193{
194 *out++ = lchan->encr.alg_id & 0xff;
195 if (lchan->encr.key_len)
196 memcpy(out, lchan->encr.key, lchan->encr.key_len);
197 return lchan->encr.key_len + 1;
198}
199
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200200static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200201{
Harald Welte59b04682009-06-10 05:40:52 +0800202 int i;
203
Harald Weltede4477a2009-12-24 12:20:20 +0100204 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200205 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200206 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100207 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800208}
209
Harald Welte32951ea2011-08-10 23:26:33 +0200210static void lchan_act_tmr_cb(void *data)
211{
212 struct gsm_lchan *lchan = data;
213
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100214 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann2731e732011-08-11 04:44:12 +0200215 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200216}
217
218static void lchan_deact_tmr_cb(void *data)
219{
220 struct gsm_lchan *lchan = data;
221
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100222 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200223 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200224}
225
226
Harald Welte59b04682009-06-10 05:40:52 +0800227/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200228int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
229 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800230{
231 struct abis_rsl_dchan_hdr *dh;
232 struct msgb *msg = rsl_msgb_alloc();
233
234 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
235 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
236 dh->chan_nr = RSL_CHAN_BCCH;
237
Philippf8321be2016-11-02 12:05:44 +0100238 if (trx->bts->type == GSM_BTS_TYPE_RBS2000
239 && type == RSL_SYSTEM_INFO_13) {
240 /* Ericsson proprietary encoding of SI13 */
241 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, RSL_ERIC_SYSTEM_INFO_13);
242 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
243 msgb_tv_put(msg, RSL_IE_ERIC_BCCH_MAPPING, 0x00);
244 } else {
245 /* Normal encoding */
246 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
247 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
248 }
Harald Welte59b04682009-06-10 05:40:52 +0800249
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200250 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800251
252 return abis_rsl_sendmsg(msg);
253}
254
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200255int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
256 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800257{
258 struct abis_rsl_common_hdr *ch;
259 struct msgb *msg = rsl_msgb_alloc();
260
261 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
262 ch->msg_discr = ABIS_RSL_MDISC_TRX;
263 ch->msg_type = RSL_MT_SACCH_FILL;
264
265 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
266 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
267
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200268 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800269
270 return abis_rsl_sendmsg(msg);
271}
272
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200273int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
274 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100275{
276 struct abis_rsl_dchan_hdr *dh;
277 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200278 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100279
280 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
281 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
282 dh->chan_nr = chan_nr;
283
284 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
285 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
286
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200287 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte10b7d8f2011-01-13 23:16:03 +0100288
289 return abis_rsl_sendmsg(msg);
290}
291
Harald Welte91afe4c2009-06-20 18:15:19 +0200292int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
293{
294 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200295 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200296 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200297
298 db = abs(db);
299 if (db > 30)
300 return -EINVAL;
301
Harald Welteed831842009-06-27 03:09:08 +0200302 msg = rsl_msgb_alloc();
303
Harald Welte91afe4c2009-06-20 18:15:19 +0200304 lchan->bs_power = db/2;
305 if (fpc)
306 lchan->bs_power |= 0x10;
307
308 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
309 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
310 dh->chan_nr = chan_nr;
311
312 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
313
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200314 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200315
316 return abis_rsl_sendmsg(msg);
317}
318
Harald Welte91afe4c2009-06-20 18:15:19 +0200319int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
320{
321 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200322 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200323 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200324 int ctl_lvl;
325
Harald Weltec4dcda02009-08-09 14:45:18 +0200326 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200327 if (ctl_lvl < 0)
328 return ctl_lvl;
329
Harald Welteed831842009-06-27 03:09:08 +0200330 msg = rsl_msgb_alloc();
331
Harald Welte91afe4c2009-06-20 18:15:19 +0200332 lchan->ms_power = ctl_lvl;
333
334 if (fpc)
335 lchan->ms_power |= 0x20;
336
337 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
338 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
339 dh->chan_nr = chan_nr;
340
341 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
342
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200343 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200344
345 return abis_rsl_sendmsg(msg);
346}
347
Harald Welte39274f42009-07-29 15:41:29 +0200348static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
349 struct gsm_lchan *lchan)
350{
Holger Hans Peter Freytherfad73652013-03-09 17:50:10 +0100351 memset(cm, 0, sizeof(*cm));
Harald Welte39274f42009-07-29 15:41:29 +0200352
353 /* FIXME: what to do with data calls ? */
Max3d94aca2016-05-11 12:45:13 +0200354 cm->dtx_dtu = 0;
355 if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
356 cm->dtx_dtu |= RSL_CMOD_DTXu;
357 if (lchan->ts->trx->bts->dtxd)
358 cm->dtx_dtu |= RSL_CMOD_DTXd;
Harald Welte39274f42009-07-29 15:41:29 +0200359
360 /* set TCH Speech/Data */
361 cm->spd_ind = lchan->rsl_cmode;
362
Harald Welte951e3512009-11-27 08:55:16 +0100363 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
364 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100365 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100366 "but tch_mode != signalling\n");
367
Harald Welte39274f42009-07-29 15:41:29 +0200368 switch (lchan->type) {
369 case GSM_LCHAN_SDCCH:
370 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
371 break;
372 case GSM_LCHAN_TCH_F:
373 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
374 break;
375 case GSM_LCHAN_TCH_H:
376 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
377 break;
378 case GSM_LCHAN_NONE:
379 case GSM_LCHAN_UNKNOWN:
380 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200381 LOGP(DRSL, LOGL_ERROR,
382 "unsupported activation lchan->type %u %s\n",
383 lchan->type, gsm_lchant_name(lchan->type));
Harald Welte39274f42009-07-29 15:41:29 +0200384 return -EINVAL;
385 }
386
387 switch (lchan->tch_mode) {
388 case GSM48_CMODE_SIGN:
389 cm->chan_rate = 0;
390 break;
391 case GSM48_CMODE_SPEECH_V1:
392 cm->chan_rate = RSL_CMOD_SP_GSM1;
393 break;
394 case GSM48_CMODE_SPEECH_EFR:
395 cm->chan_rate = RSL_CMOD_SP_GSM2;
396 break;
397 case GSM48_CMODE_SPEECH_AMR:
398 cm->chan_rate = RSL_CMOD_SP_GSM3;
399 break;
400 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200401 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200402 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200403 switch (lchan->csd_mode) {
404 case LCHAN_CSD_M_NT:
405 /* non-transparent CSD with RLP */
406 switch (lchan->tch_mode) {
407 case GSM48_CMODE_DATA_14k5:
408 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
409 break;
410 case GSM48_CMODE_DATA_12k0:
411 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
412 break;
413 case GSM48_CMODE_DATA_6k0:
414 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
415 break;
416 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200417 LOGP(DRSL, LOGL_ERROR,
418 "unsupported lchan->tch_mode %u\n",
419 lchan->tch_mode);
Harald Weltee75a47d2012-08-24 15:33:56 +0200420 return -EINVAL;
421 }
422 break;
423 /* transparent data services below */
424 case LCHAN_CSD_M_T_1200_75:
425 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
426 break;
427 case LCHAN_CSD_M_T_600:
428 cm->chan_rate = RSL_CMOD_CSD_T_600;
429 break;
430 case LCHAN_CSD_M_T_1200:
431 cm->chan_rate = RSL_CMOD_CSD_T_1200;
432 break;
433 case LCHAN_CSD_M_T_2400:
434 cm->chan_rate = RSL_CMOD_CSD_T_2400;
435 break;
436 case LCHAN_CSD_M_T_9600:
437 cm->chan_rate = RSL_CMOD_CSD_T_9600;
438 break;
439 case LCHAN_CSD_M_T_14400:
440 cm->chan_rate = RSL_CMOD_CSD_T_14400;
441 break;
442 case LCHAN_CSD_M_T_29000:
443 cm->chan_rate = RSL_CMOD_CSD_T_29000;
444 break;
445 case LCHAN_CSD_M_T_32000:
446 cm->chan_rate = RSL_CMOD_CSD_T_32000;
447 break;
448 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200449 LOGP(DRSL, LOGL_ERROR,
450 "unsupported lchan->csd_mode %u\n",
451 lchan->csd_mode);
Harald Weltee75a47d2012-08-24 15:33:56 +0200452 return -EINVAL;
453 }
Harald Weltefe14df72016-11-26 15:16:14 +0100454 break;
Harald Welte39274f42009-07-29 15:41:29 +0200455 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200456 LOGP(DRSL, LOGL_ERROR,
457 "unsupported lchan->tch_mode %u\n",
458 lchan->tch_mode);
Harald Welte39274f42009-07-29 15:41:29 +0200459 return -EINVAL;
460 }
461
462 return 0;
463}
464
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200465static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
466{
467 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
468 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
469 lchan->mr_bts_lv + 1);
470}
471
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200472static enum gsm_phys_chan_config pchan_for_lchant(enum gsm_chan_t type)
473{
474 switch (type) {
475 case GSM_LCHAN_TCH_F:
476 return GSM_PCHAN_TCH_F;
477 case GSM_LCHAN_TCH_H:
478 return GSM_PCHAN_TCH_H;
479 case GSM_LCHAN_NONE:
480 case GSM_LCHAN_PDTCH:
481 /* TODO: so far lchan->type is NONE in PDCH mode. PDTCH is only
482 * used in osmo-bts. Maybe set PDTCH and drop the NONE case
483 * here. */
484 return GSM_PCHAN_PDCH;
485 default:
486 return GSM_PCHAN_UNKNOWN;
487 }
488}
489
490/*! Tx simplified channel activation message for non-standard PDCH type. */
491static int rsl_chan_activate_lchan_as_pdch(struct gsm_lchan *lchan)
492{
493 struct msgb *msg;
494 struct abis_rsl_dchan_hdr *dh;
495
496 /* This might be called after release of the second lchan of a TCH/H,
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +0200497 * but PDCH activation must always happen on the first lchan. Make sure
498 * the calling code passes the correct lchan. */
499 OSMO_ASSERT(lchan == lchan->ts->lchan);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200500
501 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
502
503 msg = rsl_msgb_alloc();
504 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
505 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
506 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);
507
508 msgb_tv_put(msg, RSL_IE_ACT_TYPE, RSL_ACT_OSMO_PDCH);
509
Harald Weltee6fdf772016-11-16 15:17:22 +0100510 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_RBS2000 &&
511 lchan->ts->trx->bts->rbs2000.use_superchannel) {
512 const uint8_t eric_pgsl_tmr[] = { 30, 1 };
513 msgb_tv_fixed_put(msg, RSL_IE_ERIC_PGSL_TIMERS,
514 sizeof(eric_pgsl_tmr), eric_pgsl_tmr);
515 }
516
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200517 msg->dst = lchan->ts->trx->rsl_link;
518
519 return abis_rsl_sendmsg(msg);
520}
521
Harald Welte59b04682009-06-10 05:40:52 +0800522/* Chapter 8.4.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200523int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200524 uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800525{
526 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200527 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200528 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200529 uint8_t *len;
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200530 uint8_t ta;
Harald Welte59b04682009-06-10 05:40:52 +0800531
Harald Welte59b04682009-06-10 05:40:52 +0800532 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200533 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800534
Neels Hofmeyrb3985cf2016-07-14 02:51:13 +0200535 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200536 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +0200537 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200538 /* store activation type and handover reference */
Neels Hofmeyr3c0df952016-07-23 21:00:51 +0200539 lchan->dyn.act_type = act_type;
540 lchan->dyn.ho_ref = ho_ref;
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200541 return rsl_ipacc_pdch_activate(lchan->ts, 0);
542 }
543
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200544 /*
545 * If necessary, release PDCH on dynamic TS. Note that sending a
546 * release here is only necessary when in PDCH mode; for TCH types, an
547 * RSL RF Chan Release is initiated by the BTS when a voice call ends,
548 * so when we reach this, it will already be released. If a dyn TS is
549 * in PDCH mode, it is still active and we need to initiate a release
550 * from the BSC side here.
551 *
552 * If pchan_is != pchan_want, the PDCH has already been taken down and
553 * the switchover now needs to enable the TCH lchan.
554 *
555 * To switch a dyn TS between TCH/H and TCH/F, it is sufficient to send
556 * a chan activ with the new lchan type, because it will already be
557 * released.
558 */
559 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
560 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
561 && lchan->ts->dyn.pchan_is == lchan->ts->dyn.pchan_want) {
562 enum gsm_phys_chan_config pchan_want;
563 pchan_want = pchan_for_lchant(lchan->type);
564 if (lchan->ts->dyn.pchan_is != pchan_want) {
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +0200565 /*
566 * Make sure to record on lchan[0] so that we'll find
567 * it after the PDCH release.
568 */
569 struct gsm_lchan *lchan0 = lchan->ts->lchan;
570 lchan0->dyn.act_type = act_type,
571 lchan0->dyn.ho_ref = ho_ref;
572 lchan0->dyn.rqd_ref = lchan->rqd_ref;
573 lchan0->dyn.rqd_ta = lchan->rqd_ta;
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200574 lchan->rqd_ref = NULL;
575 lchan->rqd_ta = 0;
576 DEBUGP(DRSL, "%s saved rqd_ref=%p ta=%u\n",
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +0200577 gsm_lchan_name(lchan0), lchan0->rqd_ref,
578 lchan0->rqd_ta);
579 return dyn_ts_switchover_start(lchan->ts, pchan_want);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200580 }
581 }
582
583 DEBUGP(DRSL, "%s Tx RSL Channel Activate with act_type=%s\n",
584 gsm_ts_and_pchan_name(lchan->ts),
585 rsl_act_type_name(act_type));
586
587 if (act_type == RSL_ACT_OSMO_PDCH) {
588 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH) {
589 LOGP(DRSL, LOGL_ERROR,
590 "%s PDCH channel activation only allowed on %s\n",
591 gsm_ts_and_pchan_name(lchan->ts),
592 gsm_pchan_name(GSM_PCHAN_TCH_F_TCH_H_PDCH));
593 return -EINVAL;
594 }
595 return rsl_chan_activate_lchan_as_pdch(lchan);
596 }
597
598 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
599 && lchan->ts->dyn.pchan_want == GSM_PCHAN_PDCH) {
600 LOGP(DRSL, LOGL_ERROR,
601 "%s Expected PDCH activation kind\n",
602 gsm_ts_and_pchan_name(lchan->ts));
603 return -EINVAL;
604 }
605
Neels Hofmeyr89231d22016-07-23 19:49:58 +0200606 rc = channel_mode_from_lchan(&cm, lchan);
607 if (rc < 0) {
608 LOGP(DRSL, LOGL_ERROR,
609 "%s Cannot find channel mode from lchan type\n",
610 gsm_ts_and_pchan_name(lchan->ts));
611 return rc;
612 }
613
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200614 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
615
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200616 ta = lchan->rqd_ta;
617
618 /* BS11 requires TA shifted by 2 bits */
619 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
620 ta <<= 2;
621
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800622 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200623 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800624
Harald Welteed831842009-06-27 03:09:08 +0200625 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800626 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
627 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
Neels Hofmeyre88e5352016-07-23 19:51:09 +0200628
629 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
630 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(
631 lchan, lchan->ts->dyn.pchan_want);
632 else
633 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800634
635 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800636 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200637 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800638
639 /*
640 * The Channel Identification is needed for Phase1 phones
641 * and it contains the GSM48 Channel Description and the
642 * Mobile Allocation. The GSM 08.58 asks for the Mobile
643 * Allocation to have a length of zero. We are using the
644 * msgb_l3len to calculate the length of both messages.
645 */
laforgef723cf02010-06-20 21:38:19 +0200646 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200647 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200648 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800649
650 if (lchan->ts->hopping.enabled)
651 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
652 lchan->ts->hopping.ma_data);
653 else
654 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800655
656 /* update the calculated size */
657 msg->l3h = len + 1;
658 *len = msgb_l3len(msg);
659
Harald Welted2dd9de2009-08-30 15:37:11 +0900660 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200661 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900662 rc = build_encr_info(encr_info, lchan);
663 if (rc > 0)
664 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
665 }
666
Harald Welteb90d7bd2009-12-17 00:31:10 +0100667 switch (act_type) {
668 case RSL_ACT_INTER_ASYNC:
669 case RSL_ACT_INTER_SYNC:
670 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
671 break;
672 default:
673 break;
674 }
675
Harald Welte59b04682009-06-10 05:40:52 +0800676 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
677 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
678 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200679 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100680
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200681 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800682
683 return abis_rsl_sendmsg(msg);
684}
685
Harald Welte8e770492009-07-29 11:38:15 +0200686/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800687int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
688{
689 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200690 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200691 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800692
Harald Weltee6d51f92011-06-25 10:02:33 +0200693 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800694 struct rsl_ie_chan_mode cm;
695
Harald Welte39274f42009-07-29 15:41:29 +0200696 rc = channel_mode_from_lchan(&cm, lchan);
697 if (rc < 0)
698 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800699
Harald Welteed831842009-06-27 03:09:08 +0200700 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800701 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
702 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
703 dh->chan_nr = chan_nr;
704
705 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200706 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900707
708 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200709 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900710 rc = build_encr_info(encr_info, lchan);
711 if (rc > 0)
712 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
713 }
714
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200715 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100716
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200717 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900718
719 return abis_rsl_sendmsg(msg);
720}
721
722/* Chapter 8.4.6: Send the encryption command with given L3 info */
723int rsl_encryption_cmd(struct msgb *msg)
724{
725 struct abis_rsl_dchan_hdr *dh;
726 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200727 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200728 uint8_t encr_info[MAX_A5_KEY_LEN+2];
729 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900730 int rc;
731
732 /* First push the L3 IE tag and length */
733 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
734
735 /* then the link identifier (SAPI0, main sign link) */
736 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
737
738 /* then encryption information */
739 rc = build_encr_info(encr_info, lchan);
740 if (rc <= 0)
741 return rc;
742 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
743
744 /* and finally the DCHAN header */
745 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
746 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
747 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800748
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200749 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800750
751 return abis_rsl_sendmsg(msg);
752}
753
Harald Welte85a163c2009-08-10 11:43:22 +0200754/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200755int rsl_deact_sacch(struct gsm_lchan *lchan)
756{
757 struct abis_rsl_dchan_hdr *dh;
758 struct msgb *msg = rsl_msgb_alloc();
759
760 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
761 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200762 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200763
764 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200765 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200766
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100767 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200768
769 return abis_rsl_sendmsg(msg);
770}
771
Neels Hofmeyr4c136632016-08-24 14:44:11 +0200772static bool dyn_ts_should_switch_to_pdch(struct gsm_bts_trx_ts *ts)
773{
774 int ss;
775
776 if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
777 return false;
778
779 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
780 return false;
781
782 /* Already in PDCH mode? */
783 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH)
784 return false;
785
786 /* See if all lchans are released. */
787 for (ss = 0; ss < ts_subslots(ts); ss++) {
788 struct gsm_lchan *lc = &ts->lchan[ss];
789 if (lc->state != LCHAN_S_NONE) {
Neels Hofmeyr7445cf12016-08-24 14:48:39 +0200790 DEBUGP(DRSL, "%s lchan %u still in use"
791 " (type=%s,state=%s)\n",
792 gsm_ts_and_pchan_name(ts), lc->nr,
793 gsm_lchant_name(lc->type),
794 gsm_lchans_name(lc->state));
Neels Hofmeyr4c136632016-08-24 14:44:11 +0200795 /* An lchan is still used. */
796 return false;
797 }
798 }
799
800 /* All channels are released, go to PDCH mode. */
801 DEBUGP(DRSL, "%s back to PDCH\n",
802 gsm_ts_and_pchan_name(ts));
803 return true;
804}
805
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800806static void error_timeout_cb(void *data)
807{
808 struct gsm_lchan *lchan = data;
809 if (lchan->state != LCHAN_S_REL_ERR) {
810 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
811 gsm_lchan_name(lchan), lchan->state);
812 return;
813 }
814
815 /* go back to the none state */
Harald Weltefddaba52012-11-13 04:26:22 +0100816 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800817 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200818
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200819 /* Put PDCH channel back into PDCH mode, if GPRS is enabled */
820 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
821 && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE)
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200822 rsl_ipacc_pdch_activate(lchan->ts, 1);
Neels Hofmeyr982f0ea2016-08-24 14:45:44 +0200823
824 if (dyn_ts_should_switch_to_pdch(lchan->ts))
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +0200825 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800826}
827
Harald Welte08011e22011-03-04 13:41:31 +0100828static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
829
Harald Welte85a163c2009-08-10 11:43:22 +0200830/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100831static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
832 enum sacch_deact deact_sacch)
Harald Welte59b04682009-06-10 05:40:52 +0800833{
834 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800835 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100836 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800837
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100838 /* Stop timers that should lead to a channel release */
839 osmo_timer_del(&lchan->T3109);
840
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800841 if (lchan->state == LCHAN_S_REL_ERR) {
Neels Hofmeyrf0b8e8b2016-08-24 17:02:19 +0200842 LOGP(DRSL, LOGL_NOTICE, "%s is in error state, not sending release.\n",
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800843 gsm_lchan_name(lchan));
844 return -1;
845 }
846
847 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800848 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
849 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200850 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800851
852 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200853 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800854
Neels Hofmeyrd9b6b5d2016-08-22 18:40:07 +0200855 if (error)
856 DEBUGP(DRSL, "%s RF Channel Release due to error: %d\n",
857 gsm_lchan_name(lchan), error);
858 else
859 DEBUGP(DRSL, "%s RF Channel Release\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800860
861 if (error) {
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100862 /*
863 * FIXME: GSM 04.08 gives us two options for the abnormal
864 * chanel release. This can be either like in the non-existent
865 * sub-lcuase 3.5.1 or for the main signalling link deactivate
866 * the SACCH, start timer T3109 and consider the channel as
867 * released.
868 *
869 * This code is doing the later for all raido links and not
870 * only the main link. Right now all SAPIs are released on the
871 * local end, the SACCH will be de-activated and right now the
872 * T3111 will be started. First T3109 should be started and then
873 * the T3111.
874 *
875 * TODO: Move this out of the function.
876 */
877
878 /*
879 * sacch de-activate and "local end release"
880 */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100881 if (deact_sacch == SACCH_DEACTIVATE)
882 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100883 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
884
885 /*
886 * TODO: start T3109 now.
887 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800888 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800889 }
Harald Welte59b04682009-06-10 05:40:52 +0800890
Harald Welte32951ea2011-08-10 23:26:33 +0200891 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +0200892 osmo_timer_setup(&lchan->act_timer, lchan_deact_tmr_cb, lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200893 osmo_timer_schedule(&lchan->act_timer, 4, 0);
894
Harald Welte08011e22011-03-04 13:41:31 +0100895 rc = abis_rsl_sendmsg(msg);
896
Harald Welte85a163c2009-08-10 11:43:22 +0200897 /* BTS will respond by RF CHAN REL ACK */
Harald Welte08011e22011-03-04 13:41:31 +0100898 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800899}
900
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +0200901/*
902 * Special handling for channel releases in the error case.
903 */
904static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
905{
Neels Hofmeyre062d442016-10-17 01:03:53 +0200906 enum sacch_deact sacch_deact;
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +0200907 if (lchan->state != LCHAN_S_ACTIVE)
908 return 0;
Neels Hofmeyre062d442016-10-17 01:03:53 +0200909 switch (ts_pchan(lchan->ts)) {
910 case GSM_PCHAN_TCH_F:
911 case GSM_PCHAN_TCH_H:
912 case GSM_PCHAN_CCCH_SDCCH4:
913 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
914 case GSM_PCHAN_SDCCH8_SACCH8C:
915 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
916 sacch_deact = SACCH_DEACTIVATE;
917 break;
918 default:
919 sacch_deact = SACCH_NONE;
920 break;
921 }
922 return rsl_rf_chan_release(lchan, 1, sacch_deact);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +0200923}
924
Harald Welte9773f6c2011-01-14 14:16:16 +0100925static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
926{
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200927 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte9773f6c2011-01-14 14:16:16 +0100928
929 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
930
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100931 /* Stop all pending timers */
Harald Welte32951ea2011-08-10 23:26:33 +0200932 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100933 osmo_timer_del(&lchan->T3111);
Harald Welte32951ea2011-08-10 23:26:33 +0200934
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200935 /*
936 * The BTS didn't respond within the timeout to our channel
937 * release request and we have marked the channel as broken.
938 * Now we do receive an ACK and let's be conservative. If it
939 * is a sysmoBTS we know that only one RF Channel Release ACK
940 * will be sent. So let's "repair" the channel.
941 */
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200942 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200943 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200944 LOGP(DRSL, LOGL_NOTICE,
945 "%s CHAN REL ACK for broken channel. %s.\n",
946 gsm_lchan_name(lchan),
947 do_free ? "Releasing it" : "Keeping it broken");
948 if (do_free)
949 do_lchan_free(lchan);
Neels Hofmeyra8430762016-08-24 17:02:37 +0200950 if (dyn_ts_should_switch_to_pdch(lchan->ts))
951 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200952 return 0;
953 }
954
Harald Welte9773f6c2011-01-14 14:16:16 +0100955 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
956 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
957 gsm_lchan_name(lchan),
958 gsm_lchans_name(lchan->state));
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200959
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200960 do_lchan_free(lchan);
961
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200962 /*
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200963 * Check Osmocom RSL CHAN ACT style dynamic TCH/F_TCH/H_PDCH TS for pending
964 * transitions in these cases:
965 *
966 * a) after PDCH was released due to switchover request, activate TCH.
967 * BSC initiated this switchover, so dyn.pchan_is != pchan_want and
968 * lchan->type has been set to the desired GSM_LCHAN_*.
969 *
970 * b) Voice call ended and a TCH is released. If the TS is now unused,
971 * switch to PDCH. Here still dyn.pchan_is == dyn.pchan_want because
972 * we're only just notified and may decide to switch to PDCH now.
973 */
974 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
975 DEBUGP(DRSL, "%s Rx RSL Channel Release ack for lchan %u\n",
976 gsm_ts_and_pchan_name(ts), lchan->nr);
977
978 /* (a) */
979 if (ts->dyn.pchan_is != ts->dyn.pchan_want)
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +0200980 return dyn_ts_switchover_continue(ts);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200981
982 /* (b) */
Neels Hofmeyr4c136632016-08-24 14:44:11 +0200983 if (dyn_ts_should_switch_to_pdch(ts))
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +0200984 return dyn_ts_switchover_start(ts, GSM_PCHAN_PDCH);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +0200985 }
986
987 /*
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200988 * Put a dynamic TCH/F_PDCH channel back to PDCH mode iff it was
989 * released successfully. If in error, the PDCH ACT will follow after
990 * T3111 in error_timeout_cb().
991 *
992 * Any state other than LCHAN_S_REL_ERR became LCHAN_S_NONE after above
993 * do_lchan_free(). Assert this, because that's what ensures a PDCH ACT
Neels Hofmeyrb3985cf2016-07-14 02:51:13 +0200994 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200995 *
996 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200997 */
998 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
999 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyraff130f2016-07-23 20:01:49 +02001000 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr31b26302016-07-06 14:39:04 +02001001 return 0;
Neels Hofmeyraff130f2016-07-23 20:01:49 +02001002 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyrff1d7342016-06-21 20:55:14 +02001003 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyraff130f2016-07-23 20:01:49 +02001004 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte9773f6c2011-01-14 14:16:16 +01001005 return 0;
1006}
1007
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001008int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
Harald Welte1f8cbf12016-11-17 20:54:04 +01001009 uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs)
Harald Welte59b04682009-06-10 05:40:52 +08001010{
1011 struct abis_rsl_dchan_hdr *dh;
1012 struct msgb *msg = rsl_msgb_alloc();
1013
1014 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1015 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
1016 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1017
1018 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
1019 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
1020 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
1021
Harald Welte1f8cbf12016-11-17 20:54:04 +01001022 /* Ericsson wants to have this IE in case a paging message
1023 * relates to packet paging */
1024 if (bts->type == GSM_BTS_TYPE_RBS2000 && is_gprs)
1025 msgb_tv_put(msg, RSL_IE_ERIC_PACKET_PAG_IND, 0);
1026
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001027 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001028
1029 return abis_rsl_sendmsg(msg);
1030}
1031
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001032int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +08001033{
1034 int i, len = strlen(str_in);
1035
1036 for (i = 0; i < len; i++) {
1037 int num = str_in[i] - 0x30;
1038 if (num < 0 || num > 9)
1039 return -1;
1040 if (i % 2 == 0)
1041 bcd_out[i/2] = num;
1042 else
1043 bcd_out[i/2] |= (num << 4);
1044 }
1045
1046 return 0;
1047}
1048
1049/* Chapter 8.5.6 */
Alexander Couzens4e2030d2016-12-02 05:21:45 +01001050struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +08001051{
1052 struct msgb *msg = rsl_msgb_alloc();
1053 struct abis_rsl_dchan_hdr *dh;
Max6b238392017-02-09 19:23:38 +01001054 uint8_t buf[GSM_MACBLOCK_LEN];
Harald Welte59b04682009-06-10 05:40:52 +08001055
1056 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1057 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
1058 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1059
1060 switch (bts->type) {
1061 case GSM_BTS_TYPE_BS11:
1062 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
1063 break;
1064 default:
1065 /* If phase 2, construct a FULL_IMM_ASS_INFO */
1066 pad_macblock(buf, val, len);
Max6b238392017-02-09 19:23:38 +01001067 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, GSM_MACBLOCK_LEN,
1068 buf);
Harald Welte59b04682009-06-10 05:40:52 +08001069 break;
1070 }
1071
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001072 msg->dst = bts->c0->rsl_link;
Alexander Couzens4e2030d2016-12-02 05:21:45 +01001073 return msg;
1074}
1075
1076/* Chapter 8.5.6 */
1077int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
1078{
1079 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1080 if (!msg)
1081 return 1;
1082 return abis_rsl_sendmsg(msg);
1083}
1084
1085/* Chapter 8.5.6 */
1086int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val)
1087{
1088 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1089 if (!msg)
1090 return 1;
1091
1092 /* ericsson can handle a reference at the end of the message which is used in
1093 * the confirm message. The confirm message is only sent if the trailer is present */
1094 msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
1095 msgb_put_u32(msg, tlli);
Harald Welte59b04682009-06-10 05:40:52 +08001096
1097 return abis_rsl_sendmsg(msg);
1098}
1099
Harald Welte4684e632009-08-10 09:51:40 +02001100/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +02001101int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +02001102{
1103 struct msgb *msg = rsl_msgb_alloc();
1104 struct abis_rsl_dchan_hdr *dh;
1105
1106 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1107 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +02001108 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02001109 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001110 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +02001111
Harald Weltede4477a2009-12-24 12:20:20 +01001112 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001113 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +02001114
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001115 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +02001116
Harald Welte4684e632009-08-10 09:51:40 +02001117 return abis_rsl_sendmsg(msg);
1118}
1119
1120
Harald Welte59b04682009-06-10 05:40:52 +08001121/* Send "DATA REQUEST" message with given L3 Info payload */
1122/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001123int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +08001124{
Harald Welte59b04682009-06-10 05:40:52 +08001125 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001126 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +08001127 return -EINVAL;
1128 }
1129
Harald Weltee6d51f92011-06-25 10:02:33 +02001130 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +01001131 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +08001132
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001133 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001134
1135 return abis_rsl_sendmsg(msg);
1136}
1137
Harald Welteed9a5ab2009-08-09 13:47:35 +02001138/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
1139/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001140int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +02001141{
Harald Weltea22d36b2010-03-04 10:33:10 +01001142 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001143
Harald Weltee6d51f92011-06-25 10:02:33 +02001144 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +01001145 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001146 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001147
Harald Welte17091bd2012-04-26 19:42:19 +02001148 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
1149 gsm_lchan_name(lchan), link_id);
1150
Harald Welteed9a5ab2009-08-09 13:47:35 +02001151 return abis_rsl_sendmsg(msg);
1152}
1153
Andreas Eversbergac27b952013-12-05 13:25:06 +01001154static void rsl_handle_release(struct gsm_lchan *lchan);
1155
1156/* Special work handler to handle missing RSL_MT_REL_CONF message from
1157 * Nokia InSite BTS */
1158static void lchan_rel_work_cb(void *data)
1159{
1160 struct gsm_lchan *lchan = data;
1161 int sapi;
1162
1163 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1164 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
1165 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
1166 }
1167 rsl_handle_release(lchan);
1168}
1169
Harald Welte0f2e3c12009-08-08 13:15:07 +02001170/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
1171 This is what higher layers should call. The BTS then responds with
1172 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
1173 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
1174 lchan_free() */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +01001175int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
1176 enum rsl_rel_mode release_mode)
Harald Welte0f2e3c12009-08-08 13:15:07 +02001177{
Harald Welte0f2e3c12009-08-08 13:15:07 +02001178
Harald Weltea22d36b2010-03-04 10:33:10 +01001179 struct msgb *msg;
1180
Harald Weltee6d51f92011-06-25 10:02:33 +02001181 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +01001182 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +08001183 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +01001184 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001185
Harald Weltec88a4432009-12-29 10:44:17 +01001186 /* FIXME: start some timer in case we don't receive a REL ACK ? */
1187
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001188 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +02001189
Harald Welte17091bd2012-04-26 19:42:19 +02001190 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +01001191 gsm_lchan_name(lchan), link_id, release_mode);
Harald Welte17091bd2012-04-26 19:42:19 +02001192
Andreas Eversbergac27b952013-12-05 13:25:06 +01001193 abis_rsl_sendmsg(msg);
1194
1195 /* Do not wait for Nokia BTS to send the confirm. */
1196 if (is_nokia_bts(lchan->ts->trx->bts)
1197 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
1198 && release_mode == RSL_REL_LOCAL_END) {
1199 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
1200 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +02001201 osmo_timer_setup(&lchan->rel_work, lchan_rel_work_cb, lchan);
Andreas Eversbergac27b952013-12-05 13:25:06 +01001202 osmo_timer_schedule(&lchan->rel_work, 0, 0);
1203 }
1204
1205 return 0;
Harald Welte0f2e3c12009-08-08 13:15:07 +02001206}
1207
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001208int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
1209{
Neels Hofmeyr0323f352016-08-24 16:48:00 +02001210 LOGP(DRSL, LOGL_ERROR, "%s %s lchan broken: %s\n",
1211 gsm_lchan_name(lchan), gsm_lchant_name(lchan->type), reason);
1212 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001213 lchan->broken_reason = reason;
1214 return 0;
1215}
1216
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +02001217int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
1218{
Neels Hofmeyra4353c82016-06-21 21:34:46 +02001219 DEBUGP(DRSL, "%s state %s -> %s\n",
1220 gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
1221 gsm_lchans_name(state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +02001222 lchan->state = state;
1223 return 0;
1224}
1225
Harald Welte59b04682009-06-10 05:40:52 +08001226/* Chapter 8.4.2: Channel Activate Acknowledge */
1227static int rsl_rx_chan_act_ack(struct msgb *msg)
1228{
1229 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001230 struct gsm_lchan *lchan = msg->lchan;
Holger Hans Peter Freyther18e514c2016-08-18 08:49:21 +02001231 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte59b04682009-06-10 05:40:52 +08001232
1233 /* BTS has confirmed channel activation, we now need
1234 * to assign the activated channel to the MS */
1235 if (rslh->ie_chan != RSL_IE_CHAN_NR)
1236 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +01001237
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001238 osmo_timer_del(&lchan->act_timer);
Harald Welte32951ea2011-08-10 23:26:33 +02001239
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001240 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freyther18e514c2016-08-18 08:49:21 +02001241 int do_release = is_sysmobts_v2(ts->trx->bts);
1242 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel. %s\n",
1243 gsm_lchan_name(lchan),
1244 do_release ? "Releasing it" : "Keeping it broken");
1245 if (do_release) {
1246 talloc_free(lchan->rqd_ref);
1247 lchan->rqd_ref = NULL;
1248 lchan->rqd_ta = 0;
1249 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
1250 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
1251 /*
1252 * lchan_act_tmr_cb() already called
1253 * lchan_free() and cleared the lchan->type, so
1254 * calling dyn_ts_switchover_complete() here
1255 * would not have the desired effect of
1256 * mimicking an activated lchan that we can
1257 * release. Instead hack the dyn ts state to
1258 * make sure that rsl_rx_rf_chan_rel_ack() will
1259 * switch back to PDCH, i.e. have pchan_is ==
1260 * pchan_want, both != GSM_PCHAN_PDCH:
1261 */
1262 ts->dyn.pchan_is = GSM_PCHAN_NONE;
1263 ts->dyn.pchan_want = GSM_PCHAN_NONE;
1264 }
1265 rsl_rf_chan_release(msg->lchan, 0, SACCH_NONE);
1266 }
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +02001267 return 0;
1268 }
1269
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001270 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +01001271 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001272 gsm_lchan_name(lchan),
1273 gsm_lchans_name(lchan->state));
1274 rsl_lchan_set_state(lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +01001275
Holger Hans Peter Freyther18e514c2016-08-18 08:49:21 +02001276 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02001277 dyn_ts_switchover_complete(lchan);
1278
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001279 if (lchan->rqd_ref) {
1280 rsl_send_imm_assignment(lchan);
1281 talloc_free(lchan->rqd_ref);
1282 lchan->rqd_ref = NULL;
1283 lchan->rqd_ta = 0;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001284 }
1285
Neels Hofmeyrdc997402016-07-14 16:16:33 +02001286 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001287
Harald Welte59b04682009-06-10 05:40:52 +08001288 return 0;
1289}
1290
1291/* Chapter 8.4.3: Channel Activate NACK */
1292static int rsl_rx_chan_act_nack(struct msgb *msg)
1293{
1294 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1295 struct tlv_parsed tp;
1296
Harald Welte32951ea2011-08-10 23:26:33 +02001297 osmo_timer_del(&msg->lchan->act_timer);
1298
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +02001299 if (msg->lchan->state == LCHAN_S_BROKEN) {
1300 LOGP(DRSL, LOGL_ERROR,
1301 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
1302 gsm_lchan_name(msg->lchan));
1303 return -1;
1304 }
1305
Daniel Willmann9e9d44c2011-08-11 04:54:23 +02001306 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001307 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001308
Harald Welte59b04682009-06-10 05:40:52 +08001309 /* BTS has rejected channel activation ?!? */
1310 if (dh->ie_chan != RSL_IE_CHAN_NR)
1311 return -EINVAL;
1312
1313 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001314 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001315 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001316 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +02001317 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +01001318 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001319 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1320 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1321 } else
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001322 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann245ee032011-08-11 04:47:11 +02001323
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001324 } else {
1325 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1326 }
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001327
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001328 LOGPC(DRSL, LOGL_ERROR, "\n");
1329
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001330 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte59b04682009-06-10 05:40:52 +08001331 return 0;
1332}
1333
1334/* Chapter 8.4.4: Connection Failure Indication */
1335static int rsl_rx_conn_fail(struct msgb *msg)
1336{
1337 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1338 struct tlv_parsed tp;
1339
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001340 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1341 gsm_lchan_name(msg->lchan),
1342 gsm_lchans_name(msg->lchan->state));
1343
Harald Welte59b04682009-06-10 05:40:52 +08001344 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1345
Harald Weltef1a168d2009-07-28 17:58:09 +02001346 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001347 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001348 TLVP_LEN(&tp, RSL_IE_CAUSE));
1349
Harald Welte (local)4bd76642009-12-26 22:33:09 +01001350 LOGPC(DRSL, LOGL_NOTICE, "\n");
Alexander Couzensd8aad3a2016-08-02 11:34:11 +02001351 rate_ctr_inc(&msg->lchan->ts->trx->bts->network->bsc_ctrs->ctr[BSC_CTR_CHAN_RF_FAIL]);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001352 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001353}
1354
Harald Weltec20bd1d2009-11-29 19:07:28 +01001355static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1356 const char *prefix)
1357{
Harald Welte0e4fa782009-12-16 16:52:07 +01001358 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1359 prefix, rxlev2dbm(mru->full.rx_lev),
1360 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +01001361 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1362 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1363}
1364
Harald Welte50290cc2012-07-02 17:12:08 +02001365static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +01001366{
Harald Welte0e4fa782009-12-16 16:52:07 +01001367 int i;
Neels Hofmeyr86fe87b2017-02-18 22:20:46 +01001368 const char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +01001369
Max2c7690a2017-04-20 13:07:58 +02001370 if (lchan && lchan->conn) {
1371 if (lchan->conn->bsub)
1372 name = bsc_subscr_name(lchan->conn->bsub);
1373 else if (lchan->conn->subscr)
1374 name = lchan->conn->subscr->imsi;
1375 else
1376 name = lchan->name;
1377 }
Harald Welte50290cc2012-07-02 17:12:08 +02001378
1379 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001380
1381 if (mr->flags & MEAS_REP_F_DL_DTX)
1382 DEBUGPC(DMEAS, "DTXd ");
1383
1384 print_meas_rep_uni(&mr->ul, "ul");
1385 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
Max2c7690a2017-04-20 13:07:58 +02001386
Harald Weltec20bd1d2009-11-29 19:07:28 +01001387 if (mr->flags & MEAS_REP_F_MS_TO)
1388 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1389
1390 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +01001391 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001392 DEBUGPC(DMEAS, "L1_FPC=%u ",
1393 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1394 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1395 }
1396
1397 if (mr->flags & MEAS_REP_F_UL_DTX)
1398 DEBUGPC(DMEAS, "DTXu ");
1399 if (mr->flags & MEAS_REP_F_BA1)
1400 DEBUGPC(DMEAS, "BA1 ");
1401 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1402 DEBUGPC(DMEAS, "NOT VALID ");
1403 else
1404 print_meas_rep_uni(&mr->dl, "dl");
1405
1406 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +01001407 if (mr->num_cell == 7)
1408 return;
Harald Welte0e4fa782009-12-16 16:52:07 +01001409 for (i = 0; i < mr->num_cell; i++) {
1410 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +01001411 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1412 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001413 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001414}
1415
Harald Welte59b04682009-06-10 05:40:52 +08001416static int rsl_rx_meas_res(struct msgb *msg)
1417{
1418 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1419 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001420 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001421 uint8_t len;
1422 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001423 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001424
Harald Welte4baa9c52009-12-21 13:27:11 +01001425 /* check if this channel is actually active */
1426 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001427 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001428 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001429 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001430 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001431 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001432
Harald Weltef9476812009-12-15 21:36:05 +01001433 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001434 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001435
Harald Welte59b04682009-06-10 05:40:52 +08001436 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1437
Harald Weltec20bd1d2009-11-29 19:07:28 +01001438 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1439 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1440 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1441 return -EIO;
1442
1443 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001444 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001445
1446 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1447 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1448 if (len >= 3) {
1449 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001450 mr->flags |= MEAS_REP_F_DL_DTX;
1451 mr->ul.full.rx_lev = val[0] & 0x3f;
1452 mr->ul.sub.rx_lev = val[1] & 0x3f;
1453 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1454 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001455 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001456
Harald Weltef9476812009-12-15 21:36:05 +01001457 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001458
1459 /* Optional Parts */
Max2c7690a2017-04-20 13:07:58 +02001460 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) {
1461 /* According to 3GPP TS 48.058 § MS Timing Offset = Timing Offset field - 63 */
1462 mr->ms_timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET) - 63;
1463 mr->flags |= MEAS_REP_F_MS_TO;
1464 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001465
Harald Weltea1467eb2009-06-20 18:44:35 +02001466 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001467 struct e1inp_sign_link *sign_link = msg->dst;
1468
Harald Weltec20bd1d2009-11-29 19:07:28 +01001469 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001470 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001471 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001472 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001473 mr->flags |= MEAS_REP_F_FPC;
1474 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001475 /* BS11 and Nokia reports TA shifted by 2 bits */
1476 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1477 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001478 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001479 }
Harald Welte59b04682009-06-10 05:40:52 +08001480 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001481 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001482 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001483 if (rc < 0)
1484 return rc;
1485 }
1486
Harald Welte50290cc2012-07-02 17:12:08 +02001487 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001488
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001489 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001490
Harald Welte59b04682009-06-10 05:40:52 +08001491 return 0;
1492}
1493
Harald Welte6720a432009-11-29 22:45:52 +01001494/* Chapter 8.4.7 */
1495static int rsl_rx_hando_det(struct msgb *msg)
1496{
1497 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1498 struct tlv_parsed tp;
1499
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001500 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001501
1502 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1503
1504 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1505 DEBUGPC(DRSL, "access delay = %u\n",
1506 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1507 else
1508 DEBUGPC(DRSL, "\n");
1509
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001510 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001511
1512 return 0;
1513}
1514
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001515static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1516{
1517 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001518
1519 OSMO_ASSERT(lchan);
1520
1521 ts = lchan->ts;
1522 OSMO_ASSERT(ts);
1523 OSMO_ASSERT(ts->trx);
1524 OSMO_ASSERT(ts->trx->bts);
1525
1526 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
Neels Hofmeyr50c2bd42016-06-21 20:53:27 +02001527 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1528 " for channel that is no TCH/F_PDCH\n",
1529 gsm_lchan_name(lchan),
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001530 gsm_pchan_name(ts->pchan),
1531 pdch_act? "ACT" : "DEACT");
1532 return false;
1533 }
1534
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +02001535 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyr50c2bd42016-06-21 20:53:27 +02001536 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1537 " in unexpected state: %s\n",
1538 gsm_lchan_name(lchan),
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001539 gsm_pchan_name(ts->pchan),
1540 pdch_act? "ACT" : "DEACT",
1541 gsm_lchans_name(lchan->state));
1542 return false;
1543 }
1544 return true;
1545}
1546
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001547static int rsl_rx_pdch_act_ack(struct msgb *msg)
1548{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001549 if (!lchan_may_change_pdch(msg->lchan, true))
1550 return -EINVAL;
1551
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001552 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001553 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001554
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001555 return 0;
1556}
1557
1558static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1559{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001560 if (!lchan_may_change_pdch(msg->lchan, false))
1561 return -EINVAL;
1562
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001563 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001564 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001565
Neels Hofmeyr3c0df952016-07-23 21:00:51 +02001566 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn.act_type,
1567 msg->lchan->dyn.ho_ref);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001568
1569 return 0;
1570}
1571
Harald Welte59b04682009-06-10 05:40:52 +08001572static int abis_rsl_rx_dchan(struct msgb *msg)
1573{
1574 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1575 int rc = 0;
1576 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001577 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001578
Neels Hofmeyr0781eb02016-08-23 01:22:58 +02001579 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1580 "Abis RSL rx DCHAN: ");
Neels Hofmeyr0f4e8952016-10-10 03:24:05 +02001581 if (!msg->lchan)
1582 return -1;
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001583 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001584
Harald Welte59b04682009-06-10 05:40:52 +08001585 switch (rslh->c.msg_type) {
1586 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001587 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001588 rc = rsl_rx_chan_act_ack(msg);
Alexander Couzens4f598fc2016-08-23 06:27:19 +02001589 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001590 break;
1591 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001592 rc = rsl_rx_chan_act_nack(msg);
1593 break;
1594 case RSL_MT_CONN_FAIL:
1595 rc = rsl_rx_conn_fail(msg);
1596 break;
1597 case RSL_MT_MEAS_RES:
1598 rc = rsl_rx_meas_res(msg);
1599 break;
Harald Welte6720a432009-11-29 22:45:52 +01001600 case RSL_MT_HANDO_DET:
1601 rc = rsl_rx_hando_det(msg);
1602 break;
Harald Welte59b04682009-06-10 05:40:52 +08001603 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001604 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001605 break;
1606 case RSL_MT_MODE_MODIFY_ACK:
Alexander Couzens4f598fc2016-08-23 06:27:19 +02001607 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001608 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001609 break;
1610 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001611 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001612 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001613 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr6b272302016-05-31 17:51:41 +02001614 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001615 rc = rsl_rx_pdch_act_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001616 break;
1617 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001618 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001619 break;
1620 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001621 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001622 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001623 break;
1624 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001625 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001626 break;
Harald Welte59b04682009-06-10 05:40:52 +08001627 case RSL_MT_PHY_CONTEXT_CONF:
1628 case RSL_MT_PREPROC_MEAS_RES:
1629 case RSL_MT_TALKER_DET:
1630 case RSL_MT_LISTENER_DET:
1631 case RSL_MT_REMOTE_CODEC_CONF_REP:
1632 case RSL_MT_MR_CODEC_MOD_ACK:
1633 case RSL_MT_MR_CODEC_MOD_NACK:
1634 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001635 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1636 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001637 break;
1638 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001639 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1640 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001641 return -EINVAL;
1642 }
1643
1644 return rc;
1645}
1646
1647static int rsl_rx_error_rep(struct msgb *msg)
1648{
1649 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001650 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001651 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001652
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001653 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001654
1655 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1656
1657 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001658 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001659 TLVP_LEN(&tp, RSL_IE_CAUSE));
1660
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001661 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001662
1663 return 0;
1664}
1665
1666static int abis_rsl_rx_trx(struct msgb *msg)
1667{
1668 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001669 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001670 int rc = 0;
1671
1672 switch (rslh->msg_type) {
1673 case RSL_MT_ERROR_REPORT:
1674 rc = rsl_rx_error_rep(msg);
1675 break;
1676 case RSL_MT_RF_RES_IND:
1677 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001678 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001679 break;
1680 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001681 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001682 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001683 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001684 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001685 case 0x42: /* Nokia specific: SI End ACK */
1686 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1687 break;
1688 case 0x43: /* Nokia specific: SI End NACK */
1689 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1690 break;
Harald Welte59b04682009-06-10 05:40:52 +08001691 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001692 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001693 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001694 return -EINVAL;
1695 }
1696 return rc;
1697}
1698
Harald Welte427dbc42009-08-10 00:26:10 +02001699/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1700static void t3101_expired(void *data)
1701{
1702 struct gsm_lchan *lchan = data;
Maxf7f79ca2017-02-09 19:13:02 +01001703 LOGP(DRSL, LOGL_NOTICE,
1704 "%s T3101 expired: no response to IMMEDIATE ASSIGN\n",
1705 gsm_lchan_name(lchan));
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001706 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welte427dbc42009-08-10 00:26:10 +02001707}
1708
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001709/* If T3111 expires, we will send the RF Channel Request */
1710static void t3111_expired(void *data)
1711{
1712 struct gsm_lchan *lchan = data;
Maxf7f79ca2017-02-09 19:13:02 +01001713 LOGP(DRSL, LOGL_NOTICE,
1714 "%s T3111 expired: releasing RF Channel\n",
1715 gsm_lchan_name(lchan));
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001716 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1717}
1718
1719/* If T3109 expires the MS has not send a UA/UM do the error release */
1720static void t3109_expired(void *data)
1721{
1722 struct gsm_lchan *lchan = data;
1723
1724 LOGP(DRSL, LOGL_ERROR,
1725 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1726 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001727}
1728
Harald Weltea00fdd72010-12-23 14:39:29 +01001729/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1730static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1731 unsigned int num_req_refs,
1732 struct gsm48_req_ref *rqd_refs,
1733 uint8_t wait_ind)
1734{
1735 uint8_t buf[GSM_MACBLOCK_LEN];
1736 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1737
1738 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1739 memset(iar, 0, sizeof(*iar));
1740 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001741 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Weltea00fdd72010-12-23 14:39:29 +01001742 iar->page_mode = GSM48_PM_SAME;
1743
1744 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1745 iar->wait_ind1 = wait_ind;
1746
1747 if (num_req_refs >= 2)
1748 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1749 else
1750 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1751 iar->wait_ind2 = wait_ind;
1752
1753 if (num_req_refs >= 3)
1754 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1755 else
1756 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1757 iar->wait_ind3 = wait_ind;
1758
1759 if (num_req_refs >= 4)
1760 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1761 else
1762 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1763 iar->wait_ind4 = wait_ind;
1764
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001765 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1766 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1767
1768 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Weltea00fdd72010-12-23 14:39:29 +01001769}
1770
Harald Welte59b04682009-06-10 05:40:52 +08001771/* MS has requested a channel on the RACH */
1772static int rsl_rx_chan_rqd(struct msgb *msg)
1773{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001774 struct e1inp_sign_link *sign_link = msg->dst;
1775 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001776 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1777 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001778 enum gsm_chan_t lctype;
1779 enum gsm_chreq_reason_t chreq_reason;
1780 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001781 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001782 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001783
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001784 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001785 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001786
1787 /* parse request reference to be used in immediate assign */
1788 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1789 return -EINVAL;
1790
1791 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1792
1793 /* parse access delay and use as TA */
1794 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1795 return -EINVAL;
1796 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1797
1798 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1799 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001800 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1801 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001802
Alexander Couzensd8aad3a2016-08-02 11:34:11 +02001803 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL]);
Harald Welte3edc5a92009-12-22 00:41:05 +01001804
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001805 /*
1806 * We want LOCATION UPDATES to succeed and will assign a TCH
1807 * if we have no SDCCH available.
1808 */
1809 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1810
Harald Welte59b04682009-06-10 05:40:52 +08001811 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001812 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001813 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001814 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001815 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Alexander Couzensd8aad3a2016-08-02 11:34:11 +02001816 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL]);
Harald Weltea00fdd72010-12-23 14:39:29 +01001817 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1818 if (bts->network->T3122)
1819 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Weltecf7c90c2012-11-13 04:46:03 +01001820 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001821 }
1822
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02001823 /*
1824 * Expecting lchan state to be NONE, except for dyn TS in PDCH mode.
1825 * Those are expected to be ACTIVE: the PDCH release will be sent from
1826 * rsl_chan_activate_lchan() below.
1827 */
1828 if (lchan->state != LCHAN_S_NONE
1829 && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
1830 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
1831 && lchan->state == LCHAN_S_ACTIVE))
Harald Weltec88a4432009-12-29 10:44:17 +01001832 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001833 "in state %s\n", gsm_lchan_name(lchan),
1834 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001835
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001836 /* save the RACH data as we need it after the CHAN ACT ACK */
1837 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1838 if (!lchan->rqd_ref) {
1839 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1840 lchan_free(lchan);
1841 return -ENOMEM;
1842 }
1843
1844 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1845 lchan->rqd_ta = rqd_ta;
1846
Harald Welte59b04682009-06-10 05:40:52 +08001847 arfcn = lchan->ts->trx->arfcn;
1848 subch = lchan->nr;
1849
Harald Welted2dd9de2009-08-30 15:37:11 +09001850 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001851 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001852 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001853 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001854 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001855
Harald Welte32951ea2011-08-10 23:26:33 +02001856 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +02001857 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Harald Welte32951ea2011-08-10 23:26:33 +02001858 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1859
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001860 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1861 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1862 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1863 rqd_ref->ra, rqd_ta);
1864
Neels Hofmeyrfe9fdfa2016-07-15 01:26:03 +02001865 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001866
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001867 return 0;
1868}
1869
1870static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1871{
1872 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001873 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001874 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1875
Harald Welte59b04682009-06-10 05:40:52 +08001876 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001877 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001878 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001879 ia->proto_discr = GSM48_PDISC_RR;
1880 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1881 ia->page_mode = GSM48_PM_SAME;
1882 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001883
Harald Welte59b04682009-06-10 05:40:52 +08001884 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001885 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1886 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001887 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001888 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001889 } else {
laforgee06d5982010-06-20 15:18:46 +02001890 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1891 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001892 }
Harald Welte07f32182010-06-28 18:41:27 +02001893 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1894 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001895
Harald Welte427dbc42009-08-10 00:26:10 +02001896 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +02001897 osmo_timer_setup(&lchan->T3101, t3101_expired, lchan);
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001898 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001899
1900 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001901 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001902}
1903
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001904/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001905static int rsl_rx_ccch_load(struct msgb *msg)
1906{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001907 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001908 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001909 struct ccch_signal_data sd;
1910
1911 sd.bts = sign_link->trx->bts;
1912 sd.rach_slot_count = -1;
1913 sd.rach_busy_count = -1;
1914 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001915
1916 switch (rslh->data[0]) {
1917 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001918 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1919 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001920 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001921 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001922 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001923 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1924 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001925 break;
1926 case RSL_IE_RACH_LOAD:
1927 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001928 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1929 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1930 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1931 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001932 }
1933 break;
1934 default:
1935 break;
1936 }
1937
1938 return 0;
1939}
1940
1941static int abis_rsl_rx_cchan(struct msgb *msg)
1942{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001943 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001944 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1945 int rc = 0;
1946
Neels Hofmeyr0781eb02016-08-23 01:22:58 +02001947 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1948 "Abis RSL rx CCHAN: ");
Harald Welte59b04682009-06-10 05:40:52 +08001949
1950 switch (rslh->c.msg_type) {
1951 case RSL_MT_CHAN_RQD:
1952 /* MS has requested a channel on the RACH */
1953 rc = rsl_rx_chan_rqd(msg);
1954 break;
1955 case RSL_MT_CCCH_LOAD_IND:
1956 /* current load on the CCCH */
1957 rc = rsl_rx_ccch_load(msg);
1958 break;
1959 case RSL_MT_DELETE_IND:
1960 /* CCCH overloaded, IMM_ASSIGN was dropped */
1961 case RSL_MT_CBCH_LOAD_IND:
1962 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001963 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1964 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001965 break;
1966 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001967 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1968 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001969 return -EINVAL;
1970 }
1971
1972 return rc;
1973}
1974
1975static int rsl_rx_rll_err_ind(struct msgb *msg)
1976{
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001977 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001978 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001979 uint8_t rlm_cause;
Harald Welte59b04682009-06-10 05:40:52 +08001980
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001981 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1982 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1983 LOGP(DRLL, LOGL_ERROR,
1984 "%s ERROR INDICATION without mandantory cause.\n",
1985 gsm_lchan_name(msg->lchan));
1986 return -1;
1987 }
1988
1989 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001990 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001991 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001992 rsl_rlm_cause_name(rlm_cause),
1993 gsm_lchans_name(msg->lchan->state));
1994
Harald Welteed9a5ab2009-08-09 13:47:35 +02001995 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001996
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001997 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Alexander Couzensd8aad3a2016-08-02 11:34:11 +02001998 rate_ctr_inc(&msg->lchan->ts->trx->bts->network->bsc_ctrs->ctr[BSC_CTR_CHAN_RLL_ERR]);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001999 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02002000 }
Harald Welte692f5852009-07-04 09:40:05 +02002001
Harald Welte59b04682009-06-10 05:40:52 +08002002 return 0;
2003}
2004
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02002005static void rsl_handle_release(struct gsm_lchan *lchan)
2006{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08002007 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08002008 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08002009
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +01002010 /*
2011 * Maybe only one link/SAPI was releasd or the error handling
2012 * was activated. Just return now and let the other code handle
2013 * it.
2014 */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02002015 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08002016 return;
2017
2018 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2019 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2020 continue;
Harald Welte497aa982010-12-24 12:51:07 +01002021 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08002022 gsm_lchan_name(lchan), sapi);
2023 return;
2024 }
2025
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02002026
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002027 /* Stop T3109 and wait for T3111 before re-using the channel */
2028 osmo_timer_del(&lchan->T3109);
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +02002029 osmo_timer_setup(&lchan->T3111, t3111_expired, lchan);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08002030 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02002031 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02002032}
2033
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02002034/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08002035 0x02, 0x06,
2036 0x01, 0x20,
2037 0x02, 0x00,
2038 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
2039
2040static int abis_rsl_rx_rll(struct msgb *msg)
2041{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002042 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08002043 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
2044 int rc = 0;
2045 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002046 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08002047
Neels Hofmeyr0781eb02016-08-23 01:22:58 +02002048 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2049 "Abis RSL rx RLL: ");
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01002050 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01002051 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08002052
2053 switch (rllh->c.msg_type) {
2054 case RSL_MT_DATA_IND:
2055 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02002056 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08002057 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2058 rllh->data[0] == RSL_IE_L3_INFO) {
2059 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02002060 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08002061 }
2062 break;
2063 case RSL_MT_EST_IND:
2064 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02002065 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01002066 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02002067 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02002068 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08002069 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2070 rllh->data[0] == RSL_IE_L3_INFO) {
2071 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02002072 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08002073 }
2074 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02002075 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02002076 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01002077 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02002078 rll_indication(msg->lchan, rllh->link_id,
2079 BSC_RLLR_IND_EST_CONF);
2080 break;
Harald Welte59b04682009-06-10 05:40:52 +08002081 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02002082 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02002083 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01002084 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02002085 rll_indication(msg->lchan, rllh->link_id,
2086 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02002087 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002088 break;
2089 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02002090 /* BTS informs us of having received UA from MS,
2091 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02002092 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01002093 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02002094 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002095 break;
2096 case RSL_MT_ERROR_IND:
Neels Hofmeyr6fcad252016-07-26 19:39:43 +02002097 DEBUGPC(DRLL, "ERROR INDICATION\n");
Harald Welte59b04682009-06-10 05:40:52 +08002098 rc = rsl_rx_rll_err_ind(msg);
2099 break;
2100 case RSL_MT_UNIT_DATA_IND:
Neels Hofmeyr6fcad252016-07-26 19:39:43 +02002101 DEBUGPC(DRLL, "UNIT DATA INDICATION\n");
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002102 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
2103 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002104 break;
2105 default:
Neels Hofmeyr6fcad252016-07-26 19:39:43 +02002106 DEBUGPC(DRLL, "UNKNOWN\n");
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002107 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
2108 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002109 }
Harald Welte59b04682009-06-10 05:40:52 +08002110 return rc;
2111}
2112
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002113static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02002114{
Harald Welteb284b472009-12-02 01:58:23 +05302115 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02002116 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05302117 switch (lchan->type) {
2118 case GSM_LCHAN_TCH_F:
2119 return 0x00;
2120 case GSM_LCHAN_TCH_H:
2121 return 0x03;
2122 default:
2123 break;
2124 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02002125 break;
Harald Welte98d79f92009-07-28 18:11:56 +02002126 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05302127 switch (lchan->type) {
2128 case GSM_LCHAN_TCH_F:
2129 return 0x01;
2130 /* there's no half-rate EFR */
2131 default:
2132 break;
2133 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02002134 break;
Harald Welte98d79f92009-07-28 18:11:56 +02002135 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05302136 switch (lchan->type) {
2137 case GSM_LCHAN_TCH_F:
2138 return 0x02;
2139 case GSM_LCHAN_TCH_H:
2140 return 0x05;
2141 default:
2142 break;
2143 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02002144 break;
Harald Welteb284b472009-12-02 01:58:23 +05302145 default:
2146 break;
Harald Welte98d79f92009-07-28 18:11:56 +02002147 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002148 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05302149 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02002150 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02002151}
2152
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002153static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01002154{
2155 switch (lchan->tch_mode) {
2156 case GSM48_CMODE_SPEECH_V1:
2157 switch (lchan->type) {
2158 case GSM_LCHAN_TCH_F:
2159 return RTP_PT_GSM_FULL;
2160 case GSM_LCHAN_TCH_H:
2161 return RTP_PT_GSM_HALF;
2162 default:
2163 break;
2164 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02002165 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01002166 case GSM48_CMODE_SPEECH_EFR:
2167 switch (lchan->type) {
2168 case GSM_LCHAN_TCH_F:
2169 return RTP_PT_GSM_EFR;
2170 /* there's no half-rate EFR */
2171 default:
2172 break;
2173 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02002174 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01002175 case GSM48_CMODE_SPEECH_AMR:
2176 switch (lchan->type) {
2177 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01002178 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02002179 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01002180 default:
2181 break;
2182 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02002183 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01002184 default:
2185 break;
2186 }
2187 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
2188 "tch_mode == 0x%02x\n & lchan_type == %d",
2189 lchan->tch_mode, lchan->type);
2190 return 0;
2191}
2192
Harald Welte59b04682009-06-10 05:40:52 +08002193/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01002194static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
2195{
2196 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002197 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01002198
2199 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02002200 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01002201 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
2202 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
2203 }
2204
2205 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02002206 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01002207 port = ntohs(port);
2208 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
2209 lchan->abis_ip.bound_port = port;
2210 }
2211
2212 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02002213 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Weltebffa4992009-12-19 16:42:06 +01002214 conn_id = ntohs(conn_id);
2215 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
2216 lchan->abis_ip.conn_id = conn_id;
2217 }
2218
2219 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
2220 lchan->abis_ip.rtp_payload2 =
2221 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
2222 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
2223 lchan->abis_ip.rtp_payload2);
2224 }
2225
2226 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
2227 lchan->abis_ip.speech_mode =
2228 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
2229 DEBUGPC(DRSL, "speech_mode=0x%02x ",
2230 lchan->abis_ip.speech_mode);
2231 }
2232
2233 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02002234 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01002235 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
2236 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
2237 }
2238
2239 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02002240 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01002241 port = ntohs(port);
2242 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
2243 lchan->abis_ip.connect_port = port;
2244 }
2245}
2246
Harald Welte9a696d72013-02-03 12:06:58 +01002247/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
2248 * \param[in] lchan Logical Channel for which we issue CRCX
2249 */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002250int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08002251{
2252 struct msgb *msg = rsl_msgb_alloc();
2253 struct abis_rsl_dchan_hdr *dh;
2254
2255 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002256 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08002257 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02002258 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002259
Harald Welte98d79f92009-07-28 18:11:56 +02002260 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01002261 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01002262 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01002263 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01002264 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02002265
Sylvain Munaut1338a552009-12-20 22:06:40 +01002266 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
2267 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
2268 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02002269
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002270 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08002271
2272 return abis_rsl_sendmsg(msg);
2273}
2274
Harald Welte9a696d72013-02-03 12:06:58 +01002275/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
2276 * \param[in] lchan Logical Channel for which we issue MDCX
2277 * \param[in] ip Remote (MGW) IP address for RTP
2278 * \param[in] port Remote (MGW) UDP port number for RTP
2279 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
2280 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002281int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
2282 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08002283{
2284 struct msgb *msg = rsl_msgb_alloc();
2285 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002286 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02002287 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08002288
2289 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002290 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08002291 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02002292 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002293
Harald Weltebffa4992009-12-19 16:42:06 +01002294 /* we need to store these now as MDCX_ACK does not return them :( */
2295 lchan->abis_ip.rtp_payload2 = rtp_payload2;
2296 lchan->abis_ip.connect_port = port;
2297 lchan->abis_ip.connect_ip = ip;
2298
Harald Weltefb4a9e92009-07-29 12:12:18 +02002299 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01002300 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01002301 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02002302
Harald Welte98d79f92009-07-28 18:11:56 +02002303 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01002304 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
2305 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
2306 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
2307 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02002308
Harald Weltebffa4992009-12-19 16:42:06 +01002309 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
2310 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002311 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01002312 *att_ip = ia.s_addr;
2313 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
2314 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01002315 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02002316 if (rtp_payload2)
2317 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002318
2319 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08002320
2321 return abis_rsl_sendmsg(msg);
2322}
2323
Harald Welte9947d9f2009-12-20 16:51:09 +01002324/* tell BTS to connect RTP stream to our local RTP socket */
2325int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
2326{
2327 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
2328 int rc;
2329
2330 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
2331 ntohs(rs->rtp.sin_local.sin_port),
2332 /* FIXME: use RTP payload of bound socket, not BTS*/
2333 lchan->abis_ip.rtp_payload2);
2334
2335 return rc;
2336}
2337
Harald Welte6f40df02010-12-23 12:59:52 +01002338int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02002339{
2340 struct msgb *msg = rsl_msgb_alloc();
2341 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002342 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08002343
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002344 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2345 LOGP(DRSL, LOGL_ERROR,
2346 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2347 gsm_ts_name(ts),
2348 act ? "ACT" : "DEACT",
2349 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2350 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2351 return -EINVAL;
2352 }
2353
2354 if (act){
Neels Hofmeyr31b26302016-07-06 14:39:04 +02002355 /* Callers should heed the GPRS mode. */
2356 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte2b361522010-03-28 14:42:09 +08002357 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002358 ts->flags |= TS_F_PDCH_ACT_PENDING;
2359 } else {
Harald Welte2b361522010-03-28 14:42:09 +08002360 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002361 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2362 }
2363 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welteaed946e2009-10-24 10:29:22 +02002364
2365 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08002366 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02002367 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Neels Hofmeyrb5978112016-07-18 23:43:44 +02002368 dh->chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_PDCH, ts->nr, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02002369
Neels Hofmeyr6b272302016-05-31 17:51:41 +02002370 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08002371 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02002372
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002373 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02002374
2375 return abis_rsl_sendmsg(msg);
2376}
2377
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002378static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002379{
2380 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2381 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05302382 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08002383
2384 /* the BTS has acknowledged a local bind, it now tells us the IP
2385 * address and port number to which it has bound the given logical
2386 * channel */
2387
2388 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2389 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2390 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02002391 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002392 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08002393 return -EINVAL;
2394 }
Harald Welte50517742009-12-20 15:42:44 +01002395
Harald Weltebffa4992009-12-19 16:42:06 +01002396 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01002397
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002398 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002399
2400 return 0;
2401}
2402
Harald Weltebffa4992009-12-19 16:42:06 +01002403static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2404{
2405 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2406 struct tlv_parsed tv;
2407 struct gsm_lchan *lchan = msg->lchan;
2408
2409 /* the BTS has acknowledged a remote connect request and
2410 * it now tells us the IP address and port number to which it has
2411 * connected the given logical channel */
2412
2413 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2414 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002415 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01002416
2417 return 0;
2418}
2419
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002420static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002421{
2422 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2423 struct tlv_parsed tv;
2424
2425 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08002426
Harald Weltef1a168d2009-07-28 17:58:09 +02002427 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01002428 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02002429 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08002430
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002431 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02002432
Harald Welte59b04682009-06-10 05:40:52 +08002433 return 0;
2434}
2435
2436static int abis_rsl_rx_ipacc(struct msgb *msg)
2437{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002438 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08002439 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01002440 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08002441 int rc = 0;
2442
Neels Hofmeyr0781eb02016-08-23 01:22:58 +02002443 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2444 "Abis RSL rx IPACC: ");
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01002445 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002446
2447 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002448 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01002449 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002450 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002451 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002452 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002453 /* somehow the BTS was unable to bind the lchan to its local
2454 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01002455 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002456 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002457 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08002458 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01002459 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01002460 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002461 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002462 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002463 /* somehow the BTS was unable to connect the lchan to a remote
2464 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01002465 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002466 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002467 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01002468 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002469 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002470 break;
2471 default:
Harald Weltede4477a2009-12-24 12:20:20 +01002472 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002473 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002474 break;
2475 }
2476 DEBUGPC(DRSL, "\n");
2477
2478 return rc;
2479}
2480
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002481int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts,
Neels Hofmeyrb7638112016-07-23 20:08:41 +02002482 enum gsm_phys_chan_config to_pchan)
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002483{
2484 int ss;
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002485 int rc = -EIO;
2486
2487 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2488 DEBUGP(DRSL, "%s starting switchover to %s\n",
2489 gsm_ts_and_pchan_name(ts), gsm_pchan_name(to_pchan));
2490
2491 if (ts->dyn.pchan_is != ts->dyn.pchan_want) {
2492 LOGP(DRSL, LOGL_ERROR,
2493 "%s: Attempt to switch dynamic channel to %s,"
2494 " but is already in switchover.\n",
2495 gsm_ts_and_pchan_name(ts),
2496 gsm_pchan_name(to_pchan));
2497 return ts->dyn.pchan_want == to_pchan? 0 : -EAGAIN;
2498 }
2499
2500 if (ts->dyn.pchan_is == to_pchan) {
2501 LOGP(DRSL, LOGL_INFO,
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002502 "%s %s Already is in %s mode, cannot switchover.\n",
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002503 gsm_ts_name(ts), gsm_pchan_name(ts->pchan),
2504 gsm_pchan_name(to_pchan));
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002505 return -EINVAL;
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002506 }
2507
2508 /* Paranoia: let's make sure all is indeed released. */
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002509 for (ss = 0; ss < ts_subslots(ts); ss++) {
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002510 struct gsm_lchan *lc = &ts->lchan[ss];
2511 if (lc->state != LCHAN_S_NONE) {
2512 LOGP(DRSL, LOGL_ERROR,
2513 "%s Attempt to switch dynamic channel to %s,"
2514 " but is not fully released.\n",
2515 gsm_ts_and_pchan_name(ts),
2516 gsm_pchan_name(to_pchan));
2517 return -EAGAIN;
2518 }
2519 }
2520
2521 /* Record that we're busy switching. */
2522 ts->dyn.pchan_want = to_pchan;
2523
2524 /*
2525 * To switch from PDCH, we need to initiate the release from the BSC
2526 * side. dyn_ts_switchover_continue() will be called from
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002527 * rsl_rx_rf_chan_rel_ack(). PDCH is always on lchan[0].
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002528 */
2529 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH) {
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002530 rsl_lchan_set_state(ts->lchan, LCHAN_S_REL_REQ);
2531 rc = rsl_rf_chan_release(ts->lchan, 0, SACCH_NONE);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002532 if (rc) {
2533 LOGP(DRSL, LOGL_ERROR,
2534 "%s RSL RF Chan Release failed\n",
2535 gsm_ts_and_pchan_name(ts));
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002536 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002537 }
2538 return 0;
2539 }
2540
2541 /*
2542 * To switch from TCH/F and TCH/H pchans, this has been called from
2543 * rsl_rx_rf_chan_rel_ack(), i.e. release is complete. Go ahead and
2544 * activate as new type. This will always be PDCH.
2545 */
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002546 return dyn_ts_switchover_continue(ts);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002547}
2548
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002549static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts)
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002550{
2551 int rc;
2552 uint8_t act_type;
2553 uint8_t ho_ref;
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002554 int ss;
2555 struct gsm_lchan *lchan;
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002556
2557 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2558 DEBUGP(DRSL, "%s switchover: release complete,"
2559 " activating new pchan type\n",
2560 gsm_ts_and_pchan_name(ts));
2561
2562 if (ts->dyn.pchan_is == ts->dyn.pchan_want) {
2563 LOGP(DRSL, LOGL_ERROR,
2564 "%s Requested to switchover dynamic channel to the"
2565 " same type it is already in.\n",
2566 gsm_ts_and_pchan_name(ts));
2567 return 0;
2568 }
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002569
2570 for (ss = 0; ss < ts_subslots(ts); ss++) {
2571 lchan = &ts->lchan[ss];
2572 if (lchan->rqd_ref) {
2573 LOGP(DRSL, LOGL_ERROR,
2574 "%s During dyn TS switchover, expecting no"
2575 " Request Reference to be pending. Discarding!\n",
2576 gsm_lchan_name(lchan));
2577 talloc_free(lchan->rqd_ref);
2578 lchan->rqd_ref = NULL;
2579 }
2580 }
2581
2582 /*
2583 * When switching pchan modes, all lchans are unused. So always
2584 * activate whatever wants to be activated on the first lchan. (We
2585 * wouldn't remember to use lchan[1] across e.g. a PDCH deact anyway)
2586 */
2587 lchan = ts->lchan;
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002588
2589 /*
2590 * For TCH/x, the lchan->type has been set in lchan_alloc(), but it may
2591 * have been lost during channel release due to dynamic switchover.
2592 *
2593 * For PDCH, the lchan->type will actually remain NONE.
2594 * TODO: set GSM_LCHAN_PDTCH?
2595 */
2596 switch (ts->dyn.pchan_want) {
2597 case GSM_PCHAN_TCH_F:
2598 lchan->type = GSM_LCHAN_TCH_F;
2599 break;
2600 case GSM_PCHAN_TCH_H:
2601 lchan->type = GSM_LCHAN_TCH_H;
2602 break;
2603 case GSM_PCHAN_PDCH:
2604 lchan->type = GSM_LCHAN_NONE;
2605 break;
2606 default:
2607 LOGP(DRSL, LOGL_ERROR,
2608 "%s Invalid target pchan for dynamic TS\n",
2609 gsm_ts_and_pchan_name(ts));
2610 }
2611
2612 act_type = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2613 ? RSL_ACT_OSMO_PDCH
2614 : lchan->dyn.act_type;
2615 ho_ref = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2616 ? 0
2617 : lchan->dyn.ho_ref;
2618
2619 /* Fetch the rqd_ref back from before switchover started. */
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002620 lchan->rqd_ref = lchan->dyn.rqd_ref;
2621 lchan->rqd_ta = lchan->dyn.rqd_ta;
2622 lchan->dyn.rqd_ref = NULL;
2623 lchan->dyn.rqd_ta = 0;
2624
Neels Hofmeyrb6cf05e2016-08-24 16:57:31 +02002625 /* During switchover, we have received a release ack, which means that
2626 * the act_timer has been stopped. Start the timer again so we mark
2627 * this channel broken if the activation ack comes too late. */
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +02002628 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Neels Hofmeyrb6cf05e2016-08-24 16:57:31 +02002629 osmo_timer_schedule(&lchan->act_timer, 4, 0);
2630
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002631 rc = rsl_chan_activate_lchan(lchan, act_type, ho_ref);
2632 if (rc) {
2633 LOGP(DRSL, LOGL_ERROR,
2634 "%s RSL Chan Activate failed\n",
2635 gsm_ts_and_pchan_name(ts));
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002636 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002637 }
2638 return 0;
2639}
2640
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002641static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc)
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002642{
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002643 ts->dyn.pchan_want = ts->dyn.pchan_is;
2644 LOGP(DRSL, LOGL_ERROR, "%s Error %d during dynamic channel switchover."
2645 " Going back to previous pchan.\n", gsm_ts_and_pchan_name(ts),
2646 rc);
2647 return rc;
2648}
2649
2650static void dyn_ts_switchover_complete(struct gsm_lchan *lchan)
2651{
2652 enum gsm_phys_chan_config pchan_act;
2653 enum gsm_phys_chan_config pchan_was;
2654 struct gsm_bts_trx_ts *ts = lchan->ts;
2655
2656 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2657
2658 pchan_act = pchan_for_lchant(lchan->type);
2659 /*
2660 * Paranoia: do the types match?
2661 * In case of errors: we've received an act ack already, so what to do
2662 * about it? Logging the error should suffice for now.
2663 */
2664 if (pchan_act != ts->dyn.pchan_want)
2665 LOGP(DRSL, LOGL_ERROR,
2666 "%s Requested transition does not match lchan type %s\n",
2667 gsm_ts_and_pchan_name(ts),
Neels Hofmeyr8ceb9de2016-08-24 16:57:31 +02002668 gsm_lchant_name(lchan->type));
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002669
2670 pchan_was = ts->dyn.pchan_is;
2671 ts->dyn.pchan_is = ts->dyn.pchan_want = pchan_act;
2672
Neels Hofmeyrba1eab22016-08-24 14:42:58 +02002673 if (pchan_was != ts->dyn.pchan_is)
2674 LOGP(DRSL, LOGL_INFO, "%s switchover from %s complete.\n",
2675 gsm_ts_and_pchan_name(ts), gsm_pchan_name(pchan_was));
Neels Hofmeyr6c5f2782016-07-23 19:45:15 +02002676}
Harald Welte59b04682009-06-10 05:40:52 +08002677
2678/* Entry-point where L2 RSL from BTS enters */
2679int abis_rsl_rcvmsg(struct msgb *msg)
2680{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002681 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08002682 int rc = 0;
2683
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002684 if (!msg) {
2685 DEBUGP(DRSL, "Empty RSL msg?..\n");
2686 return -1;
2687 }
2688
2689 if (msgb_l2len(msg) < sizeof(*rslh)) {
2690 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02002691 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002692 return -1;
2693 }
2694
2695 rslh = msgb_l2(msg);
2696
Harald Welte59b04682009-06-10 05:40:52 +08002697 switch (rslh->msg_discr & 0xfe) {
2698 case ABIS_RSL_MDISC_RLL:
2699 rc = abis_rsl_rx_rll(msg);
2700 break;
2701 case ABIS_RSL_MDISC_DED_CHAN:
2702 rc = abis_rsl_rx_dchan(msg);
2703 break;
2704 case ABIS_RSL_MDISC_COM_CHAN:
2705 rc = abis_rsl_rx_cchan(msg);
2706 break;
2707 case ABIS_RSL_MDISC_TRX:
2708 rc = abis_rsl_rx_trx(msg);
2709 break;
2710 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002711 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08002712 rslh->msg_discr);
2713 break;
2714 case ABIS_RSL_MDISC_IPACCESS:
2715 rc = abis_rsl_rx_ipacc(msg);
2716 break;
2717 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002718 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2719 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02002720 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08002721 }
2722 msgb_free(msg);
2723 return rc;
2724}
2725
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002726int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Weltebf4ba722014-12-28 15:00:45 +01002727 struct rsl_ie_cb_cmd_type cb_command,
2728 const uint8_t *data, int len)
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002729{
2730 struct abis_rsl_dchan_hdr *dh;
2731 struct msgb *cb_cmd;
2732
2733 cb_cmd = rsl_msgb_alloc();
2734 if (!cb_cmd)
2735 return -1;
2736
Harald Weltebf4ba722014-12-28 15:00:45 +01002737 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002738 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Weltebf4ba722014-12-28 15:00:45 +01002739 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2740 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002741
Harald Weltebf4ba722014-12-28 15:00:45 +01002742 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002743 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2744
Harald Weltebf4ba722014-12-28 15:00:45 +01002745 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002746
2747 return abis_rsl_sendmsg(cb_cmd);
2748}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002749
2750int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2751{
2752 struct abis_rsl_common_hdr *ch;
2753 struct msgb *msg = rsl_msgb_alloc();
2754
2755 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2756 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2757 ch->msg_type = 0x40; /* Nokia SI Begin */
2758
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002759 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002760
2761 return abis_rsl_sendmsg(msg);
2762}
2763
2764int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2765{
2766 struct abis_rsl_common_hdr *ch;
2767 struct msgb *msg = rsl_msgb_alloc();
2768
2769 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2770 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2771 ch->msg_type = 0x41; /* Nokia SI End */
2772
2773 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2774
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002775 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002776
2777 return abis_rsl_sendmsg(msg);
2778}
2779
2780int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2781{
2782 struct abis_rsl_common_hdr *ch;
2783 struct msgb *msg = rsl_msgb_alloc();
2784
2785 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2786 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2787 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2788
2789 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2790 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2791
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002792 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002793
2794 return abis_rsl_sendmsg(msg);
2795}
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01002796
2797/**
2798 * Release all allocated SAPIs starting from @param start and
2799 * release them with the given release mode. Once the release
2800 * confirmation arrives it will be attempted to release the
2801 * the RF channel.
2802 */
2803int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2804 enum rsl_rel_mode release_mode)
2805{
2806 int no_sapi = 1;
2807 int sapi;
2808
2809 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2810 uint8_t link_id;
2811 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2812 continue;
2813
2814 link_id = sapi;
2815 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2816 link_id |= 0x40;
2817 rsl_release_request(lchan, link_id, release_mode);
2818 no_sapi = 0;
2819 }
2820
2821 return no_sapi;
2822}
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002823
2824int rsl_start_t3109(struct gsm_lchan *lchan)
2825{
2826 struct gsm_bts *bts = lchan->ts->trx->bts;
2827
2828 /* Disabled, mostly legacy code */
2829 if (bts->network->T3109 == 0)
2830 return -1;
2831
Pablo Neira Ayuso274b3842017-05-08 20:57:52 +02002832 osmo_timer_setup(&lchan->T3109, t3109_expired, lchan);
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002833 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2834 return 0;
2835}
Holger Hans Peter Freytherc63cb862012-12-25 23:45:14 +01002836
2837/**
2838 * \brief directly RF Channel Release the lchan
2839 *
2840 * When no SAPI was allocated, directly release the logical channel. This
2841 * should only be called from chan_alloc.c on channel release handling. In
2842 * case no SAPI was established the RF Channel can be directly released,
2843 */
2844int rsl_direct_rf_release(struct gsm_lchan *lchan)
2845{
2846 int i;
2847 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2848 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2849 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2850 gsm_lchan_name(lchan), i);
2851 return -1;
2852 }
2853 }
2854
2855 /* Now release it */
2856 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2857}