blob: 6ddb088809474451efe3e44d65db376fc3a77467 [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:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200345 LOGP(DRSL, LOGL_ERROR,
346 "unsupported activation lchan->type %u %s\n",
347 lchan->type, gsm_lchant_name(lchan->type));
Harald Welte39274f42009-07-29 15:41:29 +0200348 return -EINVAL;
349 }
350
351 switch (lchan->tch_mode) {
352 case GSM48_CMODE_SIGN:
353 cm->chan_rate = 0;
354 break;
355 case GSM48_CMODE_SPEECH_V1:
356 cm->chan_rate = RSL_CMOD_SP_GSM1;
357 break;
358 case GSM48_CMODE_SPEECH_EFR:
359 cm->chan_rate = RSL_CMOD_SP_GSM2;
360 break;
361 case GSM48_CMODE_SPEECH_AMR:
362 cm->chan_rate = RSL_CMOD_SP_GSM3;
363 break;
364 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200365 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200366 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200367 switch (lchan->csd_mode) {
368 case LCHAN_CSD_M_NT:
369 /* non-transparent CSD with RLP */
370 switch (lchan->tch_mode) {
371 case GSM48_CMODE_DATA_14k5:
372 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
373 break;
374 case GSM48_CMODE_DATA_12k0:
375 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
376 break;
377 case GSM48_CMODE_DATA_6k0:
378 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
379 break;
380 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200381 LOGP(DRSL, LOGL_ERROR,
382 "unsupported lchan->tch_mode %u\n",
383 lchan->tch_mode);
Harald Weltee75a47d2012-08-24 15:33:56 +0200384 return -EINVAL;
385 }
386 break;
387 /* transparent data services below */
388 case LCHAN_CSD_M_T_1200_75:
389 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
390 break;
391 case LCHAN_CSD_M_T_600:
392 cm->chan_rate = RSL_CMOD_CSD_T_600;
393 break;
394 case LCHAN_CSD_M_T_1200:
395 cm->chan_rate = RSL_CMOD_CSD_T_1200;
396 break;
397 case LCHAN_CSD_M_T_2400:
398 cm->chan_rate = RSL_CMOD_CSD_T_2400;
399 break;
400 case LCHAN_CSD_M_T_9600:
401 cm->chan_rate = RSL_CMOD_CSD_T_9600;
402 break;
403 case LCHAN_CSD_M_T_14400:
404 cm->chan_rate = RSL_CMOD_CSD_T_14400;
405 break;
406 case LCHAN_CSD_M_T_29000:
407 cm->chan_rate = RSL_CMOD_CSD_T_29000;
408 break;
409 case LCHAN_CSD_M_T_32000:
410 cm->chan_rate = RSL_CMOD_CSD_T_32000;
411 break;
412 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200413 LOGP(DRSL, LOGL_ERROR,
414 "unsupported lchan->csd_mode %u\n",
415 lchan->csd_mode);
Harald Weltee75a47d2012-08-24 15:33:56 +0200416 return -EINVAL;
417 }
Harald Welte39274f42009-07-29 15:41:29 +0200418 default:
Neels Hofmeyr4e472ba2016-07-18 23:47:24 +0200419 LOGP(DRSL, LOGL_ERROR,
420 "unsupported lchan->tch_mode %u\n",
421 lchan->tch_mode);
Harald Welte39274f42009-07-29 15:41:29 +0200422 return -EINVAL;
423 }
424
425 return 0;
426}
427
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200428static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg)
429{
430 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
431 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
432 lchan->mr_bts_lv + 1);
433}
434
Harald Welte59b04682009-06-10 05:40:52 +0800435/* Chapter 8.4.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200436int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200437 uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800438{
439 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200440 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200441 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200442 uint8_t *len;
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200443 uint8_t ta;
Harald Welte59b04682009-06-10 05:40:52 +0800444
Harald Weltee6d51f92011-06-25 10:02:33 +0200445 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800446 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200447 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800448
Harald Welte39274f42009-07-29 15:41:29 +0200449 rc = channel_mode_from_lchan(&cm, lchan);
450 if (rc < 0)
451 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800452
Neels Hofmeyrb3985cf2016-07-14 02:51:13 +0200453 /* If a TCH_F/PDCH TS is in PDCH mode, deactivate PDCH first. */
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200454 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +0200455 && (lchan->ts->flags & TS_F_PDCH_ACTIVE)) {
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200456 /* store activation type and handover reference */
457 lchan->dyn_pdch.act_type = act_type;
458 lchan->dyn_pdch.ho_ref = ho_ref;
459 return rsl_ipacc_pdch_activate(lchan->ts, 0);
460 }
461
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200462 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
463
Andreas Eversberg3ca9af32013-10-11 12:55:35 +0200464 ta = lchan->rqd_ta;
465
466 /* BS11 requires TA shifted by 2 bits */
467 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11)
468 ta <<= 2;
469
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800470 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200471 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800472
Harald Welteed831842009-06-27 03:09:08 +0200473 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800474 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
475 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
476 dh->chan_nr = chan_nr;
477
478 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800479 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200480 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800481
482 /*
483 * The Channel Identification is needed for Phase1 phones
484 * and it contains the GSM48 Channel Description and the
485 * Mobile Allocation. The GSM 08.58 asks for the Mobile
486 * Allocation to have a length of zero. We are using the
487 * msgb_l3len to calculate the length of both messages.
488 */
laforgef723cf02010-06-20 21:38:19 +0200489 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200490 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200491 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800492
493 if (lchan->ts->hopping.enabled)
494 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
495 lchan->ts->hopping.ma_data);
496 else
497 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800498
499 /* update the calculated size */
500 msg->l3h = len + 1;
501 *len = msgb_l3len(msg);
502
Harald Welted2dd9de2009-08-30 15:37:11 +0900503 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200504 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900505 rc = build_encr_info(encr_info, lchan);
506 if (rc > 0)
507 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
508 }
509
Harald Welteb90d7bd2009-12-17 00:31:10 +0100510 switch (act_type) {
511 case RSL_ACT_INTER_ASYNC:
512 case RSL_ACT_INTER_SYNC:
513 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
514 break;
515 default:
516 break;
517 }
518
Harald Welte59b04682009-06-10 05:40:52 +0800519 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
520 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
521 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200522 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100523
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200524 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800525
526 return abis_rsl_sendmsg(msg);
527}
528
Harald Welte8e770492009-07-29 11:38:15 +0200529/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800530int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
531{
532 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200533 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200534 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800535
Harald Weltee6d51f92011-06-25 10:02:33 +0200536 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800537 struct rsl_ie_chan_mode cm;
538
Harald Welte39274f42009-07-29 15:41:29 +0200539 rc = channel_mode_from_lchan(&cm, lchan);
540 if (rc < 0)
541 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800542
Harald Welteed831842009-06-27 03:09:08 +0200543 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800544 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
545 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
546 dh->chan_nr = chan_nr;
547
548 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200549 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900550
551 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200552 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900553 rc = build_encr_info(encr_info, lchan);
554 if (rc > 0)
555 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
556 }
557
Holger Hans Peter Freytherae27c1b2015-08-20 19:32:46 +0200558 mr_config_for_bts(lchan, msg);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100559
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200560 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900561
562 return abis_rsl_sendmsg(msg);
563}
564
565/* Chapter 8.4.6: Send the encryption command with given L3 info */
566int rsl_encryption_cmd(struct msgb *msg)
567{
568 struct abis_rsl_dchan_hdr *dh;
569 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200570 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200571 uint8_t encr_info[MAX_A5_KEY_LEN+2];
572 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900573 int rc;
574
575 /* First push the L3 IE tag and length */
576 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
577
578 /* then the link identifier (SAPI0, main sign link) */
579 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
580
581 /* then encryption information */
582 rc = build_encr_info(encr_info, lchan);
583 if (rc <= 0)
584 return rc;
585 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
586
587 /* and finally the DCHAN header */
588 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
589 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
590 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800591
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200592 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800593
594 return abis_rsl_sendmsg(msg);
595}
596
Harald Welte85a163c2009-08-10 11:43:22 +0200597/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200598int rsl_deact_sacch(struct gsm_lchan *lchan)
599{
600 struct abis_rsl_dchan_hdr *dh;
601 struct msgb *msg = rsl_msgb_alloc();
602
603 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
604 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200605 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200606
607 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200608 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200609
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100610 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200611
612 return abis_rsl_sendmsg(msg);
613}
614
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800615static void error_timeout_cb(void *data)
616{
617 struct gsm_lchan *lchan = data;
618 if (lchan->state != LCHAN_S_REL_ERR) {
619 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
620 gsm_lchan_name(lchan), lchan->state);
621 return;
622 }
623
624 /* go back to the none state */
Harald Weltefddaba52012-11-13 04:26:22 +0100625 LOGP(DRSL, LOGL_INFO, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800626 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200627
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200628 /* Put PDCH channel back into PDCH mode, if GPRS is enabled */
629 if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH
630 && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE)
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200631 rsl_ipacc_pdch_activate(lchan->ts, 1);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800632}
633
Harald Welte08011e22011-03-04 13:41:31 +0100634static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
635
Harald Welte85a163c2009-08-10 11:43:22 +0200636/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100637static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
638 enum sacch_deact deact_sacch)
Harald Welte59b04682009-06-10 05:40:52 +0800639{
640 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800641 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100642 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800643
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100644 /* Stop timers that should lead to a channel release */
645 osmo_timer_del(&lchan->T3109);
646
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800647 if (lchan->state == LCHAN_S_REL_ERR) {
648 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
649 gsm_lchan_name(lchan));
650 return -1;
651 }
652
653 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800654 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
655 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200656 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800657
658 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200659 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800660
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800661 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
662
663 if (error) {
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100664 /*
665 * FIXME: GSM 04.08 gives us two options for the abnormal
666 * chanel release. This can be either like in the non-existent
667 * sub-lcuase 3.5.1 or for the main signalling link deactivate
668 * the SACCH, start timer T3109 and consider the channel as
669 * released.
670 *
671 * This code is doing the later for all raido links and not
672 * only the main link. Right now all SAPIs are released on the
673 * local end, the SACCH will be de-activated and right now the
674 * T3111 will be started. First T3109 should be started and then
675 * the T3111.
676 *
677 * TODO: Move this out of the function.
678 */
679
680 /*
681 * sacch de-activate and "local end release"
682 */
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +0100683 if (deact_sacch == SACCH_DEACTIVATE)
684 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +0100685 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
686
687 /*
688 * TODO: start T3109 now.
689 */
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800690 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800691 }
Harald Welte59b04682009-06-10 05:40:52 +0800692
Harald Welte32951ea2011-08-10 23:26:33 +0200693 /* Start another timer or assume the BTS sends a ACK/NACK? */
694 lchan->act_timer.cb = lchan_deact_tmr_cb;
695 lchan->act_timer.data = lchan;
696 osmo_timer_schedule(&lchan->act_timer, 4, 0);
697
Harald Welte08011e22011-03-04 13:41:31 +0100698 rc = abis_rsl_sendmsg(msg);
699
Harald Welte85a163c2009-08-10 11:43:22 +0200700 /* BTS will respond by RF CHAN REL ACK */
Harald Welte08011e22011-03-04 13:41:31 +0100701 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800702}
703
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +0200704/*
705 * Special handling for channel releases in the error case.
706 */
707static int rsl_rf_chan_release_err(struct gsm_lchan *lchan)
708{
709 if (lchan->state != LCHAN_S_ACTIVE)
710 return 0;
711 return rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
712}
713
Harald Welte9773f6c2011-01-14 14:16:16 +0100714static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
715{
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200716 struct gsm_bts_trx_ts *ts = lchan->ts;
Harald Welte9773f6c2011-01-14 14:16:16 +0100717
718 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
719
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100720 /* Stop all pending timers */
Harald Welte32951ea2011-08-10 23:26:33 +0200721 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freytherc22f2992012-12-06 19:09:58 +0100722 osmo_timer_del(&lchan->T3111);
Harald Welte32951ea2011-08-10 23:26:33 +0200723
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200724 /*
725 * The BTS didn't respond within the timeout to our channel
726 * release request and we have marked the channel as broken.
727 * Now we do receive an ACK and let's be conservative. If it
728 * is a sysmoBTS we know that only one RF Channel Release ACK
729 * will be sent. So let's "repair" the channel.
730 */
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200731 if (lchan->state == LCHAN_S_BROKEN) {
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200732 int do_free = is_sysmobts_v2(ts->trx->bts);
Holger Hans Peter Freyther6f8ae692015-04-04 19:35:22 +0200733 LOGP(DRSL, LOGL_NOTICE,
734 "%s CHAN REL ACK for broken channel. %s.\n",
735 gsm_lchan_name(lchan),
736 do_free ? "Releasing it" : "Keeping it broken");
737 if (do_free)
738 do_lchan_free(lchan);
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200739 return 0;
740 }
741
Harald Welte9773f6c2011-01-14 14:16:16 +0100742 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
743 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
744 gsm_lchan_name(lchan),
745 gsm_lchans_name(lchan->state));
Andreas Eversberg37c3a612013-10-11 13:32:30 +0200746
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +0200747 do_lchan_free(lchan);
748
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200749 /*
750 * Put a dynamic TCH/F_PDCH channel back to PDCH mode iff it was
751 * released successfully. If in error, the PDCH ACT will follow after
752 * T3111 in error_timeout_cb().
753 *
754 * Any state other than LCHAN_S_REL_ERR became LCHAN_S_NONE after above
755 * do_lchan_free(). Assert this, because that's what ensures a PDCH ACT
Neels Hofmeyrb3985cf2016-07-14 02:51:13 +0200756 * on a TCH/F_PDCH TS in all cases.
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200757 *
758 * If GPRS is disabled, always skip the PDCH ACT.
Neels Hofmeyr01cb40d2016-06-23 22:44:20 +0200759 */
760 OSMO_ASSERT(lchan->state == LCHAN_S_NONE
761 || lchan->state == LCHAN_S_REL_ERR);
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200762 if (ts->trx->bts->gprs.mode == BTS_GPRS_NONE)
Neels Hofmeyr31b26302016-07-06 14:39:04 +0200763 return 0;
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200764 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH
Neels Hofmeyrff1d7342016-06-21 20:55:14 +0200765 && lchan->state == LCHAN_S_NONE)
Neels Hofmeyraff130f2016-07-23 20:01:49 +0200766 return rsl_ipacc_pdch_activate(ts, 1);
Harald Welte9773f6c2011-01-14 14:16:16 +0100767 return 0;
768}
769
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200770int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
771 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800772{
773 struct abis_rsl_dchan_hdr *dh;
774 struct msgb *msg = rsl_msgb_alloc();
775
776 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
777 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
778 dh->chan_nr = RSL_CHAN_PCH_AGCH;
779
780 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
781 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
782 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
783
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200784 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800785
786 return abis_rsl_sendmsg(msg);
787}
788
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200789int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800790{
791 int i, len = strlen(str_in);
792
793 for (i = 0; i < len; i++) {
794 int num = str_in[i] - 0x30;
795 if (num < 0 || num > 9)
796 return -1;
797 if (i % 2 == 0)
798 bcd_out[i/2] = num;
799 else
800 bcd_out[i/2] |= (num << 4);
801 }
802
803 return 0;
804}
805
806/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200807int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800808{
809 struct msgb *msg = rsl_msgb_alloc();
810 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200811 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800812
813 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
814 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
815 dh->chan_nr = RSL_CHAN_PCH_AGCH;
816
817 switch (bts->type) {
818 case GSM_BTS_TYPE_BS11:
819 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
820 break;
821 default:
822 /* If phase 2, construct a FULL_IMM_ASS_INFO */
823 pad_macblock(buf, val, len);
824 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
825 break;
826 }
827
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200828 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800829
830 return abis_rsl_sendmsg(msg);
831}
832
Harald Welte4684e632009-08-10 09:51:40 +0200833/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200834int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200835{
836 struct msgb *msg = rsl_msgb_alloc();
837 struct abis_rsl_dchan_hdr *dh;
838
839 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
840 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200841 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200842 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200843 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200844
Harald Weltede4477a2009-12-24 12:20:20 +0100845 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200846 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200847
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200848 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +0200849
Harald Welte4684e632009-08-10 09:51:40 +0200850 return abis_rsl_sendmsg(msg);
851}
852
853
Harald Welte59b04682009-06-10 05:40:52 +0800854/* Send "DATA REQUEST" message with given L3 Info payload */
855/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200856int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800857{
Harald Welte59b04682009-06-10 05:40:52 +0800858 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100859 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800860 return -EINVAL;
861 }
862
Harald Weltee6d51f92011-06-25 10:02:33 +0200863 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100864 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800865
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200866 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800867
868 return abis_rsl_sendmsg(msg);
869}
870
Harald Welteed9a5ab2009-08-09 13:47:35 +0200871/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
872/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200873int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200874{
Harald Weltea22d36b2010-03-04 10:33:10 +0100875 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200876
Harald Weltee6d51f92011-06-25 10:02:33 +0200877 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100878 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200879 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200880
Harald Welte17091bd2012-04-26 19:42:19 +0200881 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
882 gsm_lchan_name(lchan), link_id);
883
Harald Welteed9a5ab2009-08-09 13:47:35 +0200884 return abis_rsl_sendmsg(msg);
885}
886
Andreas Eversbergac27b952013-12-05 13:25:06 +0100887static void rsl_handle_release(struct gsm_lchan *lchan);
888
889/* Special work handler to handle missing RSL_MT_REL_CONF message from
890 * Nokia InSite BTS */
891static void lchan_rel_work_cb(void *data)
892{
893 struct gsm_lchan *lchan = data;
894 int sapi;
895
896 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
897 if (lchan->sapis[sapi] == LCHAN_SAPI_REL)
898 lchan->sapis[sapi] = LCHAN_SAPI_UNUSED;
899 }
900 rsl_handle_release(lchan);
901}
902
Harald Welte0f2e3c12009-08-08 13:15:07 +0200903/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
904 This is what higher layers should call. The BTS then responds with
905 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
906 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
907 lchan_free() */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100908int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
909 enum rsl_rel_mode release_mode)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200910{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200911
Harald Weltea22d36b2010-03-04 10:33:10 +0100912 struct msgb *msg;
913
Harald Weltee6d51f92011-06-25 10:02:33 +0200914 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100915 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800916 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100917 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200918
Harald Weltec88a4432009-12-29 10:44:17 +0100919 /* FIXME: start some timer in case we don't receive a REL ACK ? */
920
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200921 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200922
Harald Welte17091bd2012-04-26 19:42:19 +0200923 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther2806c792012-12-06 12:01:38 +0100924 gsm_lchan_name(lchan), link_id, release_mode);
Harald Welte17091bd2012-04-26 19:42:19 +0200925
Andreas Eversbergac27b952013-12-05 13:25:06 +0100926 abis_rsl_sendmsg(msg);
927
928 /* Do not wait for Nokia BTS to send the confirm. */
929 if (is_nokia_bts(lchan->ts->trx->bts)
930 && lchan->ts->trx->bts->nokia.no_loc_rel_cnf
931 && release_mode == RSL_REL_LOCAL_END) {
932 DEBUGP(DRLL, "Scheduling release, becasuse Nokia InSite BTS does not send a RELease CONFirm.\n");
933 lchan->sapis[link_id & 0x7] = LCHAN_SAPI_REL;
934 lchan->rel_work.cb = lchan_rel_work_cb;
935 lchan->rel_work.data = lchan;
936 osmo_timer_schedule(&lchan->rel_work, 0, 0);
937 }
938
939 return 0;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200940}
941
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +0100942int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
943{
944 lchan->state = LCHAN_S_BROKEN;
945 lchan->broken_reason = reason;
946 return 0;
947}
948
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200949int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
950{
Neels Hofmeyra4353c82016-06-21 21:34:46 +0200951 DEBUGP(DRSL, "%s state %s -> %s\n",
952 gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
953 gsm_lchans_name(state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200954 lchan->state = state;
955 return 0;
956}
957
Harald Welte59b04682009-06-10 05:40:52 +0800958/* Chapter 8.4.2: Channel Activate Acknowledge */
959static int rsl_rx_chan_act_ack(struct msgb *msg)
960{
961 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200962 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +0800963
964 /* BTS has confirmed channel activation, we now need
965 * to assign the activated channel to the MS */
966 if (rslh->ie_chan != RSL_IE_CHAN_NR)
967 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100968
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200969 osmo_timer_del(&lchan->act_timer);
Harald Welte32951ea2011-08-10 23:26:33 +0200970
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200971 if (lchan->state == LCHAN_S_BROKEN) {
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200972 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel.\n",
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200973 gsm_lchan_name(lchan));
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +0200974 return 0;
975 }
976
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200977 if (lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100978 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200979 gsm_lchan_name(lchan),
980 gsm_lchans_name(lchan->state));
981 rsl_lchan_set_state(lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100982
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200983 if (lchan->rqd_ref) {
984 rsl_send_imm_assignment(lchan);
985 talloc_free(lchan->rqd_ref);
986 lchan->rqd_ref = NULL;
987 lchan->rqd_ta = 0;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800988 }
989
Neels Hofmeyrdc997402016-07-14 16:16:33 +0200990 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100991
Harald Welte59b04682009-06-10 05:40:52 +0800992 return 0;
993}
994
995/* Chapter 8.4.3: Channel Activate NACK */
996static int rsl_rx_chan_act_nack(struct msgb *msg)
997{
998 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
999 struct tlv_parsed tp;
1000
Harald Welte32951ea2011-08-10 23:26:33 +02001001 osmo_timer_del(&msg->lchan->act_timer);
1002
Holger Hans Peter Freytherbd5f21f2013-05-01 18:44:04 +02001003 if (msg->lchan->state == LCHAN_S_BROKEN) {
1004 LOGP(DRSL, LOGL_ERROR,
1005 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
1006 gsm_lchan_name(msg->lchan));
1007 return -1;
1008 }
1009
Daniel Willmann9e9d44c2011-08-11 04:54:23 +02001010 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001011 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001012
Harald Welte59b04682009-06-10 05:40:52 +08001013 /* BTS has rejected channel activation ?!? */
1014 if (dh->ie_chan != RSL_IE_CHAN_NR)
1015 return -EINVAL;
1016
1017 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001018 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001019 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001020 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +02001021 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther5149c172012-12-06 19:25:06 +01001022 msg->lchan->error_cause = *cause;
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001023 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
1024 rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
1025 } else
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001026 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann245ee032011-08-11 04:47:11 +02001027
Holger Hans Peter Freyther960adfe2014-12-28 12:08:28 +01001028 } else {
1029 rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
1030 }
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001031
Harald Welte (local)ed6d7622009-12-27 11:48:11 +01001032 LOGPC(DRSL, LOGL_ERROR, "\n");
1033
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001034 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte59b04682009-06-10 05:40:52 +08001035 return 0;
1036}
1037
1038/* Chapter 8.4.4: Connection Failure Indication */
1039static int rsl_rx_conn_fail(struct msgb *msg)
1040{
1041 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1042 struct tlv_parsed tp;
1043
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001044 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING state %s ",
1045 gsm_lchan_name(msg->lchan),
1046 gsm_lchans_name(msg->lchan->state));
1047
Harald Welte59b04682009-06-10 05:40:52 +08001048 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1049
Harald Weltef1a168d2009-07-28 17:58:09 +02001050 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001051 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001052 TLVP_LEN(&tp, RSL_IE_CAUSE));
1053
Harald Welte (local)4bd76642009-12-26 22:33:09 +01001054 LOGPC(DRSL, LOGL_NOTICE, "\n");
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001055 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001056 return rsl_rf_chan_release_err(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001057}
1058
Harald Weltec20bd1d2009-11-29 19:07:28 +01001059static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1060 const char *prefix)
1061{
Harald Welte0e4fa782009-12-16 16:52:07 +01001062 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1063 prefix, rxlev2dbm(mru->full.rx_lev),
1064 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +01001065 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1066 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1067}
1068
Harald Welte50290cc2012-07-02 17:12:08 +02001069static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +01001070{
Harald Welte0e4fa782009-12-16 16:52:07 +01001071 int i;
Harald Welte50290cc2012-07-02 17:12:08 +02001072 char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +01001073
Harald Welteb764f1c2015-12-28 14:04:36 +01001074 if (lchan && lchan->conn)
Harald Welte50290cc2012-07-02 17:12:08 +02001075 name = subscr_name(lchan->conn->subscr);
1076
1077 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001078
1079 if (mr->flags & MEAS_REP_F_DL_DTX)
1080 DEBUGPC(DMEAS, "DTXd ");
1081
1082 print_meas_rep_uni(&mr->ul, "ul");
1083 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1084 if (mr->flags & MEAS_REP_F_MS_TO)
1085 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1086
1087 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +01001088 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001089 DEBUGPC(DMEAS, "L1_FPC=%u ",
1090 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1091 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1092 }
1093
1094 if (mr->flags & MEAS_REP_F_UL_DTX)
1095 DEBUGPC(DMEAS, "DTXu ");
1096 if (mr->flags & MEAS_REP_F_BA1)
1097 DEBUGPC(DMEAS, "BA1 ");
1098 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1099 DEBUGPC(DMEAS, "NOT VALID ");
1100 else
1101 print_meas_rep_uni(&mr->dl, "dl");
1102
1103 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +01001104 if (mr->num_cell == 7)
1105 return;
Harald Welte0e4fa782009-12-16 16:52:07 +01001106 for (i = 0; i < mr->num_cell; i++) {
1107 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +01001108 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1109 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001110 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001111}
1112
Harald Welte59b04682009-06-10 05:40:52 +08001113static int rsl_rx_meas_res(struct msgb *msg)
1114{
1115 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1116 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001117 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001118 uint8_t len;
1119 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001120 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001121
Harald Welte4baa9c52009-12-21 13:27:11 +01001122 /* check if this channel is actually active */
1123 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001124 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001125 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001126 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001127 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001128 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001129
Harald Weltef9476812009-12-15 21:36:05 +01001130 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001131 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001132
Harald Welte59b04682009-06-10 05:40:52 +08001133 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1134
Harald Weltec20bd1d2009-11-29 19:07:28 +01001135 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1136 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1137 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1138 return -EIO;
1139
1140 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001141 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001142
1143 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1144 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1145 if (len >= 3) {
1146 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001147 mr->flags |= MEAS_REP_F_DL_DTX;
1148 mr->ul.full.rx_lev = val[0] & 0x3f;
1149 mr->ul.sub.rx_lev = val[1] & 0x3f;
1150 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1151 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001152 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001153
Harald Weltef9476812009-12-15 21:36:05 +01001154 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001155
1156 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +08001157 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +01001158 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +01001159 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1160
Harald Weltea1467eb2009-06-20 18:44:35 +02001161 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001162 struct e1inp_sign_link *sign_link = msg->dst;
1163
Harald Weltec20bd1d2009-11-29 19:07:28 +01001164 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001165 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001166 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001167 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001168 mr->flags |= MEAS_REP_F_FPC;
1169 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001170 /* BS11 and Nokia reports TA shifted by 2 bits */
1171 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1172 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001173 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001174 }
Harald Welte59b04682009-06-10 05:40:52 +08001175 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001176 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001177 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001178 if (rc < 0)
1179 return rc;
1180 }
1181
Harald Welte50290cc2012-07-02 17:12:08 +02001182 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001183
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001184 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001185
Harald Welte59b04682009-06-10 05:40:52 +08001186 return 0;
1187}
1188
Harald Welte6720a432009-11-29 22:45:52 +01001189/* Chapter 8.4.7 */
1190static int rsl_rx_hando_det(struct msgb *msg)
1191{
1192 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1193 struct tlv_parsed tp;
1194
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001195 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001196
1197 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1198
1199 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1200 DEBUGPC(DRSL, "access delay = %u\n",
1201 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1202 else
1203 DEBUGPC(DRSL, "\n");
1204
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001205 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001206
1207 return 0;
1208}
1209
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001210static bool lchan_may_change_pdch(struct gsm_lchan *lchan, bool pdch_act)
1211{
1212 struct gsm_bts_trx_ts *ts;
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001213
1214 OSMO_ASSERT(lchan);
1215
1216 ts = lchan->ts;
1217 OSMO_ASSERT(ts);
1218 OSMO_ASSERT(ts->trx);
1219 OSMO_ASSERT(ts->trx->bts);
1220
1221 if (lchan->ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
Neels Hofmeyr50c2bd42016-06-21 20:53:27 +02001222 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1223 " for channel that is no TCH/F_PDCH\n",
1224 gsm_lchan_name(lchan),
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001225 gsm_pchan_name(ts->pchan),
1226 pdch_act? "ACT" : "DEACT");
1227 return false;
1228 }
1229
Neels Hofmeyr10b0f1d2016-06-14 13:12:00 +02001230 if (lchan->state != LCHAN_S_NONE) {
Neels Hofmeyr50c2bd42016-06-21 20:53:27 +02001231 LOGP(DRSL, LOGL_ERROR, "%s pchan=%s Rx PDCH %s ACK"
1232 " in unexpected state: %s\n",
1233 gsm_lchan_name(lchan),
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001234 gsm_pchan_name(ts->pchan),
1235 pdch_act? "ACT" : "DEACT",
1236 gsm_lchans_name(lchan->state));
1237 return false;
1238 }
1239 return true;
1240}
1241
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001242static int rsl_rx_pdch_act_ack(struct msgb *msg)
1243{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001244 if (!lchan_may_change_pdch(msg->lchan, true))
1245 return -EINVAL;
1246
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001247 msg->lchan->ts->flags |= TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001248 msg->lchan->ts->flags &= ~TS_F_PDCH_ACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001249
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001250 return 0;
1251}
1252
1253static int rsl_rx_pdch_deact_ack(struct msgb *msg)
1254{
Neels Hofmeyr6297b742016-06-13 12:28:21 +02001255 if (!lchan_may_change_pdch(msg->lchan, false))
1256 return -EINVAL;
1257
Neels Hofmeyr5a3c23c2016-06-14 14:08:35 +02001258 msg->lchan->ts->flags &= ~TS_F_PDCH_ACTIVE;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02001259 msg->lchan->ts->flags &= ~TS_F_PDCH_DEACT_PENDING;
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001260
1261 rsl_chan_activate_lchan(msg->lchan, msg->lchan->dyn_pdch.act_type,
1262 msg->lchan->dyn_pdch.ho_ref);
1263
1264 return 0;
1265}
1266
Harald Welte59b04682009-06-10 05:40:52 +08001267static int abis_rsl_rx_dchan(struct msgb *msg)
1268{
1269 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1270 int rc = 0;
1271 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001272 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001273
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001274 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001275 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001276
Harald Welte59b04682009-06-10 05:40:52 +08001277 switch (rslh->c.msg_type) {
1278 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001279 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001280 rc = rsl_rx_chan_act_ack(msg);
1281 break;
1282 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001283 rc = rsl_rx_chan_act_nack(msg);
1284 break;
1285 case RSL_MT_CONN_FAIL:
1286 rc = rsl_rx_conn_fail(msg);
1287 break;
1288 case RSL_MT_MEAS_RES:
1289 rc = rsl_rx_meas_res(msg);
1290 break;
Harald Welte6720a432009-11-29 22:45:52 +01001291 case RSL_MT_HANDO_DET:
1292 rc = rsl_rx_hando_det(msg);
1293 break;
Harald Welte59b04682009-06-10 05:40:52 +08001294 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001295 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001296 break;
1297 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001298 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001299 break;
1300 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001301 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001302 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001303 case RSL_MT_IPAC_PDCH_ACT_ACK:
Neels Hofmeyr6b272302016-05-31 17:51:41 +02001304 DEBUGP(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001305 rc = rsl_rx_pdch_act_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001306 break;
1307 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001308 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001309 break;
1310 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001311 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Andreas Eversberg37c3a612013-10-11 13:32:30 +02001312 rc = rsl_rx_pdch_deact_ack(msg);
Harald Welteaed946e2009-10-24 10:29:22 +02001313 break;
1314 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001315 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001316 break;
Harald Welte59b04682009-06-10 05:40:52 +08001317 case RSL_MT_PHY_CONTEXT_CONF:
1318 case RSL_MT_PREPROC_MEAS_RES:
1319 case RSL_MT_TALKER_DET:
1320 case RSL_MT_LISTENER_DET:
1321 case RSL_MT_REMOTE_CODEC_CONF_REP:
1322 case RSL_MT_MR_CODEC_MOD_ACK:
1323 case RSL_MT_MR_CODEC_MOD_NACK:
1324 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001325 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1326 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001327 break;
1328 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001329 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1330 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001331 return -EINVAL;
1332 }
1333
1334 return rc;
1335}
1336
1337static int rsl_rx_error_rep(struct msgb *msg)
1338{
1339 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001340 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001341 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001342
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001343 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001344
1345 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1346
1347 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001348 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001349 TLVP_LEN(&tp, RSL_IE_CAUSE));
1350
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001351 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001352
1353 return 0;
1354}
1355
1356static int abis_rsl_rx_trx(struct msgb *msg)
1357{
1358 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001359 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001360 int rc = 0;
1361
1362 switch (rslh->msg_type) {
1363 case RSL_MT_ERROR_REPORT:
1364 rc = rsl_rx_error_rep(msg);
1365 break;
1366 case RSL_MT_RF_RES_IND:
1367 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001368 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001369 break;
1370 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001371 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001372 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001373 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001374 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001375 case 0x42: /* Nokia specific: SI End ACK */
1376 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1377 break;
1378 case 0x43: /* Nokia specific: SI End NACK */
1379 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1380 break;
Harald Welte59b04682009-06-10 05:40:52 +08001381 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001382 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001383 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001384 return -EINVAL;
1385 }
1386 return rc;
1387}
1388
Harald Welte427dbc42009-08-10 00:26:10 +02001389/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1390static void t3101_expired(void *data)
1391{
1392 struct gsm_lchan *lchan = data;
1393
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001394 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welte427dbc42009-08-10 00:26:10 +02001395}
1396
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001397/* If T3111 expires, we will send the RF Channel Request */
1398static void t3111_expired(void *data)
1399{
1400 struct gsm_lchan *lchan = data;
1401
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001402 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1403}
1404
1405/* If T3109 expires the MS has not send a UA/UM do the error release */
1406static void t3109_expired(void *data)
1407{
1408 struct gsm_lchan *lchan = data;
1409
1410 LOGP(DRSL, LOGL_ERROR,
1411 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1412 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001413}
1414
Harald Weltea00fdd72010-12-23 14:39:29 +01001415/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1416static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1417 unsigned int num_req_refs,
1418 struct gsm48_req_ref *rqd_refs,
1419 uint8_t wait_ind)
1420{
1421 uint8_t buf[GSM_MACBLOCK_LEN];
1422 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1423
1424 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1425 memset(iar, 0, sizeof(*iar));
1426 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001427 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Weltea00fdd72010-12-23 14:39:29 +01001428 iar->page_mode = GSM48_PM_SAME;
1429
1430 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1431 iar->wait_ind1 = wait_ind;
1432
1433 if (num_req_refs >= 2)
1434 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1435 else
1436 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1437 iar->wait_ind2 = wait_ind;
1438
1439 if (num_req_refs >= 3)
1440 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1441 else
1442 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1443 iar->wait_ind3 = wait_ind;
1444
1445 if (num_req_refs >= 4)
1446 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1447 else
1448 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1449 iar->wait_ind4 = wait_ind;
1450
Andreas Eversbergdee934a2013-02-07 11:51:16 +01001451 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1452 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1453
1454 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Weltea00fdd72010-12-23 14:39:29 +01001455}
1456
Harald Welte59b04682009-06-10 05:40:52 +08001457/* MS has requested a channel on the RACH */
1458static int rsl_rx_chan_rqd(struct msgb *msg)
1459{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001460 struct e1inp_sign_link *sign_link = msg->dst;
1461 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001462 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1463 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001464 enum gsm_chan_t lctype;
1465 enum gsm_chreq_reason_t chreq_reason;
1466 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001467 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001468 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001469
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001470 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001471 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001472
1473 /* parse request reference to be used in immediate assign */
1474 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1475 return -EINVAL;
1476
1477 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1478
1479 /* parse access delay and use as TA */
1480 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1481 return -EINVAL;
1482 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1483
1484 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1485 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001486 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1487 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001488
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001489 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001490
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001491 /*
1492 * We want LOCATION UPDATES to succeed and will assign a TCH
1493 * if we have no SDCCH available.
1494 */
1495 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1496
Harald Welte59b04682009-06-10 05:40:52 +08001497 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001498 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001499 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001500 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001501 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001502 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001503 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1504 if (bts->network->T3122)
1505 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Weltecf7c90c2012-11-13 04:46:03 +01001506 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001507 }
1508
Harald Weltec88a4432009-12-29 10:44:17 +01001509 if (lchan->state != LCHAN_S_NONE)
1510 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001511 "in state %s\n", gsm_lchan_name(lchan),
1512 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001513
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001514 /* save the RACH data as we need it after the CHAN ACT ACK */
1515 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1516 if (!lchan->rqd_ref) {
1517 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1518 lchan_free(lchan);
1519 return -ENOMEM;
1520 }
1521
1522 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1523 lchan->rqd_ta = rqd_ta;
1524
Harald Welte59b04682009-06-10 05:40:52 +08001525 arfcn = lchan->ts->trx->arfcn;
1526 subch = lchan->nr;
1527
Harald Welted2dd9de2009-08-30 15:37:11 +09001528 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001529 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001530 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001531 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001532 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001533
Harald Welte32951ea2011-08-10 23:26:33 +02001534 /* Start another timer or assume the BTS sends a ACK/NACK? */
1535 lchan->act_timer.cb = lchan_act_tmr_cb;
1536 lchan->act_timer.data = lchan;
1537 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1538
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001539 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1540 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1541 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1542 rqd_ref->ra, rqd_ta);
1543
Neels Hofmeyrfe9fdfa2016-07-15 01:26:03 +02001544 rsl_chan_activate_lchan(lchan, RSL_ACT_INTRA_IMM_ASS, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001545
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001546 return 0;
1547}
1548
1549static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1550{
1551 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001552 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001553 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1554
Harald Welte59b04682009-06-10 05:40:52 +08001555 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001556 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001557 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001558 ia->proto_discr = GSM48_PDISC_RR;
1559 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1560 ia->page_mode = GSM48_PM_SAME;
1561 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001562
Harald Welte59b04682009-06-10 05:40:52 +08001563 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001564 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1565 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001566 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001567 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001568 } else {
laforgee06d5982010-06-20 15:18:46 +02001569 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1570 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001571 }
Harald Welte07f32182010-06-28 18:41:27 +02001572 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1573 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001574
Harald Welte427dbc42009-08-10 00:26:10 +02001575 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1576 lchan->T3101.cb = t3101_expired;
1577 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001578 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001579
1580 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001581 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001582}
1583
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001584/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001585static int rsl_rx_ccch_load(struct msgb *msg)
1586{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001587 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001588 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001589 struct ccch_signal_data sd;
1590
1591 sd.bts = sign_link->trx->bts;
1592 sd.rach_slot_count = -1;
1593 sd.rach_busy_count = -1;
1594 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001595
1596 switch (rslh->data[0]) {
1597 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001598 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1599 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001600 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001601 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001602 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001603 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1604 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001605 break;
1606 case RSL_IE_RACH_LOAD:
1607 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001608 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1609 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1610 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1611 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001612 }
1613 break;
1614 default:
1615 break;
1616 }
1617
1618 return 0;
1619}
1620
1621static int abis_rsl_rx_cchan(struct msgb *msg)
1622{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001623 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001624 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1625 int rc = 0;
1626
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001627 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001628
1629 switch (rslh->c.msg_type) {
1630 case RSL_MT_CHAN_RQD:
1631 /* MS has requested a channel on the RACH */
1632 rc = rsl_rx_chan_rqd(msg);
1633 break;
1634 case RSL_MT_CCCH_LOAD_IND:
1635 /* current load on the CCCH */
1636 rc = rsl_rx_ccch_load(msg);
1637 break;
1638 case RSL_MT_DELETE_IND:
1639 /* CCCH overloaded, IMM_ASSIGN was dropped */
1640 case RSL_MT_CBCH_LOAD_IND:
1641 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001642 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1643 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001644 break;
1645 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001646 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1647 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001648 return -EINVAL;
1649 }
1650
1651 return rc;
1652}
1653
1654static int rsl_rx_rll_err_ind(struct msgb *msg)
1655{
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001656 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001657 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001658 uint8_t rlm_cause;
Harald Welte59b04682009-06-10 05:40:52 +08001659
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001660 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1661 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1662 LOGP(DRLL, LOGL_ERROR,
1663 "%s ERROR INDICATION without mandantory cause.\n",
1664 gsm_lchan_name(msg->lchan));
1665 return -1;
1666 }
1667
1668 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001669 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s in state=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001670 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freytherde4da292014-04-19 16:45:36 +02001671 rsl_rlm_cause_name(rlm_cause),
1672 gsm_lchans_name(msg->lchan->state));
1673
Harald Welteed9a5ab2009-08-09 13:47:35 +02001674 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001675
Holger Hans Peter Freyther80abe252013-01-16 21:07:43 +01001676 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001677 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther29eb19b2014-04-19 17:38:33 +02001678 return rsl_rf_chan_release_err(msg->lchan);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001679 }
Harald Welte692f5852009-07-04 09:40:05 +02001680
Harald Welte59b04682009-06-10 05:40:52 +08001681 return 0;
1682}
1683
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001684static void rsl_handle_release(struct gsm_lchan *lchan)
1685{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001686 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001687 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001688
Holger Hans Peter Freyther701a6472011-12-28 12:11:40 +01001689 /*
1690 * Maybe only one link/SAPI was releasd or the error handling
1691 * was activated. Just return now and let the other code handle
1692 * it.
1693 */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001694 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001695 return;
1696
1697 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1698 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1699 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001700 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001701 gsm_lchan_name(lchan), sapi);
1702 return;
1703 }
1704
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001705
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01001706 /* Stop T3109 and wait for T3111 before re-using the channel */
1707 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001708 lchan->T3111.cb = t3111_expired;
1709 lchan->T3111.data = lchan;
1710 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001711 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001712}
1713
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001714/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001715 0x02, 0x06,
1716 0x01, 0x20,
1717 0x02, 0x00,
1718 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1719
1720static int abis_rsl_rx_rll(struct msgb *msg)
1721{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001722 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001723 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1724 int rc = 0;
1725 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001726 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001727
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001728 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001729 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001730 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001731
1732 switch (rllh->c.msg_type) {
1733 case RSL_MT_DATA_IND:
1734 DEBUGPC(DRLL, "DATA INDICATION\n");
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;
1742 case RSL_MT_EST_IND:
1743 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001744 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001745 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001746 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001747 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001748 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1749 rllh->data[0] == RSL_IE_L3_INFO) {
1750 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001751 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001752 }
1753 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001754 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001755 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001756 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001757 rll_indication(msg->lchan, rllh->link_id,
1758 BSC_RLLR_IND_EST_CONF);
1759 break;
Harald Welte59b04682009-06-10 05:40:52 +08001760 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001761 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001762 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001763 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001764 rll_indication(msg->lchan, rllh->link_id,
1765 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001766 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001767 break;
1768 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001769 /* BTS informs us of having received UA from MS,
1770 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001771 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001772 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001773 rsl_handle_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001774 break;
1775 case RSL_MT_ERROR_IND:
Neels Hofmeyr6fcad252016-07-26 19:39:43 +02001776 DEBUGPC(DRLL, "ERROR INDICATION\n");
Harald Welte59b04682009-06-10 05:40:52 +08001777 rc = rsl_rx_rll_err_ind(msg);
1778 break;
1779 case RSL_MT_UNIT_DATA_IND:
Neels Hofmeyr6fcad252016-07-26 19:39:43 +02001780 DEBUGPC(DRLL, "UNIT DATA INDICATION\n");
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001781 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1782 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001783 break;
1784 default:
Neels Hofmeyr6fcad252016-07-26 19:39:43 +02001785 DEBUGPC(DRLL, "UNKNOWN\n");
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001786 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1787 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001788 }
Harald Welte59b04682009-06-10 05:40:52 +08001789 return rc;
1790}
1791
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001792static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001793{
Harald Welteb284b472009-12-02 01:58:23 +05301794 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001795 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301796 switch (lchan->type) {
1797 case GSM_LCHAN_TCH_F:
1798 return 0x00;
1799 case GSM_LCHAN_TCH_H:
1800 return 0x03;
1801 default:
1802 break;
1803 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001804 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001805 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301806 switch (lchan->type) {
1807 case GSM_LCHAN_TCH_F:
1808 return 0x01;
1809 /* there's no half-rate EFR */
1810 default:
1811 break;
1812 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001813 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001814 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301815 switch (lchan->type) {
1816 case GSM_LCHAN_TCH_F:
1817 return 0x02;
1818 case GSM_LCHAN_TCH_H:
1819 return 0x05;
1820 default:
1821 break;
1822 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001823 break;
Harald Welteb284b472009-12-02 01:58:23 +05301824 default:
1825 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001826 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001827 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301828 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001829 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001830}
1831
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001832static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001833{
1834 switch (lchan->tch_mode) {
1835 case GSM48_CMODE_SPEECH_V1:
1836 switch (lchan->type) {
1837 case GSM_LCHAN_TCH_F:
1838 return RTP_PT_GSM_FULL;
1839 case GSM_LCHAN_TCH_H:
1840 return RTP_PT_GSM_HALF;
1841 default:
1842 break;
1843 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001844 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001845 case GSM48_CMODE_SPEECH_EFR:
1846 switch (lchan->type) {
1847 case GSM_LCHAN_TCH_F:
1848 return RTP_PT_GSM_EFR;
1849 /* there's no half-rate EFR */
1850 default:
1851 break;
1852 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001853 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001854 case GSM48_CMODE_SPEECH_AMR:
1855 switch (lchan->type) {
1856 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01001857 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02001858 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001859 default:
1860 break;
1861 }
Holger Hans Peter Freythere5236092014-04-04 12:14:55 +02001862 break;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001863 default:
1864 break;
1865 }
1866 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1867 "tch_mode == 0x%02x\n & lchan_type == %d",
1868 lchan->tch_mode, lchan->type);
1869 return 0;
1870}
1871
Harald Welte59b04682009-06-10 05:40:52 +08001872/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001873static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1874{
1875 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001876 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001877
1878 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001879 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_LOCAL_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01001880 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1881 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1882 }
1883
1884 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001885 port = tlvp_val16_unal(tv, RSL_IE_IPAC_LOCAL_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01001886 port = ntohs(port);
1887 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1888 lchan->abis_ip.bound_port = port;
1889 }
1890
1891 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001892 conn_id = tlvp_val16_unal(tv, RSL_IE_IPAC_CONN_ID);
Harald Weltebffa4992009-12-19 16:42:06 +01001893 conn_id = ntohs(conn_id);
1894 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1895 lchan->abis_ip.conn_id = conn_id;
1896 }
1897
1898 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1899 lchan->abis_ip.rtp_payload2 =
1900 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1901 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1902 lchan->abis_ip.rtp_payload2);
1903 }
1904
1905 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1906 lchan->abis_ip.speech_mode =
1907 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1908 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1909 lchan->abis_ip.speech_mode);
1910 }
1911
1912 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001913 ip.s_addr = tlvp_val32_unal(tv, RSL_IE_IPAC_REMOTE_IP);
Harald Weltebffa4992009-12-19 16:42:06 +01001914 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1915 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1916 }
1917
1918 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Daniel Willmannb97c9d12014-06-27 17:05:47 +02001919 port = tlvp_val16_unal(tv, RSL_IE_IPAC_REMOTE_PORT);
Harald Weltebffa4992009-12-19 16:42:06 +01001920 port = ntohs(port);
1921 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1922 lchan->abis_ip.connect_port = port;
1923 }
1924}
1925
Harald Welte9a696d72013-02-03 12:06:58 +01001926/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1927 * \param[in] lchan Logical Channel for which we issue CRCX
1928 */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001929int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001930{
1931 struct msgb *msg = rsl_msgb_alloc();
1932 struct abis_rsl_dchan_hdr *dh;
1933
1934 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001935 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001936 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001937 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001938
Harald Welte98d79f92009-07-28 18:11:56 +02001939 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001940 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001941 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001942 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001943 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001944
Sylvain Munaut1338a552009-12-20 22:06:40 +01001945 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1946 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1947 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001948
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001949 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001950
1951 return abis_rsl_sendmsg(msg);
1952}
1953
Harald Welte9a696d72013-02-03 12:06:58 +01001954/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1955 * \param[in] lchan Logical Channel for which we issue MDCX
1956 * \param[in] ip Remote (MGW) IP address for RTP
1957 * \param[in] port Remote (MGW) UDP port number for RTP
1958 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1959 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001960int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1961 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001962{
1963 struct msgb *msg = rsl_msgb_alloc();
1964 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001965 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001966 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001967
1968 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001969 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001970 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001971 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001972
Harald Weltebffa4992009-12-19 16:42:06 +01001973 /* we need to store these now as MDCX_ACK does not return them :( */
1974 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1975 lchan->abis_ip.connect_port = port;
1976 lchan->abis_ip.connect_ip = ip;
1977
Harald Weltefb4a9e92009-07-29 12:12:18 +02001978 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001979 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001980 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001981
Harald Welte98d79f92009-07-28 18:11:56 +02001982 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001983 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1984 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1985 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1986 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001987
Harald Weltebffa4992009-12-19 16:42:06 +01001988 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1989 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001990 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001991 *att_ip = ia.s_addr;
1992 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1993 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001994 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001995 if (rtp_payload2)
1996 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001997
1998 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001999
2000 return abis_rsl_sendmsg(msg);
2001}
2002
Harald Welte9947d9f2009-12-20 16:51:09 +01002003/* tell BTS to connect RTP stream to our local RTP socket */
2004int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
2005{
2006 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
2007 int rc;
2008
2009 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
2010 ntohs(rs->rtp.sin_local.sin_port),
2011 /* FIXME: use RTP payload of bound socket, not BTS*/
2012 lchan->abis_ip.rtp_payload2);
2013
2014 return rc;
2015}
2016
Harald Welte6f40df02010-12-23 12:59:52 +01002017int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02002018{
2019 struct msgb *msg = rsl_msgb_alloc();
2020 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02002021 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08002022
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002023 if (ts->flags & TS_F_PDCH_PENDING_MASK) {
2024 LOGP(DRSL, LOGL_ERROR,
2025 "%s PDCH %s requested, but a PDCH%s%s is still pending\n",
2026 gsm_ts_name(ts),
2027 act ? "ACT" : "DEACT",
2028 ts->flags & TS_F_PDCH_ACT_PENDING? " ACT" : "",
2029 ts->flags & TS_F_PDCH_DEACT_PENDING? " DEACT" : "");
2030 return -EINVAL;
2031 }
2032
2033 if (act){
Neels Hofmeyr31b26302016-07-06 14:39:04 +02002034 /* Callers should heed the GPRS mode. */
2035 OSMO_ASSERT(ts->trx->bts->gprs.mode != BTS_GPRS_NONE);
Harald Welte2b361522010-03-28 14:42:09 +08002036 msg_type = RSL_MT_IPAC_PDCH_ACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002037 ts->flags |= TS_F_PDCH_ACT_PENDING;
2038 } else {
Harald Welte2b361522010-03-28 14:42:09 +08002039 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Neels Hofmeyr1d9a3aa2016-06-15 15:32:29 +02002040 ts->flags |= TS_F_PDCH_DEACT_PENDING;
2041 }
2042 /* TODO add timeout to cancel PDCH DE/ACT */
Harald Welteaed946e2009-10-24 10:29:22 +02002043
2044 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08002045 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02002046 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02002047 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02002048
Neels Hofmeyr6b272302016-05-31 17:51:41 +02002049 DEBUGP(DRSL, "%s IPAC PDCH %sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08002050 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02002051
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002052 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02002053
2054 return abis_rsl_sendmsg(msg);
2055}
2056
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002057static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002058{
2059 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2060 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05302061 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08002062
2063 /* the BTS has acknowledged a local bind, it now tells us the IP
2064 * address and port number to which it has bound the given logical
2065 * channel */
2066
2067 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2068 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
2069 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02002070 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002071 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08002072 return -EINVAL;
2073 }
Harald Welte50517742009-12-20 15:42:44 +01002074
Harald Weltebffa4992009-12-19 16:42:06 +01002075 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01002076
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002077 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002078
2079 return 0;
2080}
2081
Harald Weltebffa4992009-12-19 16:42:06 +01002082static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
2083{
2084 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2085 struct tlv_parsed tv;
2086 struct gsm_lchan *lchan = msg->lchan;
2087
2088 /* the BTS has acknowledged a remote connect request and
2089 * it now tells us the IP address and port number to which it has
2090 * connected the given logical channel */
2091
2092 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
2093 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002094 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01002095
2096 return 0;
2097}
2098
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002099static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08002100{
2101 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
2102 struct tlv_parsed tv;
2103
2104 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08002105
Harald Weltef1a168d2009-07-28 17:58:09 +02002106 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01002107 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02002108 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08002109
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02002110 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02002111
Harald Welte59b04682009-06-10 05:40:52 +08002112 return 0;
2113}
2114
2115static int abis_rsl_rx_ipacc(struct msgb *msg)
2116{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002117 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08002118 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01002119 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08002120 int rc = 0;
2121
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002122 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01002123 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002124
2125 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002126 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01002127 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002128 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002129 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002130 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002131 /* somehow the BTS was unable to bind the lchan to its local
2132 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01002133 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002134 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002135 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08002136 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01002137 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01002138 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002139 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002140 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08002141 /* somehow the BTS was unable to connect the lchan to a remote
2142 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01002143 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08002144 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002145 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01002146 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01002147 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08002148 break;
2149 default:
Harald Weltede4477a2009-12-24 12:20:20 +01002150 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002151 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08002152 break;
2153 }
2154 DEBUGPC(DRSL, "\n");
2155
2156 return rc;
2157}
2158
2159
2160/* Entry-point where L2 RSL from BTS enters */
2161int abis_rsl_rcvmsg(struct msgb *msg)
2162{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002163 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08002164 int rc = 0;
2165
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002166 if (!msg) {
2167 DEBUGP(DRSL, "Empty RSL msg?..\n");
2168 return -1;
2169 }
2170
2171 if (msgb_l2len(msg) < sizeof(*rslh)) {
2172 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02002173 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01002174 return -1;
2175 }
2176
2177 rslh = msgb_l2(msg);
2178
Harald Welte59b04682009-06-10 05:40:52 +08002179 switch (rslh->msg_discr & 0xfe) {
2180 case ABIS_RSL_MDISC_RLL:
2181 rc = abis_rsl_rx_rll(msg);
2182 break;
2183 case ABIS_RSL_MDISC_DED_CHAN:
2184 rc = abis_rsl_rx_dchan(msg);
2185 break;
2186 case ABIS_RSL_MDISC_COM_CHAN:
2187 rc = abis_rsl_rx_cchan(msg);
2188 break;
2189 case ABIS_RSL_MDISC_TRX:
2190 rc = abis_rsl_rx_trx(msg);
2191 break;
2192 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002193 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08002194 rslh->msg_discr);
2195 break;
2196 case ABIS_RSL_MDISC_IPACCESS:
2197 rc = abis_rsl_rx_ipacc(msg);
2198 break;
2199 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01002200 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2201 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02002202 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08002203 }
2204 msgb_free(msg);
2205 return rc;
2206}
2207
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002208int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
Harald Weltebf4ba722014-12-28 15:00:45 +01002209 struct rsl_ie_cb_cmd_type cb_command,
2210 const uint8_t *data, int len)
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002211{
2212 struct abis_rsl_dchan_hdr *dh;
2213 struct msgb *cb_cmd;
2214
2215 cb_cmd = rsl_msgb_alloc();
2216 if (!cb_cmd)
2217 return -1;
2218
Harald Weltebf4ba722014-12-28 15:00:45 +01002219 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof(*dh));
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002220 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
Harald Weltebf4ba722014-12-28 15:00:45 +01002221 dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
2222 dh->chan_nr = chan_number; /* TODO: check the chan config */
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002223
Harald Weltebf4ba722014-12-28 15:00:45 +01002224 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, *(uint8_t*)&cb_command);
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002225 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2226
Harald Weltebf4ba722014-12-28 15:00:45 +01002227 cb_cmd->dst = bts->c0->rsl_link;
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08002228
2229 return abis_rsl_sendmsg(cb_cmd);
2230}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002231
2232int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2233{
2234 struct abis_rsl_common_hdr *ch;
2235 struct msgb *msg = rsl_msgb_alloc();
2236
2237 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2238 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2239 ch->msg_type = 0x40; /* Nokia SI Begin */
2240
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002241 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002242
2243 return abis_rsl_sendmsg(msg);
2244}
2245
2246int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2247{
2248 struct abis_rsl_common_hdr *ch;
2249 struct msgb *msg = rsl_msgb_alloc();
2250
2251 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2252 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2253 ch->msg_type = 0x41; /* Nokia SI End */
2254
2255 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2256
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002257 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002258
2259 return abis_rsl_sendmsg(msg);
2260}
2261
2262int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2263{
2264 struct abis_rsl_common_hdr *ch;
2265 struct msgb *msg = rsl_msgb_alloc();
2266
2267 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2268 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2269 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2270
2271 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2272 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2273
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002274 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002275
2276 return abis_rsl_sendmsg(msg);
2277}
Holger Hans Peter Freythere38af682011-12-27 22:24:17 +01002278
2279/**
2280 * Release all allocated SAPIs starting from @param start and
2281 * release them with the given release mode. Once the release
2282 * confirmation arrives it will be attempted to release the
2283 * the RF channel.
2284 */
2285int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2286 enum rsl_rel_mode release_mode)
2287{
2288 int no_sapi = 1;
2289 int sapi;
2290
2291 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2292 uint8_t link_id;
2293 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2294 continue;
2295
2296 link_id = sapi;
2297 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2298 link_id |= 0x40;
2299 rsl_release_request(lchan, link_id, release_mode);
2300 no_sapi = 0;
2301 }
2302
2303 return no_sapi;
2304}
Holger Hans Peter Freyther969a4052011-12-28 16:21:05 +01002305
2306int rsl_start_t3109(struct gsm_lchan *lchan)
2307{
2308 struct gsm_bts *bts = lchan->ts->trx->bts;
2309
2310 /* Disabled, mostly legacy code */
2311 if (bts->network->T3109 == 0)
2312 return -1;
2313
2314 lchan->T3109.cb = t3109_expired;
2315 lchan->T3109.data = lchan;
2316 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2317 return 0;
2318}
Holger Hans Peter Freytherc63cb862012-12-25 23:45:14 +01002319
2320/**
2321 * \brief directly RF Channel Release the lchan
2322 *
2323 * When no SAPI was allocated, directly release the logical channel. This
2324 * should only be called from chan_alloc.c on channel release handling. In
2325 * case no SAPI was established the RF Channel can be directly released,
2326 */
2327int rsl_direct_rf_release(struct gsm_lchan *lchan)
2328{
2329 int i;
2330 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2331 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2332 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2333 gsm_lchan_name(lchan), i);
2334 return -1;
2335 }
2336 }
2337
2338 /* Now release it */
2339 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2340}