blob: 5ae707c14e01b0f9ace61730f54642c6787afc5b [file] [log] [blame]
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte52b1f982008-12-23 20:25:15 +00002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Welte3c9c5f92010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte8470bf22008-12-25 23:28:35 +00006 *
Harald Welte52b1f982008-12-23 20:25:15 +00007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte52b1f982008-12-23 20:25:15 +000012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte52b1f982008-12-23 20:25:15 +000021 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
Harald Welte75099262009-02-16 21:12:08 +000027#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000028#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Harald Welte8470bf22008-12-25 23:28:35 +000030#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000036#include <openbsc/debug.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Maxc08ee712016-05-11 12:45:13 +020038#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include <osmocom/gsm/protocol/gsm_08_58.h>
Holger Freyther392209c2009-02-10 00:06:19 +000040#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000041#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010042#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010043#include <openbsc/rtp_proxy.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020044#include <osmocom/abis/e1_input.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010045#include <osmocom/gsm/rsl.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010046#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080047
Harald Welte8470bf22008-12-25 23:28:35 +000048#define RSL_ALLOC_SIZE 1024
49#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000050
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +010051enum sacch_deact {
52 SACCH_NONE,
53 SACCH_DEACTIVATE,
54};
55
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080056static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020057static void error_timeout_cb(void *data);
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +020058static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts);
59static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +020060static void dyn_ts_switchover_complete(struct gsm_lchan *lchan);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080061
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010062static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
63 struct gsm_meas_rep *resp)
64{
65 struct lchan_signal_data sig;
66 sig.lchan = lchan;
67 sig.mr = resp;
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +020068 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010069}
70
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010071static void do_lchan_free(struct gsm_lchan *lchan)
72{
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020073 /* We start the error timer to make the channel available again */
74 if (lchan->state == LCHAN_S_REL_ERR) {
75 lchan->error_timer.data = lchan;
76 lchan->error_timer.cb = error_timeout_cb;
77 osmo_timer_schedule(&lchan->error_timer,
78 lchan->ts->trx->bts->network->T3111 + 2, 0);
79 } else {
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010080 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020081 }
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010082 lchan_free(lchan);
83}
84
Alexander Couzens8c53c592016-08-23 06:27:19 +020085static void count_codecs(struct gsm_bts *bts, struct gsm_lchan *lchan)
86{
87 OSMO_ASSERT(bts);
88
89 if (lchan->type == GSM_LCHAN_TCH_H) {
90 switch (lchan->tch_mode) {
91 case GSM48_CMODE_SPEECH_AMR:
92 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_H]);
93 break;
94 case GSM48_CMODE_SPEECH_V1:
95 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_HR]);
96 break;
97 default:
98 break;
99 }
100 } else if (lchan->type == GSM_LCHAN_TCH_F) {
101 switch (lchan->tch_mode) {
102 case GSM48_CMODE_SPEECH_AMR:
103 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_F]);
104 break;
105 case GSM48_CMODE_SPEECH_V1:
106 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_FR]);
107 break;
108 case GSM48_CMODE_SPEECH_EFR:
109 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_EFR]);
110 break;
111 default:
112 break;
113 }
Alexander Couzens8c53c592016-08-23 06:27:19 +0200114 }
115}
116
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200117static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000118{
119 /* mask off the transparent bit ? */
120 msg_type &= 0xfe;
121
Harald Welte8470bf22008-12-25 23:28:35 +0000122 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +0000123 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +0000124 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +0000125 if (msg_type >= 0x19 && msg_type <= 0x22)
126 return ABIS_RSL_MDISC_TRX;
127 else
128 return ABIS_RSL_MDISC_COM_CHAN;
129 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000130 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +0000131 return ABIS_RSL_MDISC_DED_CHAN;
132
133 return ABIS_RSL_MDISC_LOC;
134}
135
136static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200137 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000138{
139 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
140 dh->c.msg_type = msg_type;
141 dh->ie_chan = RSL_IE_CHAN_NR;
142}
143
Neels Hofmeyr74585722016-07-23 17:38:22 +0200144/* call rsl_lchan_lookup and set the log context */
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200145static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
146 const char *log_name)
Harald Welte8470bf22008-12-25 23:28:35 +0000147{
Neels Hofmeyr74585722016-07-23 17:38:22 +0200148 int rc;
149 struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc);
Harald Welte8470bf22008-12-25 23:28:35 +0000150
Neels Hofmeyr74585722016-07-23 17:38:22 +0200151 if (!lchan) {
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200152 LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n",
153 log_name, chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000154 return NULL;
155 }
156
Neels Hofmeyr74585722016-07-23 17:38:22 +0200157 if (rc < 0)
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200158 LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n",
159 gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr);
Neels Hofmeyr74585722016-07-23 17:38:22 +0200160
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800161 if (lchan->conn)
Neels Hofmeyr89a8e722017-02-23 18:00:51 +0100162 log_set_context(LOG_CTX_VLR_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000163
164 return lchan;
165}
166
Harald Welte52b1f982008-12-23 20:25:15 +0000167/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200168uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000169{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200170 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000171
172 ret = strtoull(imsi_str, NULL, 10);
173
174 return ret;
175}
176
Harald Welte8470bf22008-12-25 23:28:35 +0000177static struct msgb *rsl_msgb_alloc(void)
178{
Harald Welte966636f2009-06-26 19:39:35 +0200179 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
180 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000181}
182
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200183static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000184{
185 memcpy(out, in, len);
186
Maxb726c2c2017-02-09 19:23:38 +0100187 if (len < GSM_MACBLOCK_LEN)
188 memset(out+len, 0x2b, GSM_MACBLOCK_LEN - len);
Harald Welte362322e2009-02-15 14:36:38 +0000189}
190
Harald Welte08d91a52009-08-30 15:37:11 +0900191/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200192static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900193{
194 *out++ = lchan->encr.alg_id & 0xff;
195 if (lchan->encr.key_len)
196 memcpy(out, lchan->encr.key, lchan->encr.key_len);
197 return lchan->encr.key_len + 1;
198}
199
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200200static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200201{
Harald Welte7f93cea2009-02-23 00:02:59 +0000202 int i;
203
Harald Welte5b8ed432009-12-24 12:20:20 +0100204 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200205 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200206 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100207 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000208}
209
Harald Weltee8bd9e82011-08-10 23:26:33 +0200210static void lchan_act_tmr_cb(void *data)
211{
212 struct gsm_lchan *lchan = data;
213
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100214 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann513da172011-08-11 04:44:12 +0200215 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200216}
217
218static void lchan_deact_tmr_cb(void *data)
219{
220 struct gsm_lchan *lchan = data;
221
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100222 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200223 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200224}
225
226
Harald Welte52b1f982008-12-23 20:25:15 +0000227/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200228int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
229 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000230{
231 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000232 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000233
234 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
235 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
236 dh->chan_nr = RSL_CHAN_BCCH;
237
Philipp309425e2016-11-02 12:05:44 +0100238 if (trx->bts->type == GSM_BTS_TYPE_RBS2000
239 && type == RSL_SYSTEM_INFO_13) {
240 /* Ericsson proprietary encoding of SI13 */
241 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, RSL_ERIC_SYSTEM_INFO_13);
242 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
243 msgb_tv_put(msg, RSL_IE_ERIC_BCCH_MAPPING, 0x00);
244 } else {
245 /* Normal encoding */
246 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
247 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
248 }
Harald Welte52b1f982008-12-23 20:25:15 +0000249
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200250 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000251
252 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000253}
254
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200255int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
256 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000257{
258 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000259 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000260
261 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
262 ch->msg_discr = ABIS_RSL_MDISC_TRX;
263 ch->msg_type = RSL_MT_SACCH_FILL;
264
265 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000266 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000267
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200268 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000269
270 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000271}
272
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200273int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
274 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100275{
276 struct abis_rsl_dchan_hdr *dh;
277 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200278 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100279
280 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
281 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
282 dh->chan_nr = chan_nr;
283
284 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
285 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
286
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200287 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100288
289 return abis_rsl_sendmsg(msg);
290}
291
Harald Weltefcd24452009-06-20 18:15:19 +0200292int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
293{
294 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200295 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200296 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200297
298 db = abs(db);
299 if (db > 30)
300 return -EINVAL;
301
Harald Welteeab33352009-06-27 03:09:08 +0200302 msg = rsl_msgb_alloc();
303
Harald Weltefcd24452009-06-20 18:15:19 +0200304 lchan->bs_power = db/2;
305 if (fpc)
306 lchan->bs_power |= 0x10;
307
308 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
309 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
310 dh->chan_nr = chan_nr;
311
312 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
313
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200314 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200315
316 return abis_rsl_sendmsg(msg);
317}
318
Harald Weltefcd24452009-06-20 18:15:19 +0200319int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
320{
321 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200322 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200323 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200324 int ctl_lvl;
325
Harald Welte66b6a8d2009-08-09 14:45:18 +0200326 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200327 if (ctl_lvl < 0)
328 return ctl_lvl;
329
Harald Welteeab33352009-06-27 03:09:08 +0200330 msg = rsl_msgb_alloc();
331
Harald Weltefcd24452009-06-20 18:15:19 +0200332 lchan->ms_power = ctl_lvl;
333
334 if (fpc)
335 lchan->ms_power |= 0x20;
336
337 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
338 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
339 dh->chan_nr = chan_nr;
340
341 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
342
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200343 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200344
345 return abis_rsl_sendmsg(msg);
346}
347
Harald Welte9943c5b2009-07-29 15:41:29 +0200348static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
349 struct gsm_lchan *lchan)
350{
Holger Hans Peter Freythere1145cf2013-03-09 17:50:10 +0100351 memset(cm, 0, sizeof(*cm));
Harald Welte9943c5b2009-07-29 15:41:29 +0200352
353 /* FIXME: what to do with data calls ? */
Maxc08ee712016-05-11 12:45:13 +0200354 cm->dtx_dtu = 0;
355 if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
356 cm->dtx_dtu |= RSL_CMOD_DTXu;
357 if (lchan->ts->trx->bts->dtxd)
358 cm->dtx_dtu |= RSL_CMOD_DTXd;
Harald Welte9943c5b2009-07-29 15:41:29 +0200359
360 /* set TCH Speech/Data */
361 cm->spd_ind = lchan->rsl_cmode;
362
Harald Welte1a79d362009-11-27 08:55:16 +0100363 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
364 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100365 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100366 "but tch_mode != signalling\n");
367
Harald Welte9943c5b2009-07-29 15:41:29 +0200368 switch (lchan->type) {
369 case GSM_LCHAN_SDCCH:
370 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
371 break;
372 case GSM_LCHAN_TCH_F:
373 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
374 break;
375 case GSM_LCHAN_TCH_H:
376 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
377 break;
378 case GSM_LCHAN_NONE:
379 case GSM_LCHAN_UNKNOWN:
380 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200381 LOGP(DRSL, LOGL_ERROR,
382 "unsupported activation lchan->type %u %s\n",
383 lchan->type, gsm_lchant_name(lchan->type));
Harald Welte9943c5b2009-07-29 15:41:29 +0200384 return -EINVAL;
385 }
386
387 switch (lchan->tch_mode) {
388 case GSM48_CMODE_SIGN:
389 cm->chan_rate = 0;
390 break;
391 case GSM48_CMODE_SPEECH_V1:
392 cm->chan_rate = RSL_CMOD_SP_GSM1;
393 break;
394 case GSM48_CMODE_SPEECH_EFR:
395 cm->chan_rate = RSL_CMOD_SP_GSM2;
396 break;
397 case GSM48_CMODE_SPEECH_AMR:
398 cm->chan_rate = RSL_CMOD_SP_GSM3;
399 break;
400 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200401 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200402 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200403 switch (lchan->csd_mode) {
404 case LCHAN_CSD_M_NT:
405 /* non-transparent CSD with RLP */
406 switch (lchan->tch_mode) {
407 case GSM48_CMODE_DATA_14k5:
408 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
409 break;
410 case GSM48_CMODE_DATA_12k0:
411 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
412 break;
413 case GSM48_CMODE_DATA_6k0:
414 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
415 break;
416 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200417 LOGP(DRSL, LOGL_ERROR,
418 "unsupported lchan->tch_mode %u\n",
419 lchan->tch_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200420 return -EINVAL;
421 }
422 break;
423 /* transparent data services below */
424 case LCHAN_CSD_M_T_1200_75:
425 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
426 break;
427 case LCHAN_CSD_M_T_600:
428 cm->chan_rate = RSL_CMOD_CSD_T_600;
429 break;
430 case LCHAN_CSD_M_T_1200:
431 cm->chan_rate = RSL_CMOD_CSD_T_1200;
432 break;
433 case LCHAN_CSD_M_T_2400:
434 cm->chan_rate = RSL_CMOD_CSD_T_2400;
435 break;
436 case LCHAN_CSD_M_T_9600:
437 cm->chan_rate = RSL_CMOD_CSD_T_9600;
438 break;
439 case LCHAN_CSD_M_T_14400:
440 cm->chan_rate = RSL_CMOD_CSD_T_14400;
441 break;
442 case LCHAN_CSD_M_T_29000:
443 cm->chan_rate = RSL_CMOD_CSD_T_29000;
444 break;
445 case LCHAN_CSD_M_T_32000:
446 cm->chan_rate = RSL_CMOD_CSD_T_32000;
447 break;
448 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200449 LOGP(DRSL, LOGL_ERROR,
450 "unsupported lchan->csd_mode %u\n",
451 lchan->csd_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200452 return -EINVAL;
453 }
Harald Welteb8e8d0a2016-11-26 15:16:14 +0100454 break;
Harald Welte9943c5b2009-07-29 15:41:29 +0200455 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200456 LOGP(DRSL, LOGL_ERROR,
457 "unsupported lchan->tch_mode %u\n",
458 lchan->tch_mode);
Harald Welte9943c5b2009-07-29 15:41:29 +0200459 return -EINVAL;
460 }
461
462 return 0;
463}
464
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200465static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
466{
467 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
468 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
469 lchan->mr_bts_lv + 1);
470}
471
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200472static enum gsm_phys_chan_config pchan_for_lchant(enum gsm_chan_t type)
473{
474 switch (type) {
475 case GSM_LCHAN_TCH_F:
476 return GSM_PCHAN_TCH_F;
477 case GSM_LCHAN_TCH_H:
478 return GSM_PCHAN_TCH_H;
479 case GSM_LCHAN_NONE:
480 case GSM_LCHAN_PDTCH:
481 /* TODO: so far lchan->type is NONE in PDCH mode. PDTCH is only
482 * used in osmo-bts. Maybe set PDTCH and drop the NONE case
483 * here. */
484 return GSM_PCHAN_PDCH;
485 default:
486 return GSM_PCHAN_UNKNOWN;
487 }
488}
489
490/*! Tx simplified channel activation message for non-standard PDCH type. */
491static int rsl_chan_activate_lchan_as_pdch(struct gsm_lchan *lchan)
492{
493 struct msgb *msg;
494 struct abis_rsl_dchan_hdr *dh;
495
496 /* This might be called after release of the second lchan of a TCH/H,
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200497 * but PDCH activation must always happen on the first lchan. Make sure
498 * the calling code passes the correct lchan. */
499 OSMO_ASSERT(lchan == lchan->ts->lchan);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200500
501 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
502
503 msg = rsl_msgb_alloc();
504 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
505 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
506 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);
507
508 msgb_tv_put(msg, RSL_IE_ACT_TYPE, RSL_ACT_OSMO_PDCH);
509
Harald Weltef7e9a342016-11-16 15:17:22 +0100510 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_RBS2000 &&
511 lchan->ts->trx->bts->rbs2000.use_superchannel) {
512 const uint8_t eric_pgsl_tmr[] = { 30, 1 };
513 msgb_tv_fixed_put(msg, RSL_IE_ERIC_PGSL_TIMERS,
514 sizeof(eric_pgsl_tmr), eric_pgsl_tmr);
515 }
516
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200517 msg->dst = lchan->ts->trx->rsl_link;
518
519 return abis_rsl_sendmsg(msg);
520}
521
Harald Welte52b1f982008-12-23 20:25:15 +0000522/* Chapter 8.4.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200523int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg723a7512013-10-11 12:55:35 +0200524 uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000525{
526 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200527 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200528 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200529 uint8_t *len;
Andreas Eversberg723a7512013-10-11 12:55:35 +0200530 uint8_t ta;
Harald Welte4b634542008-12-27 01:55:51 +0000531
Harald Welte4b634542008-12-27 01:55:51 +0000532 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200533 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000534
Neels Hofmeyrc6926d02016-07-14 02:51:13 +0200535 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200536 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200537 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200538 /* store activation type and handover reference */
Neels Hofmeyr6e999b72016-07-23 21:00:51 +0200539 lchan->dyn.act_type = act_type;
540 lchan->dyn.ho_ref = ho_ref;
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200541 return rsl_ipacc_pdch_activate(lchan->ts, 0);
542 }
543
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200544 /*
545 * If necessary, release PDCH on dynamic TS. Note that sending a
546 * release here is only necessary when in PDCH mode; for TCH types, an
547 * RSL RF Chan Release is initiated by the BTS when a voice call ends,
548 * so when we reach this, it will already be released. If a dyn TS is
549 * in PDCH mode, it is still active and we need to initiate a release
550 * from the BSC side here.
551 *
552 * If pchan_is != pchan_want, the PDCH has already been taken down and
553 * the switchover now needs to enable the TCH lchan.
554 *
555 * To switch a dyn TS between TCH/H and TCH/F, it is sufficient to send
556 * a chan activ with the new lchan type, because it will already be
557 * released.
558 */
559 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
560 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
561 && lchan->ts->dyn.pchan_is == lchan->ts->dyn.pchan_want) {
562 enum gsm_phys_chan_config pchan_want;
563 pchan_want = pchan_for_lchant(lchan->type);
564 if (lchan->ts->dyn.pchan_is != pchan_want) {
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200565 /*
566 * Make sure to record on lchan[0] so that we'll find
567 * it after the PDCH release.
568 */
569 struct gsm_lchan *lchan0 = lchan->ts->lchan;
570 lchan0->dyn.act_type = act_type,
571 lchan0->dyn.ho_ref = ho_ref;
572 lchan0->dyn.rqd_ref = lchan->rqd_ref;
573 lchan0->dyn.rqd_ta = lchan->rqd_ta;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200574 lchan->rqd_ref = NULL;
575 lchan->rqd_ta = 0;
576 DEBUGP(DRSL, "%s saved rqd_ref=%p ta=%u\n",
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200577 gsm_lchan_name(lchan0), lchan0->rqd_ref,
578 lchan0->rqd_ta);
579 return dyn_ts_switchover_start(lchan->ts, pchan_want);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200580 }
581 }
582
583 DEBUGP(DRSL, "%s Tx RSL Channel Activate with act_type=%s\n",
584 gsm_ts_and_pchan_name(lchan->ts),
585 rsl_act_type_name(act_type));
586
587 if (act_type == RSL_ACT_OSMO_PDCH) {
588 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH) {
589 LOGP(DRSL, LOGL_ERROR,
590 "%s PDCH channel activation only allowed on %s\n",
591 gsm_ts_and_pchan_name(lchan->ts),
592 gsm_pchan_name(GSM_PCHAN_TCH_F_TCH_H_PDCH));
593 return -EINVAL;
594 }
595 return rsl_chan_activate_lchan_as_pdch(lchan);
596 }
597
598 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
599 && lchan->ts->dyn.pchan_want == GSM_PCHAN_PDCH) {
600 LOGP(DRSL, LOGL_ERROR,
601 "%s Expected PDCH activation kind\n",
602 gsm_ts_and_pchan_name(lchan->ts));
603 return -EINVAL;
604 }
605
Neels Hofmeyrcf793382016-07-23 19:49:58 +0200606 rc = channel_mode_from_lchan(&cm, lchan);
607 if (rc < 0) {
608 LOGP(DRSL, LOGL_ERROR,
609 "%s Cannot find channel mode from lchan type\n",
610 gsm_ts_and_pchan_name(lchan->ts));
611 return rc;
612 }
613
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200614 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
615
Andreas Eversberg723a7512013-10-11 12:55:35 +0200616 ta = lchan->rqd_ta;
617
618 /* BS11 requires TA shifted by 2 bits */
619 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
620 ta <<= 2;
621
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800622 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200623 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000624
Harald Welteeab33352009-06-27 03:09:08 +0200625 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000626 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
627 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
Neels Hofmeyr7af652c2016-07-23 19:51:09 +0200628
629 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
630 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(
631 lchan, lchan->ts->dyn.pchan_want);
632 else
633 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000634
635 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000636 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200637 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800638
639 /*
640 * The Channel Identification is needed for Phase1 phones
641 * and it contains the GSM48 Channel Description and the
642 * Mobile Allocation. The GSM 08.58 asks for the Mobile
643 * Allocation to have a length of zero. We are using the
644 * msgb_l3len to calculate the length of both messages.
645 */
laforge694a5cf2010-06-20 21:38:19 +0200646 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200647 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200648 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800649
650 if (lchan->ts->hopping.enabled)
651 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
652 lchan->ts->hopping.ma_data);
653 else
654 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800655
656 /* update the calculated size */
657 msg->l3h = len + 1;
658 *len = msgb_l3len(msg);
659
Harald Welte08d91a52009-08-30 15:37:11 +0900660 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200661 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900662 rc = build_encr_info(encr_info, lchan);
663 if (rc > 0)
664 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
665 }
666
Harald Welte8d77b952009-12-17 00:31:10 +0100667 switch (act_type) {
668 case RSL_ACT_INTER_ASYNC:
669 case RSL_ACT_INTER_SYNC:
670 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
671 break;
672 default:
673 break;
674 }
675
Harald Welted4c9bf32009-02-15 16:56:18 +0000676 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
677 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000678 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200679 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100680
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200681 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000682
Harald Welte4b634542008-12-27 01:55:51 +0000683 return abis_rsl_sendmsg(msg);
684}
685
Harald Welte470abb72009-07-29 11:38:15 +0200686/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000687int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
688{
689 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200690 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200691 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000692
Harald Weltef6093a42011-06-25 10:02:33 +0200693 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000694 struct rsl_ie_chan_mode cm;
695
Harald Welte9943c5b2009-07-29 15:41:29 +0200696 rc = channel_mode_from_lchan(&cm, lchan);
697 if (rc < 0)
698 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000699
Harald Welteeab33352009-06-27 03:09:08 +0200700 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000701 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
702 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
703 dh->chan_nr = chan_nr;
704
705 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200706 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900707
708 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200709 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900710 rc = build_encr_info(encr_info, lchan);
711 if (rc > 0)
712 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
713 }
714
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200715 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100716
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200717 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900718
719 return abis_rsl_sendmsg(msg);
720}
721
722/* Chapter 8.4.6: Send the encryption command with given L3 info */
723int rsl_encryption_cmd(struct msgb *msg)
724{
725 struct abis_rsl_dchan_hdr *dh;
726 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200727 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200728 uint8_t encr_info[MAX_A5_KEY_LEN+2];
729 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900730 int rc;
731
732 /* First push the L3 IE tag and length */
733 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
734
735 /* then the link identifier (SAPI0, main sign link) */
736 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
737
738 /* then encryption information */
739 rc = build_encr_info(encr_info, lchan);
740 if (rc <= 0)
741 return rc;
742 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
743
744 /* and finally the DCHAN header */
745 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
746 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
747 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000748
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200749 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000750
751 return abis_rsl_sendmsg(msg);
752}
753
Harald Welte115d1032009-08-10 11:43:22 +0200754/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200755int rsl_deact_sacch(struct gsm_lchan *lchan)
756{
757 struct abis_rsl_dchan_hdr *dh;
758 struct msgb *msg = rsl_msgb_alloc();
759
760 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
761 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200762 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200763
764 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200765 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200766
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100767 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200768
769 return abis_rsl_sendmsg(msg);
770}
771
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200772static bool dyn_ts_should_switch_to_pdch(struct gsm_bts_trx_ts *ts)
773{
774 int ss;
775
776 if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
777 return false;
778
779 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
780 return false;
781
782 /* Already in PDCH mode? */
783 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH)
784 return false;
785
786 /* See if all lchans are released. */
787 for (ss = 0; ss < ts_subslots(ts); ss++) {
788 struct gsm_lchan *lc = &ts->lchan[ss];
789 if (lc->state != LCHAN_S_NONE) {
Neels Hofmeyrbaa6c552016-08-24 14:48:39 +0200790 DEBUGP(DRSL, "%s lchan %u still in use"
791 " (type=%s,state=%s)\n",
792 gsm_ts_and_pchan_name(ts), lc->nr,
793 gsm_lchant_name(lc->type),
794 gsm_lchans_name(lc->state));
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200795 /* An lchan is still used. */
796 return false;
797 }
798 }
799
800 /* All channels are released, go to PDCH mode. */
801 DEBUGP(DRSL, "%s back to PDCH\n",
802 gsm_ts_and_pchan_name(ts));
803 return true;
804}
805
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800806static void error_timeout_cb(void *data)
807{
808 struct gsm_lchan *lchan = data;
809 if (lchan->state != LCHAN_S_REL_ERR) {
810 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
811 gsm_lchan_name(lchan), lchan->state);
812 return;
813 }
814
815 /* go back to the none state */
Harald Weltea9e420e2012-11-13 04:26:22 +0100816 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800817 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200818
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +0200819 /* Put PDCH channel back into PDCH mode, if GPRS is enabled */
820 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
821 && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE)
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200822 rsl_ipacc_pdch_activate(lchan->ts, 1);
Neels Hofmeyrcd150a82016-08-24 14:45:44 +0200823
824 if (dyn_ts_should_switch_to_pdch(lchan->ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200825 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800826}
827
Harald Weltefd355a32011-03-04 13:41:31 +0100828static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
829
Harald Welte115d1032009-08-10 11:43:22 +0200830/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100831static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
832 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000833{
834 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800835 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100836 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000837
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100838 /* Stop timers that should lead to a channel release */
839 osmo_timer_del(&lchan->T3109);
840
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800841 if (lchan->state == LCHAN_S_REL_ERR) {
Neels Hofmeyrd5d39ae2016-08-24 17:02:19 +0200842 LOGP(DRSL, LOGL_NOTICE, "%s is in error state, not sending release.\n",
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800843 gsm_lchan_name(lchan));
844 return -1;
845 }
846
847 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000848 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
849 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200850 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000851
Harald Welte8470bf22008-12-25 23:28:35 +0000852 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200853 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000854
Neels Hofmeyrb3d87062016-08-22 18:40:07 +0200855 if (error)
856 DEBUGP(DRSL, "%s RF Channel Release due to error: %d\n",
857 gsm_lchan_name(lchan), error);
858 else
859 DEBUGP(DRSL, "%s RF Channel Release\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800860
861 if (error) {
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100862 /*
863 * FIXME: GSM 04.08 gives us two options for the abnormal
864 * chanel release. This can be either like in the non-existent
865 * sub-lcuase 3.5.1 or for the main signalling link deactivate
866 * the SACCH, start timer T3109 and consider the channel as
867 * released.
868 *
869 * This code is doing the later for all raido links and not
870 * only the main link. Right now all SAPIs are released on the
871 * local end, the SACCH will be de-activated and right now the
872 * T3111 will be started. First T3109 should be started and then
873 * the T3111.
874 *
875 * TODO: Move this out of the function.
876 */
877
878 /*
879 * sacch de-activate and "local end release"
880 */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100881 if (deact_sacch == SACCH_DEACTIVATE)
882 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100883 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
884
885 /*
886 * TODO: start T3109 now.
887 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800888 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800889 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000890
Harald Weltee8bd9e82011-08-10 23:26:33 +0200891 /* Start another timer or assume the BTS sends a ACK/NACK? */
892 lchan->act_timer.cb = lchan_deact_tmr_cb;
893 lchan->act_timer.data = lchan;
894 osmo_timer_schedule(&lchan->act_timer, 4, 0);
895
Harald Weltefd355a32011-03-04 13:41:31 +0100896 rc = abis_rsl_sendmsg(msg);
897
Harald Welte115d1032009-08-10 11:43:22 +0200898 /* BTS will respond by RF CHAN REL ACK */
Harald Weltefd355a32011-03-04 13:41:31 +0100899 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000900}
901
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200902/*
903 * Special handling for channel releases in the error case.
904 */
905static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
906{
Neels Hofmeyrec16c162016-10-17 01:03:53 +0200907 enum sacch_deact sacch_deact;
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200908 if (lchan->state != LCHAN_S_ACTIVE)
909 return 0;
Neels Hofmeyrec16c162016-10-17 01:03:53 +0200910 switch (ts_pchan(lchan->ts)) {
911 case GSM_PCHAN_TCH_F:
912 case GSM_PCHAN_TCH_H:
913 case GSM_PCHAN_CCCH_SDCCH4:
914 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
915 case GSM_PCHAN_SDCCH8_SACCH8C:
916 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
917 sacch_deact = SACCH_DEACTIVATE;
918 break;
919 default:
920 sacch_deact = SACCH_NONE;
921 break;
922 }
923 return rsl_rf_chan_release(lchan, 1, sacch_deact);
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200924}
925
Harald Welte64bb7542011-01-14 14:16:16 +0100926static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
927{
Neels Hofmeyr40074682016-07-23 20:01:49 +0200928 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte64bb7542011-01-14 14:16:16 +0100929
930 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
931
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100932 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200933 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100934 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200935
Holger Hans Peter Freyther6f6cbf72015-04-04 19:35:22 +0200936 /*
937 * The BTS didn't respond within the timeout to our channel
938 * release request and we have marked the channel as broken.
939 * Now we do receive an ACK and let's be conservative. If it
940 * is a sysmoBTS we know that only one RF Channel Release ACK
941 * will be sent. So let's "repair" the channel.
942 */
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200943 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyr40074682016-07-23 20:01:49 +0200944 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f6cbf72015-04-04 19:35:22 +0200945 LOGP(DRSL, LOGL_NOTICE,
946 "%s CHAN REL ACK for broken channel. %s.\n",
947 gsm_lchan_name(lchan),
948 do_free ? "Releasing it" : "Keeping it broken");
949 if (do_free)
950 do_lchan_free(lchan);
Neels Hofmeyrd35fc442016-08-24 17:02:37 +0200951 if (dyn_ts_should_switch_to_pdch(lchan->ts))
952 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200953 return 0;
954 }
955
Harald Welte64bb7542011-01-14 14:16:16 +0100956 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
957 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
958 gsm_lchan_name(lchan),
959 gsm_lchans_name(lchan->state));
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200960
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200961 do_lchan_free(lchan);
962
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200963 /*
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200964 * Check Osmocom RSL CHAN ACT style dynamic TCH/F_TCH/H_PDCH TS for pending
965 * transitions in these cases:
966 *
967 * a) after PDCH was released due to switchover request, activate TCH.
968 * BSC initiated this switchover, so dyn.pchan_is != pchan_want and
969 * lchan->type has been set to the desired GSM_LCHAN_*.
970 *
971 * b) Voice call ended and a TCH is released. If the TS is now unused,
972 * switch to PDCH. Here still dyn.pchan_is == dyn.pchan_want because
973 * we're only just notified and may decide to switch to PDCH now.
974 */
975 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
976 DEBUGP(DRSL, "%s Rx RSL Channel Release ack for lchan %u\n",
977 gsm_ts_and_pchan_name(ts), lchan->nr);
978
979 /* (a) */
980 if (ts->dyn.pchan_is != ts->dyn.pchan_want)
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200981 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200982
983 /* (b) */
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200984 if (dyn_ts_should_switch_to_pdch(ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200985 return dyn_ts_switchover_start(ts, GSM_PCHAN_PDCH);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200986 }
987
988 /*
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200989 * Put a dynamic TCH/F_PDCH channel back to PDCH mode iff it was
990 * released successfully. If in error, the PDCH ACT will follow after
991 * T3111 in error_timeout_cb().
992 *
993 * Any state other than LCHAN_S_REL_ERR became LCHAN_S_NONE after above
994 * do_lchan_free(). Assert this, because that's what ensures a PDCH ACT
Neels Hofmeyrc6926d02016-07-14 02:51:13 +0200995 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +0200996 *
997 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200998 */
999 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
1000 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyr40074682016-07-23 20:01:49 +02001001 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02001002 return 0;
Neels Hofmeyr40074682016-07-23 20:01:49 +02001003 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr82c8f752016-06-21 20:55:14 +02001004 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyr40074682016-07-23 20:01:49 +02001005 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte64bb7542011-01-14 14:16:16 +01001006 return 0;
1007}
1008
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001009int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
Harald Weltebaaf3e22016-11-17 20:54:04 +01001010 uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs)
Harald Welte52b1f982008-12-23 20:25:15 +00001011{
1012 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +00001013 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001014
1015 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1016 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
1017 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1018
1019 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +00001020 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +00001021 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
1022
Harald Weltebaaf3e22016-11-17 20:54:04 +01001023 /* Ericsson wants to have this IE in case a paging message
1024 * relates to packet paging */
1025 if (bts->type == GSM_BTS_TYPE_RBS2000 && is_gprs)
1026 msgb_tv_put(msg, RSL_IE_ERIC_PACKET_PAG_IND, 0);
1027
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001028 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001029
1030 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001031}
1032
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001033int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +00001034{
1035 int i, len = strlen(str_in);
1036
1037 for (i = 0; i < len; i++) {
1038 int num = str_in[i] - 0x30;
1039 if (num < 0 || num > 9)
1040 return -1;
1041 if (i % 2 == 0)
1042 bcd_out[i/2] = num;
1043 else
1044 bcd_out[i/2] |= (num << 4);
1045 }
1046
1047 return 0;
1048}
1049
Harald Welte702d8702008-12-26 20:25:35 +00001050/* Chapter 8.5.6 */
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001051struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +00001052{
Harald Welte8470bf22008-12-25 23:28:35 +00001053 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001054 struct abis_rsl_dchan_hdr *dh;
Maxb726c2c2017-02-09 19:23:38 +01001055 uint8_t buf[GSM_MACBLOCK_LEN];
Harald Welte52b1f982008-12-23 20:25:15 +00001056
1057 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1058 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
1059 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1060
Harald Welte362322e2009-02-15 14:36:38 +00001061 switch (bts->type) {
1062 case GSM_BTS_TYPE_BS11:
1063 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
1064 break;
1065 default:
1066 /* If phase 2, construct a FULL_IMM_ASS_INFO */
1067 pad_macblock(buf, val, len);
Maxb726c2c2017-02-09 19:23:38 +01001068 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, GSM_MACBLOCK_LEN,
1069 buf);
Harald Welte362322e2009-02-15 14:36:38 +00001070 break;
1071 }
Harald Welte52b1f982008-12-23 20:25:15 +00001072
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001073 msg->dst = bts->c0->rsl_link;
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001074 return msg;
1075}
1076
1077/* Chapter 8.5.6 */
1078int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
1079{
1080 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1081 if (!msg)
1082 return 1;
1083 return abis_rsl_sendmsg(msg);
1084}
1085
1086/* Chapter 8.5.6 */
1087int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val)
1088{
1089 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1090 if (!msg)
1091 return 1;
1092
1093 /* ericsson can handle a reference at the end of the message which is used in
1094 * the confirm message. The confirm message is only sent if the trailer is present */
1095 msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
1096 msgb_put_u32(msg, tlli);
Harald Welte8470bf22008-12-25 23:28:35 +00001097
1098 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001099}
1100
Harald Welte67fa91b2009-08-10 09:51:40 +02001101/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +02001102int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +02001103{
1104 struct msgb *msg = rsl_msgb_alloc();
1105 struct abis_rsl_dchan_hdr *dh;
1106
1107 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1108 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +02001109 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001110 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001111 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +02001112
Harald Welte5b8ed432009-12-24 12:20:20 +01001113 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001114 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +02001115
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001116 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +02001117
Harald Welte67fa91b2009-08-10 09:51:40 +02001118 return abis_rsl_sendmsg(msg);
1119}
1120
1121
Harald Welte8470bf22008-12-25 23:28:35 +00001122/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +00001123/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001124int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +00001125{
Harald Welte8470bf22008-12-25 23:28:35 +00001126 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001127 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +00001128 return -EINVAL;
1129 }
Harald Welte52b1f982008-12-23 20:25:15 +00001130
Harald Weltef6093a42011-06-25 10:02:33 +02001131 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001132 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +00001133
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001134 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001135
1136 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001137}
1138
Harald Welteedcc5272009-08-09 13:47:35 +02001139/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
1140/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001141int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +02001142{
Harald Welte3c9c5f92010-03-04 10:33:10 +01001143 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +02001144
Harald Weltef6093a42011-06-25 10:02:33 +02001145 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001146 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001147 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +02001148
Harald Weltefda74ee2012-04-26 19:42:19 +02001149 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
1150 gsm_lchan_name(lchan), link_id);
1151
Harald Welteedcc5272009-08-09 13:47:35 +02001152 return abis_rsl_sendmsg(msg);
1153}
1154
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001155static void rsl_handle_release(struct gsm_lchan *lchan);
1156
1157/* Special work handler to handle missing RSL_MT_REL_CONF message from
1158 * Nokia InSite BTS */
1159static void lchan_rel_work_cb(void *data)
1160{
1161 struct gsm_lchan *lchan = data;
1162 int sapi;
1163
1164 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1165 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
1166 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
1167 }
1168 rsl_handle_release(lchan);
1169}
1170
Harald Welted2dc1de2009-08-08 13:15:07 +02001171/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
1172 This is what higher layers should call. The BTS then responds with
1173 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
1174 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
1175 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001176int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
1177 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +02001178{
Harald Welted2dc1de2009-08-08 13:15:07 +02001179
Harald Welte3c9c5f92010-03-04 10:33:10 +01001180 struct msgb *msg;
1181
Harald Weltef6093a42011-06-25 10:02:33 +02001182 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001183 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +08001184 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001185 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +02001186
Harald Welte8e93b792009-12-29 10:44:17 +01001187 /* FIXME: start some timer in case we don't receive a REL ACK ? */
1188
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001189 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +02001190
Harald Weltefda74ee2012-04-26 19:42:19 +02001191 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001192 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +02001193
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001194 abis_rsl_sendmsg(msg);
1195
1196 /* Do not wait for Nokia BTS to send the confirm. */
1197 if (is_nokia_bts(lchan->ts->trx->bts)
1198 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
1199 && release_mode == RSL_REL_LOCAL_END) {
1200 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
1201 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
1202 lchan->rel_work.cb = lchan_rel_work_cb;
1203 lchan->rel_work.data = lchan;
1204 osmo_timer_schedule(&lchan->rel_work, 0, 0);
1205 }
1206
1207 return 0;
Harald Welted2dc1de2009-08-08 13:15:07 +02001208}
1209
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001210int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
1211{
Neels Hofmeyr423269f2016-08-24 16:48:00 +02001212 LOGP(DRSL, LOGL_ERROR, "%s %s lchan broken: %s\n",
1213 gsm_lchan_name(lchan), gsm_lchant_name(lchan->type), reason);
1214 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001215 lchan->broken_reason = reason;
1216 return 0;
1217}
1218
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001219int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
1220{
Neels Hofmeyrb0cc6422016-06-21 21:34:46 +02001221 DEBUGP(DRSL, "%s state %s -> %s\n",
1222 gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
1223 gsm_lchans_name(state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001224 lchan->state = state;
1225 return 0;
1226}
1227
Harald Welte702d8702008-12-26 20:25:35 +00001228/* Chapter 8.4.2: Channel Activate Acknowledge */
1229static int rsl_rx_chan_act_ack(struct msgb *msg)
1230{
1231 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001232 struct gsm_lchan *lchan = msg->lchan;
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001233 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte702d8702008-12-26 20:25:35 +00001234
1235 /* BTS has confirmed channel activation, we now need
1236 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +00001237 if (rslh->ie_chan != RSL_IE_CHAN_NR)
1238 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +01001239
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001240 osmo_timer_del(&lchan->act_timer);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001241
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001242 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001243 int do_release = is_sysmobts_v2(ts->trx->bts);
1244 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel. %s\n",
1245 gsm_lchan_name(lchan),
1246 do_release ? "Releasing it" : "Keeping it broken");
1247 if (do_release) {
1248 talloc_free(lchan->rqd_ref);
1249 lchan->rqd_ref = NULL;
1250 lchan->rqd_ta = 0;
1251 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
1252 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
1253 /*
1254 * lchan_act_tmr_cb() already called
1255 * lchan_free() and cleared the lchan->type, so
1256 * calling dyn_ts_switchover_complete() here
1257 * would not have the desired effect of
1258 * mimicking an activated lchan that we can
1259 * release. Instead hack the dyn ts state to
1260 * make sure that rsl_rx_rf_chan_rel_ack() will
1261 * switch back to PDCH, i.e. have pchan_is ==
1262 * pchan_want, both != GSM_PCHAN_PDCH:
1263 */
1264 ts->dyn.pchan_is = GSM_PCHAN_NONE;
1265 ts->dyn.pchan_want = GSM_PCHAN_NONE;
1266 }
1267 rsl_rf_chan_release(msg->lchan, 0, SACCH_NONE);
1268 }
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +02001269 return 0;
1270 }
1271
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001272 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +01001273 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001274 gsm_lchan_name(lchan),
1275 gsm_lchans_name(lchan->state));
1276 rsl_lchan_set_state(lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +01001277
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001278 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001279 dyn_ts_switchover_complete(lchan);
1280
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001281 if (lchan->rqd_ref) {
1282 rsl_send_imm_assignment(lchan);
1283 talloc_free(lchan->rqd_ref);
1284 lchan->rqd_ref = NULL;
1285 lchan->rqd_ta = 0;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001286 }
1287
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001288 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001289
Harald Welte4b634542008-12-27 01:55:51 +00001290 return 0;
1291}
Harald Welte702d8702008-12-26 20:25:35 +00001292
Harald Welte4b634542008-12-27 01:55:51 +00001293/* Chapter 8.4.3: Channel Activate NACK */
1294static int rsl_rx_chan_act_nack(struct msgb *msg)
1295{
Harald Welte6dab0552009-05-01 17:21:37 +00001296 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1297 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001298
Harald Weltee8bd9e82011-08-10 23:26:33 +02001299 osmo_timer_del(&msg->lchan->act_timer);
1300
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +02001301 if (msg->lchan->state == LCHAN_S_BROKEN) {
1302 LOGP(DRSL, LOGL_ERROR,
1303 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
1304 gsm_lchan_name(msg->lchan));
1305 return -1;
1306 }
1307
Daniel Willmann6fc6a122011-08-11 04:54:23 +02001308 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001309 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001310
Harald Welte6dab0552009-05-01 17:21:37 +00001311 /* BTS has rejected channel activation ?!? */
1312 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +00001313 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +00001314
1315 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001316 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001317 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001318 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +02001319 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +01001320 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001321 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1322 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1323 } else
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001324 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +02001325
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001326 } else {
1327 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1328 }
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001329
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001330 LOGPC(DRSL, LOGL_ERROR, "\n");
1331
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001332 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +00001333 return 0;
Harald Welte702d8702008-12-26 20:25:35 +00001334}
1335
Harald Welte7f93cea2009-02-23 00:02:59 +00001336/* Chapter 8.4.4: Connection Failure Indication */
1337static int rsl_rx_conn_fail(struct msgb *msg)
1338{
1339 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1340 struct tlv_parsed tp;
1341
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02001342 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1343 gsm_lchan_name(msg->lchan),
1344 gsm_lchans_name(msg->lchan->state));
1345
Harald Welte7f93cea2009-02-23 00:02:59 +00001346 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1347
Harald Welte8830e072009-07-28 17:58:09 +02001348 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001349 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001350 TLVP_LEN(&tp, RSL_IE_CAUSE));
1351
Harald Welte (local)fc057502009-12-26 22:33:09 +01001352 LOGPC(DRSL, LOGL_NOTICE, "\n");
Alexander Couzensb847a212016-08-02 11:34:11 +02001353 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 +02001354 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +00001355}
1356
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001357static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1358 const char *prefix)
1359{
Harald Welte6739dfb2009-12-16 16:52:07 +01001360 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1361 prefix, rxlev2dbm(mru->full.rx_lev),
1362 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001363 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1364 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1365}
1366
Harald Welte0c1bd612012-07-02 17:12:08 +02001367static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001368{
Harald Welte6739dfb2009-12-16 16:52:07 +01001369 int i;
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001370 const char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +01001371
Harald Welte7184bd02015-12-28 14:04:36 +01001372 if (lchan && lchan->conn)
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001373 name = bsc_subscr_name(lchan->conn->bsub);
Harald Welte0c1bd612012-07-02 17:12:08 +02001374
1375 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001376
1377 if (mr->flags & MEAS_REP_F_DL_DTX)
1378 DEBUGPC(DMEAS, "DTXd ");
1379
1380 print_meas_rep_uni(&mr->ul, "ul");
1381 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1382 if (mr->flags & MEAS_REP_F_MS_TO)
1383 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1384
1385 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +01001386 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001387 DEBUGPC(DMEAS, "L1_FPC=%u ",
1388 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1389 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1390 }
1391
1392 if (mr->flags & MEAS_REP_F_UL_DTX)
1393 DEBUGPC(DMEAS, "DTXu ");
1394 if (mr->flags & MEAS_REP_F_BA1)
1395 DEBUGPC(DMEAS, "BA1 ");
1396 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1397 DEBUGPC(DMEAS, "NOT VALID ");
1398 else
1399 print_meas_rep_uni(&mr->dl, "dl");
1400
1401 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001402 if (mr->num_cell == 7)
1403 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001404 for (i = 0; i < mr->num_cell; i++) {
1405 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001406 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1407 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001408 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001409}
1410
Harald Welte440fed02009-05-01 18:43:47 +00001411static int rsl_rx_meas_res(struct msgb *msg)
1412{
1413 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1414 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001415 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001416 uint8_t len;
1417 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001418 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001419
Harald Welteb8bfc562009-12-21 13:27:11 +01001420 /* check if this channel is actually active */
1421 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001422 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001423 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001424 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001425 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001426 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001427
Harald Welted12b0fd2009-12-15 21:36:05 +01001428 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001429 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001430
Harald Welte440fed02009-05-01 18:43:47 +00001431 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1432
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001433 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1434 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1435 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1436 return -EIO;
1437
1438 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001439 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001440
1441 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1442 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1443 if (len >= 3) {
1444 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001445 mr->flags |= MEAS_REP_F_DL_DTX;
1446 mr->ul.full.rx_lev = val[0] & 0x3f;
1447 mr->ul.sub.rx_lev = val[1] & 0x3f;
1448 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1449 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001450 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001451
Harald Welted12b0fd2009-12-15 21:36:05 +01001452 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001453
1454 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +00001455 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +01001456 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001457 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1458
Harald Weltefe9af262009-06-20 18:44:35 +02001459 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001460 struct e1inp_sign_link *sign_link = msg->dst;
1461
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001462 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001463 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001464 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001465 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001466 mr->flags |= MEAS_REP_F_FPC;
1467 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001468 /* BS11 and Nokia reports TA shifted by 2 bits */
1469 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1470 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001471 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001472 }
Harald Weltef7c43522009-06-09 20:24:21 +00001473 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001474 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001475 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001476 if (rc < 0)
1477 return rc;
1478 }
1479
Harald Welte0c1bd612012-07-02 17:12:08 +02001480 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001481
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001482 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001483
Harald Welte75d34a82009-05-23 06:11:13 +00001484 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001485}
1486
Harald Welted011e8b2009-11-29 22:45:52 +01001487/* Chapter 8.4.7 */
1488static int rsl_rx_hando_det(struct msgb *msg)
1489{
1490 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1491 struct tlv_parsed tp;
1492
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001493 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001494
1495 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1496
1497 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1498 DEBUGPC(DRSL, "access delay = %u\n",
1499 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1500 else
1501 DEBUGPC(DRSL, "\n");
1502
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001503 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001504
1505 return 0;
1506}
1507
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001508static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1509{
1510 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001511
1512 OSMO_ASSERT(lchan);
1513
1514 ts = lchan->ts;
1515 OSMO_ASSERT(ts);
1516 OSMO_ASSERT(ts->trx);
1517 OSMO_ASSERT(ts->trx->bts);
1518
1519 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
Neels Hofmeyrdd49bee2016-06-21 20:53:27 +02001520 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1521 " for channel that is no TCH/F_PDCH\n",
1522 gsm_lchan_name(lchan),
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001523 gsm_pchan_name(ts->pchan),
1524 pdch_act? "ACT" : "DEACT");
1525 return false;
1526 }
1527
Neels Hofmeyr832afa32016-06-14 13:12:00 +02001528 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyrdd49bee2016-06-21 20:53:27 +02001529 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1530 " in unexpected state: %s\n",
1531 gsm_lchan_name(lchan),
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001532 gsm_pchan_name(ts->pchan),
1533 pdch_act? "ACT" : "DEACT",
1534 gsm_lchans_name(lchan->state));
1535 return false;
1536 }
1537 return true;
1538}
1539
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001540static int rsl_rx_pdch_act_ack(struct msgb *msg)
1541{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001542 if (!lchan_may_change_pdch(msg->lchan, true))
1543 return -EINVAL;
1544
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001545 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001546 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001547
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001548 return 0;
1549}
1550
1551static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1552{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001553 if (!lchan_may_change_pdch(msg->lchan, false))
1554 return -EINVAL;
1555
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001556 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001557 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001558
Neels Hofmeyr6e999b72016-07-23 21:00:51 +02001559 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn.act_type,
1560 msg->lchan->dyn.ho_ref);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001561
1562 return 0;
1563}
1564
Harald Welte52b1f982008-12-23 20:25:15 +00001565static int abis_rsl_rx_dchan(struct msgb *msg)
1566{
Harald Welte8470bf22008-12-25 23:28:35 +00001567 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1568 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001569 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001570 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001571
Neels Hofmeyr2867f882016-08-23 01:22:58 +02001572 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1573 "Abis RSL rx DCHAN: ");
Neels Hofmeyra6ba6a32016-10-10 03:24:05 +02001574 if (!msg->lchan)
1575 return -1;
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001576 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001577
Harald Welte8470bf22008-12-25 23:28:35 +00001578 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001579 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001580 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001581 rc = rsl_rx_chan_act_ack(msg);
Alexander Couzens8c53c592016-08-23 06:27:19 +02001582 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001583 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001584 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001585 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001586 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001587 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001588 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001589 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001590 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001591 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001592 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001593 case RSL_MT_HANDO_DET:
1594 rc = rsl_rx_hando_det(msg);
1595 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001596 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001597 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001598 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001599 case RSL_MT_MODE_MODIFY_ACK:
Alexander Couzens8c53c592016-08-23 06:27:19 +02001600 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001601 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001602 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001603 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001604 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001605 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001606 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02001607 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001608 rc = rsl_rx_pdch_act_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001609 break;
1610 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001611 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001612 break;
1613 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001614 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001615 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001616 break;
1617 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001618 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001619 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001620 case RSL_MT_PHY_CONTEXT_CONF:
1621 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001622 case RSL_MT_TALKER_DET:
1623 case RSL_MT_LISTENER_DET:
1624 case RSL_MT_REMOTE_CODEC_CONF_REP:
1625 case RSL_MT_MR_CODEC_MOD_ACK:
1626 case RSL_MT_MR_CODEC_MOD_NACK:
1627 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001628 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1629 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001630 break;
1631 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001632 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1633 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001634 return -EINVAL;
1635 }
Harald Weltef325eb42009-02-19 17:07:39 +00001636
Harald Welte8470bf22008-12-25 23:28:35 +00001637 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001638}
1639
Harald Welte702d8702008-12-26 20:25:35 +00001640static int rsl_rx_error_rep(struct msgb *msg)
1641{
1642 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001643 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001644 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001645
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001646 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001647
1648 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1649
1650 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001651 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001652 TLVP_LEN(&tp, RSL_IE_CAUSE));
1653
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001654 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001655
1656 return 0;
1657}
1658
Harald Welte52b1f982008-12-23 20:25:15 +00001659static int abis_rsl_rx_trx(struct msgb *msg)
1660{
Harald Welte702d8702008-12-26 20:25:35 +00001661 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001662 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001663 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001664
1665 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001666 case RSL_MT_ERROR_REPORT:
1667 rc = rsl_rx_error_rep(msg);
1668 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001669 case RSL_MT_RF_RES_IND:
1670 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001671 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001672 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001673 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001674 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001675 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001676 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001677 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001678 case 0x42: /* Nokia specific: SI End ACK */
1679 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1680 break;
1681 case 0x43: /* Nokia specific: SI End NACK */
1682 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1683 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001684 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001685 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001686 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001687 return -EINVAL;
1688 }
Harald Welte8470bf22008-12-25 23:28:35 +00001689 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001690}
1691
Harald Welteb7e81162009-08-10 00:26:10 +02001692/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1693static void t3101_expired(void *data)
1694{
1695 struct gsm_lchan *lchan = data;
Max8dc8f232017-02-09 19:13:02 +01001696 LOGP(DRSL, LOGL_NOTICE,
1697 "%s T3101 expired: no response to IMMEDIATE ASSIGN\n",
1698 gsm_lchan_name(lchan));
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001699 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001700}
1701
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001702/* If T3111 expires, we will send the RF Channel Request */
1703static void t3111_expired(void *data)
1704{
1705 struct gsm_lchan *lchan = data;
Max8dc8f232017-02-09 19:13:02 +01001706 LOGP(DRSL, LOGL_NOTICE,
1707 "%s T3111 expired: releasing RF Channel\n",
1708 gsm_lchan_name(lchan));
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001709 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1710}
1711
1712/* If T3109 expires the MS has not send a UA/UM do the error release */
1713static void t3109_expired(void *data)
1714{
1715 struct gsm_lchan *lchan = data;
1716
1717 LOGP(DRSL, LOGL_ERROR,
1718 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1719 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001720}
1721
Harald Welte2862dca2010-12-23 14:39:29 +01001722/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1723static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1724 unsigned int num_req_refs,
1725 struct gsm48_req_ref *rqd_refs,
1726 uint8_t wait_ind)
1727{
1728 uint8_t buf[GSM_MACBLOCK_LEN];
1729 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1730
1731 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1732 memset(iar, 0, sizeof(*iar));
1733 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001734 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Welte2862dca2010-12-23 14:39:29 +01001735 iar->page_mode = GSM48_PM_SAME;
1736
1737 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1738 iar->wait_ind1 = wait_ind;
1739
1740 if (num_req_refs >= 2)
1741 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1742 else
1743 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1744 iar->wait_ind2 = wait_ind;
1745
1746 if (num_req_refs >= 3)
1747 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1748 else
1749 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1750 iar->wait_ind3 = wait_ind;
1751
1752 if (num_req_refs >= 4)
1753 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1754 else
1755 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1756 iar->wait_ind4 = wait_ind;
1757
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001758 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1759 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1760
1761 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Welte2862dca2010-12-23 14:39:29 +01001762}
1763
Harald Welte8470bf22008-12-25 23:28:35 +00001764/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001765static int rsl_rx_chan_rqd(struct msgb *msg)
1766{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001767 struct e1inp_sign_link *sign_link = msg->dst;
1768 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001769 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1770 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001771 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001772 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001773 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001774 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001775 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001776
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001777 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001778 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001779
Harald Welte8470bf22008-12-25 23:28:35 +00001780 /* parse request reference to be used in immediate assign */
1781 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1782 return -EINVAL;
1783
1784 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1785
1786 /* parse access delay and use as TA */
1787 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1788 return -EINVAL;
1789 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1790
1791 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1792 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001793 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1794 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001795
Alexander Couzensb847a212016-08-02 11:34:11 +02001796 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL]);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001797
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001798 /*
1799 * We want LOCATION UPDATES to succeed and will assign a TCH
1800 * if we have no SDCCH available.
1801 */
1802 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1803
Harald Welte8470bf22008-12-25 23:28:35 +00001804 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001805 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001806 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001807 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001808 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Alexander Couzensb847a212016-08-02 11:34:11 +02001809 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL]);
Harald Welte2862dca2010-12-23 14:39:29 +01001810 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1811 if (bts->network->T3122)
1812 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte1dcc2602012-11-13 04:46:03 +01001813 return 0;
Harald Welte8470bf22008-12-25 23:28:35 +00001814 }
1815
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001816 /*
1817 * Expecting lchan state to be NONE, except for dyn TS in PDCH mode.
1818 * Those are expected to be ACTIVE: the PDCH release will be sent from
1819 * rsl_chan_activate_lchan() below.
1820 */
1821 if (lchan->state != LCHAN_S_NONE
1822 && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
1823 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
1824 && lchan->state == LCHAN_S_ACTIVE))
Harald Welte8e93b792009-12-29 10:44:17 +01001825 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001826 "in state %s\n", gsm_lchan_name(lchan),
1827 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001828
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001829 /* save the RACH data as we need it after the CHAN ACT ACK */
1830 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1831 if (!lchan->rqd_ref) {
1832 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1833 lchan_free(lchan);
1834 return -ENOMEM;
1835 }
1836
1837 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1838 lchan->rqd_ta = rqd_ta;
1839
Harald Welte8470bf22008-12-25 23:28:35 +00001840 arfcn = lchan->ts->trx->arfcn;
1841 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001842
Harald Welte08d91a52009-08-30 15:37:11 +09001843 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001844 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001845 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001846 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001847 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001848
Harald Weltee8bd9e82011-08-10 23:26:33 +02001849 /* Start another timer or assume the BTS sends a ACK/NACK? */
1850 lchan->act_timer.cb = lchan_act_tmr_cb;
1851 lchan->act_timer.data = lchan;
1852 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1853
Andreas Eversberg2957de92011-12-16 17:45:37 +01001854 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1855 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1856 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1857 rqd_ref->ra, rqd_ta);
1858
Neels Hofmeyr81516482016-07-15 01:26:03 +02001859 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001860
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001861 return 0;
1862}
1863
1864static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1865{
1866 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001867 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001868 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1869
Harald Welte52b1f982008-12-23 20:25:15 +00001870 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001871 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001872 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001873 ia->proto_discr = GSM48_PDISC_RR;
1874 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1875 ia->page_mode = GSM48_PM_SAME;
1876 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001877
Harald Welte8470bf22008-12-25 23:28:35 +00001878 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001879 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1880 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001881 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001882 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001883 } else {
laforge09108bf2010-06-20 15:18:46 +02001884 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1885 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001886 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001887 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1888 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001889
Harald Welteb7e81162009-08-10 00:26:10 +02001890 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1891 lchan->T3101.cb = t3101_expired;
1892 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001893 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001894
Harald Welte52b1f982008-12-23 20:25:15 +00001895 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001896 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001897}
1898
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001899/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001900static int rsl_rx_ccch_load(struct msgb *msg)
1901{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001902 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001903 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001904 struct ccch_signal_data sd;
1905
1906 sd.bts = sign_link->trx->bts;
1907 sd.rach_slot_count = -1;
1908 sd.rach_busy_count = -1;
1909 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001910
1911 switch (rslh->data[0]) {
1912 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001913 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1914 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001915 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001916 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001917 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001918 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1919 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001920 break;
1921 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001922 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001923 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1924 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1925 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1926 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001927 }
Harald Welteea280442009-02-02 22:29:56 +00001928 break;
1929 default:
1930 break;
1931 }
1932
1933 return 0;
1934}
1935
Harald Welte52b1f982008-12-23 20:25:15 +00001936static int abis_rsl_rx_cchan(struct msgb *msg)
1937{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001938 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001939 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001940 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001941
Neels Hofmeyr2867f882016-08-23 01:22:58 +02001942 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1943 "Abis RSL rx CCHAN: ");
Harald Welte8470bf22008-12-25 23:28:35 +00001944
1945 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001946 case RSL_MT_CHAN_RQD:
1947 /* MS has requested a channel on the RACH */
1948 rc = rsl_rx_chan_rqd(msg);
1949 break;
Harald Welteea280442009-02-02 22:29:56 +00001950 case RSL_MT_CCCH_LOAD_IND:
1951 /* current load on the CCCH */
1952 rc = rsl_rx_ccch_load(msg);
1953 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001954 case RSL_MT_DELETE_IND:
1955 /* CCCH overloaded, IMM_ASSIGN was dropped */
1956 case RSL_MT_CBCH_LOAD_IND:
1957 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001958 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1959 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001960 break;
1961 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001962 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1963 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001964 return -EINVAL;
1965 }
Harald Welte8470bf22008-12-25 23:28:35 +00001966
1967 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001968}
1969
Harald Welte4b634542008-12-27 01:55:51 +00001970static int rsl_rx_rll_err_ind(struct msgb *msg)
1971{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001972 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001973 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001974 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00001975
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001976 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1977 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1978 LOGP(DRLL, LOGL_ERROR,
1979 "%s ERROR INDICATION without mandantory cause.\n",
1980 gsm_lchan_name(msg->lchan));
1981 return -1;
1982 }
1983
1984 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02001985 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001986 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02001987 rsl_rlm_cause_name(rlm_cause),
1988 gsm_lchans_name(msg->lchan->state));
1989
Harald Welteedcc5272009-08-09 13:47:35 +02001990 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001991
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001992 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Alexander Couzensb847a212016-08-02 11:34:11 +02001993 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 +02001994 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001995 }
Harald Welte81543bc2009-07-04 09:40:05 +02001996
Harald Welte4b634542008-12-27 01:55:51 +00001997 return 0;
1998}
Harald Weltef325eb42009-02-19 17:07:39 +00001999
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002000static void rsl_handle_release(struct gsm_lchan *lchan)
2001{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002002 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002003 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002004
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +01002005 /*
2006 * Maybe only one link/SAPI was releasd or the error handling
2007 * was activated. Just return now and let the other code handle
2008 * it.
2009 */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002010 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002011 return;
2012
2013 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2014 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2015 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01002016 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002017 gsm_lchan_name(lchan), sapi);
2018 return;
2019 }
2020
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002021
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002022 /* Stop T3109 and wait for T3111 before re-using the channel */
2023 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002024 lchan->T3111.cb = t3111_expired;
2025 lchan->T3111.data = lchan;
2026 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002027 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002028}
2029
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002030/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00002031 0x02, 0x06,
2032 0x01, 0x20,
2033 0x02, 0x00,
2034 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
2035
2036static int abis_rsl_rx_rll(struct msgb *msg)
2037{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002038 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00002039 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00002040 int rc = 0;
2041 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002042 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00002043
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002044 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2045 "Abis RSL rx RLL: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002046 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01002047 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00002048
2049 switch (rllh->c.msg_type) {
2050 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002051 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002052 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002053 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2054 rllh->data[0] == RSL_IE_L3_INFO) {
2055 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02002056 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002057 }
Harald Welte52b1f982008-12-23 20:25:15 +00002058 break;
2059 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002060 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02002061 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002062 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002063 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002064 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002065 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2066 rllh->data[0] == RSL_IE_L3_INFO) {
2067 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02002068 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002069 }
Harald Welte52b1f982008-12-23 20:25:15 +00002070 break;
Harald Welteedcc5272009-08-09 13:47:35 +02002071 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02002072 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002073 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02002074 rll_indication(msg->lchan, rllh->link_id,
2075 BSC_RLLR_IND_EST_CONF);
2076 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002077 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02002078 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02002079 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002080 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02002081 rll_indication(msg->lchan, rllh->link_id,
2082 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002083 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00002084 break;
2085 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02002086 /* BTS informs us of having received UA from MS,
2087 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02002088 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002089 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002090 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00002091 break;
2092 case RSL_MT_ERROR_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002093 DEBUGPC(DRLL, "ERROR INDICATION\n");
Harald Welte4b634542008-12-27 01:55:51 +00002094 rc = rsl_rx_rll_err_ind(msg);
2095 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002096 case RSL_MT_UNIT_DATA_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002097 DEBUGPC(DRLL, "UNIT DATA INDICATION\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002098 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
2099 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002100 break;
2101 default:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002102 DEBUGPC(DRLL, "UNKNOWN\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002103 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
2104 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002105 }
Harald Welte8470bf22008-12-25 23:28:35 +00002106 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002107}
2108
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002109static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02002110{
Harald Welte0603c9d2009-12-02 01:58:23 +05302111 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02002112 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05302113 switch (lchan->type) {
2114 case GSM_LCHAN_TCH_F:
2115 return 0x00;
2116 case GSM_LCHAN_TCH_H:
2117 return 0x03;
2118 default:
2119 break;
2120 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002121 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002122 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05302123 switch (lchan->type) {
2124 case GSM_LCHAN_TCH_F:
2125 return 0x01;
2126 /* there's no half-rate EFR */
2127 default:
2128 break;
2129 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002130 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002131 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05302132 switch (lchan->type) {
2133 case GSM_LCHAN_TCH_F:
2134 return 0x02;
2135 case GSM_LCHAN_TCH_H:
2136 return 0x05;
2137 default:
2138 break;
2139 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002140 break;
Harald Welte0603c9d2009-12-02 01:58:23 +05302141 default:
2142 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002143 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002144 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05302145 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002146 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02002147}
2148
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002149static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01002150{
2151 switch (lchan->tch_mode) {
2152 case GSM48_CMODE_SPEECH_V1:
2153 switch (lchan->type) {
2154 case GSM_LCHAN_TCH_F:
2155 return RTP_PT_GSM_FULL;
2156 case GSM_LCHAN_TCH_H:
2157 return RTP_PT_GSM_HALF;
2158 default:
2159 break;
2160 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002161 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002162 case GSM48_CMODE_SPEECH_EFR:
2163 switch (lchan->type) {
2164 case GSM_LCHAN_TCH_F:
2165 return RTP_PT_GSM_EFR;
2166 /* there's no half-rate EFR */
2167 default:
2168 break;
2169 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002170 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002171 case GSM48_CMODE_SPEECH_AMR:
2172 switch (lchan->type) {
2173 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01002174 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02002175 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002176 default:
2177 break;
2178 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002179 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002180 default:
2181 break;
2182 }
2183 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
2184 "tch_mode == 0x%02x\n & lchan_type == %d",
2185 lchan->tch_mode, lchan->type);
2186 return 0;
2187}
2188
Harald Welte75099262009-02-16 21:12:08 +00002189/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002190static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
2191{
2192 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002193 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01002194
2195 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002196 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002197 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
2198 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
2199 }
2200
2201 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002202 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002203 port = ntohs(port);
2204 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
2205 lchan->abis_ip.bound_port = port;
2206 }
2207
2208 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002209 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002210 conn_id = ntohs(conn_id);
2211 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
2212 lchan->abis_ip.conn_id = conn_id;
2213 }
2214
2215 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
2216 lchan->abis_ip.rtp_payload2 =
2217 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
2218 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
2219 lchan->abis_ip.rtp_payload2);
2220 }
2221
2222 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
2223 lchan->abis_ip.speech_mode =
2224 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
2225 DEBUGPC(DRSL, "speech_mode=0x%02x ",
2226 lchan->abis_ip.speech_mode);
2227 }
2228
2229 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002230 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002231 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
2232 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
2233 }
2234
2235 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002236 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002237 port = ntohs(port);
2238 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
2239 lchan->abis_ip.connect_port = port;
2240 }
2241}
2242
Harald Welte647db842013-02-03 12:06:58 +01002243/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
2244 * \param[in] lchan Logical Channel for which we issue CRCX
2245 */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002246int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00002247{
2248 struct msgb *msg = rsl_msgb_alloc();
2249 struct abis_rsl_dchan_hdr *dh;
2250
2251 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002252 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00002253 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002254 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002255
Harald Weltef4e79f22009-07-28 18:11:56 +02002256 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002257 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002258 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002259 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002260 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002261
Sylvain Munautb54dda42009-12-20 22:06:40 +01002262 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
2263 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
2264 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002265
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002266 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002267
2268 return abis_rsl_sendmsg(msg);
2269}
2270
Harald Welte647db842013-02-03 12:06:58 +01002271/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
2272 * \param[in] lchan Logical Channel for which we issue MDCX
2273 * \param[in] ip Remote (MGW) IP address for RTP
2274 * \param[in] port Remote (MGW) UDP port number for RTP
2275 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
2276 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002277int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
2278 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00002279{
2280 struct msgb *msg = rsl_msgb_alloc();
2281 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002282 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02002283 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00002284
2285 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002286 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00002287 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002288 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002289
Harald Welte5e3d91b2009-12-19 16:42:06 +01002290 /* we need to store these now as MDCX_ACK does not return them :( */
2291 lchan->abis_ip.rtp_payload2 = rtp_payload2;
2292 lchan->abis_ip.connect_port = port;
2293 lchan->abis_ip.connect_ip = ip;
2294
Harald Welte58ca5b72009-07-29 12:12:18 +02002295 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002296 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002297 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02002298
Harald Weltef4e79f22009-07-28 18:11:56 +02002299 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002300 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
2301 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
2302 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
2303 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002304
Harald Welte5e3d91b2009-12-19 16:42:06 +01002305 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
2306 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002307 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01002308 *att_ip = ia.s_addr;
2309 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
2310 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002311 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002312 if (rtp_payload2)
2313 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002314
2315 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002316
2317 return abis_rsl_sendmsg(msg);
2318}
2319
Harald Weltea72273e2009-12-20 16:51:09 +01002320/* tell BTS to connect RTP stream to our local RTP socket */
2321int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
2322{
2323 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
2324 int rc;
2325
2326 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
2327 ntohs(rs->rtp.sin_local.sin_port),
2328 /* FIXME: use RTP payload of bound socket, not BTS*/
2329 lchan->abis_ip.rtp_payload2);
2330
2331 return rc;
2332}
2333
Harald Welte53cd7ac2010-12-23 12:59:52 +01002334int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02002335{
2336 struct msgb *msg = rsl_msgb_alloc();
2337 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002338 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08002339
Neels Hofmeyr32019882016-06-15 15:32:29 +02002340 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2341 LOGP(DRSL, LOGL_ERROR,
2342 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2343 gsm_ts_name(ts),
2344 act ? "ACT" : "DEACT",
2345 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2346 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2347 return -EINVAL;
2348 }
2349
2350 if (act){
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02002351 /* Callers should heed the GPRS mode. */
2352 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte4563eab2010-03-28 14:42:09 +08002353 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002354 ts->flags |= TS_F_PDCH_ACT_PENDING;
2355 } else {
Harald Welte4563eab2010-03-28 14:42:09 +08002356 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002357 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2358 }
2359 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welte9c880c92009-10-24 10:29:22 +02002360
2361 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08002362 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02002363 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Neels Hofmeyrd3841102016-07-18 23:43:44 +02002364 dh->chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_PDCH, ts->nr, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02002365
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02002366 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08002367 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02002368
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002369 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02002370
2371 return abis_rsl_sendmsg(msg);
2372}
2373
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002374static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002375{
2376 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2377 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05302378 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00002379
2380 /* the BTS has acknowledged a local bind, it now tells us the IP
2381 * address and port number to which it has bound the given logical
2382 * channel */
2383
2384 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2385 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2386 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02002387 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002388 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00002389 return -EINVAL;
2390 }
Harald Welte17f5bf62009-12-20 15:42:44 +01002391
Harald Welte5e3d91b2009-12-19 16:42:06 +01002392 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01002393
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002394 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00002395
Harald Welte75099262009-02-16 21:12:08 +00002396 return 0;
2397}
2398
Harald Welte5e3d91b2009-12-19 16:42:06 +01002399static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2400{
2401 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2402 struct tlv_parsed tv;
2403 struct gsm_lchan *lchan = msg->lchan;
2404
2405 /* the BTS has acknowledged a remote connect request and
2406 * it now tells us the IP address and port number to which it has
2407 * connected the given logical channel */
2408
2409 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2410 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002411 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002412
2413 return 0;
2414}
2415
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002416static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002417{
2418 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2419 struct tlv_parsed tv;
2420
2421 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00002422
Harald Welte8830e072009-07-28 17:58:09 +02002423 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01002424 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02002425 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00002426
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002427 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02002428
Harald Welte75099262009-02-16 21:12:08 +00002429 return 0;
2430}
2431
2432static int abis_rsl_rx_ipacc(struct msgb *msg)
2433{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002434 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00002435 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01002436 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00002437 int rc = 0;
2438
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002439 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2440 "Abis RSL rx IPACC: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002441 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00002442
2443 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002444 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01002445 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002446 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002447 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002448 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002449 /* somehow the BTS was unable to bind the lchan to its local
2450 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01002451 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002452 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002453 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00002454 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01002455 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002456 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002457 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002458 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002459 /* somehow the BTS was unable to connect the lchan to a remote
2460 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01002461 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002462 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002463 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01002464 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002465 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00002466 break;
2467 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01002468 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002469 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00002470 break;
2471 }
Harald Welte6dab0552009-05-01 17:21:37 +00002472 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00002473
2474 return rc;
2475}
2476
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002477int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts,
Neels Hofmeyrd3b7fa82016-07-23 20:08:41 +02002478 enum gsm_phys_chan_config to_pchan)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002479{
2480 int ss;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002481 int rc = -EIO;
2482
2483 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2484 DEBUGP(DRSL, "%s starting switchover to %s\n",
2485 gsm_ts_and_pchan_name(ts), gsm_pchan_name(to_pchan));
2486
2487 if (ts->dyn.pchan_is != ts->dyn.pchan_want) {
2488 LOGP(DRSL, LOGL_ERROR,
2489 "%s: Attempt to switch dynamic channel to %s,"
2490 " but is already in switchover.\n",
2491 gsm_ts_and_pchan_name(ts),
2492 gsm_pchan_name(to_pchan));
2493 return ts->dyn.pchan_want == to_pchan? 0 : -EAGAIN;
2494 }
2495
2496 if (ts->dyn.pchan_is == to_pchan) {
2497 LOGP(DRSL, LOGL_INFO,
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002498 "%s %s Already is in %s mode, cannot switchover.\n",
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002499 gsm_ts_name(ts), gsm_pchan_name(ts->pchan),
2500 gsm_pchan_name(to_pchan));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002501 return -EINVAL;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002502 }
2503
2504 /* Paranoia: let's make sure all is indeed released. */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002505 for (ss = 0; ss < ts_subslots(ts); ss++) {
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002506 struct gsm_lchan *lc = &ts->lchan[ss];
2507 if (lc->state != LCHAN_S_NONE) {
2508 LOGP(DRSL, LOGL_ERROR,
2509 "%s Attempt to switch dynamic channel to %s,"
2510 " but is not fully released.\n",
2511 gsm_ts_and_pchan_name(ts),
2512 gsm_pchan_name(to_pchan));
2513 return -EAGAIN;
2514 }
2515 }
2516
2517 /* Record that we're busy switching. */
2518 ts->dyn.pchan_want = to_pchan;
2519
2520 /*
2521 * To switch from PDCH, we need to initiate the release from the BSC
2522 * side. dyn_ts_switchover_continue() will be called from
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002523 * rsl_rx_rf_chan_rel_ack(). PDCH is always on lchan[0].
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002524 */
2525 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH) {
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002526 rsl_lchan_set_state(ts->lchan, LCHAN_S_REL_REQ);
2527 rc = rsl_rf_chan_release(ts->lchan, 0, SACCH_NONE);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002528 if (rc) {
2529 LOGP(DRSL, LOGL_ERROR,
2530 "%s RSL RF Chan Release failed\n",
2531 gsm_ts_and_pchan_name(ts));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002532 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002533 }
2534 return 0;
2535 }
2536
2537 /*
2538 * To switch from TCH/F and TCH/H pchans, this has been called from
2539 * rsl_rx_rf_chan_rel_ack(), i.e. release is complete. Go ahead and
2540 * activate as new type. This will always be PDCH.
2541 */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002542 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002543}
2544
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002545static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002546{
2547 int rc;
2548 uint8_t act_type;
2549 uint8_t ho_ref;
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002550 int ss;
2551 struct gsm_lchan *lchan;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002552
2553 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2554 DEBUGP(DRSL, "%s switchover: release complete,"
2555 " activating new pchan type\n",
2556 gsm_ts_and_pchan_name(ts));
2557
2558 if (ts->dyn.pchan_is == ts->dyn.pchan_want) {
2559 LOGP(DRSL, LOGL_ERROR,
2560 "%s Requested to switchover dynamic channel to the"
2561 " same type it is already in.\n",
2562 gsm_ts_and_pchan_name(ts));
2563 return 0;
2564 }
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002565
2566 for (ss = 0; ss < ts_subslots(ts); ss++) {
2567 lchan = &ts->lchan[ss];
2568 if (lchan->rqd_ref) {
2569 LOGP(DRSL, LOGL_ERROR,
2570 "%s During dyn TS switchover, expecting no"
2571 " Request Reference to be pending. Discarding!\n",
2572 gsm_lchan_name(lchan));
2573 talloc_free(lchan->rqd_ref);
2574 lchan->rqd_ref = NULL;
2575 }
2576 }
2577
2578 /*
2579 * When switching pchan modes, all lchans are unused. So always
2580 * activate whatever wants to be activated on the first lchan. (We
2581 * wouldn't remember to use lchan[1] across e.g. a PDCH deact anyway)
2582 */
2583 lchan = ts->lchan;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002584
2585 /*
2586 * For TCH/x, the lchan->type has been set in lchan_alloc(), but it may
2587 * have been lost during channel release due to dynamic switchover.
2588 *
2589 * For PDCH, the lchan->type will actually remain NONE.
2590 * TODO: set GSM_LCHAN_PDTCH?
2591 */
2592 switch (ts->dyn.pchan_want) {
2593 case GSM_PCHAN_TCH_F:
2594 lchan->type = GSM_LCHAN_TCH_F;
2595 break;
2596 case GSM_PCHAN_TCH_H:
2597 lchan->type = GSM_LCHAN_TCH_H;
2598 break;
2599 case GSM_PCHAN_PDCH:
2600 lchan->type = GSM_LCHAN_NONE;
2601 break;
2602 default:
2603 LOGP(DRSL, LOGL_ERROR,
2604 "%s Invalid target pchan for dynamic TS\n",
2605 gsm_ts_and_pchan_name(ts));
2606 }
2607
2608 act_type = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2609 ? RSL_ACT_OSMO_PDCH
2610 : lchan->dyn.act_type;
2611 ho_ref = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2612 ? 0
2613 : lchan->dyn.ho_ref;
2614
2615 /* Fetch the rqd_ref back from before switchover started. */
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002616 lchan->rqd_ref = lchan->dyn.rqd_ref;
2617 lchan->rqd_ta = lchan->dyn.rqd_ta;
2618 lchan->dyn.rqd_ref = NULL;
2619 lchan->dyn.rqd_ta = 0;
2620
Neels Hofmeyra2ef7d62016-08-24 16:57:31 +02002621 /* During switchover, we have received a release ack, which means that
2622 * the act_timer has been stopped. Start the timer again so we mark
2623 * this channel broken if the activation ack comes too late. */
2624 lchan->act_timer.cb = lchan_act_tmr_cb;
2625 lchan->act_timer.data = lchan;
2626 osmo_timer_schedule(&lchan->act_timer, 4, 0);
2627
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002628 rc = rsl_chan_activate_lchan(lchan, act_type, ho_ref);
2629 if (rc) {
2630 LOGP(DRSL, LOGL_ERROR,
2631 "%s RSL Chan Activate failed\n",
2632 gsm_ts_and_pchan_name(ts));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002633 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002634 }
2635 return 0;
2636}
2637
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002638static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002639{
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002640 ts->dyn.pchan_want = ts->dyn.pchan_is;
2641 LOGP(DRSL, LOGL_ERROR, "%s Error %d during dynamic channel switchover."
2642 " Going back to previous pchan.\n", gsm_ts_and_pchan_name(ts),
2643 rc);
2644 return rc;
2645}
2646
2647static void dyn_ts_switchover_complete(struct gsm_lchan *lchan)
2648{
2649 enum gsm_phys_chan_config pchan_act;
2650 enum gsm_phys_chan_config pchan_was;
2651 struct gsm_bts_trx_ts *ts = lchan->ts;
2652
2653 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2654
2655 pchan_act = pchan_for_lchant(lchan->type);
2656 /*
2657 * Paranoia: do the types match?
2658 * In case of errors: we've received an act ack already, so what to do
2659 * about it? Logging the error should suffice for now.
2660 */
2661 if (pchan_act != ts->dyn.pchan_want)
2662 LOGP(DRSL, LOGL_ERROR,
2663 "%s Requested transition does not match lchan type %s\n",
2664 gsm_ts_and_pchan_name(ts),
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002665 gsm_lchant_name(lchan->type));
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002666
2667 pchan_was = ts->dyn.pchan_is;
2668 ts->dyn.pchan_is = ts->dyn.pchan_want = pchan_act;
2669
Neels Hofmeyra0a08d82016-08-24 14:42:58 +02002670 if (pchan_was != ts->dyn.pchan_is)
2671 LOGP(DRSL, LOGL_INFO, "%s switchover from %s complete.\n",
2672 gsm_ts_and_pchan_name(ts), gsm_pchan_name(pchan_was));
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002673}
Harald Welte75099262009-02-16 21:12:08 +00002674
Harald Welte52b1f982008-12-23 20:25:15 +00002675/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00002676int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00002677{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002678 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002679 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002680
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002681 if (!msg) {
2682 DEBUGP(DRSL, "Empty RSL msg?..\n");
2683 return -1;
2684 }
2685
2686 if (msgb_l2len(msg) < sizeof(*rslh)) {
2687 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02002688 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002689 return -1;
2690 }
2691
2692 rslh = msgb_l2(msg);
2693
Harald Welte52b1f982008-12-23 20:25:15 +00002694 switch (rslh->msg_discr & 0xfe) {
2695 case ABIS_RSL_MDISC_RLL:
2696 rc = abis_rsl_rx_rll(msg);
2697 break;
2698 case ABIS_RSL_MDISC_DED_CHAN:
2699 rc = abis_rsl_rx_dchan(msg);
2700 break;
2701 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00002702 rc = abis_rsl_rx_cchan(msg);
2703 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002704 case ABIS_RSL_MDISC_TRX:
2705 rc = abis_rsl_rx_trx(msg);
2706 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002707 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002708 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002709 rslh->msg_discr);
2710 break;
Harald Welte75099262009-02-16 21:12:08 +00002711 case ABIS_RSL_MDISC_IPACCESS:
2712 rc = abis_rsl_rx_ipacc(msg);
2713 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002714 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002715 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2716 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002717 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002718 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002719 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002720 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002721}
Holger Freyther3b72a892009-02-04 00:31:39 +00002722
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002723int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Welte30f1f372014-12-28 15:00:45 +01002724 struct rsl_ie_cb_cmd_type cb_command,
2725 const uint8_t *data, int len)
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002726{
2727 struct abis_rsl_dchan_hdr *dh;
2728 struct msgb *cb_cmd;
2729
2730 cb_cmd = rsl_msgb_alloc();
2731 if (!cb_cmd)
2732 return -1;
2733
Harald Welte30f1f372014-12-28 15:00:45 +01002734 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002735 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Welte30f1f372014-12-28 15:00:45 +01002736 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2737 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002738
Harald Welte30f1f372014-12-28 15:00:45 +01002739 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002740 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2741
Harald Welte30f1f372014-12-28 15:00:45 +01002742 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002743
2744 return abis_rsl_sendmsg(cb_cmd);
2745}
Dieter Spaar16646022011-07-28 00:01:50 +02002746
2747int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2748{
2749 struct abis_rsl_common_hdr *ch;
2750 struct msgb *msg = rsl_msgb_alloc();
2751
2752 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2753 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2754 ch->msg_type = 0x40; /* Nokia SI Begin */
2755
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002756 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002757
2758 return abis_rsl_sendmsg(msg);
2759}
2760
2761int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2762{
2763 struct abis_rsl_common_hdr *ch;
2764 struct msgb *msg = rsl_msgb_alloc();
2765
2766 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2767 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2768 ch->msg_type = 0x41; /* Nokia SI End */
2769
2770 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2771
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002772 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002773
2774 return abis_rsl_sendmsg(msg);
2775}
2776
2777int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2778{
2779 struct abis_rsl_common_hdr *ch;
2780 struct msgb *msg = rsl_msgb_alloc();
2781
2782 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2783 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2784 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2785
2786 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2787 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2788
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002789 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002790
2791 return abis_rsl_sendmsg(msg);
2792}
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01002793
2794/**
2795 * Release all allocated SAPIs starting from @param start and
2796 * release them with the given release mode. Once the release
2797 * confirmation arrives it will be attempted to release the
2798 * the RF channel.
2799 */
2800int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2801 enum rsl_rel_mode release_mode)
2802{
2803 int no_sapi = 1;
2804 int sapi;
2805
2806 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2807 uint8_t link_id;
2808 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2809 continue;
2810
2811 link_id = sapi;
2812 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2813 link_id |= 0x40;
2814 rsl_release_request(lchan, link_id, release_mode);
2815 no_sapi = 0;
2816 }
2817
2818 return no_sapi;
2819}
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002820
2821int rsl_start_t3109(struct gsm_lchan *lchan)
2822{
2823 struct gsm_bts *bts = lchan->ts->trx->bts;
2824
2825 /* Disabled, mostly legacy code */
2826 if (bts->network->T3109 == 0)
2827 return -1;
2828
2829 lchan->T3109.cb = t3109_expired;
2830 lchan->T3109.data = lchan;
2831 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2832 return 0;
2833}
Holger Hans Peter Freyther006e3d82012-12-25 23:45:14 +01002834
2835/**
2836 * \brief directly RF Channel Release the lchan
2837 *
2838 * When no SAPI was allocated, directly release the logical channel. This
2839 * should only be called from chan_alloc.c on channel release handling. In
2840 * case no SAPI was established the RF Channel can be directly released,
2841 */
2842int rsl_direct_rf_release(struct gsm_lchan *lchan)
2843{
2844 int i;
2845 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2846 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2847 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2848 gsm_lchan_name(lchan), i);
2849 return -1;
2850 }
2851 }
2852
2853 /* Now release it */
2854 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2855}