blob: 20dd2b5ca9bcca2bb065982e53baa492f07199cf [file] [log] [blame]
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte52b1f982008-12-23 20:25:15 +00002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Welte3c9c5f92010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte8470bf22008-12-25 23:28:35 +00006 *
Harald Welte52b1f982008-12-23 20:25:15 +00007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-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 Welte52b1f982008-12-23 20:25:15 +000012 * (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 Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000018 *
Harald Welte9af6ddf2011-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 Welte52b1f982008-12-23 20:25:15 +000021 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
Harald Welte75099262009-02-16 21:12:08 +000027#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000028#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Harald Welte8470bf22008-12-25 23:28:35 +000030#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000036#include <openbsc/debug.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Maxc08ee712016-05-11 12:45:13 +020038#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include <osmocom/gsm/protocol/gsm_08_58.h>
Holger Freyther392209c2009-02-10 00:06:19 +000040#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000041#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010042#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010043#include <openbsc/rtp_proxy.h>
Max11e4e412017-04-20 13:07:58 +020044#include <openbsc/gsm_subscriber.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020045#include <osmocom/abis/e1_input.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010046#include <osmocom/gsm/rsl.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010047#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080048
Harald Welte8470bf22008-12-25 23:28:35 +000049#define RSL_ALLOC_SIZE 1024
50#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000051
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +010052enum sacch_deact {
53 SACCH_NONE,
54 SACCH_DEACTIVATE,
55};
56
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080057static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020058static void error_timeout_cb(void *data);
Neels Hofmeyrb74a2c82016-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 Hofmeyrb91e6002016-07-23 19:45:15 +020061static void dyn_ts_switchover_complete(struct gsm_lchan *lchan);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080062
Holger Hans Peter Freyther08eebd52010-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 Ayusobbc5b992011-05-06 12:12:31 +020069 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010070}
71
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010072static void do_lchan_free(struct gsm_lchan *lchan)
73{
Holger Hans Peter Freytherf0405062014-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 Ayuso51215762017-05-08 20:57:52 +020076 osmo_timer_setup(&lchan->error_timer, error_timeout_cb, lchan);
Holger Hans Peter Freytherf0405062014-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 Freyther93599a22012-12-06 19:09:58 +010080 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020081 }
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010082 lchan_free(lchan);
83}
84
Alexander Couzens8c53c592016-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 Couzens8c53c592016-08-23 06:27:19 +0200114 }
115}
116
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200117static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000118{
119 /* mask off the transparent bit ? */
120 msg_type &= 0xfe;
121
Harald Welte8470bf22008-12-25 23:28:35 +0000122 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +0000123 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +0000124 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +0000125 if (msg_type >= 0x19 && msg_type <= 0x22)
126 return ABIS_RSL_MDISC_TRX;
127 else
128 return ABIS_RSL_MDISC_COM_CHAN;
129 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000130 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +0000131 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 Freytherc42ad8b2011-04-18 17:04:00 +0200137 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000138{
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 Hofmeyr74585722016-07-23 17:38:22 +0200144/* call rsl_lchan_lookup and set the log context */
Neels Hofmeyr2867f882016-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 Welte8470bf22008-12-25 23:28:35 +0000147{
Neels Hofmeyr74585722016-07-23 17:38:22 +0200148 int rc;
149 struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc);
Harald Welte8470bf22008-12-25 23:28:35 +0000150
Neels Hofmeyr74585722016-07-23 17:38:22 +0200151 if (!lchan) {
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200152 LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n",
153 log_name, chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000154 return NULL;
155 }
156
Neels Hofmeyr74585722016-07-23 17:38:22 +0200157 if (rc < 0)
Neels Hofmeyr2867f882016-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 Hofmeyr74585722016-07-23 17:38:22 +0200160
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800161 if (lchan->conn)
Neels Hofmeyr89a8e722017-02-23 18:00:51 +0100162 log_set_context(LOG_CTX_VLR_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000163
164 return lchan;
165}
166
Harald Welte52b1f982008-12-23 20:25:15 +0000167/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200168uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000169{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200170 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000171
172 ret = strtoull(imsi_str, NULL, 10);
173
174 return ret;
175}
176
Harald Welte8470bf22008-12-25 23:28:35 +0000177static struct msgb *rsl_msgb_alloc(void)
178{
Harald Welte966636f2009-06-26 19:39:35 +0200179 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
180 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000181}
182
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200183static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000184{
185 memcpy(out, in, len);
186
Maxb726c2c2017-02-09 19:23:38 +0100187 if (len < GSM_MACBLOCK_LEN)
188 memset(out+len, 0x2b, GSM_MACBLOCK_LEN - len);
Harald Welte362322e2009-02-15 14:36:38 +0000189}
190
Harald Welte08d91a52009-08-30 15:37:11 +0900191/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200192static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-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 Freytherc42ad8b2011-04-18 17:04:00 +0200200static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200201{
Harald Welte7f93cea2009-02-23 00:02:59 +0000202 int i;
203
Harald Welte5b8ed432009-12-24 12:20:20 +0100204 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200205 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200206 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100207 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000208}
209
Harald Weltee8bd9e82011-08-10 23:26:33 +0200210static void lchan_act_tmr_cb(void *data)
211{
212 struct gsm_lchan *lchan = data;
213
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100214 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann513da172011-08-11 04:44:12 +0200215 lchan_free(lchan);
Harald Weltee8bd9e82011-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 Freyther454140e2014-12-28 12:08:28 +0100222 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200223 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200224}
225
226
Harald Welte52b1f982008-12-23 20:25:15 +0000227/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-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 Welte52b1f982008-12-23 20:25:15 +0000230{
231 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000232 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000233
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
Philipp309425e2016-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 Welte52b1f982008-12-23 20:25:15 +0000249
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200250 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000251
252 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000253}
254
Holger Hans Peter Freytherc42ad8b2011-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 Welte52b1f982008-12-23 20:25:15 +0000257{
258 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000259 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000260
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);
Harald Welte702d8702008-12-26 20:25:35 +0000266 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000267
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200268 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000269
270 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000271}
272
Holger Hans Peter Freytherc42ad8b2011-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 Welte7a69cf02011-01-13 23:16:03 +0100275{
276 struct abis_rsl_dchan_hdr *dh;
277 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200278 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-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 Ayuso7abecfc2011-08-17 22:43:54 +0200287 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100288
289 return abis_rsl_sendmsg(msg);
290}
291
Harald Weltefcd24452009-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 Welteeab33352009-06-27 03:09:08 +0200295 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200296 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200297
298 db = abs(db);
299 if (db > 30)
300 return -EINVAL;
301
Harald Welteeab33352009-06-27 03:09:08 +0200302 msg = rsl_msgb_alloc();
303
Harald Weltefcd24452009-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 Ayuso7abecfc2011-08-17 22:43:54 +0200314 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200315
316 return abis_rsl_sendmsg(msg);
317}
318
Harald Weltefcd24452009-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 Welteeab33352009-06-27 03:09:08 +0200322 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200323 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200324 int ctl_lvl;
325
Harald Welte66b6a8d2009-08-09 14:45:18 +0200326 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200327 if (ctl_lvl < 0)
328 return ctl_lvl;
329
Harald Welteeab33352009-06-27 03:09:08 +0200330 msg = rsl_msgb_alloc();
331
Harald Weltefcd24452009-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 Ayuso7abecfc2011-08-17 22:43:54 +0200343 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200344
345 return abis_rsl_sendmsg(msg);
346}
347
Harald Welte9943c5b2009-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 Freythere1145cf2013-03-09 17:50:10 +0100351 memset(cm, 0, sizeof(*cm));
Harald Welte9943c5b2009-07-29 15:41:29 +0200352
353 /* FIXME: what to do with data calls ? */
Maxc08ee712016-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 Welte9943c5b2009-07-29 15:41:29 +0200359
360 /* set TCH Speech/Data */
361 cm->spd_ind = lchan->rsl_cmode;
362
Harald Welte1a79d362009-11-27 08:55:16 +0100363 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
364 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100365 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100366 "but tch_mode != signalling\n");
367
Harald Welte9943c5b2009-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 Hofmeyrbbbcfe52016-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 Welte9943c5b2009-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 Welte9943c5b2009-07-29 15:41:29 +0200401 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200402 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-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 Hofmeyrbbbcfe52016-07-18 23:47:24 +0200417 LOGP(DRSL, LOGL_ERROR,
418 "unsupported lchan->tch_mode %u\n",
419 lchan->tch_mode);
Harald Weltee4227982012-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 Hofmeyrbbbcfe52016-07-18 23:47:24 +0200449 LOGP(DRSL, LOGL_ERROR,
450 "unsupported lchan->csd_mode %u\n",
451 lchan->csd_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200452 return -EINVAL;
453 }
Harald Welteb8e8d0a2016-11-26 15:16:14 +0100454 break;
Harald Welte9943c5b2009-07-29 15:41:29 +0200455 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200456 LOGP(DRSL, LOGL_ERROR,
457 "unsupported lchan->tch_mode %u\n",
458 lchan->tch_mode);
Harald Welte9943c5b2009-07-29 15:41:29 +0200459 return -EINVAL;
460 }
461
462 return 0;
463}
464
Holger Hans Peter Freyther11cb7a92015-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 Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-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 Hofmeyrb91e6002016-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 Weltef7e9a342016-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 Hofmeyrb91e6002016-07-23 19:45:15 +0200517 msg->dst = lchan->ts->trx->rsl_link;
518
519 return abis_rsl_sendmsg(msg);
520}
521
Harald Welte52b1f982008-12-23 20:25:15 +0000522/* Chapter 8.4.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200523int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg723a7512013-10-11 12:55:35 +0200524 uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000525{
526 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200527 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200528 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200529 uint8_t *len;
Andreas Eversberg723a7512013-10-11 12:55:35 +0200530 uint8_t ta;
Harald Welte4b634542008-12-27 01:55:51 +0000531
Harald Welte4b634542008-12-27 01:55:51 +0000532 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200533 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000534
Neels Hofmeyrc6926d02016-07-14 02:51:13 +0200535 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200536 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200537 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200538 /* store activation type and handover reference */
Neels Hofmeyr6e999b72016-07-23 21:00:51 +0200539 lchan->dyn.act_type = act_type;
540 lchan->dyn.ho_ref = ho_ref;
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200541 return rsl_ipacc_pdch_activate(lchan->ts, 0);
542 }
543
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-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 Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-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 Hofmeyrb91e6002016-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 Hofmeyrcf793382016-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 Hofmeyr832afa32016-06-14 13:12:00 +0200614 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
615
Andreas Eversberg723a7512013-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 Freythere38bd6c2010-06-30 11:56:43 +0800622 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200623 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000624
Harald Welteeab33352009-06-27 03:09:08 +0200625 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000626 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
627 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
Neels Hofmeyr7af652c2016-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 Welte4b634542008-12-27 01:55:51 +0000634
635 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000636 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200637 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-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 */
laforge694a5cf2010-06-20 21:38:19 +0200646 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200647 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200648 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-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 Freythere38bd6c2010-06-30 11:56:43 +0800655
656 /* update the calculated size */
657 msg->l3h = len + 1;
658 *len = msgb_l3len(msg);
659
Harald Welte08d91a52009-08-30 15:37:11 +0900660 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200661 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-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 Welte8d77b952009-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 Welted4c9bf32009-02-15 16:56:18 +0000676 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
677 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000678 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200679 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100680
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200681 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000682
Harald Welte4b634542008-12-27 01:55:51 +0000683 return abis_rsl_sendmsg(msg);
684}
685
Harald Welte470abb72009-07-29 11:38:15 +0200686/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000687int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
688{
689 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200690 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200691 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000692
Harald Weltef6093a42011-06-25 10:02:33 +0200693 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000694 struct rsl_ie_chan_mode cm;
695
Harald Welte9943c5b2009-07-29 15:41:29 +0200696 rc = channel_mode_from_lchan(&cm, lchan);
697 if (rc < 0)
698 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000699
Harald Welteeab33352009-06-27 03:09:08 +0200700 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000701 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 Freytherc42ad8b2011-04-18 17:04:00 +0200706 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900707
708 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200709 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-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 Freyther11cb7a92015-08-20 19:32:46 +0200715 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100716
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200717 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-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 Weltef6093a42011-06-25 10:02:33 +0200727 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200728 uint8_t encr_info[MAX_A5_KEY_LEN+2];
729 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-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 Welteda783762009-02-18 03:29:53 +0000748
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200749 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000750
751 return abis_rsl_sendmsg(msg);
752}
753
Harald Welte115d1032009-08-10 11:43:22 +0200754/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-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 Weltef6093a42011-06-25 10:02:33 +0200762 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200763
764 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200765 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200766
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100767 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200768
769 return abis_rsl_sendmsg(msg);
770}
771
Neels Hofmeyr2ae305d2016-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 Hofmeyrbaa6c552016-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 Hofmeyr2ae305d2016-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 Freyther4b4dd102010-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 Weltea9e420e2012-11-13 04:26:22 +0100816 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800817 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200818
Neels Hofmeyr9ddd8e62016-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 Hofmeyr82c8f752016-06-21 20:55:14 +0200822 rsl_ipacc_pdch_activate(lchan->ts, 1);
Neels Hofmeyrcd150a82016-08-24 14:45:44 +0200823
824 if (dyn_ts_should_switch_to_pdch(lchan->ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200825 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800826}
827
Harald Weltefd355a32011-03-04 13:41:31 +0100828static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
829
Harald Welte115d1032009-08-10 11:43:22 +0200830/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100831static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
832 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000833{
834 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800835 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100836 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000837
Holger Hans Peter Freytherb3489392011-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 Freyther4b4dd102010-05-31 21:38:24 +0800841 if (lchan->state == LCHAN_S_REL_ERR) {
Neels Hofmeyrd5d39ae2016-08-24 17:02:19 +0200842 LOGP(DRSL, LOGL_NOTICE, "%s is in error state, not sending release.\n",
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800843 gsm_lchan_name(lchan));
844 return -1;
845 }
846
847 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000848 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
849 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200850 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000851
Harald Welte8470bf22008-12-25 23:28:35 +0000852 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200853 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000854
Neels Hofmeyrb3d87062016-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 Freyther4b4dd102010-05-31 21:38:24 +0800860
861 if (error) {
Holger Hans Peter Freyther9d50a272011-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 Freytherb3489392011-12-28 16:21:05 +0100881 if (deact_sacch == SACCH_DEACTIVATE)
882 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-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 Freyther44752d92010-06-08 11:53:33 +0800888 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800889 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000890
Harald Weltee8bd9e82011-08-10 23:26:33 +0200891 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +0200892 osmo_timer_setup(&lchan->act_timer, lchan_deact_tmr_cb, lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200893 osmo_timer_schedule(&lchan->act_timer, 4, 0);
894
Harald Weltefd355a32011-03-04 13:41:31 +0100895 rc = abis_rsl_sendmsg(msg);
896
Harald Welte115d1032009-08-10 11:43:22 +0200897 /* BTS will respond by RF CHAN REL ACK */
Harald Weltefd355a32011-03-04 13:41:31 +0100898 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000899}
900
Holger Hans Peter Freyther0e4e73a2014-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 Hofmeyrec16c162016-10-17 01:03:53 +0200906 enum sacch_deact sacch_deact;
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200907 if (lchan->state != LCHAN_S_ACTIVE)
908 return 0;
Neels Hofmeyrec16c162016-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 Freyther0e4e73a2014-04-19 17:38:33 +0200923}
924
Harald Welte64bb7542011-01-14 14:16:16 +0100925static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
926{
Neels Hofmeyr40074682016-07-23 20:01:49 +0200927 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte64bb7542011-01-14 14:16:16 +0100928
929 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
930
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100931 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200932 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100933 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200934
Holger Hans Peter Freyther6f6cbf72015-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 Freyther21776242013-05-01 18:44:04 +0200942 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyr40074682016-07-23 20:01:49 +0200943 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f6cbf72015-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 Hofmeyrd35fc442016-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 Freyther21776242013-05-01 18:44:04 +0200952 return 0;
953 }
954
Harald Welte64bb7542011-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 Eversberg9df268e2013-10-11 13:32:30 +0200959
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200960 do_lchan_free(lchan);
961
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200962 /*
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +0200980 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200981
982 /* (b) */
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200983 if (dyn_ts_should_switch_to_pdch(ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200984 return dyn_ts_switchover_start(ts, GSM_PCHAN_PDCH);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200985 }
986
987 /*
Neels Hofmeyr3f221222016-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 Hofmeyrc6926d02016-07-14 02:51:13 +0200994 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +0200995 *
996 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200997 */
998 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
999 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyr40074682016-07-23 20:01:49 +02001000 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02001001 return 0;
Neels Hofmeyr40074682016-07-23 20:01:49 +02001002 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr82c8f752016-06-21 20:55:14 +02001003 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyr40074682016-07-23 20:01:49 +02001004 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte64bb7542011-01-14 14:16:16 +01001005 return 0;
1006}
1007
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001008int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
Harald Weltebaaf3e22016-11-17 20:54:04 +01001009 uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs)
Harald Welte52b1f982008-12-23 20:25:15 +00001010{
1011 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +00001012 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001013
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);
Harald Welte255539c2008-12-28 02:26:27 +00001019 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +00001020 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
1021
Harald Weltebaaf3e22016-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 Ayuso7abecfc2011-08-17 22:43:54 +02001027 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001028
1029 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001030}
1031
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001032int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +00001033{
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
Harald Welte702d8702008-12-26 20:25:35 +00001049/* Chapter 8.5.6 */
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001050struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +00001051{
Harald Welte8470bf22008-12-25 23:28:35 +00001052 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001053 struct abis_rsl_dchan_hdr *dh;
Maxb726c2c2017-02-09 19:23:38 +01001054 uint8_t buf[GSM_MACBLOCK_LEN];
Harald Welte52b1f982008-12-23 20:25:15 +00001055
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
Harald Welte362322e2009-02-15 14:36:38 +00001060 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);
Maxb726c2c2017-02-09 19:23:38 +01001067 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, GSM_MACBLOCK_LEN,
1068 buf);
Harald Welte362322e2009-02-15 14:36:38 +00001069 break;
1070 }
Harald Welte52b1f982008-12-23 20:25:15 +00001071
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001072 msg->dst = bts->c0->rsl_link;
Alexander Couzens16dcf2a2016-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 Welte8470bf22008-12-25 23:28:35 +00001096
1097 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001098}
1099
Harald Welte67fa91b2009-08-10 09:51:40 +02001100/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +02001101int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-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 Welte3c456d02009-08-10 11:26:14 +02001108 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001109 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001110 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +02001111
Harald Welte5b8ed432009-12-24 12:20:20 +01001112 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001113 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +02001114
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001115 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +02001116
Harald Welte67fa91b2009-08-10 09:51:40 +02001117 return abis_rsl_sendmsg(msg);
1118}
1119
1120
Harald Welte8470bf22008-12-25 23:28:35 +00001121/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +00001122/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001123int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +00001124{
Harald Welte8470bf22008-12-25 23:28:35 +00001125 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001126 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +00001127 return -EINVAL;
1128 }
Harald Welte52b1f982008-12-23 20:25:15 +00001129
Harald Weltef6093a42011-06-25 10:02:33 +02001130 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001131 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +00001132
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001133 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001134
1135 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001136}
1137
Harald Welteedcc5272009-08-09 13:47:35 +02001138/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
1139/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001140int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +02001141{
Harald Welte3c9c5f92010-03-04 10:33:10 +01001142 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +02001143
Harald Weltef6093a42011-06-25 10:02:33 +02001144 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001145 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001146 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +02001147
Harald Weltefda74ee2012-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 Welteedcc5272009-08-09 13:47:35 +02001151 return abis_rsl_sendmsg(msg);
1152}
1153
Andreas Eversberg7d8fa342013-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 Welted2dc1de2009-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 Freyther5ca825e2012-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 Welted2dc1de2009-08-08 13:15:07 +02001177{
Harald Welted2dc1de2009-08-08 13:15:07 +02001178
Harald Welte3c9c5f92010-03-04 10:33:10 +01001179 struct msgb *msg;
1180
Harald Weltef6093a42011-06-25 10:02:33 +02001181 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001182 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +08001183 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001184 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +02001185
Harald Welte8e93b792009-12-29 10:44:17 +01001186 /* FIXME: start some timer in case we don't receive a REL ACK ? */
1187
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001188 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +02001189
Harald Weltefda74ee2012-04-26 19:42:19 +02001190 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001191 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +02001192
Andreas Eversberg7d8fa342013-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 Ayuso51215762017-05-08 20:57:52 +02001201 osmo_timer_setup(&lchan->rel_work, lchan_rel_work_cb, lchan);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001202 osmo_timer_schedule(&lchan->rel_work, 0, 0);
1203 }
1204
1205 return 0;
Harald Welted2dc1de2009-08-08 13:15:07 +02001206}
1207
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001208int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
1209{
Neels Hofmeyr423269f2016-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 Freyther454140e2014-12-28 12:08:28 +01001213 lchan->broken_reason = reason;
1214 return 0;
1215}
1216
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001217int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
1218{
Neels Hofmeyrb0cc6422016-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 Freyther74419492010-04-10 00:12:31 +02001222 lchan->state = state;
1223 return 0;
1224}
1225
Harald Welte702d8702008-12-26 20:25:35 +00001226/* 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 Hofmeyrf29dd5f2016-07-14 16:16:33 +02001230 struct gsm_lchan *lchan = msg->lchan;
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001231 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte702d8702008-12-26 20:25:35 +00001232
1233 /* BTS has confirmed channel activation, we now need
1234 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +00001235 if (rslh->ie_chan != RSL_IE_CHAN_NR)
1236 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +01001237
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001238 osmo_timer_del(&lchan->act_timer);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001239
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001240 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freyther46edbc42016-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 Freyther21776242013-05-01 18:44:04 +02001267 return 0;
1268 }
1269
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001270 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +01001271 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrf29dd5f2016-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 Welteb8bfc562009-12-21 13:27:11 +01001275
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001276 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001277 dyn_ts_switchover_complete(lchan);
1278
Neels Hofmeyrf29dd5f2016-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 Freyther5ba05f42010-06-22 12:11:59 +08001284 }
1285
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001286 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001287
Harald Welte4b634542008-12-27 01:55:51 +00001288 return 0;
1289}
Harald Welte702d8702008-12-26 20:25:35 +00001290
Harald Welte4b634542008-12-27 01:55:51 +00001291/* Chapter 8.4.3: Channel Activate NACK */
1292static int rsl_rx_chan_act_nack(struct msgb *msg)
1293{
Harald Welte6dab0552009-05-01 17:21:37 +00001294 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1295 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001296
Harald Weltee8bd9e82011-08-10 23:26:33 +02001297 osmo_timer_del(&msg->lchan->act_timer);
1298
Holger Hans Peter Freyther21776242013-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 Willmann6fc6a122011-08-11 04:54:23 +02001306 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001307 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001308
Harald Welte6dab0552009-05-01 17:21:37 +00001309 /* BTS has rejected channel activation ?!? */
1310 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +00001311 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +00001312
1313 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001314 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001315 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001316 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +02001317 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +01001318 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther454140e2014-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 Freytherb3489392011-12-28 16:21:05 +01001322 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +02001323
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001324 } else {
1325 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1326 }
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001327
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001328 LOGPC(DRSL, LOGL_ERROR, "\n");
1329
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001330 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +00001331 return 0;
Harald Welte702d8702008-12-26 20:25:35 +00001332}
1333
Harald Welte7f93cea2009-02-23 00:02:59 +00001334/* 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 Freyther1e93b792014-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 Welte7f93cea2009-02-23 00:02:59 +00001344 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1345
Harald Welte8830e072009-07-28 17:58:09 +02001346 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001347 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001348 TLVP_LEN(&tp, RSL_IE_CAUSE));
1349
Harald Welte (local)fc057502009-12-26 22:33:09 +01001350 LOGPC(DRSL, LOGL_NOTICE, "\n");
Alexander Couzensb847a212016-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 Freyther0e4e73a2014-04-19 17:38:33 +02001352 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +00001353}
1354
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001355static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1356 const char *prefix)
1357{
Harald Welte6739dfb2009-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 Welte3c7dc6e2009-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 Welte0c1bd612012-07-02 17:12:08 +02001365static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001366{
Harald Welte6739dfb2009-12-16 16:52:07 +01001367 int i;
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001368 const char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +01001369
Max11e4e412017-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 Welte0c1bd612012-07-02 17:12:08 +02001378
1379 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-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);
Max11e4e412017-04-20 13:07:58 +02001386
Harald Welte3c7dc6e2009-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 Welte6739dfb2009-12-16 16:52:07 +01001391 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-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 Welte479015b2009-12-19 18:33:05 +01001407 if (mr->num_cell == 7)
1408 return;
Harald Welte6739dfb2009-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 Welte303e5e02009-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 Welte6739dfb2009-12-16 16:52:07 +01001413 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001414}
1415
Harald Welte440fed02009-05-01 18:43:47 +00001416static 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 Welted12b0fd2009-12-15 21:36:05 +01001420 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001421 uint8_t len;
1422 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001423 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001424
Harald Welteb8bfc562009-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 Welte8e93b792009-12-29 10:44:17 +01001427 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001428 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001429 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001430 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001431 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001432
Harald Welted12b0fd2009-12-15 21:36:05 +01001433 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001434 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001435
Harald Welte440fed02009-05-01 18:43:47 +00001436 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1437
Harald Welte3c7dc6e2009-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 Welted12b0fd2009-12-15 21:36:05 +01001444 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-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 Welted12b0fd2009-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 Welte440fed02009-05-01 18:43:47 +00001455 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001456
Harald Welted12b0fd2009-12-15 21:36:05 +01001457 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001458
1459 /* Optional Parts */
Max11e4e412017-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 Welte3c7dc6e2009-11-29 19:07:28 +01001465
Harald Weltefe9af262009-06-20 18:44:35 +02001466 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001467 struct e1inp_sign_link *sign_link = msg->dst;
1468
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001469 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001470 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001471 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001472 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001473 mr->flags |= MEAS_REP_F_FPC;
1474 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-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 Eversberg2957de92011-12-16 17:45:37 +01001478 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001479 }
Harald Weltef7c43522009-06-09 20:24:21 +00001480 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001481 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001482 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001483 if (rc < 0)
1484 return rc;
1485 }
1486
Harald Welte0c1bd612012-07-02 17:12:08 +02001487 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001488
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001489 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001490
Harald Welte75d34a82009-05-23 06:11:13 +00001491 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001492}
1493
Harald Welted011e8b2009-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)19ef62a2009-12-27 18:16:36 +01001500 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-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 Freyther08eebd52010-12-27 13:28:20 +01001510 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001511
1512 return 0;
1513}
1514
Neels Hofmeyr285df2e2016-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 Hofmeyr285df2e2016-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 Hofmeyrdd49bee2016-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 Hofmeyr285df2e2016-06-13 12:28:21 +02001530 gsm_pchan_name(ts->pchan),
1531 pdch_act? "ACT" : "DEACT");
1532 return false;
1533 }
1534
Neels Hofmeyr832afa32016-06-14 13:12:00 +02001535 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyrdd49bee2016-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 Hofmeyr285df2e2016-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 Eversberg9df268e2013-10-11 13:32:30 +02001547static int rsl_rx_pdch_act_ack(struct msgb *msg)
1548{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001549 if (!lchan_may_change_pdch(msg->lchan, true))
1550 return -EINVAL;
1551
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001552 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001553 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001554
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001555 return 0;
1556}
1557
1558static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1559{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001560 if (!lchan_may_change_pdch(msg->lchan, false))
1561 return -EINVAL;
1562
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001563 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001564 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001565
Neels Hofmeyr6e999b72016-07-23 21:00:51 +02001566 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn.act_type,
1567 msg->lchan->dyn.ho_ref);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001568
1569 return 0;
1570}
1571
Harald Welte52b1f982008-12-23 20:25:15 +00001572static int abis_rsl_rx_dchan(struct msgb *msg)
1573{
Harald Welte8470bf22008-12-25 23:28:35 +00001574 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1575 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001576 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001577 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001578
Neels Hofmeyr2867f882016-08-23 01:22:58 +02001579 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1580 "Abis RSL rx DCHAN: ");
Neels Hofmeyra6ba6a32016-10-10 03:24:05 +02001581 if (!msg->lchan)
1582 return -1;
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001583 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001584
Harald Welte8470bf22008-12-25 23:28:35 +00001585 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001586 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001587 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001588 rc = rsl_rx_chan_act_ack(msg);
Alexander Couzens8c53c592016-08-23 06:27:19 +02001589 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001590 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001591 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001592 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001593 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001594 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001595 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001596 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001597 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001598 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001599 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001600 case RSL_MT_HANDO_DET:
1601 rc = rsl_rx_hando_det(msg);
1602 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001603 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001604 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001605 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001606 case RSL_MT_MODE_MODIFY_ACK:
Alexander Couzens8c53c592016-08-23 06:27:19 +02001607 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001608 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001609 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001610 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001611 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001612 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001613 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02001614 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001615 rc = rsl_rx_pdch_act_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001616 break;
1617 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001618 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001619 break;
1620 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001621 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001622 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001623 break;
1624 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001625 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001626 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001627 case RSL_MT_PHY_CONTEXT_CONF:
1628 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001629 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 Welte5b8ed432009-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 Welte52b1f982008-12-23 20:25:15 +00001637 break;
1638 default:
Harald Welte5b8ed432009-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 Welte52b1f982008-12-23 20:25:15 +00001641 return -EINVAL;
1642 }
Harald Weltef325eb42009-02-19 17:07:39 +00001643
Harald Welte8470bf22008-12-25 23:28:35 +00001644 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001645}
1646
Harald Welte702d8702008-12-26 20:25:35 +00001647static int rsl_rx_error_rep(struct msgb *msg)
1648{
1649 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001650 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001651 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001652
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001653 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-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 Welte5b8ed432009-12-24 12:20:20 +01001658 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001659 TLVP_LEN(&tp, RSL_IE_CAUSE));
1660
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001661 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001662
1663 return 0;
1664}
1665
Harald Welte52b1f982008-12-23 20:25:15 +00001666static int abis_rsl_rx_trx(struct msgb *msg)
1667{
Harald Welte702d8702008-12-26 20:25:35 +00001668 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001669 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001670 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001671
1672 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001673 case RSL_MT_ERROR_REPORT:
1674 rc = rsl_rx_error_rep(msg);
1675 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001676 case RSL_MT_RF_RES_IND:
1677 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001678 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001679 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001680 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001681 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001682 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001683 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001684 break;
Dieter Spaar16646022011-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 Welte52b1f982008-12-23 20:25:15 +00001691 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001692 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001693 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001694 return -EINVAL;
1695 }
Harald Welte8470bf22008-12-25 23:28:35 +00001696 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001697}
1698
Harald Welteb7e81162009-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;
Max8dc8f232017-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 Freytherb3489392011-12-28 16:21:05 +01001706 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001707}
1708
Holger Hans Peter Freytherf30c0dc2010-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;
Max8dc8f232017-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 Freytherb3489392011-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 Freytherf30c0dc2010-05-31 21:33:15 +08001727}
1728
Harald Welte2862dca2010-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 Eversberg75e13a42013-02-07 11:51:16 +01001741 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Welte2862dca2010-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 Eversberg75e13a42013-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 Welte2862dca2010-12-23 14:39:29 +01001769}
1770
Harald Welte8470bf22008-12-25 23:28:35 +00001771/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001772static int rsl_rx_chan_rqd(struct msgb *msg)
1773{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001774 struct e1inp_sign_link *sign_link = msg->dst;
1775 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001776 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1777 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001778 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001779 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001780 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001781 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001782 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001783
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001784 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001785 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001786
Harald Welte8470bf22008-12-25 23:28:35 +00001787 /* 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 Freyther78891072010-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 Welte2cbe0922008-12-29 04:09:31 +00001802
Alexander Couzensb847a212016-08-02 11:34:11 +02001803 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL]);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001804
Holger Hans Peter Freyther457c2a82010-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 Welte8470bf22008-12-25 23:28:35 +00001811 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001812 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001813 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001814 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001815 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Alexander Couzensb847a212016-08-02 11:34:11 +02001816 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL]);
Harald Welte2862dca2010-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 Welte1dcc2602012-11-13 04:46:03 +01001820 return 0;
Harald Welte8470bf22008-12-25 23:28:35 +00001821 }
1822
Neels Hofmeyrb91e6002016-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 Welte8e93b792009-12-29 10:44:17 +01001832 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001833 "in state %s\n", gsm_lchan_name(lchan),
1834 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001835
Holger Hans Peter Freyther5ba05f42010-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 Welte8470bf22008-12-25 23:28:35 +00001847 arfcn = lchan->ts->trx->arfcn;
1848 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001849
Harald Welte08d91a52009-08-30 15:37:11 +09001850 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001851 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001852 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001853 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001854 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001855
Harald Weltee8bd9e82011-08-10 23:26:33 +02001856 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001857 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001858 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1859
Andreas Eversberg2957de92011-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 Hofmeyr81516482016-07-15 01:26:03 +02001865 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001866
Holger Hans Peter Freyther5ba05f42010-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 Freytherc42ad8b2011-04-18 17:04:00 +02001873 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001874 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1875
Harald Welte52b1f982008-12-23 20:25:15 +00001876 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001877 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001878 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-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 Weltea39b0f22010-06-14 22:26:10 +02001883
Harald Welte8470bf22008-12-25 23:28:35 +00001884 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-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 Weltea39b0f22010-06-14 22:26:10 +02001887 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001888 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001889 } else {
laforge09108bf2010-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 Weltea39b0f22010-06-14 22:26:10 +02001892 }
Harald Weltea1d39a22010-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 Welte52b1f982008-12-23 20:25:15 +00001895
Harald Welteb7e81162009-08-10 00:26:10 +02001896 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001897 osmo_timer_setup(&lchan->T3101, t3101_expired, lchan);
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001898 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001899
Harald Welte52b1f982008-12-23 20:25:15 +00001900 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001901 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001902}
1903
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001904/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001905static int rsl_rx_ccch_load(struct msgb *msg)
1906{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001907 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001908 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-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 Welteea280442009-02-02 22:29:56 +00001915
1916 switch (rslh->data[0]) {
1917 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-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 Welte38e9c822010-04-19 10:24:07 +02001920 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001921 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001922 }
Holger Hans Peter Freyther54fa2c72012-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 Welteea280442009-02-02 22:29:56 +00001925 break;
1926 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001927 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-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);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001932 }
Harald Welteea280442009-02-02 22:29:56 +00001933 break;
1934 default:
1935 break;
1936 }
1937
1938 return 0;
1939}
1940
Harald Welte52b1f982008-12-23 20:25:15 +00001941static int abis_rsl_rx_cchan(struct msgb *msg)
1942{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001943 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001944 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001945 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001946
Neels Hofmeyr2867f882016-08-23 01:22:58 +02001947 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1948 "Abis RSL rx CCHAN: ");
Harald Welte8470bf22008-12-25 23:28:35 +00001949
1950 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001951 case RSL_MT_CHAN_RQD:
1952 /* MS has requested a channel on the RACH */
1953 rc = rsl_rx_chan_rqd(msg);
1954 break;
Harald Welteea280442009-02-02 22:29:56 +00001955 case RSL_MT_CCCH_LOAD_IND:
1956 /* current load on the CCCH */
1957 rc = rsl_rx_ccch_load(msg);
1958 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001959 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 Welteb1d4c8e2009-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 Welte52b1f982008-12-23 20:25:15 +00001965 break;
1966 default:
Harald Welteb1d4c8e2009-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 Welte52b1f982008-12-23 20:25:15 +00001969 return -EINVAL;
1970 }
Harald Welte8470bf22008-12-25 23:28:35 +00001971
1972 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001973}
1974
Harald Welte4b634542008-12-27 01:55:51 +00001975static int rsl_rx_rll_err_ind(struct msgb *msg)
1976{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001977 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001978 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001979 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00001980
Holger Hans Peter Freyther164ee302013-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 Freyther1e93b792014-04-19 16:45:36 +02001990 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001991 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02001992 rsl_rlm_cause_name(rlm_cause),
1993 gsm_lchans_name(msg->lchan->state));
1994
Harald Welteedcc5272009-08-09 13:47:35 +02001995 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001996
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001997 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Alexander Couzensb847a212016-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 Freyther0e4e73a2014-04-19 17:38:33 +02001999 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02002000 }
Harald Welte81543bc2009-07-04 09:40:05 +02002001
Harald Welte4b634542008-12-27 01:55:51 +00002002 return 0;
2003}
Harald Weltef325eb42009-02-19 17:07:39 +00002004
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002005static void rsl_handle_release(struct gsm_lchan *lchan)
2006{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002007 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002008 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002009
Holger Hans Peter Freyther9d50a272011-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 Freytherd7fd3062010-04-08 22:47:44 +02002015 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-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 Welte3a3c2772010-12-24 12:51:07 +01002021 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002022 gsm_lchan_name(lchan), sapi);
2023 return;
2024 }
2025
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002026
Holger Hans Peter Freytherb3489392011-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 Ayuso51215762017-05-08 20:57:52 +02002029 osmo_timer_setup(&lchan->T3111, t3111_expired, lchan);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002030 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002031 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002032}
2033
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002034/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00002035 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 Ayuso7abecfc2011-08-17 22:43:54 +02002042 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00002043 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00002044 int rc = 0;
2045 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002046 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00002047
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002048 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2049 "Abis RSL rx RLL: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002050 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01002051 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00002052
2053 switch (rllh->c.msg_type) {
2054 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002055 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002056 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002057 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)daef6062009-08-14 11:41:12 +02002060 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002061 }
Harald Welte52b1f982008-12-23 20:25:15 +00002062 break;
2063 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002064 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02002065 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002066 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002067 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002068 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002069 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)daef6062009-08-14 11:41:12 +02002072 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002073 }
Harald Welte52b1f982008-12-23 20:25:15 +00002074 break;
Harald Welteedcc5272009-08-09 13:47:35 +02002075 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02002076 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002077 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02002078 rll_indication(msg->lchan, rllh->link_id,
2079 BSC_RLLR_IND_EST_CONF);
2080 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002081 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02002082 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02002083 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002084 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02002085 rll_indication(msg->lchan, rllh->link_id,
2086 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002087 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00002088 break;
2089 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-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 Welte602f2b82009-08-04 02:50:21 +02002092 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002093 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002094 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00002095 break;
2096 case RSL_MT_ERROR_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002097 DEBUGPC(DRLL, "ERROR INDICATION\n");
Harald Welte4b634542008-12-27 01:55:51 +00002098 rc = rsl_rx_rll_err_ind(msg);
2099 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002100 case RSL_MT_UNIT_DATA_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002101 DEBUGPC(DRLL, "UNIT DATA INDICATION\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002102 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
2103 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002104 break;
2105 default:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002106 DEBUGPC(DRLL, "UNKNOWN\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002107 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
2108 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002109 }
Harald Welte8470bf22008-12-25 23:28:35 +00002110 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002111}
2112
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002113static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02002114{
Harald Welte0603c9d2009-12-02 01:58:23 +05302115 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02002116 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-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 Freyther47665242014-04-04 12:14:55 +02002125 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002126 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-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 Freyther47665242014-04-04 12:14:55 +02002134 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002135 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-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 Freyther47665242014-04-04 12:14:55 +02002144 break;
Harald Welte0603c9d2009-12-02 01:58:23 +05302145 default:
2146 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002147 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002148 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05302149 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002150 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02002151}
2152
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002153static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-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 Freyther47665242014-04-04 12:14:55 +02002165 break;
Sylvain Munautb54dda42009-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 Freyther47665242014-04-04 12:14:55 +02002174 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002175 case GSM48_CMODE_SPEECH_AMR:
2176 switch (lchan->type) {
2177 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01002178 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02002179 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002180 default:
2181 break;
2182 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002183 break;
Sylvain Munautb54dda42009-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 Welte75099262009-02-16 21:12:08 +00002193/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-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 Freytherc42ad8b2011-04-18 17:04:00 +02002197 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01002198
2199 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002200 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Welte5e3d91b2009-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 Willmann8a485f02014-06-27 17:05:47 +02002206 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Welte5e3d91b2009-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 Willmann8a485f02014-06-27 17:05:47 +02002213 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Welte5e3d91b2009-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 Willmann8a485f02014-06-27 17:05:47 +02002234 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Welte5e3d91b2009-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 Willmann8a485f02014-06-27 17:05:47 +02002240 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Welte5e3d91b2009-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 Welte647db842013-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 Freyther231163d2009-11-18 21:06:12 +01002250int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00002251{
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 Freyther231163d2009-11-18 21:06:12 +01002256 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00002257 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002258 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002259
Harald Weltef4e79f22009-07-28 18:11:56 +02002260 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002261 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002262 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002263 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002264 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002265
Sylvain Munautb54dda42009-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 Weltef4e79f22009-07-28 18:11:56 +02002269
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002270 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002271
2272 return abis_rsl_sendmsg(msg);
2273}
2274
Harald Welte647db842013-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 Freytherc42ad8b2011-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 Welte75099262009-02-16 21:12:08 +00002283{
2284 struct msgb *msg = rsl_msgb_alloc();
2285 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002286 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02002287 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00002288
2289 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002290 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00002291 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002292 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002293
Harald Welte5e3d91b2009-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 Welte58ca5b72009-07-29 12:12:18 +02002299 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002300 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002301 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02002302
Harald Weltef4e79f22009-07-28 18:11:56 +02002303 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-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 Weltef4e79f22009-07-28 18:11:56 +02002308
Harald Welte5e3d91b2009-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 Freytherc42ad8b2011-04-18 17:04:00 +02002311 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-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 Munautb54dda42009-12-20 22:06:40 +01002315 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002316 if (rtp_payload2)
2317 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002318
2319 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002320
2321 return abis_rsl_sendmsg(msg);
2322}
2323
Harald Weltea72273e2009-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 Welte53cd7ac2010-12-23 12:59:52 +01002338int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02002339{
2340 struct msgb *msg = rsl_msgb_alloc();
2341 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002342 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08002343
Neels Hofmeyr32019882016-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 Hofmeyr9ddd8e62016-07-06 14:39:04 +02002355 /* Callers should heed the GPRS mode. */
2356 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte4563eab2010-03-28 14:42:09 +08002357 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002358 ts->flags |= TS_F_PDCH_ACT_PENDING;
2359 } else {
Harald Welte4563eab2010-03-28 14:42:09 +08002360 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002361 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2362 }
2363 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welte9c880c92009-10-24 10:29:22 +02002364
2365 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08002366 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02002367 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Neels Hofmeyrd3841102016-07-18 23:43:44 +02002368 dh->chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_PDCH, ts->nr, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02002369
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02002370 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08002371 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02002372
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002373 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02002374
2375 return abis_rsl_sendmsg(msg);
2376}
2377
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002378static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002379{
2380 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2381 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05302382 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00002383
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 Welte86c162d2009-07-12 09:45:05 +02002391 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002392 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00002393 return -EINVAL;
2394 }
Harald Welte17f5bf62009-12-20 15:42:44 +01002395
Harald Welte5e3d91b2009-12-19 16:42:06 +01002396 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01002397
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002398 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00002399
Harald Welte75099262009-02-16 21:12:08 +00002400 return 0;
2401}
2402
Harald Welte5e3d91b2009-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 Ayusobbc5b992011-05-06 12:12:31 +02002415 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002416
2417 return 0;
2418}
2419
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002420static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002421{
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 Welte75099262009-02-16 21:12:08 +00002426
Harald Welte8830e072009-07-28 17:58:09 +02002427 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01002428 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02002429 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00002430
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002431 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02002432
Harald Welte75099262009-02-16 21:12:08 +00002433 return 0;
2434}
2435
2436static int abis_rsl_rx_ipacc(struct msgb *msg)
2437{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002438 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00002439 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01002440 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00002441 int rc = 0;
2442
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002443 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2444 "Abis RSL rx IPACC: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002445 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00002446
2447 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002448 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01002449 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002450 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002451 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002452 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002453 /* somehow the BTS was unable to bind the lchan to its local
2454 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01002455 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002456 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002457 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00002458 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01002459 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002460 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002461 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002462 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002463 /* somehow the BTS was unable to connect the lchan to a remote
2464 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01002465 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002466 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002467 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01002468 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002469 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00002470 break;
2471 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01002472 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002473 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00002474 break;
2475 }
Harald Welte6dab0552009-05-01 17:21:37 +00002476 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00002477
2478 return rc;
2479}
2480
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002481int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts,
Neels Hofmeyrd3b7fa82016-07-23 20:08:41 +02002482 enum gsm_phys_chan_config to_pchan)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002483{
2484 int ss;
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +02002502 "%s %s Already is in %s mode, cannot switchover.\n",
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002503 gsm_ts_name(ts), gsm_pchan_name(ts->pchan),
2504 gsm_pchan_name(to_pchan));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002505 return -EINVAL;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002506 }
2507
2508 /* Paranoia: let's make sure all is indeed released. */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002509 for (ss = 0; ss < ts_subslots(ts); ss++) {
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +02002527 * rsl_rx_rf_chan_rel_ack(). PDCH is always on lchan[0].
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002528 */
2529 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH) {
Neels Hofmeyrb74a2c82016-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 Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +02002536 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +02002546 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002547}
2548
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002549static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002550{
2551 int rc;
2552 uint8_t act_type;
2553 uint8_t ho_ref;
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002554 int ss;
2555 struct gsm_lchan *lchan;
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-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 Hofmeyrb91e6002016-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 Hofmeyrb91e6002016-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 Hofmeyra2ef7d62016-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 Ayuso51215762017-05-08 20:57:52 +02002628 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Neels Hofmeyra2ef7d62016-08-24 16:57:31 +02002629 osmo_timer_schedule(&lchan->act_timer, 4, 0);
2630
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +02002636 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002637 }
2638 return 0;
2639}
2640
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002641static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002642{
Neels Hofmeyrb91e6002016-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 Hofmeyrb74a2c82016-08-24 16:57:31 +02002668 gsm_lchant_name(lchan->type));
Neels Hofmeyrb91e6002016-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 Hofmeyra0a08d82016-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 Hofmeyrb91e6002016-07-23 19:45:15 +02002676}
Harald Welte75099262009-02-16 21:12:08 +00002677
Harald Welte52b1f982008-12-23 20:25:15 +00002678/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00002679int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00002680{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002681 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002682 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002683
Holger Hans Peter Freyther19bab732009-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 Weltef25b55e2012-05-31 20:22:34 +02002691 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002692 return -1;
2693 }
2694
2695 rslh = msgb_l2(msg);
2696
Harald Welte52b1f982008-12-23 20:25:15 +00002697 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:
Harald Welte52b1f982008-12-23 20:25:15 +00002705 rc = abis_rsl_rx_cchan(msg);
2706 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002707 case ABIS_RSL_MDISC_TRX:
2708 rc = abis_rsl_rx_trx(msg);
2709 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002710 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002711 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002712 rslh->msg_discr);
2713 break;
Harald Welte75099262009-02-16 21:12:08 +00002714 case ABIS_RSL_MDISC_IPACCESS:
2715 rc = abis_rsl_rx_ipacc(msg);
2716 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002717 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002718 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2719 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002720 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002721 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002722 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002723 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002724}
Holger Freyther3b72a892009-02-04 00:31:39 +00002725
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002726int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Welte30f1f372014-12-28 15:00:45 +01002727 struct rsl_ie_cb_cmd_type cb_command,
2728 const uint8_t *data, int len)
Holger Hans Peter Freyther8cb4a0f2010-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 Welte30f1f372014-12-28 15:00:45 +01002737 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002738 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Welte30f1f372014-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 Freyther8cb4a0f2010-07-21 15:54:32 +08002741
Harald Welte30f1f372014-12-28 15:00:45 +01002742 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002743 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2744
Harald Welte30f1f372014-12-28 15:00:45 +01002745 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002746
2747 return abis_rsl_sendmsg(cb_cmd);
2748}
Dieter Spaar16646022011-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 Ayuso7abecfc2011-08-17 22:43:54 +02002759 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-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 Ayuso7abecfc2011-08-17 22:43:54 +02002775 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-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 Ayuso7abecfc2011-08-17 22:43:54 +02002792 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002793
2794 return abis_rsl_sendmsg(msg);
2795}
Holger Hans Peter Freyther85825352011-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 Freytherb3489392011-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 Ayuso51215762017-05-08 20:57:52 +02002832 osmo_timer_setup(&lchan->T3109, t3109_expired, lchan);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002833 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2834 return 0;
2835}
Holger Hans Peter Freyther006e3d82012-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}