blob: 996860285ba341f9b14a5d0a08d511edca3426b8 [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
Neels Hofmeyrc0164792017-09-04 15:15:32 +020030#include <osmocom/bsc/gsm_data.h>
31#include <osmocom/bsc/gsm_04_08_utils.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020033#include <osmocom/bsc/abis_rsl.h>
34#include <osmocom/bsc/chan_alloc.h>
35#include <osmocom/bsc/bsc_rll.h>
36#include <osmocom/bsc/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>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020040#include <osmocom/bsc/paging.h>
41#include <osmocom/bsc/signal.h>
42#include <osmocom/bsc/meas_rep.h>
43#include <osmocom/bsc/rtp_proxy.h>
44#include <osmocom/bsc/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>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020048#include <osmocom/bsc/pcu_if.h>
49#include <osmocom/bsc/bsc_api.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080050
Harald Welte8470bf22008-12-25 23:28:35 +000051#define RSL_ALLOC_SIZE 1024
52#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000053
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +010054enum sacch_deact {
55 SACCH_NONE,
56 SACCH_DEACTIVATE,
57};
58
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080059static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020060static void error_timeout_cb(void *data);
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +020061static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts);
62static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +020063static void dyn_ts_switchover_complete(struct gsm_lchan *lchan);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080064
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010065static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
66 struct gsm_meas_rep *resp)
67{
68 struct lchan_signal_data sig;
69 sig.lchan = lchan;
70 sig.mr = resp;
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +020071 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010072}
73
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010074static void do_lchan_free(struct gsm_lchan *lchan)
75{
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020076 /* We start the error timer to make the channel available again */
77 if (lchan->state == LCHAN_S_REL_ERR) {
Pablo Neira Ayuso51215762017-05-08 20:57:52 +020078 osmo_timer_setup(&lchan->error_timer, error_timeout_cb, lchan);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020079 osmo_timer_schedule(&lchan->error_timer,
80 lchan->ts->trx->bts->network->T3111 + 2, 0);
81 } else {
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010082 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020083 }
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010084 lchan_free(lchan);
85}
86
Alexander Couzens8c53c592016-08-23 06:27:19 +020087static void count_codecs(struct gsm_bts *bts, struct gsm_lchan *lchan)
88{
89 OSMO_ASSERT(bts);
90
91 if (lchan->type == GSM_LCHAN_TCH_H) {
92 switch (lchan->tch_mode) {
93 case GSM48_CMODE_SPEECH_AMR:
94 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_H]);
95 break;
96 case GSM48_CMODE_SPEECH_V1:
97 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_HR]);
98 break;
99 default:
100 break;
101 }
102 } else if (lchan->type == GSM_LCHAN_TCH_F) {
103 switch (lchan->tch_mode) {
104 case GSM48_CMODE_SPEECH_AMR:
105 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_F]);
106 break;
107 case GSM48_CMODE_SPEECH_V1:
108 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_FR]);
109 break;
110 case GSM48_CMODE_SPEECH_EFR:
111 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_EFR]);
112 break;
113 default:
114 break;
115 }
Alexander Couzens8c53c592016-08-23 06:27:19 +0200116 }
117}
118
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200119static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000120{
121 /* mask off the transparent bit ? */
122 msg_type &= 0xfe;
123
Harald Welte8470bf22008-12-25 23:28:35 +0000124 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +0000125 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +0000126 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +0000127 if (msg_type >= 0x19 && msg_type <= 0x22)
128 return ABIS_RSL_MDISC_TRX;
129 else
130 return ABIS_RSL_MDISC_COM_CHAN;
131 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000132 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +0000133 return ABIS_RSL_MDISC_DED_CHAN;
134
135 return ABIS_RSL_MDISC_LOC;
136}
137
138static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200139 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000140{
141 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
142 dh->c.msg_type = msg_type;
143 dh->ie_chan = RSL_IE_CHAN_NR;
144}
145
Neels Hofmeyr74585722016-07-23 17:38:22 +0200146/* call rsl_lchan_lookup and set the log context */
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200147static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
148 const char *log_name)
Harald Welte8470bf22008-12-25 23:28:35 +0000149{
Neels Hofmeyr74585722016-07-23 17:38:22 +0200150 int rc;
151 struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc);
Harald Welte8470bf22008-12-25 23:28:35 +0000152
Neels Hofmeyr74585722016-07-23 17:38:22 +0200153 if (!lchan) {
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200154 LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n",
155 log_name, chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000156 return NULL;
157 }
158
Neels Hofmeyr74585722016-07-23 17:38:22 +0200159 if (rc < 0)
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200160 LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n",
161 gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr);
Neels Hofmeyr74585722016-07-23 17:38:22 +0200162
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800163 if (lchan->conn)
Harald Weltea43e0b42016-06-19 18:06:02 +0200164 log_set_context(LOG_CTX_VLR_SUBSCR, lchan->conn->vsub);
Harald Welte8470bf22008-12-25 23:28:35 +0000165
166 return lchan;
167}
168
Harald Welte52b1f982008-12-23 20:25:15 +0000169/* 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 +0200170uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000171{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200172 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000173
174 ret = strtoull(imsi_str, NULL, 10);
175
176 return ret;
177}
178
Harald Welte8470bf22008-12-25 23:28:35 +0000179static struct msgb *rsl_msgb_alloc(void)
180{
Harald Welte966636f2009-06-26 19:39:35 +0200181 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
182 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000183}
184
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200185static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000186{
187 memcpy(out, in, len);
188
Maxb726c2c2017-02-09 19:23:38 +0100189 if (len < GSM_MACBLOCK_LEN)
190 memset(out+len, 0x2b, GSM_MACBLOCK_LEN - len);
Harald Welte362322e2009-02-15 14:36:38 +0000191}
192
Harald Welte08d91a52009-08-30 15:37:11 +0900193/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200194static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900195{
196 *out++ = lchan->encr.alg_id & 0xff;
197 if (lchan->encr.key_len)
198 memcpy(out, lchan->encr.key, lchan->encr.key_len);
199 return lchan->encr.key_len + 1;
200}
201
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200202static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200203{
Harald Welte7f93cea2009-02-23 00:02:59 +0000204 int i;
205
Harald Welte5b8ed432009-12-24 12:20:20 +0100206 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200207 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200208 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100209 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000210}
211
Harald Weltee8bd9e82011-08-10 23:26:33 +0200212static void lchan_act_tmr_cb(void *data)
213{
214 struct gsm_lchan *lchan = data;
215
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100216 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann513da172011-08-11 04:44:12 +0200217 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200218}
219
220static void lchan_deact_tmr_cb(void *data)
221{
222 struct gsm_lchan *lchan = data;
223
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100224 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200225 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200226}
227
228
Harald Welte52b1f982008-12-23 20:25:15 +0000229/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Max8b1a2f82017-06-15 14:59:20 +0200230int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000231{
232 struct abis_rsl_dchan_hdr *dh;
Max8b1a2f82017-06-15 14:59:20 +0200233 const struct gsm_bts *bts = trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +0000234 struct msgb *msg = rsl_msgb_alloc();
Max8b1a2f82017-06-15 14:59:20 +0200235 uint8_t type = osmo_sitype2rsl(si_type);
236
237 if (bts->c0 != trx)
238 LOGP(DRR, LOGL_ERROR, "Attempting to set BCCH SI%s on wrong BTS%u/TRX%u\n",
239 get_value_string(osmo_sitype_strs, si_type), bts->nr, trx->nr);
Harald Welte52b1f982008-12-23 20:25:15 +0000240
241 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
242 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
243 dh->chan_nr = RSL_CHAN_BCCH;
244
Philipp309425e2016-11-02 12:05:44 +0100245 if (trx->bts->type == GSM_BTS_TYPE_RBS2000
246 && type == RSL_SYSTEM_INFO_13) {
247 /* Ericsson proprietary encoding of SI13 */
248 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, RSL_ERIC_SYSTEM_INFO_13);
Harald Welte4c5a0372017-07-15 23:56:12 +0200249 if (data)
250 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
Philipp309425e2016-11-02 12:05:44 +0100251 msgb_tv_put(msg, RSL_IE_ERIC_BCCH_MAPPING, 0x00);
252 } else {
253 /* Normal encoding */
254 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte4c5a0372017-07-15 23:56:12 +0200255 if (data)
256 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
Philipp309425e2016-11-02 12:05:44 +0100257 }
Harald Welte52b1f982008-12-23 20:25:15 +0000258
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200259 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000260
261 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000262}
263
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200264int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
265 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000266{
267 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000268 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000269
270 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
271 ch->msg_discr = ABIS_RSL_MDISC_TRX;
272 ch->msg_type = RSL_MT_SACCH_FILL;
273
274 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte4c5a0372017-07-15 23:56:12 +0200275 if (data)
276 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000277
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200278 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000279
280 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000281}
282
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200283int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
284 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100285{
286 struct abis_rsl_dchan_hdr *dh;
287 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200288 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100289
290 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
291 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
292 dh->chan_nr = chan_nr;
293
294 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte4c5a0372017-07-15 23:56:12 +0200295 if (data)
296 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte7a69cf02011-01-13 23:16:03 +0100297
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200298 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100299
300 return abis_rsl_sendmsg(msg);
301}
302
Harald Weltefcd24452009-06-20 18:15:19 +0200303int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
304{
305 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200306 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200307 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200308
309 db = abs(db);
310 if (db > 30)
311 return -EINVAL;
312
Harald Welteeab33352009-06-27 03:09:08 +0200313 msg = rsl_msgb_alloc();
314
Harald Weltefcd24452009-06-20 18:15:19 +0200315 lchan->bs_power = db/2;
316 if (fpc)
317 lchan->bs_power |= 0x10;
318
319 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
320 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
321 dh->chan_nr = chan_nr;
322
323 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
324
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200325 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200326
327 return abis_rsl_sendmsg(msg);
328}
329
Harald Weltefcd24452009-06-20 18:15:19 +0200330int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
331{
332 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200333 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200334 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200335 int ctl_lvl;
336
Harald Welte66b6a8d2009-08-09 14:45:18 +0200337 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200338 if (ctl_lvl < 0)
339 return ctl_lvl;
340
Harald Welteeab33352009-06-27 03:09:08 +0200341 msg = rsl_msgb_alloc();
342
Harald Weltefcd24452009-06-20 18:15:19 +0200343 lchan->ms_power = ctl_lvl;
344
345 if (fpc)
346 lchan->ms_power |= 0x20;
347
348 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
349 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
350 dh->chan_nr = chan_nr;
351
352 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
353
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200354 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200355
356 return abis_rsl_sendmsg(msg);
357}
358
Harald Welte9943c5b2009-07-29 15:41:29 +0200359static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
360 struct gsm_lchan *lchan)
361{
Holger Hans Peter Freythere1145cf2013-03-09 17:50:10 +0100362 memset(cm, 0, sizeof(*cm));
Harald Welte9943c5b2009-07-29 15:41:29 +0200363
364 /* FIXME: what to do with data calls ? */
Maxc08ee712016-05-11 12:45:13 +0200365 cm->dtx_dtu = 0;
366 if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
367 cm->dtx_dtu |= RSL_CMOD_DTXu;
368 if (lchan->ts->trx->bts->dtxd)
369 cm->dtx_dtu |= RSL_CMOD_DTXd;
Harald Welte9943c5b2009-07-29 15:41:29 +0200370
371 /* set TCH Speech/Data */
372 cm->spd_ind = lchan->rsl_cmode;
373
Harald Welte1a79d362009-11-27 08:55:16 +0100374 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
375 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100376 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100377 "but tch_mode != signalling\n");
378
Harald Welte9943c5b2009-07-29 15:41:29 +0200379 switch (lchan->type) {
380 case GSM_LCHAN_SDCCH:
381 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
382 break;
383 case GSM_LCHAN_TCH_F:
384 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
385 break;
386 case GSM_LCHAN_TCH_H:
387 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
388 break;
389 case GSM_LCHAN_NONE:
390 case GSM_LCHAN_UNKNOWN:
391 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200392 LOGP(DRSL, LOGL_ERROR,
393 "unsupported activation lchan->type %u %s\n",
394 lchan->type, gsm_lchant_name(lchan->type));
Harald Welte9943c5b2009-07-29 15:41:29 +0200395 return -EINVAL;
396 }
397
398 switch (lchan->tch_mode) {
399 case GSM48_CMODE_SIGN:
400 cm->chan_rate = 0;
401 break;
402 case GSM48_CMODE_SPEECH_V1:
403 cm->chan_rate = RSL_CMOD_SP_GSM1;
404 break;
405 case GSM48_CMODE_SPEECH_EFR:
406 cm->chan_rate = RSL_CMOD_SP_GSM2;
407 break;
408 case GSM48_CMODE_SPEECH_AMR:
409 cm->chan_rate = RSL_CMOD_SP_GSM3;
410 break;
411 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200412 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200413 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200414 switch (lchan->csd_mode) {
415 case LCHAN_CSD_M_NT:
416 /* non-transparent CSD with RLP */
417 switch (lchan->tch_mode) {
418 case GSM48_CMODE_DATA_14k5:
419 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
420 break;
421 case GSM48_CMODE_DATA_12k0:
422 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
423 break;
424 case GSM48_CMODE_DATA_6k0:
425 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
426 break;
427 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200428 LOGP(DRSL, LOGL_ERROR,
429 "unsupported lchan->tch_mode %u\n",
430 lchan->tch_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200431 return -EINVAL;
432 }
433 break;
434 /* transparent data services below */
435 case LCHAN_CSD_M_T_1200_75:
436 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
437 break;
438 case LCHAN_CSD_M_T_600:
439 cm->chan_rate = RSL_CMOD_CSD_T_600;
440 break;
441 case LCHAN_CSD_M_T_1200:
442 cm->chan_rate = RSL_CMOD_CSD_T_1200;
443 break;
444 case LCHAN_CSD_M_T_2400:
445 cm->chan_rate = RSL_CMOD_CSD_T_2400;
446 break;
447 case LCHAN_CSD_M_T_9600:
448 cm->chan_rate = RSL_CMOD_CSD_T_9600;
449 break;
450 case LCHAN_CSD_M_T_14400:
451 cm->chan_rate = RSL_CMOD_CSD_T_14400;
452 break;
453 case LCHAN_CSD_M_T_29000:
454 cm->chan_rate = RSL_CMOD_CSD_T_29000;
455 break;
456 case LCHAN_CSD_M_T_32000:
457 cm->chan_rate = RSL_CMOD_CSD_T_32000;
458 break;
459 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200460 LOGP(DRSL, LOGL_ERROR,
461 "unsupported lchan->csd_mode %u\n",
462 lchan->csd_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200463 return -EINVAL;
464 }
Harald Welteb8e8d0a2016-11-26 15:16:14 +0100465 break;
Harald Welte9943c5b2009-07-29 15:41:29 +0200466 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200467 LOGP(DRSL, LOGL_ERROR,
468 "unsupported lchan->tch_mode %u\n",
469 lchan->tch_mode);
Harald Welte9943c5b2009-07-29 15:41:29 +0200470 return -EINVAL;
471 }
472
473 return 0;
474}
475
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200476static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
477{
478 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
479 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
480 lchan->mr_bts_lv + 1);
481}
482
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200483static enum gsm_phys_chan_config pchan_for_lchant(enum gsm_chan_t type)
484{
485 switch (type) {
486 case GSM_LCHAN_TCH_F:
487 return GSM_PCHAN_TCH_F;
488 case GSM_LCHAN_TCH_H:
489 return GSM_PCHAN_TCH_H;
490 case GSM_LCHAN_NONE:
491 case GSM_LCHAN_PDTCH:
492 /* TODO: so far lchan->type is NONE in PDCH mode. PDTCH is only
493 * used in osmo-bts. Maybe set PDTCH and drop the NONE case
494 * here. */
495 return GSM_PCHAN_PDCH;
496 default:
497 return GSM_PCHAN_UNKNOWN;
498 }
499}
500
501/*! Tx simplified channel activation message for non-standard PDCH type. */
502static int rsl_chan_activate_lchan_as_pdch(struct gsm_lchan *lchan)
503{
504 struct msgb *msg;
505 struct abis_rsl_dchan_hdr *dh;
506
507 /* This might be called after release of the second lchan of a TCH/H,
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200508 * but PDCH activation must always happen on the first lchan. Make sure
509 * the calling code passes the correct lchan. */
510 OSMO_ASSERT(lchan == lchan->ts->lchan);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200511
512 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
513
514 msg = rsl_msgb_alloc();
515 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
516 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
517 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);
518
519 msgb_tv_put(msg, RSL_IE_ACT_TYPE, RSL_ACT_OSMO_PDCH);
520
Harald Weltef7e9a342016-11-16 15:17:22 +0100521 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_RBS2000 &&
522 lchan->ts->trx->bts->rbs2000.use_superchannel) {
523 const uint8_t eric_pgsl_tmr[] = { 30, 1 };
524 msgb_tv_fixed_put(msg, RSL_IE_ERIC_PGSL_TIMERS,
525 sizeof(eric_pgsl_tmr), eric_pgsl_tmr);
526 }
527
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200528 msg->dst = lchan->ts->trx->rsl_link;
529
530 return abis_rsl_sendmsg(msg);
531}
532
Harald Welte52b1f982008-12-23 20:25:15 +0000533/* Chapter 8.4.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200534int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg723a7512013-10-11 12:55:35 +0200535 uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000536{
537 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200538 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200539 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200540 uint8_t *len;
Andreas Eversberg723a7512013-10-11 12:55:35 +0200541 uint8_t ta;
Harald Welte4b634542008-12-27 01:55:51 +0000542
Harald Welte4b634542008-12-27 01:55:51 +0000543 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200544 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000545
Neels Hofmeyrc6926d02016-07-14 02:51:13 +0200546 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200547 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200548 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200549 /* store activation type and handover reference */
Neels Hofmeyr6e999b72016-07-23 21:00:51 +0200550 lchan->dyn.act_type = act_type;
551 lchan->dyn.ho_ref = ho_ref;
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200552 return rsl_ipacc_pdch_activate(lchan->ts, 0);
553 }
554
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200555 /*
556 * If necessary, release PDCH on dynamic TS. Note that sending a
557 * release here is only necessary when in PDCH mode; for TCH types, an
558 * RSL RF Chan Release is initiated by the BTS when a voice call ends,
559 * so when we reach this, it will already be released. If a dyn TS is
560 * in PDCH mode, it is still active and we need to initiate a release
561 * from the BSC side here.
562 *
563 * If pchan_is != pchan_want, the PDCH has already been taken down and
564 * the switchover now needs to enable the TCH lchan.
565 *
566 * To switch a dyn TS between TCH/H and TCH/F, it is sufficient to send
567 * a chan activ with the new lchan type, because it will already be
568 * released.
569 */
570 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
571 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
572 && lchan->ts->dyn.pchan_is == lchan->ts->dyn.pchan_want) {
573 enum gsm_phys_chan_config pchan_want;
574 pchan_want = pchan_for_lchant(lchan->type);
575 if (lchan->ts->dyn.pchan_is != pchan_want) {
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200576 /*
577 * Make sure to record on lchan[0] so that we'll find
578 * it after the PDCH release.
579 */
580 struct gsm_lchan *lchan0 = lchan->ts->lchan;
581 lchan0->dyn.act_type = act_type,
582 lchan0->dyn.ho_ref = ho_ref;
583 lchan0->dyn.rqd_ref = lchan->rqd_ref;
584 lchan0->dyn.rqd_ta = lchan->rqd_ta;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200585 lchan->rqd_ref = NULL;
586 lchan->rqd_ta = 0;
587 DEBUGP(DRSL, "%s saved rqd_ref=%p ta=%u\n",
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200588 gsm_lchan_name(lchan0), lchan0->rqd_ref,
589 lchan0->rqd_ta);
590 return dyn_ts_switchover_start(lchan->ts, pchan_want);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200591 }
592 }
593
594 DEBUGP(DRSL, "%s Tx RSL Channel Activate with act_type=%s\n",
595 gsm_ts_and_pchan_name(lchan->ts),
596 rsl_act_type_name(act_type));
597
598 if (act_type == RSL_ACT_OSMO_PDCH) {
599 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH) {
600 LOGP(DRSL, LOGL_ERROR,
601 "%s PDCH channel activation only allowed on %s\n",
602 gsm_ts_and_pchan_name(lchan->ts),
603 gsm_pchan_name(GSM_PCHAN_TCH_F_TCH_H_PDCH));
604 return -EINVAL;
605 }
606 return rsl_chan_activate_lchan_as_pdch(lchan);
607 }
608
609 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
610 && lchan->ts->dyn.pchan_want == GSM_PCHAN_PDCH) {
611 LOGP(DRSL, LOGL_ERROR,
612 "%s Expected PDCH activation kind\n",
613 gsm_ts_and_pchan_name(lchan->ts));
614 return -EINVAL;
615 }
616
Neels Hofmeyrcf793382016-07-23 19:49:58 +0200617 rc = channel_mode_from_lchan(&cm, lchan);
618 if (rc < 0) {
619 LOGP(DRSL, LOGL_ERROR,
620 "%s Cannot find channel mode from lchan type\n",
621 gsm_ts_and_pchan_name(lchan->ts));
622 return rc;
623 }
624
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200625 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
626
Andreas Eversberg723a7512013-10-11 12:55:35 +0200627 ta = lchan->rqd_ta;
628
629 /* BS11 requires TA shifted by 2 bits */
630 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
631 ta <<= 2;
632
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800633 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200634 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000635
Harald Welteeab33352009-06-27 03:09:08 +0200636 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000637 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
638 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
Neels Hofmeyr7af652c2016-07-23 19:51:09 +0200639
640 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
641 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(
642 lchan, lchan->ts->dyn.pchan_want);
643 else
644 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000645
646 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000647 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200648 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800649
650 /*
651 * The Channel Identification is needed for Phase1 phones
652 * and it contains the GSM48 Channel Description and the
653 * Mobile Allocation. The GSM 08.58 asks for the Mobile
654 * Allocation to have a length of zero. We are using the
655 * msgb_l3len to calculate the length of both messages.
656 */
laforge694a5cf2010-06-20 21:38:19 +0200657 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200658 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200659 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800660
661 if (lchan->ts->hopping.enabled)
662 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
663 lchan->ts->hopping.ma_data);
664 else
665 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800666
667 /* update the calculated size */
668 msg->l3h = len + 1;
669 *len = msgb_l3len(msg);
670
Harald Welte08d91a52009-08-30 15:37:11 +0900671 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200672 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900673 rc = build_encr_info(encr_info, lchan);
674 if (rc > 0)
675 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
676 }
677
Harald Welte8d77b952009-12-17 00:31:10 +0100678 switch (act_type) {
679 case RSL_ACT_INTER_ASYNC:
680 case RSL_ACT_INTER_SYNC:
681 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
682 break;
683 default:
684 break;
685 }
686
Harald Welted4c9bf32009-02-15 16:56:18 +0000687 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
688 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000689 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200690 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100691
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200692 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000693
Harald Welte4b634542008-12-27 01:55:51 +0000694 return abis_rsl_sendmsg(msg);
695}
696
Harald Welte470abb72009-07-29 11:38:15 +0200697/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000698int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
699{
700 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200701 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200702 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000703
Harald Weltef6093a42011-06-25 10:02:33 +0200704 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000705 struct rsl_ie_chan_mode cm;
706
Harald Welte9943c5b2009-07-29 15:41:29 +0200707 rc = channel_mode_from_lchan(&cm, lchan);
708 if (rc < 0)
709 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000710
Harald Welteeab33352009-06-27 03:09:08 +0200711 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000712 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
713 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
714 dh->chan_nr = chan_nr;
715
716 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200717 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900718
719 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200720 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900721 rc = build_encr_info(encr_info, lchan);
722 if (rc > 0)
723 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
724 }
725
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200726 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100727
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200728 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900729
730 return abis_rsl_sendmsg(msg);
731}
732
733/* Chapter 8.4.6: Send the encryption command with given L3 info */
734int rsl_encryption_cmd(struct msgb *msg)
735{
736 struct abis_rsl_dchan_hdr *dh;
737 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200738 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200739 uint8_t encr_info[MAX_A5_KEY_LEN+2];
740 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900741 int rc;
742
743 /* First push the L3 IE tag and length */
744 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
745
746 /* then the link identifier (SAPI0, main sign link) */
747 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
748
749 /* then encryption information */
750 rc = build_encr_info(encr_info, lchan);
751 if (rc <= 0)
752 return rc;
753 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
754
755 /* and finally the DCHAN header */
756 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
757 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
758 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000759
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200760 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000761
762 return abis_rsl_sendmsg(msg);
763}
764
Harald Welte115d1032009-08-10 11:43:22 +0200765/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200766int rsl_deact_sacch(struct gsm_lchan *lchan)
767{
768 struct abis_rsl_dchan_hdr *dh;
769 struct msgb *msg = rsl_msgb_alloc();
770
771 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
772 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200773 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200774
775 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200776 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200777
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100778 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200779
780 return abis_rsl_sendmsg(msg);
781}
782
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200783static bool dyn_ts_should_switch_to_pdch(struct gsm_bts_trx_ts *ts)
784{
785 int ss;
786
787 if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
788 return false;
789
790 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
791 return false;
792
793 /* Already in PDCH mode? */
794 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH)
795 return false;
796
797 /* See if all lchans are released. */
798 for (ss = 0; ss < ts_subslots(ts); ss++) {
799 struct gsm_lchan *lc = &ts->lchan[ss];
800 if (lc->state != LCHAN_S_NONE) {
Neels Hofmeyrbaa6c552016-08-24 14:48:39 +0200801 DEBUGP(DRSL, "%s lchan %u still in use"
802 " (type=%s,state=%s)\n",
803 gsm_ts_and_pchan_name(ts), lc->nr,
804 gsm_lchant_name(lc->type),
805 gsm_lchans_name(lc->state));
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200806 /* An lchan is still used. */
807 return false;
808 }
809 }
810
811 /* All channels are released, go to PDCH mode. */
812 DEBUGP(DRSL, "%s back to PDCH\n",
813 gsm_ts_and_pchan_name(ts));
814 return true;
815}
816
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800817static void error_timeout_cb(void *data)
818{
819 struct gsm_lchan *lchan = data;
820 if (lchan->state != LCHAN_S_REL_ERR) {
821 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
822 gsm_lchan_name(lchan), lchan->state);
823 return;
824 }
825
826 /* go back to the none state */
Harald Weltea9e420e2012-11-13 04:26:22 +0100827 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800828 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200829
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +0200830 /* Put PDCH channel back into PDCH mode, if GPRS is enabled */
831 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
832 && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE)
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200833 rsl_ipacc_pdch_activate(lchan->ts, 1);
Neels Hofmeyrcd150a82016-08-24 14:45:44 +0200834
835 if (dyn_ts_should_switch_to_pdch(lchan->ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200836 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800837}
838
Harald Weltefd355a32011-03-04 13:41:31 +0100839static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
840
Harald Welte115d1032009-08-10 11:43:22 +0200841/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100842static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
843 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000844{
845 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800846 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100847 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000848
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100849 /* Stop timers that should lead to a channel release */
850 osmo_timer_del(&lchan->T3109);
851
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800852 if (lchan->state == LCHAN_S_REL_ERR) {
Neels Hofmeyrd5d39ae2016-08-24 17:02:19 +0200853 LOGP(DRSL, LOGL_NOTICE, "%s is in error state, not sending release.\n",
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800854 gsm_lchan_name(lchan));
855 return -1;
856 }
857
858 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000859 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
860 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200861 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000862
Harald Welte8470bf22008-12-25 23:28:35 +0000863 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200864 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000865
Neels Hofmeyrb3d87062016-08-22 18:40:07 +0200866 if (error)
867 DEBUGP(DRSL, "%s RF Channel Release due to error: %d\n",
868 gsm_lchan_name(lchan), error);
869 else
870 DEBUGP(DRSL, "%s RF Channel Release\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800871
872 if (error) {
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100873 /*
874 * FIXME: GSM 04.08 gives us two options for the abnormal
875 * chanel release. This can be either like in the non-existent
876 * sub-lcuase 3.5.1 or for the main signalling link deactivate
877 * the SACCH, start timer T3109 and consider the channel as
878 * released.
879 *
880 * This code is doing the later for all raido links and not
881 * only the main link. Right now all SAPIs are released on the
882 * local end, the SACCH will be de-activated and right now the
883 * T3111 will be started. First T3109 should be started and then
884 * the T3111.
885 *
886 * TODO: Move this out of the function.
887 */
888
889 /*
890 * sacch de-activate and "local end release"
891 */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100892 if (deact_sacch == SACCH_DEACTIVATE)
893 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100894 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
895
896 /*
897 * TODO: start T3109 now.
898 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800899 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800900 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000901
Harald Weltee8bd9e82011-08-10 23:26:33 +0200902 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +0200903 osmo_timer_setup(&lchan->act_timer, lchan_deact_tmr_cb, lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200904 osmo_timer_schedule(&lchan->act_timer, 4, 0);
905
Harald Weltefd355a32011-03-04 13:41:31 +0100906 rc = abis_rsl_sendmsg(msg);
907
Harald Welte115d1032009-08-10 11:43:22 +0200908 /* BTS will respond by RF CHAN REL ACK */
Harald Weltefd355a32011-03-04 13:41:31 +0100909 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000910}
911
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200912/*
913 * Special handling for channel releases in the error case.
914 */
915static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
916{
Neels Hofmeyrec16c162016-10-17 01:03:53 +0200917 enum sacch_deact sacch_deact;
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200918 if (lchan->state != LCHAN_S_ACTIVE)
919 return 0;
Neels Hofmeyrec16c162016-10-17 01:03:53 +0200920 switch (ts_pchan(lchan->ts)) {
921 case GSM_PCHAN_TCH_F:
922 case GSM_PCHAN_TCH_H:
923 case GSM_PCHAN_CCCH_SDCCH4:
924 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
925 case GSM_PCHAN_SDCCH8_SACCH8C:
926 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
927 sacch_deact = SACCH_DEACTIVATE;
928 break;
929 default:
930 sacch_deact = SACCH_NONE;
931 break;
932 }
933 return rsl_rf_chan_release(lchan, 1, sacch_deact);
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200934}
935
Harald Welte64bb7542011-01-14 14:16:16 +0100936static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
937{
Neels Hofmeyr40074682016-07-23 20:01:49 +0200938 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte64bb7542011-01-14 14:16:16 +0100939
940 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
941
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100942 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200943 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100944 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200945
Holger Hans Peter Freyther6f6cbf72015-04-04 19:35:22 +0200946 /*
947 * The BTS didn't respond within the timeout to our channel
948 * release request and we have marked the channel as broken.
949 * Now we do receive an ACK and let's be conservative. If it
950 * is a sysmoBTS we know that only one RF Channel Release ACK
951 * will be sent. So let's "repair" the channel.
952 */
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200953 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyr40074682016-07-23 20:01:49 +0200954 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f6cbf72015-04-04 19:35:22 +0200955 LOGP(DRSL, LOGL_NOTICE,
956 "%s CHAN REL ACK for broken channel. %s.\n",
957 gsm_lchan_name(lchan),
958 do_free ? "Releasing it" : "Keeping it broken");
959 if (do_free)
960 do_lchan_free(lchan);
Neels Hofmeyrd35fc442016-08-24 17:02:37 +0200961 if (dyn_ts_should_switch_to_pdch(lchan->ts))
962 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200963 return 0;
964 }
965
Harald Welte64bb7542011-01-14 14:16:16 +0100966 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
967 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
968 gsm_lchan_name(lchan),
969 gsm_lchans_name(lchan->state));
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200970
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200971 do_lchan_free(lchan);
972
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200973 /*
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200974 * Check Osmocom RSL CHAN ACT style dynamic TCH/F_TCH/H_PDCH TS for pending
975 * transitions in these cases:
976 *
977 * a) after PDCH was released due to switchover request, activate TCH.
978 * BSC initiated this switchover, so dyn.pchan_is != pchan_want and
979 * lchan->type has been set to the desired GSM_LCHAN_*.
980 *
981 * b) Voice call ended and a TCH is released. If the TS is now unused,
982 * switch to PDCH. Here still dyn.pchan_is == dyn.pchan_want because
983 * we're only just notified and may decide to switch to PDCH now.
984 */
985 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
986 DEBUGP(DRSL, "%s Rx RSL Channel Release ack for lchan %u\n",
987 gsm_ts_and_pchan_name(ts), lchan->nr);
988
989 /* (a) */
990 if (ts->dyn.pchan_is != ts->dyn.pchan_want)
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200991 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200992
993 /* (b) */
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200994 if (dyn_ts_should_switch_to_pdch(ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200995 return dyn_ts_switchover_start(ts, GSM_PCHAN_PDCH);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200996 }
997
998 /*
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200999 * Put a dynamic TCH/F_PDCH channel back to PDCH mode iff it was
1000 * released successfully. If in error, the PDCH ACT will follow after
1001 * T3111 in error_timeout_cb().
1002 *
1003 * Any state other than LCHAN_S_REL_ERR became LCHAN_S_NONE after above
1004 * do_lchan_free(). Assert this, because that's what ensures a PDCH ACT
Neels Hofmeyrc6926d02016-07-14 02:51:13 +02001005 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02001006 *
1007 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr3f221222016-06-23 22:44:20 +02001008 */
1009 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
1010 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyr40074682016-07-23 20:01:49 +02001011 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02001012 return 0;
Neels Hofmeyr40074682016-07-23 20:01:49 +02001013 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr82c8f752016-06-21 20:55:14 +02001014 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyr40074682016-07-23 20:01:49 +02001015 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte64bb7542011-01-14 14:16:16 +01001016 return 0;
1017}
1018
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001019int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
Harald Weltebaaf3e22016-11-17 20:54:04 +01001020 uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs)
Harald Welte52b1f982008-12-23 20:25:15 +00001021{
1022 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +00001023 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001024
1025 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1026 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
1027 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1028
1029 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +00001030 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +00001031 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
1032
Harald Weltebaaf3e22016-11-17 20:54:04 +01001033 /* Ericsson wants to have this IE in case a paging message
1034 * relates to packet paging */
1035 if (bts->type == GSM_BTS_TYPE_RBS2000 && is_gprs)
1036 msgb_tv_put(msg, RSL_IE_ERIC_PACKET_PAG_IND, 0);
1037
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001038 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001039
1040 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001041}
1042
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001043int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +00001044{
1045 int i, len = strlen(str_in);
1046
1047 for (i = 0; i < len; i++) {
1048 int num = str_in[i] - 0x30;
1049 if (num < 0 || num > 9)
1050 return -1;
1051 if (i % 2 == 0)
1052 bcd_out[i/2] = num;
1053 else
1054 bcd_out[i/2] |= (num << 4);
1055 }
1056
1057 return 0;
1058}
1059
Harald Welte702d8702008-12-26 20:25:35 +00001060/* Chapter 8.5.6 */
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001061struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +00001062{
Harald Welte8470bf22008-12-25 23:28:35 +00001063 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001064 struct abis_rsl_dchan_hdr *dh;
Maxb726c2c2017-02-09 19:23:38 +01001065 uint8_t buf[GSM_MACBLOCK_LEN];
Harald Welte52b1f982008-12-23 20:25:15 +00001066
1067 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1068 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
1069 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1070
Harald Welte362322e2009-02-15 14:36:38 +00001071 switch (bts->type) {
1072 case GSM_BTS_TYPE_BS11:
1073 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
1074 break;
1075 default:
1076 /* If phase 2, construct a FULL_IMM_ASS_INFO */
1077 pad_macblock(buf, val, len);
Maxb726c2c2017-02-09 19:23:38 +01001078 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, GSM_MACBLOCK_LEN,
1079 buf);
Harald Welte362322e2009-02-15 14:36:38 +00001080 break;
1081 }
Harald Welte52b1f982008-12-23 20:25:15 +00001082
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001083 msg->dst = bts->c0->rsl_link;
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001084 return msg;
1085}
1086
1087/* Chapter 8.5.6 */
1088int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
1089{
1090 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1091 if (!msg)
1092 return 1;
1093 return abis_rsl_sendmsg(msg);
1094}
1095
1096/* Chapter 8.5.6 */
1097int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val)
1098{
1099 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1100 if (!msg)
1101 return 1;
1102
1103 /* ericsson can handle a reference at the end of the message which is used in
1104 * the confirm message. The confirm message is only sent if the trailer is present */
1105 msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
1106 msgb_put_u32(msg, tlli);
Harald Welte8470bf22008-12-25 23:28:35 +00001107
1108 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001109}
1110
Harald Welte67fa91b2009-08-10 09:51:40 +02001111/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +02001112int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +02001113{
1114 struct msgb *msg = rsl_msgb_alloc();
1115 struct abis_rsl_dchan_hdr *dh;
1116
1117 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1118 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +02001119 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001120 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001121 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +02001122
Harald Welte5b8ed432009-12-24 12:20:20 +01001123 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001124 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +02001125
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001126 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +02001127
Harald Welte67fa91b2009-08-10 09:51:40 +02001128 return abis_rsl_sendmsg(msg);
1129}
1130
1131
Harald Welte8470bf22008-12-25 23:28:35 +00001132/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +00001133/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001134int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +00001135{
Harald Welte8470bf22008-12-25 23:28:35 +00001136 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001137 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +00001138 return -EINVAL;
1139 }
Harald Welte52b1f982008-12-23 20:25:15 +00001140
Harald Weltef6093a42011-06-25 10:02:33 +02001141 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001142 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +00001143
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001144 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001145
1146 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001147}
1148
Harald Welteedcc5272009-08-09 13:47:35 +02001149/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
1150/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001151int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +02001152{
Harald Welte3c9c5f92010-03-04 10:33:10 +01001153 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +02001154
Harald Weltef6093a42011-06-25 10:02:33 +02001155 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001156 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001157 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +02001158
Harald Weltefda74ee2012-04-26 19:42:19 +02001159 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
1160 gsm_lchan_name(lchan), link_id);
1161
Harald Welteedcc5272009-08-09 13:47:35 +02001162 return abis_rsl_sendmsg(msg);
1163}
1164
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001165static void rsl_handle_release(struct gsm_lchan *lchan);
1166
1167/* Special work handler to handle missing RSL_MT_REL_CONF message from
1168 * Nokia InSite BTS */
1169static void lchan_rel_work_cb(void *data)
1170{
1171 struct gsm_lchan *lchan = data;
1172 int sapi;
1173
1174 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1175 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
1176 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
1177 }
1178 rsl_handle_release(lchan);
1179}
1180
Harald Welted2dc1de2009-08-08 13:15:07 +02001181/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
1182 This is what higher layers should call. The BTS then responds with
1183 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
1184 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
1185 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001186int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
1187 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +02001188{
Harald Welted2dc1de2009-08-08 13:15:07 +02001189
Harald Welte3c9c5f92010-03-04 10:33:10 +01001190 struct msgb *msg;
1191
Harald Weltef6093a42011-06-25 10:02:33 +02001192 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001193 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +08001194 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001195 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +02001196
Harald Welte8e93b792009-12-29 10:44:17 +01001197 /* FIXME: start some timer in case we don't receive a REL ACK ? */
1198
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001199 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +02001200
Harald Weltefda74ee2012-04-26 19:42:19 +02001201 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001202 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +02001203
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001204 abis_rsl_sendmsg(msg);
1205
1206 /* Do not wait for Nokia BTS to send the confirm. */
1207 if (is_nokia_bts(lchan->ts->trx->bts)
1208 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
1209 && release_mode == RSL_REL_LOCAL_END) {
1210 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
1211 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001212 osmo_timer_setup(&lchan->rel_work, lchan_rel_work_cb, lchan);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001213 osmo_timer_schedule(&lchan->rel_work, 0, 0);
1214 }
1215
1216 return 0;
Harald Welted2dc1de2009-08-08 13:15:07 +02001217}
1218
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001219int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
1220{
Neels Hofmeyr423269f2016-08-24 16:48:00 +02001221 LOGP(DRSL, LOGL_ERROR, "%s %s lchan broken: %s\n",
1222 gsm_lchan_name(lchan), gsm_lchant_name(lchan->type), reason);
1223 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001224 lchan->broken_reason = reason;
1225 return 0;
1226}
1227
Maxdc10ce92017-09-06 18:20:36 +02001228int rsl_lchan_set_state_with_log(struct gsm_lchan *lchan, enum gsm_lchan_state state, const char *file, unsigned line)
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001229{
Maxdc10ce92017-09-06 18:20:36 +02001230 if (lchan->state != state)
1231 LOGPSRC(DRSL, LOGL_DEBUG, file, line, "%s state %s -> %s\n",
1232 gsm_lchan_name(lchan), gsm_lchans_name(lchan->state), gsm_lchans_name(state));
1233
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001234 lchan->state = state;
1235 return 0;
1236}
1237
Harald Welte702d8702008-12-26 20:25:35 +00001238/* Chapter 8.4.2: Channel Activate Acknowledge */
1239static int rsl_rx_chan_act_ack(struct msgb *msg)
1240{
1241 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001242 struct gsm_lchan *lchan = msg->lchan;
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001243 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte702d8702008-12-26 20:25:35 +00001244
1245 /* BTS has confirmed channel activation, we now need
1246 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +00001247 if (rslh->ie_chan != RSL_IE_CHAN_NR)
1248 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +01001249
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001250 osmo_timer_del(&lchan->act_timer);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001251
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001252 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001253 int do_release = is_sysmobts_v2(ts->trx->bts);
1254 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel. %s\n",
1255 gsm_lchan_name(lchan),
1256 do_release ? "Releasing it" : "Keeping it broken");
1257 if (do_release) {
1258 talloc_free(lchan->rqd_ref);
1259 lchan->rqd_ref = NULL;
1260 lchan->rqd_ta = 0;
1261 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
1262 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
1263 /*
1264 * lchan_act_tmr_cb() already called
1265 * lchan_free() and cleared the lchan->type, so
1266 * calling dyn_ts_switchover_complete() here
1267 * would not have the desired effect of
1268 * mimicking an activated lchan that we can
1269 * release. Instead hack the dyn ts state to
1270 * make sure that rsl_rx_rf_chan_rel_ack() will
1271 * switch back to PDCH, i.e. have pchan_is ==
1272 * pchan_want, both != GSM_PCHAN_PDCH:
1273 */
1274 ts->dyn.pchan_is = GSM_PCHAN_NONE;
1275 ts->dyn.pchan_want = GSM_PCHAN_NONE;
1276 }
1277 rsl_rf_chan_release(msg->lchan, 0, SACCH_NONE);
1278 }
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +02001279 return 0;
1280 }
1281
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001282 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +01001283 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001284 gsm_lchan_name(lchan),
1285 gsm_lchans_name(lchan->state));
1286 rsl_lchan_set_state(lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +01001287
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001288 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001289 dyn_ts_switchover_complete(lchan);
1290
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001291 if (lchan->rqd_ref) {
1292 rsl_send_imm_assignment(lchan);
1293 talloc_free(lchan->rqd_ref);
1294 lchan->rqd_ref = NULL;
1295 lchan->rqd_ta = 0;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001296 }
1297
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001298 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001299
Philipp Maierb4999b62016-10-26 15:19:41 +02001300 /* Update bts attributes inside the PCU */
1301 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH ||
1302 ts->pchan == GSM_PCHAN_TCH_F_PDCH ||
1303 ts->pchan == GSM_PCHAN_PDCH)
1304 pcu_info_update(ts->trx->bts);
1305
Harald Welte4b634542008-12-27 01:55:51 +00001306 return 0;
1307}
Harald Welte702d8702008-12-26 20:25:35 +00001308
Harald Welte4b634542008-12-27 01:55:51 +00001309/* Chapter 8.4.3: Channel Activate NACK */
1310static int rsl_rx_chan_act_nack(struct msgb *msg)
1311{
Harald Welte6dab0552009-05-01 17:21:37 +00001312 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1313 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001314
Harald Weltee8bd9e82011-08-10 23:26:33 +02001315 osmo_timer_del(&msg->lchan->act_timer);
1316
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +02001317 if (msg->lchan->state == LCHAN_S_BROKEN) {
1318 LOGP(DRSL, LOGL_ERROR,
1319 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
1320 gsm_lchan_name(msg->lchan));
1321 return -1;
1322 }
1323
Daniel Willmann6fc6a122011-08-11 04:54:23 +02001324 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001325 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001326
Harald Welte6dab0552009-05-01 17:21:37 +00001327 /* BTS has rejected channel activation ?!? */
1328 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +00001329 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +00001330
1331 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001332 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001333 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001334 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +02001335 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +01001336 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001337 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1338 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1339 } else
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001340 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +02001341
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001342 } else {
1343 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1344 }
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001345
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001346 LOGPC(DRSL, LOGL_ERROR, "\n");
1347
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001348 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +00001349 return 0;
Harald Welte702d8702008-12-26 20:25:35 +00001350}
1351
Harald Welte7f93cea2009-02-23 00:02:59 +00001352/* Chapter 8.4.4: Connection Failure Indication */
1353static int rsl_rx_conn_fail(struct msgb *msg)
1354{
1355 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1356 struct tlv_parsed tp;
1357
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02001358 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1359 gsm_lchan_name(msg->lchan),
1360 gsm_lchans_name(msg->lchan->state));
1361
Harald Welte7f93cea2009-02-23 00:02:59 +00001362 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1363
Harald Welte8830e072009-07-28 17:58:09 +02001364 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001365 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001366 TLVP_LEN(&tp, RSL_IE_CAUSE));
1367
Harald Welte (local)fc057502009-12-26 22:33:09 +01001368 LOGPC(DRSL, LOGL_NOTICE, "\n");
Alexander Couzensb847a212016-08-02 11:34:11 +02001369 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 +02001370 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +00001371}
1372
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001373static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1374 const char *prefix)
1375{
Harald Welte6739dfb2009-12-16 16:52:07 +01001376 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1377 prefix, rxlev2dbm(mru->full.rx_lev),
1378 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001379 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1380 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1381}
1382
Harald Welte0c1bd612012-07-02 17:12:08 +02001383static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001384{
Harald Welte6739dfb2009-12-16 16:52:07 +01001385 int i;
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001386 const char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +01001387
Max11e4e412017-04-20 13:07:58 +02001388 if (lchan && lchan->conn) {
1389 if (lchan->conn->bsub)
1390 name = bsc_subscr_name(lchan->conn->bsub);
Max11e4e412017-04-20 13:07:58 +02001391 else
1392 name = lchan->name;
1393 }
Harald Welte0c1bd612012-07-02 17:12:08 +02001394
1395 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001396
1397 if (mr->flags & MEAS_REP_F_DL_DTX)
1398 DEBUGPC(DMEAS, "DTXd ");
1399
1400 print_meas_rep_uni(&mr->ul, "ul");
1401 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
Max11e4e412017-04-20 13:07:58 +02001402
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001403 if (mr->flags & MEAS_REP_F_MS_TO)
1404 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1405
1406 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +01001407 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001408 DEBUGPC(DMEAS, "L1_FPC=%u ",
1409 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1410 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1411 }
1412
1413 if (mr->flags & MEAS_REP_F_UL_DTX)
1414 DEBUGPC(DMEAS, "DTXu ");
1415 if (mr->flags & MEAS_REP_F_BA1)
1416 DEBUGPC(DMEAS, "BA1 ");
1417 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1418 DEBUGPC(DMEAS, "NOT VALID ");
1419 else
1420 print_meas_rep_uni(&mr->dl, "dl");
1421
1422 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001423 if (mr->num_cell == 7)
1424 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001425 for (i = 0; i < mr->num_cell; i++) {
1426 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001427 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1428 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001429 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001430}
1431
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +02001432static struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
1433{
1434 struct gsm_meas_rep *meas_rep;
1435
1436 meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
1437 memset(meas_rep, 0, sizeof(*meas_rep));
1438 meas_rep->lchan = lchan;
1439 lchan->meas_rep_idx = (lchan->meas_rep_idx + 1)
1440 % ARRAY_SIZE(lchan->meas_rep);
1441
1442 return meas_rep;
1443}
1444
Harald Welte440fed02009-05-01 18:43:47 +00001445static int rsl_rx_meas_res(struct msgb *msg)
1446{
1447 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1448 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001449 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001450 uint8_t len;
1451 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001452 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001453
Harald Welteb8bfc562009-12-21 13:27:11 +01001454 /* check if this channel is actually active */
1455 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001456 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001457 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001458 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001459 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001460 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001461
Harald Welted12b0fd2009-12-15 21:36:05 +01001462 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001463 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001464
Harald Welte440fed02009-05-01 18:43:47 +00001465 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1466
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001467 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1468 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1469 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1470 return -EIO;
1471
1472 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001473 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001474
1475 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1476 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1477 if (len >= 3) {
1478 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001479 mr->flags |= MEAS_REP_F_DL_DTX;
1480 mr->ul.full.rx_lev = val[0] & 0x3f;
1481 mr->ul.sub.rx_lev = val[1] & 0x3f;
1482 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1483 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001484 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001485
Harald Welted12b0fd2009-12-15 21:36:05 +01001486 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001487
1488 /* Optional Parts */
Max11e4e412017-04-20 13:07:58 +02001489 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) {
1490 /* According to 3GPP TS 48.058 § MS Timing Offset = Timing Offset field - 63 */
1491 mr->ms_timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET) - 63;
1492 mr->flags |= MEAS_REP_F_MS_TO;
1493 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001494
Harald Weltefe9af262009-06-20 18:44:35 +02001495 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001496 struct e1inp_sign_link *sign_link = msg->dst;
1497
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001498 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001499 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001500 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001501 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001502 mr->flags |= MEAS_REP_F_FPC;
1503 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001504 /* BS11 and Nokia reports TA shifted by 2 bits */
1505 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1506 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001507 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001508 }
Harald Weltef7c43522009-06-09 20:24:21 +00001509 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001510 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001511 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001512 if (rc < 0)
1513 return rc;
1514 }
1515
Harald Welte0c1bd612012-07-02 17:12:08 +02001516 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001517
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001518 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001519
Harald Welte75d34a82009-05-23 06:11:13 +00001520 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001521}
1522
Harald Welted011e8b2009-11-29 22:45:52 +01001523/* Chapter 8.4.7 */
1524static int rsl_rx_hando_det(struct msgb *msg)
1525{
1526 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1527 struct tlv_parsed tp;
1528
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001529 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001530
1531 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1532
1533 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1534 DEBUGPC(DRSL, "access delay = %u\n",
1535 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1536 else
1537 DEBUGPC(DRSL, "\n");
1538
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001539 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001540
1541 return 0;
1542}
1543
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001544static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1545{
1546 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001547
1548 OSMO_ASSERT(lchan);
1549
1550 ts = lchan->ts;
1551 OSMO_ASSERT(ts);
1552 OSMO_ASSERT(ts->trx);
1553 OSMO_ASSERT(ts->trx->bts);
1554
1555 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
Neels Hofmeyrdd49bee2016-06-21 20:53:27 +02001556 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1557 " for channel that is no TCH/F_PDCH\n",
1558 gsm_lchan_name(lchan),
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001559 gsm_pchan_name(ts->pchan),
1560 pdch_act? "ACT" : "DEACT");
1561 return false;
1562 }
1563
Neels Hofmeyr832afa32016-06-14 13:12:00 +02001564 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyrdd49bee2016-06-21 20:53:27 +02001565 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1566 " in unexpected state: %s\n",
1567 gsm_lchan_name(lchan),
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001568 gsm_pchan_name(ts->pchan),
1569 pdch_act? "ACT" : "DEACT",
1570 gsm_lchans_name(lchan->state));
1571 return false;
1572 }
1573 return true;
1574}
1575
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001576static int rsl_rx_pdch_act_ack(struct msgb *msg)
1577{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001578 if (!lchan_may_change_pdch(msg->lchan, true))
1579 return -EINVAL;
1580
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001581 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001582 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001583
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001584 return 0;
1585}
1586
1587static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1588{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001589 if (!lchan_may_change_pdch(msg->lchan, false))
1590 return -EINVAL;
1591
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001592 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001593 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001594
Neels Hofmeyr6e999b72016-07-23 21:00:51 +02001595 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn.act_type,
1596 msg->lchan->dyn.ho_ref);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001597
1598 return 0;
1599}
1600
Harald Welte52b1f982008-12-23 20:25:15 +00001601static int abis_rsl_rx_dchan(struct msgb *msg)
1602{
Harald Welte8470bf22008-12-25 23:28:35 +00001603 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1604 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001605 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001606 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001607
Neels Hofmeyr2867f882016-08-23 01:22:58 +02001608 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1609 "Abis RSL rx DCHAN: ");
Neels Hofmeyra6ba6a32016-10-10 03:24:05 +02001610 if (!msg->lchan)
1611 return -1;
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001612 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001613
Harald Welte8470bf22008-12-25 23:28:35 +00001614 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001615 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001616 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001617 rc = rsl_rx_chan_act_ack(msg);
Alexander Couzens8c53c592016-08-23 06:27:19 +02001618 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001619 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001620 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001621 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001622 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001623 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001624 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001625 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001626 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001627 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001628 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001629 case RSL_MT_HANDO_DET:
1630 rc = rsl_rx_hando_det(msg);
1631 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001632 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001633 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001634 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001635 case RSL_MT_MODE_MODIFY_ACK:
Alexander Couzens8c53c592016-08-23 06:27:19 +02001636 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001637 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001638 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001639 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001640 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001641 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001642 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02001643 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001644 rc = rsl_rx_pdch_act_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001645 break;
1646 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001647 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001648 break;
1649 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001650 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001651 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001652 break;
1653 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001654 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001655 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001656 case RSL_MT_PHY_CONTEXT_CONF:
1657 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001658 case RSL_MT_TALKER_DET:
1659 case RSL_MT_LISTENER_DET:
1660 case RSL_MT_REMOTE_CODEC_CONF_REP:
1661 case RSL_MT_MR_CODEC_MOD_ACK:
1662 case RSL_MT_MR_CODEC_MOD_NACK:
1663 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001664 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1665 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001666 break;
1667 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001668 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1669 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001670 return -EINVAL;
1671 }
Harald Weltef325eb42009-02-19 17:07:39 +00001672
Harald Welte8470bf22008-12-25 23:28:35 +00001673 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001674}
1675
Harald Welte702d8702008-12-26 20:25:35 +00001676static int rsl_rx_error_rep(struct msgb *msg)
1677{
1678 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001679 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001680 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001681
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001682 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001683
1684 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1685
1686 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001687 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001688 TLVP_LEN(&tp, RSL_IE_CAUSE));
1689
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001690 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001691
1692 return 0;
1693}
1694
Harald Welte52b1f982008-12-23 20:25:15 +00001695static int abis_rsl_rx_trx(struct msgb *msg)
1696{
Harald Welte702d8702008-12-26 20:25:35 +00001697 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001698 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001699 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001700
1701 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001702 case RSL_MT_ERROR_REPORT:
1703 rc = rsl_rx_error_rep(msg);
1704 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001705 case RSL_MT_RF_RES_IND:
1706 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001707 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001708 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001709 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001710 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001711 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001712 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001713 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001714 case 0x42: /* Nokia specific: SI End ACK */
1715 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1716 break;
1717 case 0x43: /* Nokia specific: SI End NACK */
1718 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1719 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001720 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001721 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001722 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001723 return -EINVAL;
1724 }
Harald Welte8470bf22008-12-25 23:28:35 +00001725 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001726}
1727
Harald Welteb7e81162009-08-10 00:26:10 +02001728/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1729static void t3101_expired(void *data)
1730{
1731 struct gsm_lchan *lchan = data;
Max8dc8f232017-02-09 19:13:02 +01001732 LOGP(DRSL, LOGL_NOTICE,
1733 "%s T3101 expired: no response to IMMEDIATE ASSIGN\n",
1734 gsm_lchan_name(lchan));
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001735 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001736}
1737
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001738/* If T3111 expires, we will send the RF Channel Request */
1739static void t3111_expired(void *data)
1740{
1741 struct gsm_lchan *lchan = data;
Max8dc8f232017-02-09 19:13:02 +01001742 LOGP(DRSL, LOGL_NOTICE,
1743 "%s T3111 expired: releasing RF Channel\n",
1744 gsm_lchan_name(lchan));
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001745 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1746}
1747
1748/* If T3109 expires the MS has not send a UA/UM do the error release */
1749static void t3109_expired(void *data)
1750{
1751 struct gsm_lchan *lchan = data;
1752
1753 LOGP(DRSL, LOGL_ERROR,
1754 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1755 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001756}
1757
Harald Welte2862dca2010-12-23 14:39:29 +01001758/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1759static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1760 unsigned int num_req_refs,
1761 struct gsm48_req_ref *rqd_refs,
1762 uint8_t wait_ind)
1763{
1764 uint8_t buf[GSM_MACBLOCK_LEN];
1765 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1766
1767 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1768 memset(iar, 0, sizeof(*iar));
1769 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001770 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Welte2862dca2010-12-23 14:39:29 +01001771 iar->page_mode = GSM48_PM_SAME;
1772
1773 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1774 iar->wait_ind1 = wait_ind;
1775
1776 if (num_req_refs >= 2)
1777 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1778 else
1779 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1780 iar->wait_ind2 = wait_ind;
1781
1782 if (num_req_refs >= 3)
1783 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1784 else
1785 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1786 iar->wait_ind3 = wait_ind;
1787
1788 if (num_req_refs >= 4)
1789 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1790 else
1791 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1792 iar->wait_ind4 = wait_ind;
1793
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001794 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1795 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1796
1797 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Welte2862dca2010-12-23 14:39:29 +01001798}
1799
Philipp Maierb4999b62016-10-26 15:19:41 +02001800/* Handle packet channel rach requests */
1801static int rsl_rx_pchan_rqd(struct msgb *msg, struct gsm_bts *bts)
1802{
1803 struct gsm48_req_ref *rqd_ref;
1804 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1805 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1806 uint8_t ra = rqd_ref->ra;
1807 uint8_t t1, t2, t3;
1808 uint32_t fn;
1809 uint8_t rqd_ta;
1810 uint8_t is_11bit;
1811
1812 /* Process rach request and forward contained information to PCU */
1813 if (ra == 0x7F) {
1814 is_11bit = 1;
1815
1816 /* FIXME: Also handle 11 bit rach requests */
1817 LOGP(DRSL, LOGL_ERROR, "BTS %d eleven bit access burst not supported yet!\n",bts->nr);
1818 return -EINVAL;
1819 } else {
1820 is_11bit = 0;
1821 t1 = rqd_ref->t1;
1822 t2 = rqd_ref->t2;
1823 t3 = rqd_ref->t3_low | (rqd_ref->t3_high << 3);
1824 fn = (51 * ((t3-t2) % 26) + t3 + 51 * 26 * t1);
1825
1826 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1827 }
1828
1829 return pcu_tx_rach_ind(bts, rqd_ta, ra, fn, is_11bit,
1830 GSM_L1_BURST_TYPE_ACCESS_0);
1831}
1832
Harald Welte8470bf22008-12-25 23:28:35 +00001833/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001834static int rsl_rx_chan_rqd(struct msgb *msg)
1835{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001836 struct e1inp_sign_link *sign_link = msg->dst;
1837 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001838 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1839 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001840 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001841 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001842 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001843 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001844 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001845
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001846 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001847 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001848
Harald Welte8470bf22008-12-25 23:28:35 +00001849 /* parse request reference to be used in immediate assign */
1850 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1851 return -EINVAL;
1852
1853 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1854
1855 /* parse access delay and use as TA */
1856 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1857 return -EINVAL;
1858 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1859
Philipp Maierb4999b62016-10-26 15:19:41 +02001860 /* Determine channel request cause code */
1861 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
1862 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: reason: %s (ra=0x%02x, neci=0x%02x, chreq_reason=0x%02x)\n",
1863 msg->lchan->ts->trx->bts->nr,
1864 get_value_string(gsm_chreq_descs, chreq_reason),
1865 rqd_ref->ra, bts->network->neci, chreq_reason);
1866
1867 /* Handle PDCH related rach requests (in case of BSC-co-located-PCU */
1868 if (chreq_reason == GSM_CHREQ_REASON_PDCH)
1869 return rsl_rx_pchan_rqd(msg, bts);
1870
Harald Welte8470bf22008-12-25 23:28:35 +00001871 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1872 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001873 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
Harald Welte2cbe0922008-12-29 04:09:31 +00001874
Alexander Couzensb847a212016-08-02 11:34:11 +02001875 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL]);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001876
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001877 /*
1878 * We want LOCATION UPDATES to succeed and will assign a TCH
1879 * if we have no SDCCH available.
1880 */
1881 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1882
Harald Welte8470bf22008-12-25 23:28:35 +00001883 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001884 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001885 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001886 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001887 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Alexander Couzensb847a212016-08-02 11:34:11 +02001888 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL]);
Harald Welte2862dca2010-12-23 14:39:29 +01001889 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1890 if (bts->network->T3122)
1891 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte1dcc2602012-11-13 04:46:03 +01001892 return 0;
Harald Welte8470bf22008-12-25 23:28:35 +00001893 }
1894
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001895 /*
1896 * Expecting lchan state to be NONE, except for dyn TS in PDCH mode.
1897 * Those are expected to be ACTIVE: the PDCH release will be sent from
1898 * rsl_chan_activate_lchan() below.
1899 */
1900 if (lchan->state != LCHAN_S_NONE
1901 && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
1902 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
1903 && lchan->state == LCHAN_S_ACTIVE))
Harald Welte8e93b792009-12-29 10:44:17 +01001904 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001905 "in state %s\n", gsm_lchan_name(lchan),
1906 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001907
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001908 /* save the RACH data as we need it after the CHAN ACT ACK */
1909 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1910 if (!lchan->rqd_ref) {
1911 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1912 lchan_free(lchan);
1913 return -ENOMEM;
1914 }
1915
1916 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1917 lchan->rqd_ta = rqd_ta;
1918
Harald Welte8470bf22008-12-25 23:28:35 +00001919 arfcn = lchan->ts->trx->arfcn;
1920 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001921
Harald Welte08d91a52009-08-30 15:37:11 +09001922 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001923 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001924 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001925 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001926 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001927
Harald Weltee8bd9e82011-08-10 23:26:33 +02001928 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001929 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001930 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1931
Andreas Eversberg2957de92011-12-16 17:45:37 +01001932 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1933 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1934 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1935 rqd_ref->ra, rqd_ta);
1936
Neels Hofmeyr81516482016-07-15 01:26:03 +02001937 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001938
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001939 return 0;
1940}
1941
1942static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1943{
1944 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001945 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001946 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1947
Harald Welte52b1f982008-12-23 20:25:15 +00001948 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001949 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001950 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001951 ia->proto_discr = GSM48_PDISC_RR;
1952 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1953 ia->page_mode = GSM48_PM_SAME;
1954 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001955
Harald Welte8470bf22008-12-25 23:28:35 +00001956 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001957 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1958 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001959 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001960 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001961 } else {
laforge09108bf2010-06-20 15:18:46 +02001962 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1963 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001964 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001965 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1966 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001967
Harald Welteb7e81162009-08-10 00:26:10 +02001968 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001969 osmo_timer_setup(&lchan->T3101, t3101_expired, lchan);
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001970 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001971
Harald Welte52b1f982008-12-23 20:25:15 +00001972 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001973 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001974}
1975
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001976/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001977static int rsl_rx_ccch_load(struct msgb *msg)
1978{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001979 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001980 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001981 struct ccch_signal_data sd;
1982
1983 sd.bts = sign_link->trx->bts;
1984 sd.rach_slot_count = -1;
1985 sd.rach_busy_count = -1;
1986 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001987
1988 switch (rslh->data[0]) {
1989 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001990 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1991 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001992 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001993 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001994 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001995 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1996 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001997 break;
1998 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001999 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01002000 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
2001 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
2002 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
2003 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00002004 }
Harald Welteea280442009-02-02 22:29:56 +00002005 break;
2006 default:
2007 break;
2008 }
2009
2010 return 0;
2011}
2012
Harald Welte52b1f982008-12-23 20:25:15 +00002013static int abis_rsl_rx_cchan(struct msgb *msg)
2014{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002015 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00002016 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002017 int rc = 0;
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002018 uint32_t tlli;
Harald Welte52b1f982008-12-23 20:25:15 +00002019
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002020 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
2021 "Abis RSL rx CCHAN: ");
Harald Welte8470bf22008-12-25 23:28:35 +00002022
2023 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00002024 case RSL_MT_CHAN_RQD:
2025 /* MS has requested a channel on the RACH */
2026 rc = rsl_rx_chan_rqd(msg);
2027 break;
Harald Welteea280442009-02-02 22:29:56 +00002028 case RSL_MT_CCCH_LOAD_IND:
2029 /* current load on the CCCH */
2030 rc = rsl_rx_ccch_load(msg);
2031 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002032 case RSL_MT_DELETE_IND:
2033 /* CCCH overloaded, IMM_ASSIGN was dropped */
2034 case RSL_MT_CBCH_LOAD_IND:
2035 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002036 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
2037 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002038 break;
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002039 case 0x10: /* Ericsson specific: Immediate Assign Sent */
2040 /* FIXME: Replace the messy message parsing below
2041 * with proper TV parser */
2042 LOGP(DRSL, LOGL_INFO, "IMM.ass sent\n");
Alexander Couzens2faeb1a2017-03-13 11:00:59 +01002043 if(msg->len < 9)
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002044 LOGP(DRSL, LOGL_ERROR, "short IMM.ass sent message!\n");
2045 else if(msg->data[4] != 0xf1)
2046 LOGP(DRSL, LOGL_ERROR, "unsupported IMM.ass message format! (please fix)\n");
2047 else {
Alexander Couzens271ceca2017-03-13 11:06:52 +01002048 msgb_pull(msg, 5); /* drop previous data to use msg_pull_u32 */
2049 tlli = msgb_pull_u32(msg);
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002050 pcu_tx_imm_ass_sent(sign_link->trx->bts, tlli);
2051 }
2052 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002053 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002054 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
2055 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002056 return -EINVAL;
2057 }
Harald Welte8470bf22008-12-25 23:28:35 +00002058
2059 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002060}
2061
Harald Welte4b634542008-12-27 01:55:51 +00002062static int rsl_rx_rll_err_ind(struct msgb *msg)
2063{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002064 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00002065 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002066 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00002067
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002068 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
2069 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
2070 LOGP(DRLL, LOGL_ERROR,
2071 "%s ERROR INDICATION without mandantory cause.\n",
2072 gsm_lchan_name(msg->lchan));
2073 return -1;
2074 }
2075
2076 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02002077 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002078 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02002079 rsl_rlm_cause_name(rlm_cause),
2080 gsm_lchans_name(msg->lchan->state));
2081
Harald Welteedcc5272009-08-09 13:47:35 +02002082 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01002083
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002084 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Alexander Couzensb847a212016-08-02 11:34:11 +02002085 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 +02002086 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02002087 }
Harald Welte81543bc2009-07-04 09:40:05 +02002088
Harald Welte4b634542008-12-27 01:55:51 +00002089 return 0;
2090}
Harald Weltef325eb42009-02-19 17:07:39 +00002091
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002092static void rsl_handle_release(struct gsm_lchan *lchan)
2093{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002094 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002095 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002096
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +01002097 /*
2098 * Maybe only one link/SAPI was releasd or the error handling
2099 * was activated. Just return now and let the other code handle
2100 * it.
2101 */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002102 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002103 return;
2104
2105 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2106 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2107 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01002108 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002109 gsm_lchan_name(lchan), sapi);
2110 return;
2111 }
2112
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002113
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002114 /* Stop T3109 and wait for T3111 before re-using the channel */
2115 osmo_timer_del(&lchan->T3109);
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02002116 osmo_timer_setup(&lchan->T3111, t3111_expired, lchan);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002117 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002118 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002119}
2120
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002121/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00002122 0x02, 0x06,
2123 0x01, 0x20,
2124 0x02, 0x00,
2125 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
2126
2127static int abis_rsl_rx_rll(struct msgb *msg)
2128{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002129 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00002130 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00002131 int rc = 0;
2132 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002133 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00002134
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002135 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2136 "Abis RSL rx RLL: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002137 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01002138 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00002139
2140 switch (rllh->c.msg_type) {
2141 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002142 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002143 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002144 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2145 rllh->data[0] == RSL_IE_L3_INFO) {
2146 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02002147 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002148 }
Harald Welte52b1f982008-12-23 20:25:15 +00002149 break;
2150 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002151 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02002152 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002153 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002154 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002155 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002156 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2157 rllh->data[0] == RSL_IE_L3_INFO) {
2158 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02002159 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002160 }
Harald Welte52b1f982008-12-23 20:25:15 +00002161 break;
Harald Welteedcc5272009-08-09 13:47:35 +02002162 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02002163 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002164 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02002165 rll_indication(msg->lchan, rllh->link_id,
2166 BSC_RLLR_IND_EST_CONF);
2167 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002168 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02002169 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02002170 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002171 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02002172 rll_indication(msg->lchan, rllh->link_id,
2173 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002174 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00002175 break;
2176 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02002177 /* BTS informs us of having received UA from MS,
2178 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02002179 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002180 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002181 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00002182 break;
2183 case RSL_MT_ERROR_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002184 DEBUGPC(DRLL, "ERROR INDICATION\n");
Harald Welte4b634542008-12-27 01:55:51 +00002185 rc = rsl_rx_rll_err_ind(msg);
2186 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002187 case RSL_MT_UNIT_DATA_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002188 DEBUGPC(DRLL, "UNIT DATA INDICATION\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002189 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
2190 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002191 break;
2192 default:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002193 DEBUGPC(DRLL, "UNKNOWN\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002194 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
2195 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002196 }
Harald Welte8470bf22008-12-25 23:28:35 +00002197 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002198}
2199
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002200static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02002201{
Harald Welte0603c9d2009-12-02 01:58:23 +05302202 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02002203 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05302204 switch (lchan->type) {
2205 case GSM_LCHAN_TCH_F:
2206 return 0x00;
2207 case GSM_LCHAN_TCH_H:
2208 return 0x03;
2209 default:
2210 break;
2211 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002212 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002213 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05302214 switch (lchan->type) {
2215 case GSM_LCHAN_TCH_F:
2216 return 0x01;
2217 /* there's no half-rate EFR */
2218 default:
2219 break;
2220 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002221 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002222 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05302223 switch (lchan->type) {
2224 case GSM_LCHAN_TCH_F:
2225 return 0x02;
2226 case GSM_LCHAN_TCH_H:
2227 return 0x05;
2228 default:
2229 break;
2230 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002231 break;
Harald Welte0603c9d2009-12-02 01:58:23 +05302232 default:
2233 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002234 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002235 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05302236 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002237 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02002238}
2239
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002240static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01002241{
2242 switch (lchan->tch_mode) {
2243 case GSM48_CMODE_SPEECH_V1:
2244 switch (lchan->type) {
2245 case GSM_LCHAN_TCH_F:
2246 return RTP_PT_GSM_FULL;
2247 case GSM_LCHAN_TCH_H:
2248 return RTP_PT_GSM_HALF;
2249 default:
2250 break;
2251 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002252 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002253 case GSM48_CMODE_SPEECH_EFR:
2254 switch (lchan->type) {
2255 case GSM_LCHAN_TCH_F:
2256 return RTP_PT_GSM_EFR;
2257 /* there's no half-rate EFR */
2258 default:
2259 break;
2260 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002261 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002262 case GSM48_CMODE_SPEECH_AMR:
2263 switch (lchan->type) {
2264 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01002265 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02002266 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002267 default:
2268 break;
2269 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002270 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002271 default:
2272 break;
2273 }
2274 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
2275 "tch_mode == 0x%02x\n & lchan_type == %d",
2276 lchan->tch_mode, lchan->type);
2277 return 0;
2278}
2279
Harald Welte75099262009-02-16 21:12:08 +00002280/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002281static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
2282{
2283 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002284 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01002285
2286 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002287 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002288 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
2289 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
2290 }
2291
2292 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002293 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002294 port = ntohs(port);
2295 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
2296 lchan->abis_ip.bound_port = port;
2297 }
2298
2299 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002300 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002301 conn_id = ntohs(conn_id);
2302 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
2303 lchan->abis_ip.conn_id = conn_id;
2304 }
2305
2306 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
2307 lchan->abis_ip.rtp_payload2 =
2308 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
2309 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
2310 lchan->abis_ip.rtp_payload2);
2311 }
2312
2313 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
2314 lchan->abis_ip.speech_mode =
2315 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
2316 DEBUGPC(DRSL, "speech_mode=0x%02x ",
2317 lchan->abis_ip.speech_mode);
2318 }
2319
2320 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002321 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002322 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
2323 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
2324 }
2325
2326 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002327 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002328 port = ntohs(port);
2329 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
2330 lchan->abis_ip.connect_port = port;
2331 }
Philipp Maier39f62bb2017-04-09 12:32:51 +02002332
2333 DEBUGPC(DRSL, "\n");
Harald Welte5e3d91b2009-12-19 16:42:06 +01002334}
2335
Harald Welte647db842013-02-03 12:06:58 +01002336/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
2337 * \param[in] lchan Logical Channel for which we issue CRCX
2338 */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002339int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00002340{
2341 struct msgb *msg = rsl_msgb_alloc();
2342 struct abis_rsl_dchan_hdr *dh;
2343
2344 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002345 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00002346 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002347 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002348
Harald Weltef4e79f22009-07-28 18:11:56 +02002349 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002350 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002351 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002352 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002353 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002354
Sylvain Munautb54dda42009-12-20 22:06:40 +01002355 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
2356 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
2357 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002358
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002359 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002360
2361 return abis_rsl_sendmsg(msg);
2362}
2363
Harald Welte647db842013-02-03 12:06:58 +01002364/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
2365 * \param[in] lchan Logical Channel for which we issue MDCX
2366 * \param[in] ip Remote (MGW) IP address for RTP
2367 * \param[in] port Remote (MGW) UDP port number for RTP
2368 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
2369 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002370int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
2371 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00002372{
2373 struct msgb *msg = rsl_msgb_alloc();
2374 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002375 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02002376 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00002377
2378 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002379 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00002380 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002381 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002382
Harald Welte5e3d91b2009-12-19 16:42:06 +01002383 /* we need to store these now as MDCX_ACK does not return them :( */
2384 lchan->abis_ip.rtp_payload2 = rtp_payload2;
2385 lchan->abis_ip.connect_port = port;
2386 lchan->abis_ip.connect_ip = ip;
2387
Harald Welte58ca5b72009-07-29 12:12:18 +02002388 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002389 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002390 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02002391
Harald Weltef4e79f22009-07-28 18:11:56 +02002392 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002393 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
2394 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
2395 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
2396 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002397
Harald Welte5e3d91b2009-12-19 16:42:06 +01002398 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
2399 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002400 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01002401 *att_ip = ia.s_addr;
2402 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
2403 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002404 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002405 if (rtp_payload2)
2406 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002407
2408 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002409
2410 return abis_rsl_sendmsg(msg);
2411}
2412
Harald Weltea72273e2009-12-20 16:51:09 +01002413/* tell BTS to connect RTP stream to our local RTP socket */
2414int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
2415{
2416 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
2417 int rc;
2418
2419 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
2420 ntohs(rs->rtp.sin_local.sin_port),
2421 /* FIXME: use RTP payload of bound socket, not BTS*/
2422 lchan->abis_ip.rtp_payload2);
2423
2424 return rc;
2425}
2426
Harald Welte53cd7ac2010-12-23 12:59:52 +01002427int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02002428{
2429 struct msgb *msg = rsl_msgb_alloc();
2430 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002431 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08002432
Neels Hofmeyr32019882016-06-15 15:32:29 +02002433 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2434 LOGP(DRSL, LOGL_ERROR,
2435 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2436 gsm_ts_name(ts),
2437 act ? "ACT" : "DEACT",
2438 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2439 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2440 return -EINVAL;
2441 }
2442
2443 if (act){
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02002444 /* Callers should heed the GPRS mode. */
2445 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte4563eab2010-03-28 14:42:09 +08002446 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002447 ts->flags |= TS_F_PDCH_ACT_PENDING;
2448 } else {
Harald Welte4563eab2010-03-28 14:42:09 +08002449 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002450 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2451 }
2452 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welte9c880c92009-10-24 10:29:22 +02002453
2454 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08002455 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02002456 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee4dd94d2017-08-01 18:35:49 +02002457 dh->chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_TCH_F, ts->nr, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02002458
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02002459 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08002460 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02002461
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002462 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02002463
2464 return abis_rsl_sendmsg(msg);
2465}
2466
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002467static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002468{
2469 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2470 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05302471 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00002472
2473 /* the BTS has acknowledged a local bind, it now tells us the IP
2474 * address and port number to which it has bound the given logical
2475 * channel */
2476
2477 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2478 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2479 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02002480 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002481 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00002482 return -EINVAL;
2483 }
Harald Welte17f5bf62009-12-20 15:42:44 +01002484
Harald Welte5e3d91b2009-12-19 16:42:06 +01002485 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01002486
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002487 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00002488
Harald Welte75099262009-02-16 21:12:08 +00002489 return 0;
2490}
2491
Harald Welte5e3d91b2009-12-19 16:42:06 +01002492static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2493{
2494 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2495 struct tlv_parsed tv;
2496 struct gsm_lchan *lchan = msg->lchan;
2497
2498 /* the BTS has acknowledged a remote connect request and
2499 * it now tells us the IP address and port number to which it has
2500 * connected the given logical channel */
2501
2502 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2503 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002504 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002505
2506 return 0;
2507}
2508
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002509static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002510{
2511 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2512 struct tlv_parsed tv;
2513
2514 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00002515
Harald Welte8830e072009-07-28 17:58:09 +02002516 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01002517 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02002518 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00002519
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002520 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02002521
Harald Welte75099262009-02-16 21:12:08 +00002522 return 0;
2523}
2524
2525static int abis_rsl_rx_ipacc(struct msgb *msg)
2526{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002527 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00002528 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01002529 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00002530 int rc = 0;
2531
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002532 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2533 "Abis RSL rx IPACC: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002534 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00002535
2536 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002537 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01002538 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002539 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002540 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002541 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002542 /* somehow the BTS was unable to bind the lchan to its local
2543 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01002544 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002545 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002546 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00002547 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01002548 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002549 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002550 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002551 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002552 /* somehow the BTS was unable to connect the lchan to a remote
2553 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01002554 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002555 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002556 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01002557 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002558 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00002559 break;
2560 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01002561 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002562 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00002563 break;
2564 }
2565
2566 return rc;
2567}
2568
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002569int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts,
Neels Hofmeyrd3b7fa82016-07-23 20:08:41 +02002570 enum gsm_phys_chan_config to_pchan)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002571{
2572 int ss;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002573 int rc = -EIO;
2574
2575 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2576 DEBUGP(DRSL, "%s starting switchover to %s\n",
2577 gsm_ts_and_pchan_name(ts), gsm_pchan_name(to_pchan));
2578
2579 if (ts->dyn.pchan_is != ts->dyn.pchan_want) {
2580 LOGP(DRSL, LOGL_ERROR,
2581 "%s: Attempt to switch dynamic channel to %s,"
2582 " but is already in switchover.\n",
2583 gsm_ts_and_pchan_name(ts),
2584 gsm_pchan_name(to_pchan));
2585 return ts->dyn.pchan_want == to_pchan? 0 : -EAGAIN;
2586 }
2587
2588 if (ts->dyn.pchan_is == to_pchan) {
2589 LOGP(DRSL, LOGL_INFO,
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002590 "%s %s Already is in %s mode, cannot switchover.\n",
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002591 gsm_ts_name(ts), gsm_pchan_name(ts->pchan),
2592 gsm_pchan_name(to_pchan));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002593 return -EINVAL;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002594 }
2595
2596 /* Paranoia: let's make sure all is indeed released. */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002597 for (ss = 0; ss < ts_subslots(ts); ss++) {
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002598 struct gsm_lchan *lc = &ts->lchan[ss];
2599 if (lc->state != LCHAN_S_NONE) {
2600 LOGP(DRSL, LOGL_ERROR,
2601 "%s Attempt to switch dynamic channel to %s,"
2602 " but is not fully released.\n",
2603 gsm_ts_and_pchan_name(ts),
2604 gsm_pchan_name(to_pchan));
2605 return -EAGAIN;
2606 }
2607 }
2608
2609 /* Record that we're busy switching. */
2610 ts->dyn.pchan_want = to_pchan;
2611
2612 /*
2613 * To switch from PDCH, we need to initiate the release from the BSC
2614 * side. dyn_ts_switchover_continue() will be called from
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002615 * rsl_rx_rf_chan_rel_ack(). PDCH is always on lchan[0].
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002616 */
2617 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH) {
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002618 rsl_lchan_set_state(ts->lchan, LCHAN_S_REL_REQ);
2619 rc = rsl_rf_chan_release(ts->lchan, 0, SACCH_NONE);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002620 if (rc) {
2621 LOGP(DRSL, LOGL_ERROR,
2622 "%s RSL RF Chan Release failed\n",
2623 gsm_ts_and_pchan_name(ts));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002624 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002625 }
2626 return 0;
2627 }
2628
2629 /*
2630 * To switch from TCH/F and TCH/H pchans, this has been called from
2631 * rsl_rx_rf_chan_rel_ack(), i.e. release is complete. Go ahead and
2632 * activate as new type. This will always be PDCH.
2633 */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002634 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002635}
2636
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002637static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002638{
2639 int rc;
2640 uint8_t act_type;
2641 uint8_t ho_ref;
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002642 int ss;
2643 struct gsm_lchan *lchan;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002644
2645 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2646 DEBUGP(DRSL, "%s switchover: release complete,"
2647 " activating new pchan type\n",
2648 gsm_ts_and_pchan_name(ts));
2649
2650 if (ts->dyn.pchan_is == ts->dyn.pchan_want) {
2651 LOGP(DRSL, LOGL_ERROR,
2652 "%s Requested to switchover dynamic channel to the"
2653 " same type it is already in.\n",
2654 gsm_ts_and_pchan_name(ts));
2655 return 0;
2656 }
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002657
2658 for (ss = 0; ss < ts_subslots(ts); ss++) {
2659 lchan = &ts->lchan[ss];
2660 if (lchan->rqd_ref) {
2661 LOGP(DRSL, LOGL_ERROR,
2662 "%s During dyn TS switchover, expecting no"
2663 " Request Reference to be pending. Discarding!\n",
2664 gsm_lchan_name(lchan));
2665 talloc_free(lchan->rqd_ref);
2666 lchan->rqd_ref = NULL;
2667 }
2668 }
2669
2670 /*
2671 * When switching pchan modes, all lchans are unused. So always
2672 * activate whatever wants to be activated on the first lchan. (We
2673 * wouldn't remember to use lchan[1] across e.g. a PDCH deact anyway)
2674 */
2675 lchan = ts->lchan;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002676
2677 /*
2678 * For TCH/x, the lchan->type has been set in lchan_alloc(), but it may
2679 * have been lost during channel release due to dynamic switchover.
2680 *
2681 * For PDCH, the lchan->type will actually remain NONE.
2682 * TODO: set GSM_LCHAN_PDTCH?
2683 */
2684 switch (ts->dyn.pchan_want) {
2685 case GSM_PCHAN_TCH_F:
2686 lchan->type = GSM_LCHAN_TCH_F;
2687 break;
2688 case GSM_PCHAN_TCH_H:
2689 lchan->type = GSM_LCHAN_TCH_H;
2690 break;
2691 case GSM_PCHAN_PDCH:
2692 lchan->type = GSM_LCHAN_NONE;
2693 break;
2694 default:
2695 LOGP(DRSL, LOGL_ERROR,
2696 "%s Invalid target pchan for dynamic TS\n",
2697 gsm_ts_and_pchan_name(ts));
2698 }
2699
2700 act_type = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2701 ? RSL_ACT_OSMO_PDCH
2702 : lchan->dyn.act_type;
2703 ho_ref = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2704 ? 0
2705 : lchan->dyn.ho_ref;
2706
2707 /* Fetch the rqd_ref back from before switchover started. */
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002708 lchan->rqd_ref = lchan->dyn.rqd_ref;
2709 lchan->rqd_ta = lchan->dyn.rqd_ta;
2710 lchan->dyn.rqd_ref = NULL;
2711 lchan->dyn.rqd_ta = 0;
2712
Neels Hofmeyra2ef7d62016-08-24 16:57:31 +02002713 /* During switchover, we have received a release ack, which means that
2714 * the act_timer has been stopped. Start the timer again so we mark
2715 * this channel broken if the activation ack comes too late. */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02002716 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Neels Hofmeyra2ef7d62016-08-24 16:57:31 +02002717 osmo_timer_schedule(&lchan->act_timer, 4, 0);
2718
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002719 rc = rsl_chan_activate_lchan(lchan, act_type, ho_ref);
2720 if (rc) {
2721 LOGP(DRSL, LOGL_ERROR,
2722 "%s RSL Chan Activate failed\n",
2723 gsm_ts_and_pchan_name(ts));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002724 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002725 }
2726 return 0;
2727}
2728
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002729static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002730{
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002731 ts->dyn.pchan_want = ts->dyn.pchan_is;
2732 LOGP(DRSL, LOGL_ERROR, "%s Error %d during dynamic channel switchover."
2733 " Going back to previous pchan.\n", gsm_ts_and_pchan_name(ts),
2734 rc);
2735 return rc;
2736}
2737
2738static void dyn_ts_switchover_complete(struct gsm_lchan *lchan)
2739{
2740 enum gsm_phys_chan_config pchan_act;
2741 enum gsm_phys_chan_config pchan_was;
2742 struct gsm_bts_trx_ts *ts = lchan->ts;
2743
2744 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2745
2746 pchan_act = pchan_for_lchant(lchan->type);
2747 /*
2748 * Paranoia: do the types match?
2749 * In case of errors: we've received an act ack already, so what to do
2750 * about it? Logging the error should suffice for now.
2751 */
2752 if (pchan_act != ts->dyn.pchan_want)
2753 LOGP(DRSL, LOGL_ERROR,
2754 "%s Requested transition does not match lchan type %s\n",
2755 gsm_ts_and_pchan_name(ts),
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002756 gsm_lchant_name(lchan->type));
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002757
2758 pchan_was = ts->dyn.pchan_is;
2759 ts->dyn.pchan_is = ts->dyn.pchan_want = pchan_act;
2760
Neels Hofmeyra0a08d82016-08-24 14:42:58 +02002761 if (pchan_was != ts->dyn.pchan_is)
2762 LOGP(DRSL, LOGL_INFO, "%s switchover from %s complete.\n",
2763 gsm_ts_and_pchan_name(ts), gsm_pchan_name(pchan_was));
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002764}
Harald Welte75099262009-02-16 21:12:08 +00002765
Harald Welte52b1f982008-12-23 20:25:15 +00002766/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00002767int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00002768{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002769 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002770 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002771
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002772 if (!msg) {
2773 DEBUGP(DRSL, "Empty RSL msg?..\n");
2774 return -1;
2775 }
2776
2777 if (msgb_l2len(msg) < sizeof(*rslh)) {
2778 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02002779 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002780 return -1;
2781 }
2782
2783 rslh = msgb_l2(msg);
2784
Harald Welte52b1f982008-12-23 20:25:15 +00002785 switch (rslh->msg_discr & 0xfe) {
2786 case ABIS_RSL_MDISC_RLL:
2787 rc = abis_rsl_rx_rll(msg);
2788 break;
2789 case ABIS_RSL_MDISC_DED_CHAN:
2790 rc = abis_rsl_rx_dchan(msg);
2791 break;
2792 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00002793 rc = abis_rsl_rx_cchan(msg);
2794 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002795 case ABIS_RSL_MDISC_TRX:
2796 rc = abis_rsl_rx_trx(msg);
2797 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002798 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002799 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002800 rslh->msg_discr);
2801 break;
Harald Welte75099262009-02-16 21:12:08 +00002802 case ABIS_RSL_MDISC_IPACCESS:
2803 rc = abis_rsl_rx_ipacc(msg);
2804 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002805 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002806 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2807 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002808 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002809 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002810 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002811 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002812}
Holger Freyther3b72a892009-02-04 00:31:39 +00002813
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002814int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Welte30f1f372014-12-28 15:00:45 +01002815 struct rsl_ie_cb_cmd_type cb_command,
2816 const uint8_t *data, int len)
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002817{
2818 struct abis_rsl_dchan_hdr *dh;
2819 struct msgb *cb_cmd;
2820
2821 cb_cmd = rsl_msgb_alloc();
2822 if (!cb_cmd)
2823 return -1;
2824
Harald Welte30f1f372014-12-28 15:00:45 +01002825 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002826 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Welte30f1f372014-12-28 15:00:45 +01002827 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2828 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002829
Harald Welte30f1f372014-12-28 15:00:45 +01002830 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002831 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2832
Harald Welte30f1f372014-12-28 15:00:45 +01002833 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002834
2835 return abis_rsl_sendmsg(cb_cmd);
2836}
Dieter Spaar16646022011-07-28 00:01:50 +02002837
2838int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2839{
2840 struct abis_rsl_common_hdr *ch;
2841 struct msgb *msg = rsl_msgb_alloc();
2842
2843 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2844 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2845 ch->msg_type = 0x40; /* Nokia SI Begin */
2846
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002847 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002848
2849 return abis_rsl_sendmsg(msg);
2850}
2851
2852int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2853{
2854 struct abis_rsl_common_hdr *ch;
2855 struct msgb *msg = rsl_msgb_alloc();
2856
2857 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2858 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2859 ch->msg_type = 0x41; /* Nokia SI End */
2860
2861 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2862
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002863 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002864
2865 return abis_rsl_sendmsg(msg);
2866}
2867
2868int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2869{
2870 struct abis_rsl_common_hdr *ch;
2871 struct msgb *msg = rsl_msgb_alloc();
2872
2873 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2874 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2875 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2876
2877 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2878 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2879
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002880 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002881
2882 return abis_rsl_sendmsg(msg);
2883}
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01002884
2885/**
2886 * Release all allocated SAPIs starting from @param start and
2887 * release them with the given release mode. Once the release
2888 * confirmation arrives it will be attempted to release the
2889 * the RF channel.
2890 */
2891int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2892 enum rsl_rel_mode release_mode)
2893{
2894 int no_sapi = 1;
2895 int sapi;
2896
2897 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2898 uint8_t link_id;
2899 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2900 continue;
2901
2902 link_id = sapi;
2903 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2904 link_id |= 0x40;
2905 rsl_release_request(lchan, link_id, release_mode);
2906 no_sapi = 0;
2907 }
2908
2909 return no_sapi;
2910}
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002911
2912int rsl_start_t3109(struct gsm_lchan *lchan)
2913{
2914 struct gsm_bts *bts = lchan->ts->trx->bts;
2915
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02002916 osmo_timer_setup(&lchan->T3109, t3109_expired, lchan);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002917 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2918 return 0;
2919}
Holger Hans Peter Freyther006e3d82012-12-25 23:45:14 +01002920
2921/**
2922 * \brief directly RF Channel Release the lchan
2923 *
2924 * When no SAPI was allocated, directly release the logical channel. This
2925 * should only be called from chan_alloc.c on channel release handling. In
2926 * case no SAPI was established the RF Channel can be directly released,
2927 */
2928int rsl_direct_rf_release(struct gsm_lchan *lchan)
2929{
2930 int i;
2931 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2932 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2933 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2934 gsm_lchan_name(lchan), i);
2935 return -1;
2936 }
2937 }
2938
2939 /* Now release it */
2940 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2941}