blob: baefd54f6bccd20536618f89ce426ecbdecf3318 [file] [log] [blame]
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte59b04682009-06-10 05:40:52 +08002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Weltea22d36b2010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte59b04682009-06-10 05:40:52 +08006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte0e3e88e2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte59b04682009-06-10 05:40:52 +080012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte0e3e88e2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte59b04682009-06-10 05:40:52 +080018 *
Harald Welte0e3e88e2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte59b04682009-06-10 05:40:52 +080021 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
Harald Welte59b04682009-06-10 05:40:52 +080027#include <netinet/in.h>
28#include <arpa/inet.h>
29
30#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080036#include <openbsc/debug.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Max3d94aca2016-05-11 12:45:13 +020038#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include <osmocom/gsm/protocol/gsm_08_58.h>
Harald Welte59b04682009-06-10 05:40:52 +080040#include <openbsc/paging.h>
41#include <openbsc/signal.h>
Harald Weltec20bd1d2009-11-29 19:07:28 +010042#include <openbsc/meas_rep.h>
Harald Welte50517742009-12-20 15:42:44 +010043#include <openbsc/rtp_proxy.h>
Pablo Neira Ayuso42e41df2011-08-17 22:44:07 +020044#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010045#include <osmocom/gsm/rsl.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010046#include <osmocom/core/talloc.h>
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080047
Harald Welte59b04682009-06-10 05:40:52 +080048#define RSL_ALLOC_SIZE 1024
49#define RSL_ALLOC_HEADROOM 128
50
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +010051enum sacch_deact {
52 SACCH_NONE,
53 SACCH_DEACTIVATE,
54};
55
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080056static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020057static void error_timeout_cb(void *data);
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080058
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010059static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
60 struct gsm_meas_rep *resp)
61{
62 struct lchan_signal_data sig;
63 sig.lchan = lchan;
64 sig.mr = resp;
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +020065 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010066}
67
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010068static void do_lchan_free(struct gsm_lchan *lchan)
69{
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020070 /* We start the error timer to make the channel available again */
71 if (lchan->state == LCHAN_S_REL_ERR) {
72 lchan->error_timer.data = lchan;
73 lchan->error_timer.cb = error_timeout_cb;
74 osmo_timer_schedule(&lchan->error_timer,
75 lchan->ts->trx->bts->network->T3111 + 2, 0);
76 } else {
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010077 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freytherda9fb8c2014-04-06 12:21:05 +020078 }
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +010079 lchan_free(lchan);
80}
81
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020082static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080083{
84 /* mask off the transparent bit ? */
85 msg_type &= 0xfe;
86
87 if ((msg_type & 0xf0) == 0x00)
88 return ABIS_RSL_MDISC_RLL;
89 if ((msg_type & 0xf0) == 0x10) {
90 if (msg_type >= 0x19 && msg_type <= 0x22)
91 return ABIS_RSL_MDISC_TRX;
92 else
93 return ABIS_RSL_MDISC_COM_CHAN;
94 }
95 if ((msg_type & 0xe0) == 0x20)
96 return ABIS_RSL_MDISC_DED_CHAN;
97
98 return ABIS_RSL_MDISC_LOC;
99}
100
101static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200102 uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +0800103{
104 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
105 dh->c.msg_type = msg_type;
106 dh->ie_chan = RSL_IE_CHAN_NR;
107}
108
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200109/* call rsl_lchan_lookup and set the log context */
110static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte59b04682009-06-10 05:40:52 +0800111{
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200112 int rc;
113 struct gsm_lchan *lchan = rsl_lchan_lookup(trx, chan_nr, &rc);
Harald Welte59b04682009-06-10 05:40:52 +0800114
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200115 if (!lchan) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100116 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800117 return NULL;
118 }
119
Neels Hofmeyr0a771992016-07-23 17:38:22 +0200120 if (rc < 0)
121 LOGP(DRSL, LOGL_ERROR, "%s mismatching chan_nr=0x%02x\n",
122 gsm_ts_and_pchan_name(lchan->ts), chan_nr);
123
Harald Welte51d2a592010-03-26 21:28:59 +0800124 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800125 if (lchan->conn)
126 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800127
128 return lchan;
129}
130
Harald Welte59b04682009-06-10 05:40:52 +0800131/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200132uint64_t str_to_imsi(const char *imsi_str)
Harald Welte59b04682009-06-10 05:40:52 +0800133{
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200134 uint64_t ret;
Harald Welte59b04682009-06-10 05:40:52 +0800135
136 ret = strtoull(imsi_str, NULL, 10);
137
138 return ret;
139}
140
Harald Welte59b04682009-06-10 05:40:52 +0800141static struct msgb *rsl_msgb_alloc(void)
142{
Harald Welte9cfc9352009-06-26 19:39:35 +0200143 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
144 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800145}
146
147#define MACBLOCK_SIZE 23
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200148static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800149{
150 memcpy(out, in, len);
151
152 if (len < MACBLOCK_SIZE)
153 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
154}
155
Harald Welted2dd9de2009-08-30 15:37:11 +0900156/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200157static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welted2dd9de2009-08-30 15:37:11 +0900158{
159 *out++ = lchan->encr.alg_id & 0xff;
160 if (lchan->encr.key_len)
161 memcpy(out, lchan->encr.key, lchan->encr.key_len);
162 return lchan->encr.key_len + 1;
163}
164
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200165static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200166{
Harald Welte59b04682009-06-10 05:40:52 +0800167 int i;
168
Harald Weltede4477a2009-12-24 12:20:20 +0100169 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200170 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200171 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100172 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800173}
174
Harald Welte32951ea2011-08-10 23:26:33 +0200175static void lchan_act_tmr_cb(void *data)
176{
177 struct gsm_lchan *lchan = data;
178
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200179 LOGP(DRSL, LOGL_ERROR,
180 "%s Timeout during activation. Marked as broken.\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200181 gsm_lchan_name(lchan));
182
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100183 rsl_lchan_mark_broken(lchan, "activation timeout");
Daniel Willmann2731e732011-08-11 04:44:12 +0200184 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200185}
186
187static void lchan_deact_tmr_cb(void *data)
188{
189 struct gsm_lchan *lchan = data;
190
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200191 LOGP(DRSL, LOGL_ERROR,
192 "%s Timeout during deactivation! Marked as broken.\n",
Harald Welte32951ea2011-08-10 23:26:33 +0200193 gsm_lchan_name(lchan));
194
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100195 rsl_lchan_mark_broken(lchan, "de-activation timeout");
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200196 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200197}
198
199
Harald Welte59b04682009-06-10 05:40:52 +0800200/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200201int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
202 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800203{
204 struct abis_rsl_dchan_hdr *dh;
205 struct msgb *msg = rsl_msgb_alloc();
206
207 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
208 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
209 dh->chan_nr = RSL_CHAN_BCCH;
210
211 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
212 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
213
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200214 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800215
216 return abis_rsl_sendmsg(msg);
217}
218
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200219int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
220 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800221{
222 struct abis_rsl_common_hdr *ch;
223 struct msgb *msg = rsl_msgb_alloc();
224
225 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
226 ch->msg_discr = ABIS_RSL_MDISC_TRX;
227 ch->msg_type = RSL_MT_SACCH_FILL;
228
229 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
230 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
231
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200232 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800233
234 return abis_rsl_sendmsg(msg);
235}
236
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200237int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
238 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100239{
240 struct abis_rsl_dchan_hdr *dh;
241 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200242 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100243
244 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
245 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
246 dh->chan_nr = chan_nr;
247
248 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
249 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
250
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200251 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte10b7d8f2011-01-13 23:16:03 +0100252
253 return abis_rsl_sendmsg(msg);
254}
255
Harald Welte91afe4c2009-06-20 18:15:19 +0200256int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
257{
258 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200259 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200260 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200261
262 db = abs(db);
263 if (db > 30)
264 return -EINVAL;
265
Harald Welteed831842009-06-27 03:09:08 +0200266 msg = rsl_msgb_alloc();
267
Harald Welte91afe4c2009-06-20 18:15:19 +0200268 lchan->bs_power = db/2;
269 if (fpc)
270 lchan->bs_power |= 0x10;
271
272 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
273 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
274 dh->chan_nr = chan_nr;
275
276 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
277
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200278 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200279
280 return abis_rsl_sendmsg(msg);
281}
282
Harald Welte91afe4c2009-06-20 18:15:19 +0200283int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
284{
285 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200286 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200287 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200288 int ctl_lvl;
289
Harald Weltec4dcda02009-08-09 14:45:18 +0200290 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200291 if (ctl_lvl < 0)
292 return ctl_lvl;
293
Harald Welteed831842009-06-27 03:09:08 +0200294 msg = rsl_msgb_alloc();
295
Harald Welte91afe4c2009-06-20 18:15:19 +0200296 lchan->ms_power = ctl_lvl;
297
298 if (fpc)
299 lchan->ms_power |= 0x20;
300
301 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
302 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
303 dh->chan_nr = chan_nr;
304
305 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
306
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200307 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200308
309 return abis_rsl_sendmsg(msg);
310}
311
Harald Welte39274f42009-07-29 15:41:29 +0200312static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
313 struct gsm_lchan *lchan)
314{
Holger Hans Peter Freytherfad73652013-03-09 17:50:10 +0100315 memset(cm, 0, sizeof(*cm));
Harald Welte39274f42009-07-29 15:41:29 +0200316
317 /* FIXME: what to do with data calls ? */
Max3d94aca2016-05-11 12:45:13 +0200318 cm->dtx_dtu = 0;
319 if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
320 cm->dtx_dtu |= RSL_CMOD_DTXu;
321 if (lchan->ts->trx->bts->dtxd)
322 cm->dtx_dtu |= RSL_CMOD_DTXd;
Harald Welte39274f42009-07-29 15:41:29 +0200323
324 /* set TCH Speech/Data */
325 cm->spd_ind = lchan->rsl_cmode;
326
Harald Welte951e3512009-11-27 08:55:16 +0100327 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
328 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100329 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100330 "but tch_mode != signalling\n");
331
Harald Welte39274f42009-07-29 15:41:29 +0200332 switch (lchan->type) {
333 case GSM_LCHAN_SDCCH:
334 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
335 break;
336 case GSM_LCHAN_TCH_F:
337 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
338 break;
339 case GSM_LCHAN_TCH_H:
340 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
341 break;
342 case GSM_LCHAN_NONE:
343 case GSM_LCHAN_UNKNOWN:
344 default:
345 return -EINVAL;
346 }
347
348 switch (lchan->tch_mode) {
349 case GSM48_CMODE_SIGN:
350 cm->chan_rate = 0;
351 break;
352 case GSM48_CMODE_SPEECH_V1:
353 cm->chan_rate = RSL_CMOD_SP_GSM1;
354 break;
355 case GSM48_CMODE_SPEECH_EFR:
356 cm->chan_rate = RSL_CMOD_SP_GSM2;
357 break;
358 case GSM48_CMODE_SPEECH_AMR:
359 cm->chan_rate = RSL_CMOD_SP_GSM3;
360 break;
361 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200362 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200363 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200364 switch (lchan->csd_mode) {
365 case LCHAN_CSD_M_NT:
366 /* non-transparent CSD with RLP */
367 switch (lchan->tch_mode) {
368 case GSM48_CMODE_DATA_14k5:
369 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
370 break;
371 case GSM48_CMODE_DATA_12k0:
372 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
373 break;
374 case GSM48_CMODE_DATA_6k0:
375 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
376 break;
377 default:
378 return -EINVAL;
379 }
380 break;
381 /* transparent data services below */
382 case LCHAN_CSD_M_T_1200_75:
383 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
384 break;
385 case LCHAN_CSD_M_T_600:
386 cm->chan_rate = RSL_CMOD_CSD_T_600;
387 break;
388 case LCHAN_CSD_M_T_1200:
389 cm->chan_rate = RSL_CMOD_CSD_T_1200;
390 break;
391 case LCHAN_CSD_M_T_2400:
392 cm->chan_rate = RSL_CMOD_CSD_T_2400;
393 break;
394 case LCHAN_CSD_M_T_9600:
395 cm->chan_rate = RSL_CMOD_CSD_T_9600;
396 break;
397 case LCHAN_CSD_M_T_14400:
398 cm->chan_rate = RSL_CMOD_CSD_T_14400;
399 break;
400 case LCHAN_CSD_M_T_29000:
401 cm->chan_rate = RSL_CMOD_CSD_T_29000;
402 break;
403 case LCHAN_CSD_M_T_32000:
404 cm->chan_rate = RSL_CMOD_CSD_T_32000;
405 break;
406 default:
407 return -EINVAL;
408 }
Harald Welte39274f42009-07-29 15:41:29 +0200409 default:
410 return -EINVAL;
411 }
412
413 return 0;
414}
415
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200416static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
417{
418 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
419 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
420 lchan->mr_bts_lv + 1);
421}
422
Harald Welte59b04682009-06-10 05:40:52 +0800423/* Chapter 8.4.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200424int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200425 uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800426{
427 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200428 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200429 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200430 uint8_t *len;
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200431 uint8_t ta;
Harald Welte59b04682009-06-10 05:40:52 +0800432
Harald Weltee6d51f92011-06-25 10:02:33 +0200433 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800434 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200435 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800436
Harald Welte39274f42009-07-29 15:41:29 +0200437 rc = channel_mode_from_lchan(&cm, lchan);
438 if (rc < 0)
439 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800440
Neels Hofmeyrb3985cf2016-07-14 02:51:13 +0200441 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200442 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +0200443 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200444 /* store activation type and handover reference */
445 lchan->dyn_pdch.act_type = act_type;
446 lchan->dyn_pdch.ho_ref = ho_ref;
447 return rsl_ipacc_pdch_activate(lchan->ts, 0);
448 }
449
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200450 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
451
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200452 ta = lchan->rqd_ta;
453
454 /* BS11 requires TA shifted by 2 bits */
455 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
456 ta <<= 2;
457
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800458 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200459 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800460
Harald Welteed831842009-06-27 03:09:08 +0200461 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800462 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
463 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
464 dh->chan_nr = chan_nr;
465
466 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800467 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200468 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800469
470 /*
471 * The Channel Identification is needed for Phase1 phones
472 * and it contains the GSM48 Channel Description and the
473 * Mobile Allocation. The GSM 08.58 asks for the Mobile
474 * Allocation to have a length of zero. We are using the
475 * msgb_l3len to calculate the length of both messages.
476 */
laforgef723cf02010-06-20 21:38:19 +0200477 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200478 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200479 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800480
481 if (lchan->ts->hopping.enabled)
482 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
483 lchan->ts->hopping.ma_data);
484 else
485 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800486
487 /* update the calculated size */
488 msg->l3h = len + 1;
489 *len = msgb_l3len(msg);
490
Harald Welted2dd9de2009-08-30 15:37:11 +0900491 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200492 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900493 rc = build_encr_info(encr_info, lchan);
494 if (rc > 0)
495 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
496 }
497
Harald Welteb90d7bd2009-12-17 00:31:10 +0100498 switch (act_type) {
499 case RSL_ACT_INTER_ASYNC:
500 case RSL_ACT_INTER_SYNC:
501 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
502 break;
503 default:
504 break;
505 }
506
Harald Welte59b04682009-06-10 05:40:52 +0800507 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
508 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
509 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200510 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100511
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200512 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800513
514 return abis_rsl_sendmsg(msg);
515}
516
Harald Welte8e770492009-07-29 11:38:15 +0200517/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800518int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
519{
520 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200521 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200522 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800523
Harald Weltee6d51f92011-06-25 10:02:33 +0200524 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800525 struct rsl_ie_chan_mode cm;
526
Harald Welte39274f42009-07-29 15:41:29 +0200527 rc = channel_mode_from_lchan(&cm, lchan);
528 if (rc < 0)
529 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800530
Harald Welteed831842009-06-27 03:09:08 +0200531 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800532 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
533 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
534 dh->chan_nr = chan_nr;
535
536 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200537 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900538
539 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200540 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900541 rc = build_encr_info(encr_info, lchan);
542 if (rc > 0)
543 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
544 }
545
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200546 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100547
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200548 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900549
550 return abis_rsl_sendmsg(msg);
551}
552
553/* Chapter 8.4.6: Send the encryption command with given L3 info */
554int rsl_encryption_cmd(struct msgb *msg)
555{
556 struct abis_rsl_dchan_hdr *dh;
557 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200558 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200559 uint8_t encr_info[MAX_A5_KEY_LEN+2];
560 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900561 int rc;
562
563 /* First push the L3 IE tag and length */
564 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
565
566 /* then the link identifier (SAPI0, main sign link) */
567 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
568
569 /* then encryption information */
570 rc = build_encr_info(encr_info, lchan);
571 if (rc <= 0)
572 return rc;
573 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
574
575 /* and finally the DCHAN header */
576 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
577 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
578 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800579
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200580 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800581
582 return abis_rsl_sendmsg(msg);
583}
584
Harald Welte85a163c2009-08-10 11:43:22 +0200585/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200586int rsl_deact_sacch(struct gsm_lchan *lchan)
587{
588 struct abis_rsl_dchan_hdr *dh;
589 struct msgb *msg = rsl_msgb_alloc();
590
591 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
592 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200593 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200594
595 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200596 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200597
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100598 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200599
600 return abis_rsl_sendmsg(msg);
601}
602
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800603static void error_timeout_cb(void *data)
604{
605 struct gsm_lchan *lchan = data;
606 if (lchan->state != LCHAN_S_REL_ERR) {
607 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
608 gsm_lchan_name(lchan), lchan->state);
609 return;
610 }
611
612 /* go back to the none state */
Harald Weltefddaba52012-11-13 04:26:22 +0100613 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800614 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200615
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200616 /* Put PDCH channel back into PDCH mode, if GPRS is enabled */
617 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
618 && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE)
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200619 rsl_ipacc_pdch_activate(lchan->ts, 1);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800620}
621
Harald Welte08011e22011-03-04 13:41:31 +0100622static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
623
Harald Welte85a163c2009-08-10 11:43:22 +0200624/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100625static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
626 enum sacch_deact deact_sacch)
Harald Welte59b04682009-06-10 05:40:52 +0800627{
628 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800629 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100630 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800631
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100632 /* Stop timers that should lead to a channel release */
633 osmo_timer_del(&lchan->T3109);
634
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800635 if (lchan->state == LCHAN_S_REL_ERR) {
636 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
637 gsm_lchan_name(lchan));
638 return -1;
639 }
640
641 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800642 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
643 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200644 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800645
646 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200647 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800648
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800649 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
650
651 if (error) {
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100652 /*
653 * FIXME: GSM 04.08 gives us two options for the abnormal
654 * chanel release. This can be either like in the non-existent
655 * sub-lcuase 3.5.1 or for the main signalling link deactivate
656 * the SACCH, start timer T3109 and consider the channel as
657 * released.
658 *
659 * This code is doing the later for all raido links and not
660 * only the main link. Right now all SAPIs are released on the
661 * local end, the SACCH will be de-activated and right now the
662 * T3111 will be started. First T3109 should be started and then
663 * the T3111.
664 *
665 * TODO: Move this out of the function.
666 */
667
668 /*
669 * sacch de-activate and "local end release"
670 */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100671 if (deact_sacch == SACCH_DEACTIVATE)
672 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100673 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
674
675 /*
676 * TODO: start T3109 now.
677 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800678 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800679 }
Harald Welte59b04682009-06-10 05:40:52 +0800680
Harald Welte32951ea2011-08-10 23:26:33 +0200681 /* Start another timer or assume the BTS sends a ACK/NACK? */
682 lchan->act_timer.cb = lchan_deact_tmr_cb;
683 lchan->act_timer.data = lchan;
684 osmo_timer_schedule(&lchan->act_timer, 4, 0);
685
Harald Welte08011e22011-03-04 13:41:31 +0100686 rc = abis_rsl_sendmsg(msg);
687
Harald Welte85a163c2009-08-10 11:43:22 +0200688 /* BTS will respond by RF CHAN REL ACK */
Harald Welte08011e22011-03-04 13:41:31 +0100689 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800690}
691
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +0200692/*
693 * Special handling for channel releases in the error case.
694 */
695static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
696{
697 if (lchan->state != LCHAN_S_ACTIVE)
698 return 0;
699 return rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
700}
701
Harald Welte9773f6c2011-01-14 14:16:16 +0100702static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
703{
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200704 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte9773f6c2011-01-14 14:16:16 +0100705
706 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
707
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100708 /* Stop all pending timers */
Harald Welte32951ea2011-08-10 23:26:33 +0200709 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100710 osmo_timer_del(&lchan->T3111);
Harald Welte32951ea2011-08-10 23:26:33 +0200711
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200712 /*
713 * The BTS didn't respond within the timeout to our channel
714 * release request and we have marked the channel as broken.
715 * Now we do receive an ACK and let's be conservative. If it
716 * is a sysmoBTS we know that only one RF Channel Release ACK
717 * will be sent. So let's "repair" the channel.
718 */
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200719 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200720 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200721 LOGP(DRSL, LOGL_NOTICE,
722 "%s CHAN REL ACK for broken channel. %s.\n",
723 gsm_lchan_name(lchan),
724 do_free ? "Releasing it" : "Keeping it broken");
725 if (do_free)
726 do_lchan_free(lchan);
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200727 return 0;
728 }
729
Harald Welte9773f6c2011-01-14 14:16:16 +0100730 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
731 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
732 gsm_lchan_name(lchan),
733 gsm_lchans_name(lchan->state));
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200734
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200735 do_lchan_free(lchan);
736
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200737 /*
738 * Put a dynamic TCH/F_PDCH channel back to PDCH mode iff it was
739 * released successfully. If in error, the PDCH ACT will follow after
740 * T3111 in error_timeout_cb().
741 *
742 * Any state other than LCHAN_S_REL_ERR became LCHAN_S_NONE after above
743 * do_lchan_free(). Assert this, because that's what ensures a PDCH ACT
Neels Hofmeyrb3985cf2016-07-14 02:51:13 +0200744 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200745 *
746 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200747 */
748 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
749 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200750 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200751 return 0;
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200752 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200753 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200754 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte9773f6c2011-01-14 14:16:16 +0100755 return 0;
756}
757
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200758int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
759 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800760{
761 struct abis_rsl_dchan_hdr *dh;
762 struct msgb *msg = rsl_msgb_alloc();
763
764 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
765 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
766 dh->chan_nr = RSL_CHAN_PCH_AGCH;
767
768 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
769 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
770 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
771
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200772 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800773
774 return abis_rsl_sendmsg(msg);
775}
776
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200777int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800778{
779 int i, len = strlen(str_in);
780
781 for (i = 0; i < len; i++) {
782 int num = str_in[i] - 0x30;
783 if (num < 0 || num > 9)
784 return -1;
785 if (i % 2 == 0)
786 bcd_out[i/2] = num;
787 else
788 bcd_out[i/2] |= (num << 4);
789 }
790
791 return 0;
792}
793
794/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200795int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800796{
797 struct msgb *msg = rsl_msgb_alloc();
798 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200799 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800800
801 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
802 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
803 dh->chan_nr = RSL_CHAN_PCH_AGCH;
804
805 switch (bts->type) {
806 case GSM_BTS_TYPE_BS11:
807 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
808 break;
809 default:
810 /* If phase 2, construct a FULL_IMM_ASS_INFO */
811 pad_macblock(buf, val, len);
812 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
813 break;
814 }
815
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200816 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800817
818 return abis_rsl_sendmsg(msg);
819}
820
Harald Welte4684e632009-08-10 09:51:40 +0200821/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200822int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200823{
824 struct msgb *msg = rsl_msgb_alloc();
825 struct abis_rsl_dchan_hdr *dh;
826
827 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
828 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200829 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200830 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200831 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200832
Harald Weltede4477a2009-12-24 12:20:20 +0100833 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200834 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200835
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200836 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +0200837
Harald Welte4684e632009-08-10 09:51:40 +0200838 return abis_rsl_sendmsg(msg);
839}
840
841
Harald Welte59b04682009-06-10 05:40:52 +0800842/* Send "DATA REQUEST" message with given L3 Info payload */
843/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200844int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800845{
Harald Welte59b04682009-06-10 05:40:52 +0800846 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100847 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800848 return -EINVAL;
849 }
850
Harald Weltee6d51f92011-06-25 10:02:33 +0200851 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100852 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800853
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200854 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800855
856 return abis_rsl_sendmsg(msg);
857}
858
Harald Welteed9a5ab2009-08-09 13:47:35 +0200859/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
860/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200861int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200862{
Harald Weltea22d36b2010-03-04 10:33:10 +0100863 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200864
Harald Weltee6d51f92011-06-25 10:02:33 +0200865 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100866 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200867 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200868
Harald Welte17091bd2012-04-26 19:42:19 +0200869 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
870 gsm_lchan_name(lchan), link_id);
871
Harald Welteed9a5ab2009-08-09 13:47:35 +0200872 return abis_rsl_sendmsg(msg);
873}
874
Andreas Eversbergac27b952013-12-05 13:25:06 +0100875static void rsl_handle_release(struct gsm_lchan *lchan);
876
877/* Special work handler to handle missing RSL_MT_REL_CONF message from
878 * Nokia InSite BTS */
879static void lchan_rel_work_cb(void *data)
880{
881 struct gsm_lchan *lchan = data;
882 int sapi;
883
884 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
885 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
886 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
887 }
888 rsl_handle_release(lchan);
889}
890
Harald Welte0f2e3c12009-08-08 13:15:07 +0200891/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
892 This is what higher layers should call. The BTS then responds with
893 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
894 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
895 lchan_free() */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100896int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
897 enum rsl_rel_mode release_mode)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200898{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200899
Harald Weltea22d36b2010-03-04 10:33:10 +0100900 struct msgb *msg;
901
Harald Weltee6d51f92011-06-25 10:02:33 +0200902 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100903 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800904 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100905 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200906
Harald Weltec88a4432009-12-29 10:44:17 +0100907 /* FIXME: start some timer in case we don't receive a REL ACK ? */
908
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200909 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200910
Harald Welte17091bd2012-04-26 19:42:19 +0200911 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100912 gsm_lchan_name(lchan), link_id, release_mode);
Harald Welte17091bd2012-04-26 19:42:19 +0200913
Andreas Eversbergac27b952013-12-05 13:25:06 +0100914 abis_rsl_sendmsg(msg);
915
916 /* Do not wait for Nokia BTS to send the confirm. */
917 if (is_nokia_bts(lchan->ts->trx->bts)
918 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
919 && release_mode == RSL_REL_LOCAL_END) {
920 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
921 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
922 lchan->rel_work.cb = lchan_rel_work_cb;
923 lchan->rel_work.data = lchan;
924 osmo_timer_schedule(&lchan->rel_work, 0, 0);
925 }
926
927 return 0;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200928}
929
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100930int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
931{
932 lchan->state = LCHAN_S_BROKEN;
933 lchan->broken_reason = reason;
934 return 0;
935}
936
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200937int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
938{
Neels Hofmeyra4353c82016-06-21 21:34:46 +0200939 DEBUGP(DRSL, "%s state %s -> %s\n",
940 gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
941 gsm_lchans_name(state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200942 lchan->state = state;
943 return 0;
944}
945
Harald Welte59b04682009-06-10 05:40:52 +0800946/* Chapter 8.4.2: Channel Activate Acknowledge */
947static int rsl_rx_chan_act_ack(struct msgb *msg)
948{
949 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200950 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +0800951
952 /* BTS has confirmed channel activation, we now need
953 * to assign the activated channel to the MS */
954 if (rslh->ie_chan != RSL_IE_CHAN_NR)
955 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100956
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200957 osmo_timer_del(&lchan->act_timer);
Harald Welte32951ea2011-08-10 23:26:33 +0200958
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200959 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200960 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel.\n",
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200961 gsm_lchan_name(lchan));
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200962 return 0;
963 }
964
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200965 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100966 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200967 gsm_lchan_name(lchan),
968 gsm_lchans_name(lchan->state));
969 rsl_lchan_set_state(lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100970
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200971 if (lchan->rqd_ref) {
972 rsl_send_imm_assignment(lchan);
973 talloc_free(lchan->rqd_ref);
974 lchan->rqd_ref = NULL;
975 lchan->rqd_ta = 0;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800976 }
977
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200978 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100979
Harald Welte59b04682009-06-10 05:40:52 +0800980 return 0;
981}
982
983/* Chapter 8.4.3: Channel Activate NACK */
984static int rsl_rx_chan_act_nack(struct msgb *msg)
985{
986 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
987 struct tlv_parsed tp;
988
Harald Welte32951ea2011-08-10 23:26:33 +0200989 osmo_timer_del(&msg->lchan->act_timer);
990
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200991 if (msg->lchan->state == LCHAN_S_BROKEN) {
992 LOGP(DRSL, LOGL_ERROR,
993 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
994 gsm_lchan_name(msg->lchan));
995 return -1;
996 }
997
Daniel Willmann9e9d44c2011-08-11 04:54:23 +0200998 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100999 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001000
Harald Welte59b04682009-06-10 05:40:52 +08001001 /* BTS has rejected channel activation ?!? */
1002 if (dh->ie_chan != RSL_IE_CHAN_NR)
1003 return -EINVAL;
1004
1005 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001006 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001007 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001008 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +02001009 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +01001010 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001011 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1012 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1013 } else
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001014 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann245ee032011-08-11 04:47:11 +02001015
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001016 } else {
1017 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1018 }
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001019
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001020 LOGPC(DRSL, LOGL_ERROR, "\n");
1021
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001022 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte59b04682009-06-10 05:40:52 +08001023 return 0;
1024}
1025
1026/* Chapter 8.4.4: Connection Failure Indication */
1027static int rsl_rx_conn_fail(struct msgb *msg)
1028{
1029 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1030 struct tlv_parsed tp;
1031
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001032 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1033 gsm_lchan_name(msg->lchan),
1034 gsm_lchans_name(msg->lchan->state));
1035
Harald Welte59b04682009-06-10 05:40:52 +08001036 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1037
Harald Weltef1a168d2009-07-28 17:58:09 +02001038 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001039 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001040 TLVP_LEN(&tp, RSL_IE_CAUSE));
1041
Harald Welte (local)4bd76642009-12-26 22:33:09 +01001042 LOGPC(DRSL, LOGL_NOTICE, "\n");
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001043 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001044 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001045}
1046
Harald Weltec20bd1d2009-11-29 19:07:28 +01001047static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1048 const char *prefix)
1049{
Harald Welte0e4fa782009-12-16 16:52:07 +01001050 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1051 prefix, rxlev2dbm(mru->full.rx_lev),
1052 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +01001053 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1054 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1055}
1056
Harald Welte50290cc2012-07-02 17:12:08 +02001057static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +01001058{
Harald Welte0e4fa782009-12-16 16:52:07 +01001059 int i;
Harald Welte50290cc2012-07-02 17:12:08 +02001060 char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +01001061
Harald Welteb764f1c2015-12-28 14:04:36 +01001062 if (lchan && lchan->conn)
Harald Welte50290cc2012-07-02 17:12:08 +02001063 name = subscr_name(lchan->conn->subscr);
1064
1065 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001066
1067 if (mr->flags & MEAS_REP_F_DL_DTX)
1068 DEBUGPC(DMEAS, "DTXd ");
1069
1070 print_meas_rep_uni(&mr->ul, "ul");
1071 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1072 if (mr->flags & MEAS_REP_F_MS_TO)
1073 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1074
1075 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +01001076 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001077 DEBUGPC(DMEAS, "L1_FPC=%u ",
1078 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1079 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1080 }
1081
1082 if (mr->flags & MEAS_REP_F_UL_DTX)
1083 DEBUGPC(DMEAS, "DTXu ");
1084 if (mr->flags & MEAS_REP_F_BA1)
1085 DEBUGPC(DMEAS, "BA1 ");
1086 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1087 DEBUGPC(DMEAS, "NOT VALID ");
1088 else
1089 print_meas_rep_uni(&mr->dl, "dl");
1090
1091 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +01001092 if (mr->num_cell == 7)
1093 return;
Harald Welte0e4fa782009-12-16 16:52:07 +01001094 for (i = 0; i < mr->num_cell; i++) {
1095 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +01001096 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1097 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001098 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001099}
1100
Harald Welte59b04682009-06-10 05:40:52 +08001101static int rsl_rx_meas_res(struct msgb *msg)
1102{
1103 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1104 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001105 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001106 uint8_t len;
1107 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001108 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001109
Harald Welte4baa9c52009-12-21 13:27:11 +01001110 /* check if this channel is actually active */
1111 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001112 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001113 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001114 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001115 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001116 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001117
Harald Weltef9476812009-12-15 21:36:05 +01001118 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001119 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001120
Harald Welte59b04682009-06-10 05:40:52 +08001121 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1122
Harald Weltec20bd1d2009-11-29 19:07:28 +01001123 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1124 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1125 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1126 return -EIO;
1127
1128 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001129 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001130
1131 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1132 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1133 if (len >= 3) {
1134 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001135 mr->flags |= MEAS_REP_F_DL_DTX;
1136 mr->ul.full.rx_lev = val[0] & 0x3f;
1137 mr->ul.sub.rx_lev = val[1] & 0x3f;
1138 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1139 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001140 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001141
Harald Weltef9476812009-12-15 21:36:05 +01001142 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001143
1144 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +08001145 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +01001146 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +01001147 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1148
Harald Weltea1467eb2009-06-20 18:44:35 +02001149 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001150 struct e1inp_sign_link *sign_link = msg->dst;
1151
Harald Weltec20bd1d2009-11-29 19:07:28 +01001152 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001153 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001154 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001155 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001156 mr->flags |= MEAS_REP_F_FPC;
1157 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001158 /* BS11 and Nokia reports TA shifted by 2 bits */
1159 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1160 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001161 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001162 }
Harald Welte59b04682009-06-10 05:40:52 +08001163 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001164 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001165 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001166 if (rc < 0)
1167 return rc;
1168 }
1169
Harald Welte50290cc2012-07-02 17:12:08 +02001170 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001171
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001172 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001173
Harald Welte59b04682009-06-10 05:40:52 +08001174 return 0;
1175}
1176
Harald Welte6720a432009-11-29 22:45:52 +01001177/* Chapter 8.4.7 */
1178static int rsl_rx_hando_det(struct msgb *msg)
1179{
1180 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1181 struct tlv_parsed tp;
1182
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001183 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001184
1185 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1186
1187 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1188 DEBUGPC(DRSL, "access delay = %u\n",
1189 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1190 else
1191 DEBUGPC(DRSL, "\n");
1192
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001193 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001194
1195 return 0;
1196}
1197
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001198static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1199{
1200 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001201
1202 OSMO_ASSERT(lchan);
1203
1204 ts = lchan->ts;
1205 OSMO_ASSERT(ts);
1206 OSMO_ASSERT(ts->trx);
1207 OSMO_ASSERT(ts->trx->bts);
1208
1209 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
Neels Hofmeyr50c2bd42016-06-21 20:53:27 +02001210 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1211 " for channel that is no TCH/F_PDCH\n",
1212 gsm_lchan_name(lchan),
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001213 gsm_pchan_name(ts->pchan),
1214 pdch_act? "ACT" : "DEACT");
1215 return false;
1216 }
1217
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +02001218 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyr50c2bd42016-06-21 20:53:27 +02001219 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1220 " in unexpected state: %s\n",
1221 gsm_lchan_name(lchan),
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001222 gsm_pchan_name(ts->pchan),
1223 pdch_act? "ACT" : "DEACT",
1224 gsm_lchans_name(lchan->state));
1225 return false;
1226 }
1227 return true;
1228}
1229
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001230static int rsl_rx_pdch_act_ack(struct msgb *msg)
1231{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001232 if (!lchan_may_change_pdch(msg->lchan, true))
1233 return -EINVAL;
1234
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001235 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001236 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001237
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001238 return 0;
1239}
1240
1241static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1242{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001243 if (!lchan_may_change_pdch(msg->lchan, false))
1244 return -EINVAL;
1245
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001246 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001247 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001248
1249 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn_pdch.act_type,
1250 msg->lchan->dyn_pdch.ho_ref);
1251
1252 return 0;
1253}
1254
Harald Welte59b04682009-06-10 05:40:52 +08001255static int abis_rsl_rx_dchan(struct msgb *msg)
1256{
1257 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1258 int rc = 0;
1259 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001260 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001261
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001262 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001263 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001264
Harald Welte59b04682009-06-10 05:40:52 +08001265 switch (rslh->c.msg_type) {
1266 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001267 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001268 rc = rsl_rx_chan_act_ack(msg);
1269 break;
1270 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001271 rc = rsl_rx_chan_act_nack(msg);
1272 break;
1273 case RSL_MT_CONN_FAIL:
1274 rc = rsl_rx_conn_fail(msg);
1275 break;
1276 case RSL_MT_MEAS_RES:
1277 rc = rsl_rx_meas_res(msg);
1278 break;
Harald Welte6720a432009-11-29 22:45:52 +01001279 case RSL_MT_HANDO_DET:
1280 rc = rsl_rx_hando_det(msg);
1281 break;
Harald Welte59b04682009-06-10 05:40:52 +08001282 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001283 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001284 break;
1285 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001286 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001287 break;
1288 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001289 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001290 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001291 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr6b272302016-05-31 17:51:41 +02001292 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001293 rc = rsl_rx_pdch_act_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001294 break;
1295 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001296 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001297 break;
1298 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001299 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001300 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001301 break;
1302 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001303 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001304 break;
Harald Welte59b04682009-06-10 05:40:52 +08001305 case RSL_MT_PHY_CONTEXT_CONF:
1306 case RSL_MT_PREPROC_MEAS_RES:
1307 case RSL_MT_TALKER_DET:
1308 case RSL_MT_LISTENER_DET:
1309 case RSL_MT_REMOTE_CODEC_CONF_REP:
1310 case RSL_MT_MR_CODEC_MOD_ACK:
1311 case RSL_MT_MR_CODEC_MOD_NACK:
1312 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001313 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1314 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001315 break;
1316 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001317 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1318 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001319 return -EINVAL;
1320 }
1321
1322 return rc;
1323}
1324
1325static int rsl_rx_error_rep(struct msgb *msg)
1326{
1327 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001328 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001329 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001330
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001331 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001332
1333 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1334
1335 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001336 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001337 TLVP_LEN(&tp, RSL_IE_CAUSE));
1338
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001339 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001340
1341 return 0;
1342}
1343
1344static int abis_rsl_rx_trx(struct msgb *msg)
1345{
1346 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001347 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001348 int rc = 0;
1349
1350 switch (rslh->msg_type) {
1351 case RSL_MT_ERROR_REPORT:
1352 rc = rsl_rx_error_rep(msg);
1353 break;
1354 case RSL_MT_RF_RES_IND:
1355 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001356 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001357 break;
1358 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001359 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001360 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001361 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001362 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001363 case 0x42: /* Nokia specific: SI End ACK */
1364 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1365 break;
1366 case 0x43: /* Nokia specific: SI End NACK */
1367 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1368 break;
Harald Welte59b04682009-06-10 05:40:52 +08001369 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001370 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001371 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001372 return -EINVAL;
1373 }
1374 return rc;
1375}
1376
Harald Welte427dbc42009-08-10 00:26:10 +02001377/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1378static void t3101_expired(void *data)
1379{
1380 struct gsm_lchan *lchan = data;
1381
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001382 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welte427dbc42009-08-10 00:26:10 +02001383}
1384
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001385/* If T3111 expires, we will send the RF Channel Request */
1386static void t3111_expired(void *data)
1387{
1388 struct gsm_lchan *lchan = data;
1389
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001390 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1391}
1392
1393/* If T3109 expires the MS has not send a UA/UM do the error release */
1394static void t3109_expired(void *data)
1395{
1396 struct gsm_lchan *lchan = data;
1397
1398 LOGP(DRSL, LOGL_ERROR,
1399 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1400 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001401}
1402
Harald Weltea00fdd72010-12-23 14:39:29 +01001403/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1404static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1405 unsigned int num_req_refs,
1406 struct gsm48_req_ref *rqd_refs,
1407 uint8_t wait_ind)
1408{
1409 uint8_t buf[GSM_MACBLOCK_LEN];
1410 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1411
1412 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1413 memset(iar, 0, sizeof(*iar));
1414 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001415 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Weltea00fdd72010-12-23 14:39:29 +01001416 iar->page_mode = GSM48_PM_SAME;
1417
1418 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1419 iar->wait_ind1 = wait_ind;
1420
1421 if (num_req_refs >= 2)
1422 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1423 else
1424 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1425 iar->wait_ind2 = wait_ind;
1426
1427 if (num_req_refs >= 3)
1428 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1429 else
1430 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1431 iar->wait_ind3 = wait_ind;
1432
1433 if (num_req_refs >= 4)
1434 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1435 else
1436 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1437 iar->wait_ind4 = wait_ind;
1438
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001439 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1440 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1441
1442 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Weltea00fdd72010-12-23 14:39:29 +01001443}
1444
Harald Welte59b04682009-06-10 05:40:52 +08001445/* MS has requested a channel on the RACH */
1446static int rsl_rx_chan_rqd(struct msgb *msg)
1447{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001448 struct e1inp_sign_link *sign_link = msg->dst;
1449 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001450 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1451 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001452 enum gsm_chan_t lctype;
1453 enum gsm_chreq_reason_t chreq_reason;
1454 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001455 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001456 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001457
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001458 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001459 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001460
1461 /* parse request reference to be used in immediate assign */
1462 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1463 return -EINVAL;
1464
1465 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1466
1467 /* parse access delay and use as TA */
1468 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1469 return -EINVAL;
1470 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1471
1472 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1473 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001474 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1475 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001476
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001477 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001478
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001479 /*
1480 * We want LOCATION UPDATES to succeed and will assign a TCH
1481 * if we have no SDCCH available.
1482 */
1483 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1484
Harald Welte59b04682009-06-10 05:40:52 +08001485 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001486 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001487 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001488 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001489 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001490 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001491 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1492 if (bts->network->T3122)
1493 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Weltecf7c90c2012-11-13 04:46:03 +01001494 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001495 }
1496
Harald Weltec88a4432009-12-29 10:44:17 +01001497 if (lchan->state != LCHAN_S_NONE)
1498 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001499 "in state %s\n", gsm_lchan_name(lchan),
1500 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001501
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001502 /* save the RACH data as we need it after the CHAN ACT ACK */
1503 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1504 if (!lchan->rqd_ref) {
1505 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1506 lchan_free(lchan);
1507 return -ENOMEM;
1508 }
1509
1510 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1511 lchan->rqd_ta = rqd_ta;
1512
Harald Welte59b04682009-06-10 05:40:52 +08001513 arfcn = lchan->ts->trx->arfcn;
1514 subch = lchan->nr;
1515
Harald Welted2dd9de2009-08-30 15:37:11 +09001516 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001517 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001518 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001519 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001520 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001521
Harald Welte32951ea2011-08-10 23:26:33 +02001522 /* Start another timer or assume the BTS sends a ACK/NACK? */
1523 lchan->act_timer.cb = lchan_act_tmr_cb;
1524 lchan->act_timer.data = lchan;
1525 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1526
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001527 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1528 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1529 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1530 rqd_ref->ra, rqd_ta);
1531
Neels Hofmeyrfe9fdfa2016-07-15 01:26:03 +02001532 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001533
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001534 return 0;
1535}
1536
1537static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1538{
1539 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001540 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001541 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1542
Harald Welte59b04682009-06-10 05:40:52 +08001543 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001544 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001545 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001546 ia->proto_discr = GSM48_PDISC_RR;
1547 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1548 ia->page_mode = GSM48_PM_SAME;
1549 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001550
Harald Welte59b04682009-06-10 05:40:52 +08001551 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001552 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1553 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001554 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001555 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001556 } else {
laforgee06d5982010-06-20 15:18:46 +02001557 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1558 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001559 }
Harald Welte07f32182010-06-28 18:41:27 +02001560 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1561 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001562
Harald Welte427dbc42009-08-10 00:26:10 +02001563 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1564 lchan->T3101.cb = t3101_expired;
1565 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001566 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001567
1568 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001569 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001570}
1571
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001572/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001573static int rsl_rx_ccch_load(struct msgb *msg)
1574{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001575 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001576 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001577 struct ccch_signal_data sd;
1578
1579 sd.bts = sign_link->trx->bts;
1580 sd.rach_slot_count = -1;
1581 sd.rach_busy_count = -1;
1582 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001583
1584 switch (rslh->data[0]) {
1585 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001586 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1587 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001588 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001589 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001590 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001591 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1592 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001593 break;
1594 case RSL_IE_RACH_LOAD:
1595 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001596 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1597 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1598 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1599 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001600 }
1601 break;
1602 default:
1603 break;
1604 }
1605
1606 return 0;
1607}
1608
1609static int abis_rsl_rx_cchan(struct msgb *msg)
1610{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001611 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001612 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1613 int rc = 0;
1614
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001615 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001616
1617 switch (rslh->c.msg_type) {
1618 case RSL_MT_CHAN_RQD:
1619 /* MS has requested a channel on the RACH */
1620 rc = rsl_rx_chan_rqd(msg);
1621 break;
1622 case RSL_MT_CCCH_LOAD_IND:
1623 /* current load on the CCCH */
1624 rc = rsl_rx_ccch_load(msg);
1625 break;
1626 case RSL_MT_DELETE_IND:
1627 /* CCCH overloaded, IMM_ASSIGN was dropped */
1628 case RSL_MT_CBCH_LOAD_IND:
1629 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001630 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1631 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001632 break;
1633 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001634 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1635 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001636 return -EINVAL;
1637 }
1638
1639 return rc;
1640}
1641
1642static int rsl_rx_rll_err_ind(struct msgb *msg)
1643{
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001644 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001645 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001646 uint8_t rlm_cause;
Harald Welte59b04682009-06-10 05:40:52 +08001647
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001648 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1649 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1650 LOGP(DRLL, LOGL_ERROR,
1651 "%s ERROR INDICATION without mandantory cause.\n",
1652 gsm_lchan_name(msg->lchan));
1653 return -1;
1654 }
1655
1656 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001657 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001658 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001659 rsl_rlm_cause_name(rlm_cause),
1660 gsm_lchans_name(msg->lchan->state));
1661
Harald Welteed9a5ab2009-08-09 13:47:35 +02001662 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001663
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001664 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001665 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001666 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001667 }
Harald Welte692f5852009-07-04 09:40:05 +02001668
Harald Welte59b04682009-06-10 05:40:52 +08001669 return 0;
1670}
1671
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001672static void rsl_handle_release(struct gsm_lchan *lchan)
1673{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001674 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001675 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001676
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +01001677 /*
1678 * Maybe only one link/SAPI was releasd or the error handling
1679 * was activated. Just return now and let the other code handle
1680 * it.
1681 */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001682 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001683 return;
1684
1685 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1686 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1687 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001688 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001689 gsm_lchan_name(lchan), sapi);
1690 return;
1691 }
1692
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001693
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001694 /* Stop T3109 and wait for T3111 before re-using the channel */
1695 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001696 lchan->T3111.cb = t3111_expired;
1697 lchan->T3111.data = lchan;
1698 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001699 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001700}
1701
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001702/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001703 0x02, 0x06,
1704 0x01, 0x20,
1705 0x02, 0x00,
1706 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1707
1708static int abis_rsl_rx_rll(struct msgb *msg)
1709{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001710 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001711 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1712 int rc = 0;
1713 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001714 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001715
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001716 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001717 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001718 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001719
1720 switch (rllh->c.msg_type) {
1721 case RSL_MT_DATA_IND:
1722 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001723 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001724 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1725 rllh->data[0] == RSL_IE_L3_INFO) {
1726 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001727 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001728 }
1729 break;
1730 case RSL_MT_EST_IND:
1731 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001732 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001733 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001734 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001735 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001736 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1737 rllh->data[0] == RSL_IE_L3_INFO) {
1738 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001739 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001740 }
1741 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001742 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001743 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001744 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001745 rll_indication(msg->lchan, rllh->link_id,
1746 BSC_RLLR_IND_EST_CONF);
1747 break;
Harald Welte59b04682009-06-10 05:40:52 +08001748 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001749 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001750 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001751 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001752 rll_indication(msg->lchan, rllh->link_id,
1753 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001754 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001755 break;
1756 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001757 /* BTS informs us of having received UA from MS,
1758 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001759 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001760 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001761 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001762 break;
1763 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001764 rc = rsl_rx_rll_err_ind(msg);
1765 break;
1766 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001767 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1768 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001769 break;
1770 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001771 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1772 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001773 }
Harald Welte59b04682009-06-10 05:40:52 +08001774 return rc;
1775}
1776
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001777static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001778{
Harald Welteb284b472009-12-02 01:58:23 +05301779 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001780 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301781 switch (lchan->type) {
1782 case GSM_LCHAN_TCH_F:
1783 return 0x00;
1784 case GSM_LCHAN_TCH_H:
1785 return 0x03;
1786 default:
1787 break;
1788 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001789 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001790 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301791 switch (lchan->type) {
1792 case GSM_LCHAN_TCH_F:
1793 return 0x01;
1794 /* there's no half-rate EFR */
1795 default:
1796 break;
1797 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001798 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001799 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301800 switch (lchan->type) {
1801 case GSM_LCHAN_TCH_F:
1802 return 0x02;
1803 case GSM_LCHAN_TCH_H:
1804 return 0x05;
1805 default:
1806 break;
1807 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001808 break;
Harald Welteb284b472009-12-02 01:58:23 +05301809 default:
1810 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001811 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001812 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301813 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001814 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001815}
1816
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001817static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001818{
1819 switch (lchan->tch_mode) {
1820 case GSM48_CMODE_SPEECH_V1:
1821 switch (lchan->type) {
1822 case GSM_LCHAN_TCH_F:
1823 return RTP_PT_GSM_FULL;
1824 case GSM_LCHAN_TCH_H:
1825 return RTP_PT_GSM_HALF;
1826 default:
1827 break;
1828 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001829 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001830 case GSM48_CMODE_SPEECH_EFR:
1831 switch (lchan->type) {
1832 case GSM_LCHAN_TCH_F:
1833 return RTP_PT_GSM_EFR;
1834 /* there's no half-rate EFR */
1835 default:
1836 break;
1837 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001838 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001839 case GSM48_CMODE_SPEECH_AMR:
1840 switch (lchan->type) {
1841 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01001842 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02001843 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001844 default:
1845 break;
1846 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001847 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001848 default:
1849 break;
1850 }
1851 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1852 "tch_mode == 0x%02x\n & lchan_type == %d",
1853 lchan->tch_mode, lchan->type);
1854 return 0;
1855}
1856
Harald Welte59b04682009-06-10 05:40:52 +08001857/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001858static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1859{
1860 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001861 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001862
1863 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001864 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01001865 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1866 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1867 }
1868
1869 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001870 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01001871 port = ntohs(port);
1872 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1873 lchan->abis_ip.bound_port = port;
1874 }
1875
1876 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001877 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Weltebffa4992009-12-19 16:42:06 +01001878 conn_id = ntohs(conn_id);
1879 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1880 lchan->abis_ip.conn_id = conn_id;
1881 }
1882
1883 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1884 lchan->abis_ip.rtp_payload2 =
1885 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1886 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1887 lchan->abis_ip.rtp_payload2);
1888 }
1889
1890 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1891 lchan->abis_ip.speech_mode =
1892 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1893 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1894 lchan->abis_ip.speech_mode);
1895 }
1896
1897 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001898 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01001899 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1900 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1901 }
1902
1903 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001904 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01001905 port = ntohs(port);
1906 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1907 lchan->abis_ip.connect_port = port;
1908 }
1909}
1910
Harald Welte9a696d72013-02-03 12:06:58 +01001911/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1912 * \param[in] lchan Logical Channel for which we issue CRCX
1913 */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001914int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001915{
1916 struct msgb *msg = rsl_msgb_alloc();
1917 struct abis_rsl_dchan_hdr *dh;
1918
1919 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001920 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001921 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001922 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001923
Harald Welte98d79f92009-07-28 18:11:56 +02001924 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001925 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001926 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001927 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001928 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001929
Sylvain Munaut1338a552009-12-20 22:06:40 +01001930 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1931 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1932 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001933
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001934 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001935
1936 return abis_rsl_sendmsg(msg);
1937}
1938
Harald Welte9a696d72013-02-03 12:06:58 +01001939/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1940 * \param[in] lchan Logical Channel for which we issue MDCX
1941 * \param[in] ip Remote (MGW) IP address for RTP
1942 * \param[in] port Remote (MGW) UDP port number for RTP
1943 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1944 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001945int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1946 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001947{
1948 struct msgb *msg = rsl_msgb_alloc();
1949 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001950 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001951 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001952
1953 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001954 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001955 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001956 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001957
Harald Weltebffa4992009-12-19 16:42:06 +01001958 /* we need to store these now as MDCX_ACK does not return them :( */
1959 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1960 lchan->abis_ip.connect_port = port;
1961 lchan->abis_ip.connect_ip = ip;
1962
Harald Weltefb4a9e92009-07-29 12:12:18 +02001963 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001964 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001965 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001966
Harald Welte98d79f92009-07-28 18:11:56 +02001967 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001968 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1969 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1970 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1971 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001972
Harald Weltebffa4992009-12-19 16:42:06 +01001973 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1974 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001975 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001976 *att_ip = ia.s_addr;
1977 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1978 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001979 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001980 if (rtp_payload2)
1981 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001982
1983 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001984
1985 return abis_rsl_sendmsg(msg);
1986}
1987
Harald Welte9947d9f2009-12-20 16:51:09 +01001988/* tell BTS to connect RTP stream to our local RTP socket */
1989int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1990{
1991 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1992 int rc;
1993
1994 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1995 ntohs(rs->rtp.sin_local.sin_port),
1996 /* FIXME: use RTP payload of bound socket, not BTS*/
1997 lchan->abis_ip.rtp_payload2);
1998
1999 return rc;
2000}
2001
Harald Welte6f40df02010-12-23 12:59:52 +01002002int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02002003{
2004 struct msgb *msg = rsl_msgb_alloc();
2005 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002006 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08002007
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002008 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2009 LOGP(DRSL, LOGL_ERROR,
2010 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2011 gsm_ts_name(ts),
2012 act ? "ACT" : "DEACT",
2013 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2014 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2015 return -EINVAL;
2016 }
2017
2018 if (act){
Neels Hofmeyr31b26302016-07-06 14:39:04 +02002019 /* Callers should heed the GPRS mode. */
2020 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte2b361522010-03-28 14:42:09 +08002021 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002022 ts->flags |= TS_F_PDCH_ACT_PENDING;
2023 } else {
Harald Welte2b361522010-03-28 14:42:09 +08002024 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002025 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2026 }
2027 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welteaed946e2009-10-24 10:29:22 +02002028
2029 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08002030 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02002031 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02002032 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02002033
Neels Hofmeyr6b272302016-05-31 17:51:41 +02002034 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08002035 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02002036
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002037 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02002038
2039 return abis_rsl_sendmsg(msg);
2040}
2041
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002042static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002043{
2044 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2045 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05302046 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08002047
2048 /* the BTS has acknowledged a local bind, it now tells us the IP
2049 * address and port number to which it has bound the given logical
2050 * channel */
2051
2052 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2053 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2054 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02002055 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002056 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08002057 return -EINVAL;
2058 }
Harald Welte50517742009-12-20 15:42:44 +01002059
Harald Weltebffa4992009-12-19 16:42:06 +01002060 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01002061
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002062 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002063
2064 return 0;
2065}
2066
Harald Weltebffa4992009-12-19 16:42:06 +01002067static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2068{
2069 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2070 struct tlv_parsed tv;
2071 struct gsm_lchan *lchan = msg->lchan;
2072
2073 /* the BTS has acknowledged a remote connect request and
2074 * it now tells us the IP address and port number to which it has
2075 * connected the given logical channel */
2076
2077 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2078 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002079 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01002080
2081 return 0;
2082}
2083
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002084static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002085{
2086 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2087 struct tlv_parsed tv;
2088
2089 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08002090
Harald Weltef1a168d2009-07-28 17:58:09 +02002091 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01002092 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02002093 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08002094
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002095 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02002096
Harald Welte59b04682009-06-10 05:40:52 +08002097 return 0;
2098}
2099
2100static int abis_rsl_rx_ipacc(struct msgb *msg)
2101{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002102 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08002103 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01002104 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08002105 int rc = 0;
2106
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002107 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01002108 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002109
2110 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002111 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01002112 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002113 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002114 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002115 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002116 /* somehow the BTS was unable to bind the lchan to its local
2117 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01002118 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002119 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002120 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08002121 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01002122 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01002123 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002124 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002125 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002126 /* somehow the BTS was unable to connect the lchan to a remote
2127 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01002128 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002129 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002130 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01002131 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002132 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002133 break;
2134 default:
Harald Weltede4477a2009-12-24 12:20:20 +01002135 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002136 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002137 break;
2138 }
2139 DEBUGPC(DRSL, "\n");
2140
2141 return rc;
2142}
2143
2144
2145/* Entry-point where L2 RSL from BTS enters */
2146int abis_rsl_rcvmsg(struct msgb *msg)
2147{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002148 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08002149 int rc = 0;
2150
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002151 if (!msg) {
2152 DEBUGP(DRSL, "Empty RSL msg?..\n");
2153 return -1;
2154 }
2155
2156 if (msgb_l2len(msg) < sizeof(*rslh)) {
2157 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02002158 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002159 return -1;
2160 }
2161
2162 rslh = msgb_l2(msg);
2163
Harald Welte59b04682009-06-10 05:40:52 +08002164 switch (rslh->msg_discr & 0xfe) {
2165 case ABIS_RSL_MDISC_RLL:
2166 rc = abis_rsl_rx_rll(msg);
2167 break;
2168 case ABIS_RSL_MDISC_DED_CHAN:
2169 rc = abis_rsl_rx_dchan(msg);
2170 break;
2171 case ABIS_RSL_MDISC_COM_CHAN:
2172 rc = abis_rsl_rx_cchan(msg);
2173 break;
2174 case ABIS_RSL_MDISC_TRX:
2175 rc = abis_rsl_rx_trx(msg);
2176 break;
2177 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002178 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08002179 rslh->msg_discr);
2180 break;
2181 case ABIS_RSL_MDISC_IPACCESS:
2182 rc = abis_rsl_rx_ipacc(msg);
2183 break;
2184 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002185 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2186 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02002187 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08002188 }
2189 msgb_free(msg);
2190 return rc;
2191}
2192
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002193int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Weltebf4ba722014-12-28 15:00:45 +01002194 struct rsl_ie_cb_cmd_type cb_command,
2195 const uint8_t *data, int len)
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002196{
2197 struct abis_rsl_dchan_hdr *dh;
2198 struct msgb *cb_cmd;
2199
2200 cb_cmd = rsl_msgb_alloc();
2201 if (!cb_cmd)
2202 return -1;
2203
Harald Weltebf4ba722014-12-28 15:00:45 +01002204 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002205 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Weltebf4ba722014-12-28 15:00:45 +01002206 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2207 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002208
Harald Weltebf4ba722014-12-28 15:00:45 +01002209 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002210 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2211
Harald Weltebf4ba722014-12-28 15:00:45 +01002212 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002213
2214 return abis_rsl_sendmsg(cb_cmd);
2215}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002216
2217int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2218{
2219 struct abis_rsl_common_hdr *ch;
2220 struct msgb *msg = rsl_msgb_alloc();
2221
2222 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2223 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2224 ch->msg_type = 0x40; /* Nokia SI Begin */
2225
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002226 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002227
2228 return abis_rsl_sendmsg(msg);
2229}
2230
2231int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2232{
2233 struct abis_rsl_common_hdr *ch;
2234 struct msgb *msg = rsl_msgb_alloc();
2235
2236 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2237 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2238 ch->msg_type = 0x41; /* Nokia SI End */
2239
2240 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2241
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002242 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002243
2244 return abis_rsl_sendmsg(msg);
2245}
2246
2247int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2248{
2249 struct abis_rsl_common_hdr *ch;
2250 struct msgb *msg = rsl_msgb_alloc();
2251
2252 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2253 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2254 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2255
2256 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2257 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2258
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002259 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002260
2261 return abis_rsl_sendmsg(msg);
2262}
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01002263
2264/**
2265 * Release all allocated SAPIs starting from @param start and
2266 * release them with the given release mode. Once the release
2267 * confirmation arrives it will be attempted to release the
2268 * the RF channel.
2269 */
2270int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2271 enum rsl_rel_mode release_mode)
2272{
2273 int no_sapi = 1;
2274 int sapi;
2275
2276 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2277 uint8_t link_id;
2278 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2279 continue;
2280
2281 link_id = sapi;
2282 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2283 link_id |= 0x40;
2284 rsl_release_request(lchan, link_id, release_mode);
2285 no_sapi = 0;
2286 }
2287
2288 return no_sapi;
2289}
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002290
2291int rsl_start_t3109(struct gsm_lchan *lchan)
2292{
2293 struct gsm_bts *bts = lchan->ts->trx->bts;
2294
2295 /* Disabled, mostly legacy code */
2296 if (bts->network->T3109 == 0)
2297 return -1;
2298
2299 lchan->T3109.cb = t3109_expired;
2300 lchan->T3109.data = lchan;
2301 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2302 return 0;
2303}
Holger Hans Peter Freytherc63cb862012-12-25 23:45:14 +01002304
2305/**
2306 * \brief directly RF Channel Release the lchan
2307 *
2308 * When no SAPI was allocated, directly release the logical channel. This
2309 * should only be called from chan_alloc.c on channel release handling. In
2310 * case no SAPI was established the RF Channel can be directly released,
2311 */
2312int rsl_direct_rf_release(struct gsm_lchan *lchan)
2313{
2314 int i;
2315 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2316 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2317 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2318 gsm_lchan_name(lchan), i);
2319 return -1;
2320 }
2321 }
2322
2323 /* Now release it */
2324 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2325}