blob: 3337b90ac10caa4512ea205235e166fde3351d3b [file] [log] [blame]
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte52b1f982008-12-23 20:25:15 +00002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Welte3c9c5f92010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte8470bf22008-12-25 23:28:35 +00006 *
Harald Welte52b1f982008-12-23 20:25:15 +00007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte52b1f982008-12-23 20:25:15 +000012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte52b1f982008-12-23 20:25:15 +000021 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
Harald Welte75099262009-02-16 21:12:08 +000027#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000028#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Harald Welte8470bf22008-12-25 23:28:35 +000030#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000036#include <openbsc/debug.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Maxc08ee712016-05-11 12:45:13 +020038#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include <osmocom/gsm/protocol/gsm_08_58.h>
Holger Freyther392209c2009-02-10 00:06:19 +000040#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000041#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010042#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010043#include <openbsc/rtp_proxy.h>
Max11e4e412017-04-20 13:07:58 +020044#include <openbsc/gsm_subscriber.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020045#include <osmocom/abis/e1_input.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010046#include <osmocom/gsm/rsl.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010047#include <osmocom/core/talloc.h>
Philipp Maierb4999b62016-10-26 15:19:41 +020048#include <openbsc/pcu_if.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080049
Harald Welte8470bf22008-12-25 23:28:35 +000050#define RSL_ALLOC_SIZE 1024
51#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000052
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +010053enum sacch_deact {
54 SACCH_NONE,
55 SACCH_DEACTIVATE,
56};
57
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080058static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020059static void error_timeout_cb(void *data);
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +020060static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts);
61static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +020062static void dyn_ts_switchover_complete(struct gsm_lchan *lchan);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080063
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010064static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
65 struct gsm_meas_rep *resp)
66{
67 struct lchan_signal_data sig;
68 sig.lchan = lchan;
69 sig.mr = resp;
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +020070 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010071}
72
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010073static void do_lchan_free(struct gsm_lchan *lchan)
74{
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020075 /* We start the error timer to make the channel available again */
76 if (lchan->state == LCHAN_S_REL_ERR) {
Pablo Neira Ayuso51215762017-05-08 20:57:52 +020077 osmo_timer_setup(&lchan->error_timer, error_timeout_cb, lchan);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020078 osmo_timer_schedule(&lchan->error_timer,
79 lchan->ts->trx->bts->network->T3111 + 2, 0);
80 } else {
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010081 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherf0405062014-04-06 12:21:05 +020082 }
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010083 lchan_free(lchan);
84}
85
Alexander Couzens8c53c592016-08-23 06:27:19 +020086static void count_codecs(struct gsm_bts *bts, struct gsm_lchan *lchan)
87{
88 OSMO_ASSERT(bts);
89
90 if (lchan->type == GSM_LCHAN_TCH_H) {
91 switch (lchan->tch_mode) {
92 case GSM48_CMODE_SPEECH_AMR:
93 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_H]);
94 break;
95 case GSM48_CMODE_SPEECH_V1:
96 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_HR]);
97 break;
98 default:
99 break;
100 }
101 } else if (lchan->type == GSM_LCHAN_TCH_F) {
102 switch (lchan->tch_mode) {
103 case GSM48_CMODE_SPEECH_AMR:
104 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_AMR_F]);
105 break;
106 case GSM48_CMODE_SPEECH_V1:
107 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_V1_FR]);
108 break;
109 case GSM48_CMODE_SPEECH_EFR:
110 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CODEC_EFR]);
111 break;
112 default:
113 break;
114 }
Alexander Couzens8c53c592016-08-23 06:27:19 +0200115 }
116}
117
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200118static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000119{
120 /* mask off the transparent bit ? */
121 msg_type &= 0xfe;
122
Harald Welte8470bf22008-12-25 23:28:35 +0000123 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +0000124 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +0000125 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +0000126 if (msg_type >= 0x19 && msg_type <= 0x22)
127 return ABIS_RSL_MDISC_TRX;
128 else
129 return ABIS_RSL_MDISC_COM_CHAN;
130 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000131 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +0000132 return ABIS_RSL_MDISC_DED_CHAN;
133
134 return ABIS_RSL_MDISC_LOC;
135}
136
137static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200138 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +0000139{
140 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
141 dh->c.msg_type = msg_type;
142 dh->ie_chan = RSL_IE_CHAN_NR;
143}
144
Neels Hofmeyr74585722016-07-23 17:38:22 +0200145/* call rsl_lchan_lookup and set the log context */
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200146static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
147 const char *log_name)
Harald Welte8470bf22008-12-25 23:28:35 +0000148{
Neels Hofmeyr74585722016-07-23 17:38:22 +0200149 int rc;
150 struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc);
Harald Welte8470bf22008-12-25 23:28:35 +0000151
Neels Hofmeyr74585722016-07-23 17:38:22 +0200152 if (!lchan) {
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200153 LOGP(DRSL, LOGL_ERROR, "%sunknown chan_nr=0x%02x\n",
154 log_name, chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000155 return NULL;
156 }
157
Neels Hofmeyr74585722016-07-23 17:38:22 +0200158 if (rc < 0)
Neels Hofmeyr2867f882016-08-23 01:22:58 +0200159 LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n",
160 gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr);
Neels Hofmeyr74585722016-07-23 17:38:22 +0200161
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800162 if (lchan->conn)
Harald Welte2483f1b2016-06-19 18:06:02 +0200163 log_set_context(LOG_CTX_VLR_SUBSCR, lchan->conn->vsub);
Harald Welte8470bf22008-12-25 23:28:35 +0000164
165 return lchan;
166}
167
Harald Welte52b1f982008-12-23 20:25:15 +0000168/* 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 +0200169uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000170{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200171 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000172
173 ret = strtoull(imsi_str, NULL, 10);
174
175 return ret;
176}
177
Harald Welte8470bf22008-12-25 23:28:35 +0000178static struct msgb *rsl_msgb_alloc(void)
179{
Harald Welte966636f2009-06-26 19:39:35 +0200180 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
181 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000182}
183
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200184static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000185{
186 memcpy(out, in, len);
187
Maxb726c2c2017-02-09 19:23:38 +0100188 if (len < GSM_MACBLOCK_LEN)
189 memset(out+len, 0x2b, GSM_MACBLOCK_LEN - len);
Harald Welte362322e2009-02-15 14:36:38 +0000190}
191
Harald Welte08d91a52009-08-30 15:37:11 +0900192/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200193static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900194{
195 *out++ = lchan->encr.alg_id & 0xff;
196 if (lchan->encr.key_len)
197 memcpy(out, lchan->encr.key, lchan->encr.key_len);
198 return lchan->encr.key_len + 1;
199}
200
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200201static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200202{
Harald Welte7f93cea2009-02-23 00:02:59 +0000203 int i;
204
Harald Welte5b8ed432009-12-24 12:20:20 +0100205 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200206 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200207 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100208 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000209}
210
Harald Weltee8bd9e82011-08-10 23:26:33 +0200211static void lchan_act_tmr_cb(void *data)
212{
213 struct gsm_lchan *lchan = data;
214
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100215 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann513da172011-08-11 04:44:12 +0200216 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200217}
218
219static void lchan_deact_tmr_cb(void *data)
220{
221 struct gsm_lchan *lchan = data;
222
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +0100223 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200224 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200225}
226
227
Harald Welte52b1f982008-12-23 20:25:15 +0000228/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Max8b1a2f82017-06-15 14:59:20 +0200229int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000230{
231 struct abis_rsl_dchan_hdr *dh;
Max8b1a2f82017-06-15 14:59:20 +0200232 const struct gsm_bts *bts = trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +0000233 struct msgb *msg = rsl_msgb_alloc();
Max8b1a2f82017-06-15 14:59:20 +0200234 uint8_t type = osmo_sitype2rsl(si_type);
235
236 if (bts->c0 != trx)
237 LOGP(DRR, LOGL_ERROR, "Attempting to set BCCH SI%s on wrong BTS%u/TRX%u\n",
238 get_value_string(osmo_sitype_strs, si_type), bts->nr, trx->nr);
Harald Welte52b1f982008-12-23 20:25:15 +0000239
240 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
241 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
242 dh->chan_nr = RSL_CHAN_BCCH;
243
Philipp309425e2016-11-02 12:05:44 +0100244 if (trx->bts->type == GSM_BTS_TYPE_RBS2000
245 && type == RSL_SYSTEM_INFO_13) {
246 /* Ericsson proprietary encoding of SI13 */
247 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, RSL_ERIC_SYSTEM_INFO_13);
Harald Welte942175c2017-07-15 23:56:12 +0200248 if (data)
249 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
Philipp309425e2016-11-02 12:05:44 +0100250 msgb_tv_put(msg, RSL_IE_ERIC_BCCH_MAPPING, 0x00);
251 } else {
252 /* Normal encoding */
253 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte942175c2017-07-15 23:56:12 +0200254 if (data)
255 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
Philipp309425e2016-11-02 12:05:44 +0100256 }
Harald Welte52b1f982008-12-23 20:25:15 +0000257
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200258 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000259
260 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000261}
262
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200263int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
264 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000265{
266 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000267 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000268
269 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
270 ch->msg_discr = ABIS_RSL_MDISC_TRX;
271 ch->msg_type = RSL_MT_SACCH_FILL;
272
273 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte942175c2017-07-15 23:56:12 +0200274 if (data)
275 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000276
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200277 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000278
279 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000280}
281
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200282int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
283 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100284{
285 struct abis_rsl_dchan_hdr *dh;
286 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200287 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100288
289 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
290 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
291 dh->chan_nr = chan_nr;
292
293 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte942175c2017-07-15 23:56:12 +0200294 if (data)
295 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte7a69cf02011-01-13 23:16:03 +0100296
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200297 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100298
299 return abis_rsl_sendmsg(msg);
300}
301
Harald Weltefcd24452009-06-20 18:15:19 +0200302int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
303{
304 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200305 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200306 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200307
308 db = abs(db);
309 if (db > 30)
310 return -EINVAL;
311
Harald Welteeab33352009-06-27 03:09:08 +0200312 msg = rsl_msgb_alloc();
313
Harald Weltefcd24452009-06-20 18:15:19 +0200314 lchan->bs_power = db/2;
315 if (fpc)
316 lchan->bs_power |= 0x10;
317
318 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
319 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
320 dh->chan_nr = chan_nr;
321
322 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
323
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200324 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200325
326 return abis_rsl_sendmsg(msg);
327}
328
Harald Weltefcd24452009-06-20 18:15:19 +0200329int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
330{
331 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200332 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200333 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200334 int ctl_lvl;
335
Harald Welte66b6a8d2009-08-09 14:45:18 +0200336 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200337 if (ctl_lvl < 0)
338 return ctl_lvl;
339
Harald Welteeab33352009-06-27 03:09:08 +0200340 msg = rsl_msgb_alloc();
341
Harald Weltefcd24452009-06-20 18:15:19 +0200342 lchan->ms_power = ctl_lvl;
343
344 if (fpc)
345 lchan->ms_power |= 0x20;
346
347 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
348 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
349 dh->chan_nr = chan_nr;
350
351 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
352
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200353 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200354
355 return abis_rsl_sendmsg(msg);
356}
357
Harald Welte9943c5b2009-07-29 15:41:29 +0200358static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
359 struct gsm_lchan *lchan)
360{
Holger Hans Peter Freythere1145cf2013-03-09 17:50:10 +0100361 memset(cm, 0, sizeof(*cm));
Harald Welte9943c5b2009-07-29 15:41:29 +0200362
363 /* FIXME: what to do with data calls ? */
Maxc08ee712016-05-11 12:45:13 +0200364 cm->dtx_dtu = 0;
365 if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
366 cm->dtx_dtu |= RSL_CMOD_DTXu;
367 if (lchan->ts->trx->bts->dtxd)
368 cm->dtx_dtu |= RSL_CMOD_DTXd;
Harald Welte9943c5b2009-07-29 15:41:29 +0200369
370 /* set TCH Speech/Data */
371 cm->spd_ind = lchan->rsl_cmode;
372
Harald Welte1a79d362009-11-27 08:55:16 +0100373 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
374 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100375 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100376 "but tch_mode != signalling\n");
377
Harald Welte9943c5b2009-07-29 15:41:29 +0200378 switch (lchan->type) {
379 case GSM_LCHAN_SDCCH:
380 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
381 break;
382 case GSM_LCHAN_TCH_F:
383 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
384 break;
385 case GSM_LCHAN_TCH_H:
386 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
387 break;
388 case GSM_LCHAN_NONE:
389 case GSM_LCHAN_UNKNOWN:
390 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200391 LOGP(DRSL, LOGL_ERROR,
392 "unsupported activation lchan->type %u %s\n",
393 lchan->type, gsm_lchant_name(lchan->type));
Harald Welte9943c5b2009-07-29 15:41:29 +0200394 return -EINVAL;
395 }
396
397 switch (lchan->tch_mode) {
398 case GSM48_CMODE_SIGN:
399 cm->chan_rate = 0;
400 break;
401 case GSM48_CMODE_SPEECH_V1:
402 cm->chan_rate = RSL_CMOD_SP_GSM1;
403 break;
404 case GSM48_CMODE_SPEECH_EFR:
405 cm->chan_rate = RSL_CMOD_SP_GSM2;
406 break;
407 case GSM48_CMODE_SPEECH_AMR:
408 cm->chan_rate = RSL_CMOD_SP_GSM3;
409 break;
410 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200411 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200412 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200413 switch (lchan->csd_mode) {
414 case LCHAN_CSD_M_NT:
415 /* non-transparent CSD with RLP */
416 switch (lchan->tch_mode) {
417 case GSM48_CMODE_DATA_14k5:
418 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
419 break;
420 case GSM48_CMODE_DATA_12k0:
421 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
422 break;
423 case GSM48_CMODE_DATA_6k0:
424 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
425 break;
426 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200427 LOGP(DRSL, LOGL_ERROR,
428 "unsupported lchan->tch_mode %u\n",
429 lchan->tch_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200430 return -EINVAL;
431 }
432 break;
433 /* transparent data services below */
434 case LCHAN_CSD_M_T_1200_75:
435 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
436 break;
437 case LCHAN_CSD_M_T_600:
438 cm->chan_rate = RSL_CMOD_CSD_T_600;
439 break;
440 case LCHAN_CSD_M_T_1200:
441 cm->chan_rate = RSL_CMOD_CSD_T_1200;
442 break;
443 case LCHAN_CSD_M_T_2400:
444 cm->chan_rate = RSL_CMOD_CSD_T_2400;
445 break;
446 case LCHAN_CSD_M_T_9600:
447 cm->chan_rate = RSL_CMOD_CSD_T_9600;
448 break;
449 case LCHAN_CSD_M_T_14400:
450 cm->chan_rate = RSL_CMOD_CSD_T_14400;
451 break;
452 case LCHAN_CSD_M_T_29000:
453 cm->chan_rate = RSL_CMOD_CSD_T_29000;
454 break;
455 case LCHAN_CSD_M_T_32000:
456 cm->chan_rate = RSL_CMOD_CSD_T_32000;
457 break;
458 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200459 LOGP(DRSL, LOGL_ERROR,
460 "unsupported lchan->csd_mode %u\n",
461 lchan->csd_mode);
Harald Weltee4227982012-08-24 15:33:56 +0200462 return -EINVAL;
463 }
Harald Welteb8e8d0a2016-11-26 15:16:14 +0100464 break;
Harald Welte9943c5b2009-07-29 15:41:29 +0200465 default:
Neels Hofmeyrbbbcfe52016-07-18 23:47:24 +0200466 LOGP(DRSL, LOGL_ERROR,
467 "unsupported lchan->tch_mode %u\n",
468 lchan->tch_mode);
Harald Welte9943c5b2009-07-29 15:41:29 +0200469 return -EINVAL;
470 }
471
472 return 0;
473}
474
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200475static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
476{
477 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
478 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
479 lchan->mr_bts_lv + 1);
480}
481
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200482static enum gsm_phys_chan_config pchan_for_lchant(enum gsm_chan_t type)
483{
484 switch (type) {
485 case GSM_LCHAN_TCH_F:
486 return GSM_PCHAN_TCH_F;
487 case GSM_LCHAN_TCH_H:
488 return GSM_PCHAN_TCH_H;
489 case GSM_LCHAN_NONE:
490 case GSM_LCHAN_PDTCH:
491 /* TODO: so far lchan->type is NONE in PDCH mode. PDTCH is only
492 * used in osmo-bts. Maybe set PDTCH and drop the NONE case
493 * here. */
494 return GSM_PCHAN_PDCH;
495 default:
496 return GSM_PCHAN_UNKNOWN;
497 }
498}
499
500/*! Tx simplified channel activation message for non-standard PDCH type. */
501static int rsl_chan_activate_lchan_as_pdch(struct gsm_lchan *lchan)
502{
503 struct msgb *msg;
504 struct abis_rsl_dchan_hdr *dh;
505
506 /* This might be called after release of the second lchan of a TCH/H,
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200507 * but PDCH activation must always happen on the first lchan. Make sure
508 * the calling code passes the correct lchan. */
509 OSMO_ASSERT(lchan == lchan->ts->lchan);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200510
511 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
512
513 msg = rsl_msgb_alloc();
514 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
515 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
516 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);
517
518 msgb_tv_put(msg, RSL_IE_ACT_TYPE, RSL_ACT_OSMO_PDCH);
519
Harald Weltef7e9a342016-11-16 15:17:22 +0100520 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_RBS2000 &&
521 lchan->ts->trx->bts->rbs2000.use_superchannel) {
522 const uint8_t eric_pgsl_tmr[] = { 30, 1 };
523 msgb_tv_fixed_put(msg, RSL_IE_ERIC_PGSL_TIMERS,
524 sizeof(eric_pgsl_tmr), eric_pgsl_tmr);
525 }
526
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200527 msg->dst = lchan->ts->trx->rsl_link;
528
529 return abis_rsl_sendmsg(msg);
530}
531
Harald Welte52b1f982008-12-23 20:25:15 +0000532/* Chapter 8.4.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200533int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg723a7512013-10-11 12:55:35 +0200534 uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000535{
536 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200537 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200538 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200539 uint8_t *len;
Andreas Eversberg723a7512013-10-11 12:55:35 +0200540 uint8_t ta;
Harald Welte4b634542008-12-27 01:55:51 +0000541
Harald Welte4b634542008-12-27 01:55:51 +0000542 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200543 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000544
Neels Hofmeyrc6926d02016-07-14 02:51:13 +0200545 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200546 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200547 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200548 /* store activation type and handover reference */
Neels Hofmeyr6e999b72016-07-23 21:00:51 +0200549 lchan->dyn.act_type = act_type;
550 lchan->dyn.ho_ref = ho_ref;
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200551 return rsl_ipacc_pdch_activate(lchan->ts, 0);
552 }
553
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200554 /*
555 * If necessary, release PDCH on dynamic TS. Note that sending a
556 * release here is only necessary when in PDCH mode; for TCH types, an
557 * RSL RF Chan Release is initiated by the BTS when a voice call ends,
558 * so when we reach this, it will already be released. If a dyn TS is
559 * in PDCH mode, it is still active and we need to initiate a release
560 * from the BSC side here.
561 *
562 * If pchan_is != pchan_want, the PDCH has already been taken down and
563 * the switchover now needs to enable the TCH lchan.
564 *
565 * To switch a dyn TS between TCH/H and TCH/F, it is sufficient to send
566 * a chan activ with the new lchan type, because it will already be
567 * released.
568 */
569 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
570 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
571 && lchan->ts->dyn.pchan_is == lchan->ts->dyn.pchan_want) {
572 enum gsm_phys_chan_config pchan_want;
573 pchan_want = pchan_for_lchant(lchan->type);
574 if (lchan->ts->dyn.pchan_is != pchan_want) {
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200575 /*
576 * Make sure to record on lchan[0] so that we'll find
577 * it after the PDCH release.
578 */
579 struct gsm_lchan *lchan0 = lchan->ts->lchan;
580 lchan0->dyn.act_type = act_type,
581 lchan0->dyn.ho_ref = ho_ref;
582 lchan0->dyn.rqd_ref = lchan->rqd_ref;
583 lchan0->dyn.rqd_ta = lchan->rqd_ta;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200584 lchan->rqd_ref = NULL;
585 lchan->rqd_ta = 0;
586 DEBUGP(DRSL, "%s saved rqd_ref=%p ta=%u\n",
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200587 gsm_lchan_name(lchan0), lchan0->rqd_ref,
588 lchan0->rqd_ta);
589 return dyn_ts_switchover_start(lchan->ts, pchan_want);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200590 }
591 }
592
593 DEBUGP(DRSL, "%s Tx RSL Channel Activate with act_type=%s\n",
594 gsm_ts_and_pchan_name(lchan->ts),
595 rsl_act_type_name(act_type));
596
597 if (act_type == RSL_ACT_OSMO_PDCH) {
598 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH) {
599 LOGP(DRSL, LOGL_ERROR,
600 "%s PDCH channel activation only allowed on %s\n",
601 gsm_ts_and_pchan_name(lchan->ts),
602 gsm_pchan_name(GSM_PCHAN_TCH_F_TCH_H_PDCH));
603 return -EINVAL;
604 }
605 return rsl_chan_activate_lchan_as_pdch(lchan);
606 }
607
608 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
609 && lchan->ts->dyn.pchan_want == GSM_PCHAN_PDCH) {
610 LOGP(DRSL, LOGL_ERROR,
611 "%s Expected PDCH activation kind\n",
612 gsm_ts_and_pchan_name(lchan->ts));
613 return -EINVAL;
614 }
615
Neels Hofmeyrcf793382016-07-23 19:49:58 +0200616 rc = channel_mode_from_lchan(&cm, lchan);
617 if (rc < 0) {
618 LOGP(DRSL, LOGL_ERROR,
619 "%s Cannot find channel mode from lchan type\n",
620 gsm_ts_and_pchan_name(lchan->ts));
621 return rc;
622 }
623
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200624 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
625
Andreas Eversberg723a7512013-10-11 12:55:35 +0200626 ta = lchan->rqd_ta;
627
628 /* BS11 requires TA shifted by 2 bits */
629 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
630 ta <<= 2;
631
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800632 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200633 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000634
Harald Welteeab33352009-06-27 03:09:08 +0200635 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000636 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
637 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
Neels Hofmeyr7af652c2016-07-23 19:51:09 +0200638
639 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
640 dh->chan_nr = gsm_lchan_as_pchan2chan_nr(
641 lchan, lchan->ts->dyn.pchan_want);
642 else
643 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000644
645 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000646 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200647 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800648
649 /*
650 * The Channel Identification is needed for Phase1 phones
651 * and it contains the GSM48 Channel Description and the
652 * Mobile Allocation. The GSM 08.58 asks for the Mobile
653 * Allocation to have a length of zero. We are using the
654 * msgb_l3len to calculate the length of both messages.
655 */
laforge694a5cf2010-06-20 21:38:19 +0200656 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200657 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200658 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800659
660 if (lchan->ts->hopping.enabled)
661 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
662 lchan->ts->hopping.ma_data);
663 else
664 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800665
666 /* update the calculated size */
667 msg->l3h = len + 1;
668 *len = msgb_l3len(msg);
669
Harald Welte08d91a52009-08-30 15:37:11 +0900670 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200671 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900672 rc = build_encr_info(encr_info, lchan);
673 if (rc > 0)
674 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
675 }
676
Harald Welte8d77b952009-12-17 00:31:10 +0100677 switch (act_type) {
678 case RSL_ACT_INTER_ASYNC:
679 case RSL_ACT_INTER_SYNC:
680 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
681 break;
682 default:
683 break;
684 }
685
Harald Welted4c9bf32009-02-15 16:56:18 +0000686 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
687 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000688 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200689 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100690
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200691 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000692
Harald Welte4b634542008-12-27 01:55:51 +0000693 return abis_rsl_sendmsg(msg);
694}
695
Harald Welte470abb72009-07-29 11:38:15 +0200696/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000697int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
698{
699 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200700 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200701 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000702
Harald Weltef6093a42011-06-25 10:02:33 +0200703 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000704 struct rsl_ie_chan_mode cm;
705
Harald Welte9943c5b2009-07-29 15:41:29 +0200706 rc = channel_mode_from_lchan(&cm, lchan);
707 if (rc < 0)
708 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000709
Harald Welteeab33352009-06-27 03:09:08 +0200710 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000711 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
712 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
713 dh->chan_nr = chan_nr;
714
715 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200716 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900717
718 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200719 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900720 rc = build_encr_info(encr_info, lchan);
721 if (rc > 0)
722 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
723 }
724
Holger Hans Peter Freyther11cb7a92015-08-20 19:32:46 +0200725 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100726
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200727 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900728
729 return abis_rsl_sendmsg(msg);
730}
731
732/* Chapter 8.4.6: Send the encryption command with given L3 info */
733int rsl_encryption_cmd(struct msgb *msg)
734{
735 struct abis_rsl_dchan_hdr *dh;
736 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200737 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200738 uint8_t encr_info[MAX_A5_KEY_LEN+2];
739 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900740 int rc;
741
742 /* First push the L3 IE tag and length */
743 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
744
745 /* then the link identifier (SAPI0, main sign link) */
746 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
747
748 /* then encryption information */
749 rc = build_encr_info(encr_info, lchan);
750 if (rc <= 0)
751 return rc;
752 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
753
754 /* and finally the DCHAN header */
755 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
756 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
757 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000758
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200759 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000760
761 return abis_rsl_sendmsg(msg);
762}
763
Harald Welte115d1032009-08-10 11:43:22 +0200764/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200765int rsl_deact_sacch(struct gsm_lchan *lchan)
766{
767 struct abis_rsl_dchan_hdr *dh;
768 struct msgb *msg = rsl_msgb_alloc();
769
770 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
771 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200772 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200773
774 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200775 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200776
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100777 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200778
779 return abis_rsl_sendmsg(msg);
780}
781
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200782static bool dyn_ts_should_switch_to_pdch(struct gsm_bts_trx_ts *ts)
783{
784 int ss;
785
786 if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
787 return false;
788
789 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
790 return false;
791
792 /* Already in PDCH mode? */
793 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH)
794 return false;
795
796 /* See if all lchans are released. */
797 for (ss = 0; ss < ts_subslots(ts); ss++) {
798 struct gsm_lchan *lc = &ts->lchan[ss];
799 if (lc->state != LCHAN_S_NONE) {
Neels Hofmeyrbaa6c552016-08-24 14:48:39 +0200800 DEBUGP(DRSL, "%s lchan %u still in use"
801 " (type=%s,state=%s)\n",
802 gsm_ts_and_pchan_name(ts), lc->nr,
803 gsm_lchant_name(lc->type),
804 gsm_lchans_name(lc->state));
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200805 /* An lchan is still used. */
806 return false;
807 }
808 }
809
810 /* All channels are released, go to PDCH mode. */
811 DEBUGP(DRSL, "%s back to PDCH\n",
812 gsm_ts_and_pchan_name(ts));
813 return true;
814}
815
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800816static void error_timeout_cb(void *data)
817{
818 struct gsm_lchan *lchan = data;
819 if (lchan->state != LCHAN_S_REL_ERR) {
820 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
821 gsm_lchan_name(lchan), lchan->state);
822 return;
823 }
824
825 /* go back to the none state */
Harald Weltea9e420e2012-11-13 04:26:22 +0100826 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800827 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200828
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +0200829 /* Put PDCH channel back into PDCH mode, if GPRS is enabled */
830 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
831 && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE)
Neels Hofmeyr82c8f752016-06-21 20:55:14 +0200832 rsl_ipacc_pdch_activate(lchan->ts, 1);
Neels Hofmeyrcd150a82016-08-24 14:45:44 +0200833
834 if (dyn_ts_should_switch_to_pdch(lchan->ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200835 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800836}
837
Harald Weltefd355a32011-03-04 13:41:31 +0100838static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
839
Harald Welte115d1032009-08-10 11:43:22 +0200840/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100841static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
842 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000843{
844 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800845 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100846 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000847
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100848 /* Stop timers that should lead to a channel release */
849 osmo_timer_del(&lchan->T3109);
850
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800851 if (lchan->state == LCHAN_S_REL_ERR) {
Neels Hofmeyrd5d39ae2016-08-24 17:02:19 +0200852 LOGP(DRSL, LOGL_NOTICE, "%s is in error state, not sending release.\n",
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800853 gsm_lchan_name(lchan));
854 return -1;
855 }
856
857 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000858 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
859 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200860 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000861
Harald Welte8470bf22008-12-25 23:28:35 +0000862 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200863 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000864
Neels Hofmeyrb3d87062016-08-22 18:40:07 +0200865 if (error)
866 DEBUGP(DRSL, "%s RF Channel Release due to error: %d\n",
867 gsm_lchan_name(lchan), error);
868 else
869 DEBUGP(DRSL, "%s RF Channel Release\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800870
871 if (error) {
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100872 /*
873 * FIXME: GSM 04.08 gives us two options for the abnormal
874 * chanel release. This can be either like in the non-existent
875 * sub-lcuase 3.5.1 or for the main signalling link deactivate
876 * the SACCH, start timer T3109 and consider the channel as
877 * released.
878 *
879 * This code is doing the later for all raido links and not
880 * only the main link. Right now all SAPIs are released on the
881 * local end, the SACCH will be de-activated and right now the
882 * T3111 will be started. First T3109 should be started and then
883 * the T3111.
884 *
885 * TODO: Move this out of the function.
886 */
887
888 /*
889 * sacch de-activate and "local end release"
890 */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100891 if (deact_sacch == SACCH_DEACTIVATE)
892 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100893 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
894
895 /*
896 * TODO: start T3109 now.
897 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800898 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800899 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000900
Harald Weltee8bd9e82011-08-10 23:26:33 +0200901 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +0200902 osmo_timer_setup(&lchan->act_timer, lchan_deact_tmr_cb, lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200903 osmo_timer_schedule(&lchan->act_timer, 4, 0);
904
Harald Weltefd355a32011-03-04 13:41:31 +0100905 rc = abis_rsl_sendmsg(msg);
906
Harald Welte115d1032009-08-10 11:43:22 +0200907 /* BTS will respond by RF CHAN REL ACK */
Harald Weltefd355a32011-03-04 13:41:31 +0100908 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000909}
910
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200911/*
912 * Special handling for channel releases in the error case.
913 */
914static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
915{
Neels Hofmeyrec16c162016-10-17 01:03:53 +0200916 enum sacch_deact sacch_deact;
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200917 if (lchan->state != LCHAN_S_ACTIVE)
918 return 0;
Neels Hofmeyrec16c162016-10-17 01:03:53 +0200919 switch (ts_pchan(lchan->ts)) {
920 case GSM_PCHAN_TCH_F:
921 case GSM_PCHAN_TCH_H:
922 case GSM_PCHAN_CCCH_SDCCH4:
923 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
924 case GSM_PCHAN_SDCCH8_SACCH8C:
925 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
926 sacch_deact = SACCH_DEACTIVATE;
927 break;
928 default:
929 sacch_deact = SACCH_NONE;
930 break;
931 }
932 return rsl_rf_chan_release(lchan, 1, sacch_deact);
Holger Hans Peter Freyther0e4e73a2014-04-19 17:38:33 +0200933}
934
Harald Welte64bb7542011-01-14 14:16:16 +0100935static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
936{
Neels Hofmeyr40074682016-07-23 20:01:49 +0200937 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte64bb7542011-01-14 14:16:16 +0100938
939 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
940
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100941 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200942 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100943 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200944
Holger Hans Peter Freyther6f6cbf72015-04-04 19:35:22 +0200945 /*
946 * The BTS didn't respond within the timeout to our channel
947 * release request and we have marked the channel as broken.
948 * Now we do receive an ACK and let's be conservative. If it
949 * is a sysmoBTS we know that only one RF Channel Release ACK
950 * will be sent. So let's "repair" the channel.
951 */
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200952 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyr40074682016-07-23 20:01:49 +0200953 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f6cbf72015-04-04 19:35:22 +0200954 LOGP(DRSL, LOGL_NOTICE,
955 "%s CHAN REL ACK for broken channel. %s.\n",
956 gsm_lchan_name(lchan),
957 do_free ? "Releasing it" : "Keeping it broken");
958 if (do_free)
959 do_lchan_free(lchan);
Neels Hofmeyrd35fc442016-08-24 17:02:37 +0200960 if (dyn_ts_should_switch_to_pdch(lchan->ts))
961 dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH);
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200962 return 0;
963 }
964
Harald Welte64bb7542011-01-14 14:16:16 +0100965 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
966 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
967 gsm_lchan_name(lchan),
968 gsm_lchans_name(lchan->state));
Andreas Eversberg9df268e2013-10-11 13:32:30 +0200969
Neels Hofmeyr832afa32016-06-14 13:12:00 +0200970 do_lchan_free(lchan);
971
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200972 /*
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200973 * Check Osmocom RSL CHAN ACT style dynamic TCH/F_TCH/H_PDCH TS for pending
974 * transitions in these cases:
975 *
976 * a) after PDCH was released due to switchover request, activate TCH.
977 * BSC initiated this switchover, so dyn.pchan_is != pchan_want and
978 * lchan->type has been set to the desired GSM_LCHAN_*.
979 *
980 * b) Voice call ended and a TCH is released. If the TS is now unused,
981 * switch to PDCH. Here still dyn.pchan_is == dyn.pchan_want because
982 * we're only just notified and may decide to switch to PDCH now.
983 */
984 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
985 DEBUGP(DRSL, "%s Rx RSL Channel Release ack for lchan %u\n",
986 gsm_ts_and_pchan_name(ts), lchan->nr);
987
988 /* (a) */
989 if (ts->dyn.pchan_is != ts->dyn.pchan_want)
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200990 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200991
992 /* (b) */
Neels Hofmeyr2ae305d2016-08-24 14:44:11 +0200993 if (dyn_ts_should_switch_to_pdch(ts))
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +0200994 return dyn_ts_switchover_start(ts, GSM_PCHAN_PDCH);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +0200995 }
996
997 /*
Neels Hofmeyr3f221222016-06-23 22:44:20 +0200998 * Put a dynamic TCH/F_PDCH channel back to PDCH mode iff it was
999 * released successfully. If in error, the PDCH ACT will follow after
1000 * T3111 in error_timeout_cb().
1001 *
1002 * Any state other than LCHAN_S_REL_ERR became LCHAN_S_NONE after above
1003 * do_lchan_free(). Assert this, because that's what ensures a PDCH ACT
Neels Hofmeyrc6926d02016-07-14 02:51:13 +02001004 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02001005 *
1006 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr3f221222016-06-23 22:44:20 +02001007 */
1008 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
1009 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyr40074682016-07-23 20:01:49 +02001010 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02001011 return 0;
Neels Hofmeyr40074682016-07-23 20:01:49 +02001012 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr82c8f752016-06-21 20:55:14 +02001013 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyr40074682016-07-23 20:01:49 +02001014 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte64bb7542011-01-14 14:16:16 +01001015 return 0;
1016}
1017
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001018int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
Harald Weltebaaf3e22016-11-17 20:54:04 +01001019 uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs)
Harald Welte52b1f982008-12-23 20:25:15 +00001020{
1021 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +00001022 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001023
1024 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1025 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
1026 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1027
1028 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +00001029 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +00001030 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
1031
Harald Weltebaaf3e22016-11-17 20:54:04 +01001032 /* Ericsson wants to have this IE in case a paging message
1033 * relates to packet paging */
1034 if (bts->type == GSM_BTS_TYPE_RBS2000 && is_gprs)
1035 msgb_tv_put(msg, RSL_IE_ERIC_PACKET_PAG_IND, 0);
1036
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001037 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001038
1039 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001040}
1041
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001042int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +00001043{
1044 int i, len = strlen(str_in);
1045
1046 for (i = 0; i < len; i++) {
1047 int num = str_in[i] - 0x30;
1048 if (num < 0 || num > 9)
1049 return -1;
1050 if (i % 2 == 0)
1051 bcd_out[i/2] = num;
1052 else
1053 bcd_out[i/2] |= (num << 4);
1054 }
1055
1056 return 0;
1057}
1058
Harald Welte702d8702008-12-26 20:25:35 +00001059/* Chapter 8.5.6 */
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001060struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +00001061{
Harald Welte8470bf22008-12-25 23:28:35 +00001062 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +00001063 struct abis_rsl_dchan_hdr *dh;
Maxb726c2c2017-02-09 19:23:38 +01001064 uint8_t buf[GSM_MACBLOCK_LEN];
Harald Welte52b1f982008-12-23 20:25:15 +00001065
1066 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1067 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
1068 dh->chan_nr = RSL_CHAN_PCH_AGCH;
1069
Harald Welte362322e2009-02-15 14:36:38 +00001070 switch (bts->type) {
1071 case GSM_BTS_TYPE_BS11:
1072 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
1073 break;
1074 default:
1075 /* If phase 2, construct a FULL_IMM_ASS_INFO */
1076 pad_macblock(buf, val, len);
Maxb726c2c2017-02-09 19:23:38 +01001077 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, GSM_MACBLOCK_LEN,
1078 buf);
Harald Welte362322e2009-02-15 14:36:38 +00001079 break;
1080 }
Harald Welte52b1f982008-12-23 20:25:15 +00001081
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001082 msg->dst = bts->c0->rsl_link;
Alexander Couzens16dcf2a2016-12-02 05:21:45 +01001083 return msg;
1084}
1085
1086/* Chapter 8.5.6 */
1087int rsl_imm_assign_cmd(struct gsm_bts *bts, 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 return abis_rsl_sendmsg(msg);
1093}
1094
1095/* Chapter 8.5.6 */
1096int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val)
1097{
1098 struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
1099 if (!msg)
1100 return 1;
1101
1102 /* ericsson can handle a reference at the end of the message which is used in
1103 * the confirm message. The confirm message is only sent if the trailer is present */
1104 msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
1105 msgb_put_u32(msg, tlli);
Harald Welte8470bf22008-12-25 23:28:35 +00001106
1107 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001108}
1109
Harald Welte67fa91b2009-08-10 09:51:40 +02001110/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +02001111int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +02001112{
1113 struct msgb *msg = rsl_msgb_alloc();
1114 struct abis_rsl_dchan_hdr *dh;
1115
1116 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1117 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +02001118 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001119 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001120 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +02001121
Harald Welte5b8ed432009-12-24 12:20:20 +01001122 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001123 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +02001124
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001125 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +02001126
Harald Welte67fa91b2009-08-10 09:51:40 +02001127 return abis_rsl_sendmsg(msg);
1128}
1129
1130
Harald Welte8470bf22008-12-25 23:28:35 +00001131/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +00001132/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001133int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +00001134{
Harald Welte8470bf22008-12-25 23:28:35 +00001135 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001136 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +00001137 return -EINVAL;
1138 }
Harald Welte52b1f982008-12-23 20:25:15 +00001139
Harald Weltef6093a42011-06-25 10:02:33 +02001140 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001141 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +00001142
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001143 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +00001144
1145 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +00001146}
1147
Harald Welteedcc5272009-08-09 13:47:35 +02001148/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
1149/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001150int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +02001151{
Harald Welte3c9c5f92010-03-04 10:33:10 +01001152 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +02001153
Harald Weltef6093a42011-06-25 10:02:33 +02001154 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001155 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001156 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +02001157
Harald Weltefda74ee2012-04-26 19:42:19 +02001158 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
1159 gsm_lchan_name(lchan), link_id);
1160
Harald Welteedcc5272009-08-09 13:47:35 +02001161 return abis_rsl_sendmsg(msg);
1162}
1163
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001164static void rsl_handle_release(struct gsm_lchan *lchan);
1165
1166/* Special work handler to handle missing RSL_MT_REL_CONF message from
1167 * Nokia InSite BTS */
1168static void lchan_rel_work_cb(void *data)
1169{
1170 struct gsm_lchan *lchan = data;
1171 int sapi;
1172
1173 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1174 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
1175 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
1176 }
1177 rsl_handle_release(lchan);
1178}
1179
Harald Welted2dc1de2009-08-08 13:15:07 +02001180/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
1181 This is what higher layers should call. The BTS then responds with
1182 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
1183 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
1184 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001185int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
1186 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +02001187{
Harald Welted2dc1de2009-08-08 13:15:07 +02001188
Harald Welte3c9c5f92010-03-04 10:33:10 +01001189 struct msgb *msg;
1190
Harald Weltef6093a42011-06-25 10:02:33 +02001191 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +01001192 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +08001193 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001194 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +02001195
Harald Welte8e93b792009-12-29 10:44:17 +01001196 /* FIXME: start some timer in case we don't receive a REL ACK ? */
1197
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001198 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +02001199
Harald Weltefda74ee2012-04-26 19:42:19 +02001200 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +01001201 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +02001202
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001203 abis_rsl_sendmsg(msg);
1204
1205 /* Do not wait for Nokia BTS to send the confirm. */
1206 if (is_nokia_bts(lchan->ts->trx->bts)
1207 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
1208 && release_mode == RSL_REL_LOCAL_END) {
1209 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
1210 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001211 osmo_timer_setup(&lchan->rel_work, lchan_rel_work_cb, lchan);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001212 osmo_timer_schedule(&lchan->rel_work, 0, 0);
1213 }
1214
1215 return 0;
Harald Welted2dc1de2009-08-08 13:15:07 +02001216}
1217
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001218int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
1219{
Neels Hofmeyr423269f2016-08-24 16:48:00 +02001220 LOGP(DRSL, LOGL_ERROR, "%s %s lchan broken: %s\n",
1221 gsm_lchan_name(lchan), gsm_lchant_name(lchan->type), reason);
1222 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001223 lchan->broken_reason = reason;
1224 return 0;
1225}
1226
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001227int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
1228{
Neels Hofmeyrb0cc6422016-06-21 21:34:46 +02001229 DEBUGP(DRSL, "%s state %s -> %s\n",
1230 gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
1231 gsm_lchans_name(state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001232 lchan->state = state;
1233 return 0;
1234}
1235
Harald Welte702d8702008-12-26 20:25:35 +00001236/* Chapter 8.4.2: Channel Activate Acknowledge */
1237static int rsl_rx_chan_act_ack(struct msgb *msg)
1238{
1239 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001240 struct gsm_lchan *lchan = msg->lchan;
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001241 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte702d8702008-12-26 20:25:35 +00001242
1243 /* BTS has confirmed channel activation, we now need
1244 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +00001245 if (rslh->ie_chan != RSL_IE_CHAN_NR)
1246 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +01001247
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001248 osmo_timer_del(&lchan->act_timer);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001249
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001250 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001251 int do_release = is_sysmobts_v2(ts->trx->bts);
1252 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel. %s\n",
1253 gsm_lchan_name(lchan),
1254 do_release ? "Releasing it" : "Keeping it broken");
1255 if (do_release) {
1256 talloc_free(lchan->rqd_ref);
1257 lchan->rqd_ref = NULL;
1258 lchan->rqd_ta = 0;
1259 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
1260 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
1261 /*
1262 * lchan_act_tmr_cb() already called
1263 * lchan_free() and cleared the lchan->type, so
1264 * calling dyn_ts_switchover_complete() here
1265 * would not have the desired effect of
1266 * mimicking an activated lchan that we can
1267 * release. Instead hack the dyn ts state to
1268 * make sure that rsl_rx_rf_chan_rel_ack() will
1269 * switch back to PDCH, i.e. have pchan_is ==
1270 * pchan_want, both != GSM_PCHAN_PDCH:
1271 */
1272 ts->dyn.pchan_is = GSM_PCHAN_NONE;
1273 ts->dyn.pchan_want = GSM_PCHAN_NONE;
1274 }
1275 rsl_rf_chan_release(msg->lchan, 0, SACCH_NONE);
1276 }
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +02001277 return 0;
1278 }
1279
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001280 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +01001281 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001282 gsm_lchan_name(lchan),
1283 gsm_lchans_name(lchan->state));
1284 rsl_lchan_set_state(lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +01001285
Holger Hans Peter Freyther46edbc42016-08-18 08:49:21 +02001286 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001287 dyn_ts_switchover_complete(lchan);
1288
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001289 if (lchan->rqd_ref) {
1290 rsl_send_imm_assignment(lchan);
1291 talloc_free(lchan->rqd_ref);
1292 lchan->rqd_ref = NULL;
1293 lchan->rqd_ta = 0;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001294 }
1295
Neels Hofmeyrf29dd5f2016-07-14 16:16:33 +02001296 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001297
Philipp Maierb4999b62016-10-26 15:19:41 +02001298 /* Update bts attributes inside the PCU */
1299 if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH ||
1300 ts->pchan == GSM_PCHAN_TCH_F_PDCH ||
1301 ts->pchan == GSM_PCHAN_PDCH)
1302 pcu_info_update(ts->trx->bts);
1303
Harald Welte4b634542008-12-27 01:55:51 +00001304 return 0;
1305}
Harald Welte702d8702008-12-26 20:25:35 +00001306
Harald Welte4b634542008-12-27 01:55:51 +00001307/* Chapter 8.4.3: Channel Activate NACK */
1308static int rsl_rx_chan_act_nack(struct msgb *msg)
1309{
Harald Welte6dab0552009-05-01 17:21:37 +00001310 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1311 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001312
Harald Weltee8bd9e82011-08-10 23:26:33 +02001313 osmo_timer_del(&msg->lchan->act_timer);
1314
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +02001315 if (msg->lchan->state == LCHAN_S_BROKEN) {
1316 LOGP(DRSL, LOGL_ERROR,
1317 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
1318 gsm_lchan_name(msg->lchan));
1319 return -1;
1320 }
1321
Daniel Willmann6fc6a122011-08-11 04:54:23 +02001322 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001323 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001324
Harald Welte6dab0552009-05-01 17:21:37 +00001325 /* BTS has rejected channel activation ?!? */
1326 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +00001327 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +00001328
1329 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001330 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001331 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001332 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +02001333 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +01001334 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001335 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1336 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1337 } else
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001338 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +02001339
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001340 } else {
1341 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1342 }
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001343
Harald Welte (local)91b603d2009-12-27 11:48:11 +01001344 LOGPC(DRSL, LOGL_ERROR, "\n");
1345
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001346 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +00001347 return 0;
Harald Welte702d8702008-12-26 20:25:35 +00001348}
1349
Harald Welte7f93cea2009-02-23 00:02:59 +00001350/* Chapter 8.4.4: Connection Failure Indication */
1351static int rsl_rx_conn_fail(struct msgb *msg)
1352{
1353 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1354 struct tlv_parsed tp;
1355
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02001356 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1357 gsm_lchan_name(msg->lchan),
1358 gsm_lchans_name(msg->lchan->state));
1359
Harald Welte7f93cea2009-02-23 00:02:59 +00001360 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1361
Harald Welte8830e072009-07-28 17:58:09 +02001362 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001363 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001364 TLVP_LEN(&tp, RSL_IE_CAUSE));
1365
Harald Welte (local)fc057502009-12-26 22:33:09 +01001366 LOGPC(DRSL, LOGL_NOTICE, "\n");
Alexander Couzensb847a212016-08-02 11:34:11 +02001367 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 +02001368 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +00001369}
1370
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001371static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1372 const char *prefix)
1373{
Harald Welte6739dfb2009-12-16 16:52:07 +01001374 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1375 prefix, rxlev2dbm(mru->full.rx_lev),
1376 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001377 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1378 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1379}
1380
Harald Welte0c1bd612012-07-02 17:12:08 +02001381static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001382{
Harald Welte6739dfb2009-12-16 16:52:07 +01001383 int i;
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001384 const char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +01001385
Max11e4e412017-04-20 13:07:58 +02001386 if (lchan && lchan->conn) {
1387 if (lchan->conn->bsub)
1388 name = bsc_subscr_name(lchan->conn->bsub);
Max11e4e412017-04-20 13:07:58 +02001389 else
1390 name = lchan->name;
1391 }
Harald Welte0c1bd612012-07-02 17:12:08 +02001392
1393 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001394
1395 if (mr->flags & MEAS_REP_F_DL_DTX)
1396 DEBUGPC(DMEAS, "DTXd ");
1397
1398 print_meas_rep_uni(&mr->ul, "ul");
1399 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
Max11e4e412017-04-20 13:07:58 +02001400
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001401 if (mr->flags & MEAS_REP_F_MS_TO)
1402 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1403
1404 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +01001405 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001406 DEBUGPC(DMEAS, "L1_FPC=%u ",
1407 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1408 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1409 }
1410
1411 if (mr->flags & MEAS_REP_F_UL_DTX)
1412 DEBUGPC(DMEAS, "DTXu ");
1413 if (mr->flags & MEAS_REP_F_BA1)
1414 DEBUGPC(DMEAS, "BA1 ");
1415 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1416 DEBUGPC(DMEAS, "NOT VALID ");
1417 else
1418 print_meas_rep_uni(&mr->dl, "dl");
1419
1420 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001421 if (mr->num_cell == 7)
1422 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001423 for (i = 0; i < mr->num_cell; i++) {
1424 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001425 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1426 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001427 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001428}
1429
Neels Hofmeyre2f24d52017-05-08 15:12:20 +02001430static struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
1431{
1432 struct gsm_meas_rep *meas_rep;
1433
1434 meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
1435 memset(meas_rep, 0, sizeof(*meas_rep));
1436 meas_rep->lchan = lchan;
1437 lchan->meas_rep_idx = (lchan->meas_rep_idx + 1)
1438 % ARRAY_SIZE(lchan->meas_rep);
1439
1440 return meas_rep;
1441}
1442
Harald Welte440fed02009-05-01 18:43:47 +00001443static int rsl_rx_meas_res(struct msgb *msg)
1444{
1445 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1446 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001447 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001448 uint8_t len;
1449 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001450 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001451
Harald Welteb8bfc562009-12-21 13:27:11 +01001452 /* check if this channel is actually active */
1453 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001454 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001455 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001456 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001457 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001458 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001459
Harald Welted12b0fd2009-12-15 21:36:05 +01001460 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001461 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001462
Harald Welte440fed02009-05-01 18:43:47 +00001463 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1464
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001465 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1466 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1467 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1468 return -EIO;
1469
1470 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001471 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001472
1473 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1474 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1475 if (len >= 3) {
1476 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001477 mr->flags |= MEAS_REP_F_DL_DTX;
1478 mr->ul.full.rx_lev = val[0] & 0x3f;
1479 mr->ul.sub.rx_lev = val[1] & 0x3f;
1480 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1481 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001482 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001483
Harald Welted12b0fd2009-12-15 21:36:05 +01001484 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001485
1486 /* Optional Parts */
Max11e4e412017-04-20 13:07:58 +02001487 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) {
1488 /* According to 3GPP TS 48.058 § MS Timing Offset = Timing Offset field - 63 */
1489 mr->ms_timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET) - 63;
1490 mr->flags |= MEAS_REP_F_MS_TO;
1491 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001492
Harald Weltefe9af262009-06-20 18:44:35 +02001493 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001494 struct e1inp_sign_link *sign_link = msg->dst;
1495
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001496 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001497 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001498 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001499 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001500 mr->flags |= MEAS_REP_F_FPC;
1501 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001502 /* BS11 and Nokia reports TA shifted by 2 bits */
1503 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1504 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001505 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001506 }
Harald Weltef7c43522009-06-09 20:24:21 +00001507 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001508 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001509 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001510 if (rc < 0)
1511 return rc;
1512 }
1513
Harald Welte0c1bd612012-07-02 17:12:08 +02001514 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001515
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001516 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001517
Harald Welte75d34a82009-05-23 06:11:13 +00001518 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001519}
1520
Harald Welted011e8b2009-11-29 22:45:52 +01001521/* Chapter 8.4.7 */
1522static int rsl_rx_hando_det(struct msgb *msg)
1523{
1524 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1525 struct tlv_parsed tp;
1526
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001527 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001528
1529 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1530
1531 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1532 DEBUGPC(DRSL, "access delay = %u\n",
1533 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1534 else
1535 DEBUGPC(DRSL, "\n");
1536
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001537 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001538
1539 return 0;
1540}
1541
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001542static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1543{
1544 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001545
1546 OSMO_ASSERT(lchan);
1547
1548 ts = lchan->ts;
1549 OSMO_ASSERT(ts);
1550 OSMO_ASSERT(ts->trx);
1551 OSMO_ASSERT(ts->trx->bts);
1552
1553 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
Neels Hofmeyrdd49bee2016-06-21 20:53:27 +02001554 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1555 " for channel that is no TCH/F_PDCH\n",
1556 gsm_lchan_name(lchan),
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001557 gsm_pchan_name(ts->pchan),
1558 pdch_act? "ACT" : "DEACT");
1559 return false;
1560 }
1561
Neels Hofmeyr832afa32016-06-14 13:12:00 +02001562 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyrdd49bee2016-06-21 20:53:27 +02001563 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1564 " in unexpected state: %s\n",
1565 gsm_lchan_name(lchan),
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001566 gsm_pchan_name(ts->pchan),
1567 pdch_act? "ACT" : "DEACT",
1568 gsm_lchans_name(lchan->state));
1569 return false;
1570 }
1571 return true;
1572}
1573
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001574static int rsl_rx_pdch_act_ack(struct msgb *msg)
1575{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001576 if (!lchan_may_change_pdch(msg->lchan, true))
1577 return -EINVAL;
1578
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001579 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001580 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001581
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001582 return 0;
1583}
1584
1585static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1586{
Neels Hofmeyr285df2e2016-06-13 12:28:21 +02001587 if (!lchan_may_change_pdch(msg->lchan, false))
1588 return -EINVAL;
1589
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001590 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr32019882016-06-15 15:32:29 +02001591 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001592
Neels Hofmeyr6e999b72016-07-23 21:00:51 +02001593 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn.act_type,
1594 msg->lchan->dyn.ho_ref);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001595
1596 return 0;
1597}
1598
Harald Welte52b1f982008-12-23 20:25:15 +00001599static int abis_rsl_rx_dchan(struct msgb *msg)
1600{
Harald Welte8470bf22008-12-25 23:28:35 +00001601 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1602 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001603 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001604 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001605
Neels Hofmeyr2867f882016-08-23 01:22:58 +02001606 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
1607 "Abis RSL rx DCHAN: ");
Neels Hofmeyra6ba6a32016-10-10 03:24:05 +02001608 if (!msg->lchan)
1609 return -1;
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001610 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001611
Harald Welte8470bf22008-12-25 23:28:35 +00001612 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001613 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001614 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001615 rc = rsl_rx_chan_act_ack(msg);
Alexander Couzens8c53c592016-08-23 06:27:19 +02001616 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001617 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001618 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001619 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001620 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001621 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001622 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001623 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001624 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001625 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001626 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001627 case RSL_MT_HANDO_DET:
1628 rc = rsl_rx_hando_det(msg);
1629 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001630 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001631 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001632 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001633 case RSL_MT_MODE_MODIFY_ACK:
Alexander Couzens8c53c592016-08-23 06:27:19 +02001634 count_codecs(sign_link->trx->bts, msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001635 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001636 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001637 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001638 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001639 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001640 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02001641 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001642 rc = rsl_rx_pdch_act_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001643 break;
1644 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001645 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001646 break;
1647 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001648 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg9df268e2013-10-11 13:32:30 +02001649 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welte9c880c92009-10-24 10:29:22 +02001650 break;
1651 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001652 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001653 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001654 case RSL_MT_PHY_CONTEXT_CONF:
1655 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001656 case RSL_MT_TALKER_DET:
1657 case RSL_MT_LISTENER_DET:
1658 case RSL_MT_REMOTE_CODEC_CONF_REP:
1659 case RSL_MT_MR_CODEC_MOD_ACK:
1660 case RSL_MT_MR_CODEC_MOD_NACK:
1661 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001662 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1663 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001664 break;
1665 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001666 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1667 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001668 return -EINVAL;
1669 }
Harald Weltef325eb42009-02-19 17:07:39 +00001670
Harald Welte8470bf22008-12-25 23:28:35 +00001671 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001672}
1673
Harald Welte702d8702008-12-26 20:25:35 +00001674static int rsl_rx_error_rep(struct msgb *msg)
1675{
1676 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001677 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001678 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001679
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001680 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001681
1682 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1683
1684 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001685 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001686 TLVP_LEN(&tp, RSL_IE_CAUSE));
1687
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001688 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001689
1690 return 0;
1691}
1692
Harald Welte52b1f982008-12-23 20:25:15 +00001693static int abis_rsl_rx_trx(struct msgb *msg)
1694{
Harald Welte702d8702008-12-26 20:25:35 +00001695 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001696 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001697 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001698
1699 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001700 case RSL_MT_ERROR_REPORT:
1701 rc = rsl_rx_error_rep(msg);
1702 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001703 case RSL_MT_RF_RES_IND:
1704 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001705 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001706 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001707 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001708 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001709 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001710 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001711 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001712 case 0x42: /* Nokia specific: SI End ACK */
1713 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1714 break;
1715 case 0x43: /* Nokia specific: SI End NACK */
1716 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1717 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001718 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001719 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001720 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001721 return -EINVAL;
1722 }
Harald Welte8470bf22008-12-25 23:28:35 +00001723 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001724}
1725
Harald Welteb7e81162009-08-10 00:26:10 +02001726/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1727static void t3101_expired(void *data)
1728{
1729 struct gsm_lchan *lchan = data;
Max8dc8f232017-02-09 19:13:02 +01001730 LOGP(DRSL, LOGL_NOTICE,
1731 "%s T3101 expired: no response to IMMEDIATE ASSIGN\n",
1732 gsm_lchan_name(lchan));
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001733 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001734}
1735
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001736/* If T3111 expires, we will send the RF Channel Request */
1737static void t3111_expired(void *data)
1738{
1739 struct gsm_lchan *lchan = data;
Max8dc8f232017-02-09 19:13:02 +01001740 LOGP(DRSL, LOGL_NOTICE,
1741 "%s T3111 expired: releasing RF Channel\n",
1742 gsm_lchan_name(lchan));
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001743 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1744}
1745
1746/* If T3109 expires the MS has not send a UA/UM do the error release */
1747static void t3109_expired(void *data)
1748{
1749 struct gsm_lchan *lchan = data;
1750
1751 LOGP(DRSL, LOGL_ERROR,
1752 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1753 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001754}
1755
Harald Welte2862dca2010-12-23 14:39:29 +01001756/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1757static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1758 unsigned int num_req_refs,
1759 struct gsm48_req_ref *rqd_refs,
1760 uint8_t wait_ind)
1761{
1762 uint8_t buf[GSM_MACBLOCK_LEN];
1763 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1764
1765 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1766 memset(iar, 0, sizeof(*iar));
1767 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001768 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Welte2862dca2010-12-23 14:39:29 +01001769 iar->page_mode = GSM48_PM_SAME;
1770
1771 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1772 iar->wait_ind1 = wait_ind;
1773
1774 if (num_req_refs >= 2)
1775 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1776 else
1777 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1778 iar->wait_ind2 = wait_ind;
1779
1780 if (num_req_refs >= 3)
1781 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1782 else
1783 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1784 iar->wait_ind3 = wait_ind;
1785
1786 if (num_req_refs >= 4)
1787 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1788 else
1789 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1790 iar->wait_ind4 = wait_ind;
1791
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001792 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1793 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1794
1795 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Welte2862dca2010-12-23 14:39:29 +01001796}
1797
Philipp Maierb4999b62016-10-26 15:19:41 +02001798/* Handle packet channel rach requests */
1799static int rsl_rx_pchan_rqd(struct msgb *msg, struct gsm_bts *bts)
1800{
1801 struct gsm48_req_ref *rqd_ref;
1802 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1803 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1804 uint8_t ra = rqd_ref->ra;
1805 uint8_t t1, t2, t3;
1806 uint32_t fn;
1807 uint8_t rqd_ta;
1808 uint8_t is_11bit;
1809
1810 /* Process rach request and forward contained information to PCU */
1811 if (ra == 0x7F) {
1812 is_11bit = 1;
1813
1814 /* FIXME: Also handle 11 bit rach requests */
1815 LOGP(DRSL, LOGL_ERROR, "BTS %d eleven bit access burst not supported yet!\n",bts->nr);
1816 return -EINVAL;
1817 } else {
1818 is_11bit = 0;
1819 t1 = rqd_ref->t1;
1820 t2 = rqd_ref->t2;
1821 t3 = rqd_ref->t3_low | (rqd_ref->t3_high << 3);
1822 fn = (51 * ((t3-t2) % 26) + t3 + 51 * 26 * t1);
1823
1824 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1825 }
1826
1827 return pcu_tx_rach_ind(bts, rqd_ta, ra, fn, is_11bit,
1828 GSM_L1_BURST_TYPE_ACCESS_0);
1829}
1830
Harald Welte8470bf22008-12-25 23:28:35 +00001831/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001832static int rsl_rx_chan_rqd(struct msgb *msg)
1833{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001834 struct e1inp_sign_link *sign_link = msg->dst;
1835 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001836 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1837 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001838 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001839 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001840 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001841 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001842 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001843
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001844 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001845 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001846
Harald Welte8470bf22008-12-25 23:28:35 +00001847 /* parse request reference to be used in immediate assign */
1848 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1849 return -EINVAL;
1850
1851 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1852
1853 /* parse access delay and use as TA */
1854 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1855 return -EINVAL;
1856 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1857
Philipp Maierb4999b62016-10-26 15:19:41 +02001858 /* Determine channel request cause code */
1859 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
1860 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: reason: %s (ra=0x%02x, neci=0x%02x, chreq_reason=0x%02x)\n",
1861 msg->lchan->ts->trx->bts->nr,
1862 get_value_string(gsm_chreq_descs, chreq_reason),
1863 rqd_ref->ra, bts->network->neci, chreq_reason);
1864
1865 /* Handle PDCH related rach requests (in case of BSC-co-located-PCU */
1866 if (chreq_reason == GSM_CHREQ_REASON_PDCH)
1867 return rsl_rx_pchan_rqd(msg, bts);
1868
Harald Welte8470bf22008-12-25 23:28:35 +00001869 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1870 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001871 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
Harald Welte2cbe0922008-12-29 04:09:31 +00001872
Alexander Couzensb847a212016-08-02 11:34:11 +02001873 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL]);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001874
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001875 /*
1876 * We want LOCATION UPDATES to succeed and will assign a TCH
1877 * if we have no SDCCH available.
1878 */
1879 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1880
Harald Welte8470bf22008-12-25 23:28:35 +00001881 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001882 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001883 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001884 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001885 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Alexander Couzensb847a212016-08-02 11:34:11 +02001886 rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL]);
Harald Welte2862dca2010-12-23 14:39:29 +01001887 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1888 if (bts->network->T3122)
1889 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte1dcc2602012-11-13 04:46:03 +01001890 return 0;
Harald Welte8470bf22008-12-25 23:28:35 +00001891 }
1892
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02001893 /*
1894 * Expecting lchan state to be NONE, except for dyn TS in PDCH mode.
1895 * Those are expected to be ACTIVE: the PDCH release will be sent from
1896 * rsl_chan_activate_lchan() below.
1897 */
1898 if (lchan->state != LCHAN_S_NONE
1899 && !(lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
1900 && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH
1901 && lchan->state == LCHAN_S_ACTIVE))
Harald Welte8e93b792009-12-29 10:44:17 +01001902 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001903 "in state %s\n", gsm_lchan_name(lchan),
1904 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001905
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001906 /* save the RACH data as we need it after the CHAN ACT ACK */
1907 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1908 if (!lchan->rqd_ref) {
1909 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1910 lchan_free(lchan);
1911 return -ENOMEM;
1912 }
1913
1914 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1915 lchan->rqd_ta = rqd_ta;
1916
Harald Welte8470bf22008-12-25 23:28:35 +00001917 arfcn = lchan->ts->trx->arfcn;
1918 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001919
Harald Welte08d91a52009-08-30 15:37:11 +09001920 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001921 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001922 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001923 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001924 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001925
Harald Weltee8bd9e82011-08-10 23:26:33 +02001926 /* Start another timer or assume the BTS sends a ACK/NACK? */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001927 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +02001928 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1929
Andreas Eversberg2957de92011-12-16 17:45:37 +01001930 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1931 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1932 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1933 rqd_ref->ra, rqd_ta);
1934
Neels Hofmeyr81516482016-07-15 01:26:03 +02001935 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001936
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001937 return 0;
1938}
1939
1940static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1941{
1942 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001943 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001944 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1945
Harald Welte52b1f982008-12-23 20:25:15 +00001946 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001947 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001948 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001949 ia->proto_discr = GSM48_PDISC_RR;
1950 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1951 ia->page_mode = GSM48_PM_SAME;
1952 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001953
Harald Welte8470bf22008-12-25 23:28:35 +00001954 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001955 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1956 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001957 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001958 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001959 } else {
laforge09108bf2010-06-20 15:18:46 +02001960 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1961 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001962 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001963 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1964 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001965
Harald Welteb7e81162009-08-10 00:26:10 +02001966 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02001967 osmo_timer_setup(&lchan->T3101, t3101_expired, lchan);
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001968 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001969
Harald Welte52b1f982008-12-23 20:25:15 +00001970 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001971 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001972}
1973
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001974/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001975static int rsl_rx_ccch_load(struct msgb *msg)
1976{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001977 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001978 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001979 struct ccch_signal_data sd;
1980
1981 sd.bts = sign_link->trx->bts;
1982 sd.rach_slot_count = -1;
1983 sd.rach_busy_count = -1;
1984 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001985
1986 switch (rslh->data[0]) {
1987 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001988 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1989 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001990 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001991 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001992 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001993 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1994 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001995 break;
1996 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001997 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001998 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1999 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
2000 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
2001 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00002002 }
Harald Welteea280442009-02-02 22:29:56 +00002003 break;
2004 default:
2005 break;
2006 }
2007
2008 return 0;
2009}
2010
Harald Welte52b1f982008-12-23 20:25:15 +00002011static int abis_rsl_rx_cchan(struct msgb *msg)
2012{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002013 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00002014 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002015 int rc = 0;
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002016 uint32_t tlli;
Harald Welte52b1f982008-12-23 20:25:15 +00002017
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002018 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr,
2019 "Abis RSL rx CCHAN: ");
Harald Welte8470bf22008-12-25 23:28:35 +00002020
2021 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00002022 case RSL_MT_CHAN_RQD:
2023 /* MS has requested a channel on the RACH */
2024 rc = rsl_rx_chan_rqd(msg);
2025 break;
Harald Welteea280442009-02-02 22:29:56 +00002026 case RSL_MT_CCCH_LOAD_IND:
2027 /* current load on the CCCH */
2028 rc = rsl_rx_ccch_load(msg);
2029 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002030 case RSL_MT_DELETE_IND:
2031 /* CCCH overloaded, IMM_ASSIGN was dropped */
2032 case RSL_MT_CBCH_LOAD_IND:
2033 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002034 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
2035 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002036 break;
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002037 case 0x10: /* Ericsson specific: Immediate Assign Sent */
2038 /* FIXME: Replace the messy message parsing below
2039 * with proper TV parser */
2040 LOGP(DRSL, LOGL_INFO, "IMM.ass sent\n");
Alexander Couzens2faeb1a2017-03-13 11:00:59 +01002041 if(msg->len < 9)
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002042 LOGP(DRSL, LOGL_ERROR, "short IMM.ass sent message!\n");
2043 else if(msg->data[4] != 0xf1)
2044 LOGP(DRSL, LOGL_ERROR, "unsupported IMM.ass message format! (please fix)\n");
2045 else {
Alexander Couzens271ceca2017-03-13 11:06:52 +01002046 msgb_pull(msg, 5); /* drop previous data to use msg_pull_u32 */
2047 tlli = msgb_pull_u32(msg);
Philipp Maierf8aeb2c2016-12-02 19:04:34 +01002048 pcu_tx_imm_ass_sent(sign_link->trx->bts, tlli);
2049 }
2050 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002051 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002052 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
2053 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002054 return -EINVAL;
2055 }
Harald Welte8470bf22008-12-25 23:28:35 +00002056
2057 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002058}
2059
Harald Welte4b634542008-12-27 01:55:51 +00002060static int rsl_rx_rll_err_ind(struct msgb *msg)
2061{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002062 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00002063 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002064 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00002065
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002066 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
2067 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
2068 LOGP(DRLL, LOGL_ERROR,
2069 "%s ERROR INDICATION without mandantory cause.\n",
2070 gsm_lchan_name(msg->lchan));
2071 return -1;
2072 }
2073
2074 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02002075 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002076 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther1e93b792014-04-19 16:45:36 +02002077 rsl_rlm_cause_name(rlm_cause),
2078 gsm_lchans_name(msg->lchan->state));
2079
Harald Welteedcc5272009-08-09 13:47:35 +02002080 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01002081
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01002082 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Alexander Couzensb847a212016-08-02 11:34:11 +02002083 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 +02002084 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02002085 }
Harald Welte81543bc2009-07-04 09:40:05 +02002086
Harald Welte4b634542008-12-27 01:55:51 +00002087 return 0;
2088}
Harald Weltef325eb42009-02-19 17:07:39 +00002089
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002090static void rsl_handle_release(struct gsm_lchan *lchan)
2091{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002092 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002093 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002094
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +01002095 /*
2096 * Maybe only one link/SAPI was releasd or the error handling
2097 * was activated. Just return now and let the other code handle
2098 * it.
2099 */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002100 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002101 return;
2102
2103 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2104 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2105 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01002106 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08002107 gsm_lchan_name(lchan), sapi);
2108 return;
2109 }
2110
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02002111
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002112 /* Stop T3109 and wait for T3111 before re-using the channel */
2113 osmo_timer_del(&lchan->T3109);
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02002114 osmo_timer_setup(&lchan->T3111, t3111_expired, lchan);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08002115 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002116 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002117}
2118
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002119/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00002120 0x02, 0x06,
2121 0x01, 0x20,
2122 0x02, 0x00,
2123 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
2124
2125static int abis_rsl_rx_rll(struct msgb *msg)
2126{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002127 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00002128 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00002129 int rc = 0;
2130 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002131 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00002132
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002133 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2134 "Abis RSL rx RLL: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002135 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01002136 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00002137
2138 switch (rllh->c.msg_type) {
2139 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002140 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002141 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002142 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2143 rllh->data[0] == RSL_IE_L3_INFO) {
2144 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02002145 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002146 }
Harald Welte52b1f982008-12-23 20:25:15 +00002147 break;
2148 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00002149 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02002150 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002151 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02002152 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02002153 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00002154 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
2155 rllh->data[0] == RSL_IE_L3_INFO) {
2156 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02002157 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00002158 }
Harald Welte52b1f982008-12-23 20:25:15 +00002159 break;
Harald Welteedcc5272009-08-09 13:47:35 +02002160 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02002161 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002162 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02002163 rll_indication(msg->lchan, rllh->link_id,
2164 BSC_RLLR_IND_EST_CONF);
2165 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002166 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02002167 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02002168 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002169 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02002170 rll_indication(msg->lchan, rllh->link_id,
2171 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002172 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00002173 break;
2174 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02002175 /* BTS informs us of having received UA from MS,
2176 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02002177 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01002178 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02002179 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00002180 break;
2181 case RSL_MT_ERROR_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002182 DEBUGPC(DRLL, "ERROR INDICATION\n");
Harald Welte4b634542008-12-27 01:55:51 +00002183 rc = rsl_rx_rll_err_ind(msg);
2184 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002185 case RSL_MT_UNIT_DATA_IND:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002186 DEBUGPC(DRLL, "UNIT DATA INDICATION\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002187 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
2188 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002189 break;
2190 default:
Neels Hofmeyre3dc4982016-07-26 19:39:43 +02002191 DEBUGPC(DRLL, "UNKNOWN\n");
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002192 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
2193 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00002194 }
Harald Welte8470bf22008-12-25 23:28:35 +00002195 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002196}
2197
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002198static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02002199{
Harald Welte0603c9d2009-12-02 01:58:23 +05302200 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02002201 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05302202 switch (lchan->type) {
2203 case GSM_LCHAN_TCH_F:
2204 return 0x00;
2205 case GSM_LCHAN_TCH_H:
2206 return 0x03;
2207 default:
2208 break;
2209 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002210 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002211 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05302212 switch (lchan->type) {
2213 case GSM_LCHAN_TCH_F:
2214 return 0x01;
2215 /* there's no half-rate EFR */
2216 default:
2217 break;
2218 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002219 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002220 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05302221 switch (lchan->type) {
2222 case GSM_LCHAN_TCH_F:
2223 return 0x02;
2224 case GSM_LCHAN_TCH_H:
2225 return 0x05;
2226 default:
2227 break;
2228 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002229 break;
Harald Welte0603c9d2009-12-02 01:58:23 +05302230 default:
2231 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02002232 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002233 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05302234 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002235 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02002236}
2237
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002238static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01002239{
2240 switch (lchan->tch_mode) {
2241 case GSM48_CMODE_SPEECH_V1:
2242 switch (lchan->type) {
2243 case GSM_LCHAN_TCH_F:
2244 return RTP_PT_GSM_FULL;
2245 case GSM_LCHAN_TCH_H:
2246 return RTP_PT_GSM_HALF;
2247 default:
2248 break;
2249 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002250 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002251 case GSM48_CMODE_SPEECH_EFR:
2252 switch (lchan->type) {
2253 case GSM_LCHAN_TCH_F:
2254 return RTP_PT_GSM_EFR;
2255 /* there's no half-rate EFR */
2256 default:
2257 break;
2258 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002259 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002260 case GSM48_CMODE_SPEECH_AMR:
2261 switch (lchan->type) {
2262 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01002263 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02002264 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002265 default:
2266 break;
2267 }
Holger Hans Peter Freyther47665242014-04-04 12:14:55 +02002268 break;
Sylvain Munautb54dda42009-12-20 22:06:40 +01002269 default:
2270 break;
2271 }
2272 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
2273 "tch_mode == 0x%02x\n & lchan_type == %d",
2274 lchan->tch_mode, lchan->type);
2275 return 0;
2276}
2277
Harald Welte75099262009-02-16 21:12:08 +00002278/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002279static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
2280{
2281 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002282 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01002283
2284 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002285 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002286 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
2287 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
2288 }
2289
2290 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002291 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002292 port = ntohs(port);
2293 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
2294 lchan->abis_ip.bound_port = port;
2295 }
2296
2297 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002298 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002299 conn_id = ntohs(conn_id);
2300 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
2301 lchan->abis_ip.conn_id = conn_id;
2302 }
2303
2304 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
2305 lchan->abis_ip.rtp_payload2 =
2306 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
2307 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
2308 lchan->abis_ip.rtp_payload2);
2309 }
2310
2311 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
2312 lchan->abis_ip.speech_mode =
2313 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
2314 DEBUGPC(DRSL, "speech_mode=0x%02x ",
2315 lchan->abis_ip.speech_mode);
2316 }
2317
2318 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002319 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002320 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
2321 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
2322 }
2323
2324 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmann8a485f02014-06-27 17:05:47 +02002325 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002326 port = ntohs(port);
2327 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
2328 lchan->abis_ip.connect_port = port;
2329 }
2330}
2331
Harald Welte647db842013-02-03 12:06:58 +01002332/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
2333 * \param[in] lchan Logical Channel for which we issue CRCX
2334 */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002335int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00002336{
2337 struct msgb *msg = rsl_msgb_alloc();
2338 struct abis_rsl_dchan_hdr *dh;
2339
2340 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002341 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00002342 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002343 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002344
Harald Weltef4e79f22009-07-28 18:11:56 +02002345 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002346 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002347 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002348 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002349 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002350
Sylvain Munautb54dda42009-12-20 22:06:40 +01002351 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
2352 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
2353 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002354
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002355 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002356
2357 return abis_rsl_sendmsg(msg);
2358}
2359
Harald Welte647db842013-02-03 12:06:58 +01002360/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
2361 * \param[in] lchan Logical Channel for which we issue MDCX
2362 * \param[in] ip Remote (MGW) IP address for RTP
2363 * \param[in] port Remote (MGW) UDP port number for RTP
2364 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
2365 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002366int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
2367 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00002368{
2369 struct msgb *msg = rsl_msgb_alloc();
2370 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002371 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02002372 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00002373
2374 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002375 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00002376 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02002377 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00002378
Harald Welte5e3d91b2009-12-19 16:42:06 +01002379 /* we need to store these now as MDCX_ACK does not return them :( */
2380 lchan->abis_ip.rtp_payload2 = rtp_payload2;
2381 lchan->abis_ip.connect_port = port;
2382 lchan->abis_ip.connect_ip = ip;
2383
Harald Welte58ca5b72009-07-29 12:12:18 +02002384 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01002385 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002386 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02002387
Harald Weltef4e79f22009-07-28 18:11:56 +02002388 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002389 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
2390 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
2391 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
2392 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02002393
Harald Welte5e3d91b2009-12-19 16:42:06 +01002394 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
2395 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002396 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01002397 *att_ip = ia.s_addr;
2398 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
2399 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01002400 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02002401 if (rtp_payload2)
2402 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002403
2404 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00002405
2406 return abis_rsl_sendmsg(msg);
2407}
2408
Harald Weltea72273e2009-12-20 16:51:09 +01002409/* tell BTS to connect RTP stream to our local RTP socket */
2410int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
2411{
2412 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
2413 int rc;
2414
2415 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
2416 ntohs(rs->rtp.sin_local.sin_port),
2417 /* FIXME: use RTP payload of bound socket, not BTS*/
2418 lchan->abis_ip.rtp_payload2);
2419
2420 return rc;
2421}
2422
Harald Welte53cd7ac2010-12-23 12:59:52 +01002423int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02002424{
2425 struct msgb *msg = rsl_msgb_alloc();
2426 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02002427 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08002428
Neels Hofmeyr32019882016-06-15 15:32:29 +02002429 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2430 LOGP(DRSL, LOGL_ERROR,
2431 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2432 gsm_ts_name(ts),
2433 act ? "ACT" : "DEACT",
2434 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2435 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2436 return -EINVAL;
2437 }
2438
2439 if (act){
Neels Hofmeyr9ddd8e62016-07-06 14:39:04 +02002440 /* Callers should heed the GPRS mode. */
2441 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte4563eab2010-03-28 14:42:09 +08002442 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002443 ts->flags |= TS_F_PDCH_ACT_PENDING;
2444 } else {
Harald Welte4563eab2010-03-28 14:42:09 +08002445 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr32019882016-06-15 15:32:29 +02002446 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2447 }
2448 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welte9c880c92009-10-24 10:29:22 +02002449
2450 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08002451 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02002452 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Neels Hofmeyrd3841102016-07-18 23:43:44 +02002453 dh->chan_nr = gsm_pchan2chan_nr(GSM_PCHAN_PDCH, ts->nr, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02002454
Neels Hofmeyr9f5d2312016-05-31 17:51:41 +02002455 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08002456 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02002457
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002458 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02002459
2460 return abis_rsl_sendmsg(msg);
2461}
2462
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002463static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002464{
2465 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2466 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05302467 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00002468
2469 /* the BTS has acknowledged a local bind, it now tells us the IP
2470 * address and port number to which it has bound the given logical
2471 * channel */
2472
2473 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2474 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2475 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02002476 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002477 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00002478 return -EINVAL;
2479 }
Harald Welte17f5bf62009-12-20 15:42:44 +01002480
Harald Welte5e3d91b2009-12-19 16:42:06 +01002481 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01002482
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002483 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00002484
Harald Welte75099262009-02-16 21:12:08 +00002485 return 0;
2486}
2487
Harald Welte5e3d91b2009-12-19 16:42:06 +01002488static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2489{
2490 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2491 struct tlv_parsed tv;
2492 struct gsm_lchan *lchan = msg->lchan;
2493
2494 /* the BTS has acknowledged a remote connect request and
2495 * it now tells us the IP address and port number to which it has
2496 * connected the given logical channel */
2497
2498 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2499 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002500 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002501
2502 return 0;
2503}
2504
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002505static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00002506{
2507 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2508 struct tlv_parsed tv;
2509
2510 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00002511
Harald Welte8830e072009-07-28 17:58:09 +02002512 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01002513 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02002514 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00002515
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02002516 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02002517
Harald Welte75099262009-02-16 21:12:08 +00002518 return 0;
2519}
2520
2521static int abis_rsl_rx_ipacc(struct msgb *msg)
2522{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002523 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00002524 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01002525 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00002526 int rc = 0;
2527
Neels Hofmeyr2867f882016-08-23 01:22:58 +02002528 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr,
2529 "Abis RSL rx IPACC: ");
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01002530 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00002531
2532 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002533 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01002534 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002535 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002536 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002537 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002538 /* somehow the BTS was unable to bind the lchan to its local
2539 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01002540 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002541 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002542 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00002543 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01002544 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002545 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002546 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002547 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002548 /* somehow the BTS was unable to connect the lchan to a remote
2549 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01002550 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002551 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002552 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01002553 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002554 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00002555 break;
2556 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01002557 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002558 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00002559 break;
2560 }
Harald Welte6dab0552009-05-01 17:21:37 +00002561 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00002562
2563 return rc;
2564}
2565
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002566int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts,
Neels Hofmeyrd3b7fa82016-07-23 20:08:41 +02002567 enum gsm_phys_chan_config to_pchan)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002568{
2569 int ss;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002570 int rc = -EIO;
2571
2572 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2573 DEBUGP(DRSL, "%s starting switchover to %s\n",
2574 gsm_ts_and_pchan_name(ts), gsm_pchan_name(to_pchan));
2575
2576 if (ts->dyn.pchan_is != ts->dyn.pchan_want) {
2577 LOGP(DRSL, LOGL_ERROR,
2578 "%s: Attempt to switch dynamic channel to %s,"
2579 " but is already in switchover.\n",
2580 gsm_ts_and_pchan_name(ts),
2581 gsm_pchan_name(to_pchan));
2582 return ts->dyn.pchan_want == to_pchan? 0 : -EAGAIN;
2583 }
2584
2585 if (ts->dyn.pchan_is == to_pchan) {
2586 LOGP(DRSL, LOGL_INFO,
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002587 "%s %s Already is in %s mode, cannot switchover.\n",
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002588 gsm_ts_name(ts), gsm_pchan_name(ts->pchan),
2589 gsm_pchan_name(to_pchan));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002590 return -EINVAL;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002591 }
2592
2593 /* Paranoia: let's make sure all is indeed released. */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002594 for (ss = 0; ss < ts_subslots(ts); ss++) {
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002595 struct gsm_lchan *lc = &ts->lchan[ss];
2596 if (lc->state != LCHAN_S_NONE) {
2597 LOGP(DRSL, LOGL_ERROR,
2598 "%s Attempt to switch dynamic channel to %s,"
2599 " but is not fully released.\n",
2600 gsm_ts_and_pchan_name(ts),
2601 gsm_pchan_name(to_pchan));
2602 return -EAGAIN;
2603 }
2604 }
2605
2606 /* Record that we're busy switching. */
2607 ts->dyn.pchan_want = to_pchan;
2608
2609 /*
2610 * To switch from PDCH, we need to initiate the release from the BSC
2611 * side. dyn_ts_switchover_continue() will be called from
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002612 * rsl_rx_rf_chan_rel_ack(). PDCH is always on lchan[0].
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002613 */
2614 if (ts->dyn.pchan_is == GSM_PCHAN_PDCH) {
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002615 rsl_lchan_set_state(ts->lchan, LCHAN_S_REL_REQ);
2616 rc = rsl_rf_chan_release(ts->lchan, 0, SACCH_NONE);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002617 if (rc) {
2618 LOGP(DRSL, LOGL_ERROR,
2619 "%s RSL RF Chan Release failed\n",
2620 gsm_ts_and_pchan_name(ts));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002621 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002622 }
2623 return 0;
2624 }
2625
2626 /*
2627 * To switch from TCH/F and TCH/H pchans, this has been called from
2628 * rsl_rx_rf_chan_rel_ack(), i.e. release is complete. Go ahead and
2629 * activate as new type. This will always be PDCH.
2630 */
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002631 return dyn_ts_switchover_continue(ts);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002632}
2633
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002634static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002635{
2636 int rc;
2637 uint8_t act_type;
2638 uint8_t ho_ref;
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002639 int ss;
2640 struct gsm_lchan *lchan;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002641
2642 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2643 DEBUGP(DRSL, "%s switchover: release complete,"
2644 " activating new pchan type\n",
2645 gsm_ts_and_pchan_name(ts));
2646
2647 if (ts->dyn.pchan_is == ts->dyn.pchan_want) {
2648 LOGP(DRSL, LOGL_ERROR,
2649 "%s Requested to switchover dynamic channel to the"
2650 " same type it is already in.\n",
2651 gsm_ts_and_pchan_name(ts));
2652 return 0;
2653 }
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002654
2655 for (ss = 0; ss < ts_subslots(ts); ss++) {
2656 lchan = &ts->lchan[ss];
2657 if (lchan->rqd_ref) {
2658 LOGP(DRSL, LOGL_ERROR,
2659 "%s During dyn TS switchover, expecting no"
2660 " Request Reference to be pending. Discarding!\n",
2661 gsm_lchan_name(lchan));
2662 talloc_free(lchan->rqd_ref);
2663 lchan->rqd_ref = NULL;
2664 }
2665 }
2666
2667 /*
2668 * When switching pchan modes, all lchans are unused. So always
2669 * activate whatever wants to be activated on the first lchan. (We
2670 * wouldn't remember to use lchan[1] across e.g. a PDCH deact anyway)
2671 */
2672 lchan = ts->lchan;
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002673
2674 /*
2675 * For TCH/x, the lchan->type has been set in lchan_alloc(), but it may
2676 * have been lost during channel release due to dynamic switchover.
2677 *
2678 * For PDCH, the lchan->type will actually remain NONE.
2679 * TODO: set GSM_LCHAN_PDTCH?
2680 */
2681 switch (ts->dyn.pchan_want) {
2682 case GSM_PCHAN_TCH_F:
2683 lchan->type = GSM_LCHAN_TCH_F;
2684 break;
2685 case GSM_PCHAN_TCH_H:
2686 lchan->type = GSM_LCHAN_TCH_H;
2687 break;
2688 case GSM_PCHAN_PDCH:
2689 lchan->type = GSM_LCHAN_NONE;
2690 break;
2691 default:
2692 LOGP(DRSL, LOGL_ERROR,
2693 "%s Invalid target pchan for dynamic TS\n",
2694 gsm_ts_and_pchan_name(ts));
2695 }
2696
2697 act_type = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2698 ? RSL_ACT_OSMO_PDCH
2699 : lchan->dyn.act_type;
2700 ho_ref = (ts->dyn.pchan_want == GSM_PCHAN_PDCH)
2701 ? 0
2702 : lchan->dyn.ho_ref;
2703
2704 /* Fetch the rqd_ref back from before switchover started. */
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002705 lchan->rqd_ref = lchan->dyn.rqd_ref;
2706 lchan->rqd_ta = lchan->dyn.rqd_ta;
2707 lchan->dyn.rqd_ref = NULL;
2708 lchan->dyn.rqd_ta = 0;
2709
Neels Hofmeyra2ef7d62016-08-24 16:57:31 +02002710 /* During switchover, we have received a release ack, which means that
2711 * the act_timer has been stopped. Start the timer again so we mark
2712 * this channel broken if the activation ack comes too late. */
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02002713 osmo_timer_setup(&lchan->act_timer, lchan_act_tmr_cb, lchan);
Neels Hofmeyra2ef7d62016-08-24 16:57:31 +02002714 osmo_timer_schedule(&lchan->act_timer, 4, 0);
2715
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002716 rc = rsl_chan_activate_lchan(lchan, act_type, ho_ref);
2717 if (rc) {
2718 LOGP(DRSL, LOGL_ERROR,
2719 "%s RSL Chan Activate failed\n",
2720 gsm_ts_and_pchan_name(ts));
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002721 return dyn_ts_switchover_failed(ts, rc);
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002722 }
2723 return 0;
2724}
2725
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002726static int dyn_ts_switchover_failed(struct gsm_bts_trx_ts *ts, int rc)
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002727{
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002728 ts->dyn.pchan_want = ts->dyn.pchan_is;
2729 LOGP(DRSL, LOGL_ERROR, "%s Error %d during dynamic channel switchover."
2730 " Going back to previous pchan.\n", gsm_ts_and_pchan_name(ts),
2731 rc);
2732 return rc;
2733}
2734
2735static void dyn_ts_switchover_complete(struct gsm_lchan *lchan)
2736{
2737 enum gsm_phys_chan_config pchan_act;
2738 enum gsm_phys_chan_config pchan_was;
2739 struct gsm_bts_trx_ts *ts = lchan->ts;
2740
2741 OSMO_ASSERT(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH);
2742
2743 pchan_act = pchan_for_lchant(lchan->type);
2744 /*
2745 * Paranoia: do the types match?
2746 * In case of errors: we've received an act ack already, so what to do
2747 * about it? Logging the error should suffice for now.
2748 */
2749 if (pchan_act != ts->dyn.pchan_want)
2750 LOGP(DRSL, LOGL_ERROR,
2751 "%s Requested transition does not match lchan type %s\n",
2752 gsm_ts_and_pchan_name(ts),
Neels Hofmeyrb74a2c82016-08-24 16:57:31 +02002753 gsm_lchant_name(lchan->type));
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002754
2755 pchan_was = ts->dyn.pchan_is;
2756 ts->dyn.pchan_is = ts->dyn.pchan_want = pchan_act;
2757
Neels Hofmeyra0a08d82016-08-24 14:42:58 +02002758 if (pchan_was != ts->dyn.pchan_is)
2759 LOGP(DRSL, LOGL_INFO, "%s switchover from %s complete.\n",
2760 gsm_ts_and_pchan_name(ts), gsm_pchan_name(pchan_was));
Neels Hofmeyrb91e6002016-07-23 19:45:15 +02002761}
Harald Welte75099262009-02-16 21:12:08 +00002762
Harald Welte52b1f982008-12-23 20:25:15 +00002763/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00002764int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00002765{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002766 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002767 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002768
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002769 if (!msg) {
2770 DEBUGP(DRSL, "Empty RSL msg?..\n");
2771 return -1;
2772 }
2773
2774 if (msgb_l2len(msg) < sizeof(*rslh)) {
2775 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02002776 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002777 return -1;
2778 }
2779
2780 rslh = msgb_l2(msg);
2781
Harald Welte52b1f982008-12-23 20:25:15 +00002782 switch (rslh->msg_discr & 0xfe) {
2783 case ABIS_RSL_MDISC_RLL:
2784 rc = abis_rsl_rx_rll(msg);
2785 break;
2786 case ABIS_RSL_MDISC_DED_CHAN:
2787 rc = abis_rsl_rx_dchan(msg);
2788 break;
2789 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00002790 rc = abis_rsl_rx_cchan(msg);
2791 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002792 case ABIS_RSL_MDISC_TRX:
2793 rc = abis_rsl_rx_trx(msg);
2794 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002795 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002796 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002797 rslh->msg_discr);
2798 break;
Harald Welte75099262009-02-16 21:12:08 +00002799 case ABIS_RSL_MDISC_IPACCESS:
2800 rc = abis_rsl_rx_ipacc(msg);
2801 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002802 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002803 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2804 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002805 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002806 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002807 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002808 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002809}
Holger Freyther3b72a892009-02-04 00:31:39 +00002810
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002811int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Welte30f1f372014-12-28 15:00:45 +01002812 struct rsl_ie_cb_cmd_type cb_command,
2813 const uint8_t *data, int len)
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002814{
2815 struct abis_rsl_dchan_hdr *dh;
2816 struct msgb *cb_cmd;
2817
2818 cb_cmd = rsl_msgb_alloc();
2819 if (!cb_cmd)
2820 return -1;
2821
Harald Welte30f1f372014-12-28 15:00:45 +01002822 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002823 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Welte30f1f372014-12-28 15:00:45 +01002824 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2825 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002826
Harald Welte30f1f372014-12-28 15:00:45 +01002827 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002828 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2829
Harald Welte30f1f372014-12-28 15:00:45 +01002830 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002831
2832 return abis_rsl_sendmsg(cb_cmd);
2833}
Dieter Spaar16646022011-07-28 00:01:50 +02002834
2835int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2836{
2837 struct abis_rsl_common_hdr *ch;
2838 struct msgb *msg = rsl_msgb_alloc();
2839
2840 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2841 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2842 ch->msg_type = 0x40; /* Nokia SI Begin */
2843
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002844 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002845
2846 return abis_rsl_sendmsg(msg);
2847}
2848
2849int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2850{
2851 struct abis_rsl_common_hdr *ch;
2852 struct msgb *msg = rsl_msgb_alloc();
2853
2854 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2855 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2856 ch->msg_type = 0x41; /* Nokia SI End */
2857
2858 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2859
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002860 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002861
2862 return abis_rsl_sendmsg(msg);
2863}
2864
2865int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2866{
2867 struct abis_rsl_common_hdr *ch;
2868 struct msgb *msg = rsl_msgb_alloc();
2869
2870 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2871 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2872 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2873
2874 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2875 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2876
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002877 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002878
2879 return abis_rsl_sendmsg(msg);
2880}
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01002881
2882/**
2883 * Release all allocated SAPIs starting from @param start and
2884 * release them with the given release mode. Once the release
2885 * confirmation arrives it will be attempted to release the
2886 * the RF channel.
2887 */
2888int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2889 enum rsl_rel_mode release_mode)
2890{
2891 int no_sapi = 1;
2892 int sapi;
2893
2894 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2895 uint8_t link_id;
2896 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2897 continue;
2898
2899 link_id = sapi;
2900 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2901 link_id |= 0x40;
2902 rsl_release_request(lchan, link_id, release_mode);
2903 no_sapi = 0;
2904 }
2905
2906 return no_sapi;
2907}
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002908
2909int rsl_start_t3109(struct gsm_lchan *lchan)
2910{
2911 struct gsm_bts *bts = lchan->ts->trx->bts;
2912
Pablo Neira Ayuso51215762017-05-08 20:57:52 +02002913 osmo_timer_setup(&lchan->T3109, t3109_expired, lchan);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002914 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2915 return 0;
2916}
Holger Hans Peter Freyther006e3d82012-12-25 23:45:14 +01002917
2918/**
2919 * \brief directly RF Channel Release the lchan
2920 *
2921 * When no SAPI was allocated, directly release the logical channel. This
2922 * should only be called from chan_alloc.c on channel release handling. In
2923 * case no SAPI was established the RF Channel can be directly released,
2924 */
2925int rsl_direct_rf_release(struct gsm_lchan *lchan)
2926{
2927 int i;
2928 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2929 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2930 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2931 gsm_lchan_name(lchan), i);
2932 return -1;
2933 }
2934 }
2935
2936 /* Now release it */
2937 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2938}