blob: 644706f7bd76c81c425d5a6e03107f85fde0e3a4 [file] [log] [blame]
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte52b1f982008-12-23 20:25:15 +00002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Welte3c9c5f92010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte8470bf22008-12-25 23:28:35 +00006 *
Harald Welte52b1f982008-12-23 20:25:15 +00007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte52b1f982008-12-23 20:25:15 +000012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte52b1f982008-12-23 20:25:15 +000021 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
Harald Welte75099262009-02-16 21:12:08 +000027#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000028#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Harald Welte8470bf22008-12-25 23:28:35 +000030#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000036#include <openbsc/debug.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Holger Freyther392209c2009-02-10 00:06:19 +000038#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000039#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010040#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010041#include <openbsc/rtp_proxy.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020042#include <osmocom/abis/e1_input.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010043#include <osmocom/gsm/rsl.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080045
Harald Welte8470bf22008-12-25 23:28:35 +000046#define RSL_ALLOC_SIZE 1024
47#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000048
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +010049enum sacch_deact {
50 SACCH_NONE,
51 SACCH_DEACTIVATE,
52};
53
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080054static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
55
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010056static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
57 struct gsm_meas_rep *resp)
58{
59 struct lchan_signal_data sig;
60 sig.lchan = lchan;
61 sig.mr = resp;
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +020062 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010063}
64
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010065static void do_lchan_free(struct gsm_lchan *lchan)
66{
67 /* we have an error timer pending to release that */
68 if (lchan->state != LCHAN_S_REL_ERR)
69 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
70 lchan_free(lchan);
71}
72
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020073static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000074{
75 /* mask off the transparent bit ? */
76 msg_type &= 0xfe;
77
Harald Welte8470bf22008-12-25 23:28:35 +000078 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000079 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000080 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000081 if (msg_type >= 0x19 && msg_type <= 0x22)
82 return ABIS_RSL_MDISC_TRX;
83 else
84 return ABIS_RSL_MDISC_COM_CHAN;
85 }
Harald Welte2d5b6382008-12-27 19:46:06 +000086 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000087 return ABIS_RSL_MDISC_DED_CHAN;
88
89 return ABIS_RSL_MDISC_LOC;
90}
91
92static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020093 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000094{
95 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
96 dh->c.msg_type = msg_type;
97 dh->ie_chan = RSL_IE_CHAN_NR;
98}
99
Harald Welte8470bf22008-12-25 23:28:35 +0000100/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200101struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte8470bf22008-12-25 23:28:35 +0000102{
103 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200104 uint8_t ts_nr = chan_nr & 0x07;
105 uint8_t cbits = chan_nr >> 3;
106 uint8_t lch_idx;
Harald Welte8470bf22008-12-25 23:28:35 +0000107 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
108
109 if (cbits == 0x01) {
110 lch_idx = 0; /* TCH/F */
Harald Weltea1499d02009-10-24 10:25:50 +0200111 if (ts->pchan != GSM_PCHAN_TCH_F &&
112 ts->pchan != GSM_PCHAN_PDCH &&
113 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100114 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000115 chan_nr, ts->pchan);
116 } else if ((cbits & 0x1e) == 0x02) {
117 lch_idx = cbits & 0x1; /* TCH/H */
118 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100119 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000120 chan_nr, ts->pchan);
121 } else if ((cbits & 0x1c) == 0x04) {
122 lch_idx = cbits & 0x3; /* SDCCH/4 */
123 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100124 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000125 chan_nr, ts->pchan);
126 } else if ((cbits & 0x18) == 0x08) {
127 lch_idx = cbits & 0x7; /* SDCCH/8 */
128 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100129 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000130 chan_nr, ts->pchan);
131 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
132 lch_idx = 0;
133 if (ts->pchan != GSM_PCHAN_CCCH &&
134 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100135 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000136 chan_nr, ts->pchan);
137 /* FIXME: we should not return first sdcch4 !!! */
138 } else {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100139 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000140 return NULL;
141 }
142
143 lchan = &ts->lchan[lch_idx];
Harald Weltedc5062b2010-03-26 21:28:59 +0800144 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800145 if (lchan->conn)
146 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000147
148 return lchan;
149}
150
Harald Welte52b1f982008-12-23 20:25:15 +0000151/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200152uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000153{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200154 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000155
156 ret = strtoull(imsi_str, NULL, 10);
157
158 return ret;
159}
160
Harald Welte8470bf22008-12-25 23:28:35 +0000161static struct msgb *rsl_msgb_alloc(void)
162{
Harald Welte966636f2009-06-26 19:39:35 +0200163 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
164 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000165}
166
Harald Welte362322e2009-02-15 14:36:38 +0000167#define MACBLOCK_SIZE 23
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200168static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000169{
170 memcpy(out, in, len);
171
172 if (len < MACBLOCK_SIZE)
173 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
174}
175
Harald Welte08d91a52009-08-30 15:37:11 +0900176/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200177static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900178{
179 *out++ = lchan->encr.alg_id & 0xff;
180 if (lchan->encr.key_len)
181 memcpy(out, lchan->encr.key, lchan->encr.key_len);
182 return lchan->encr.key_len + 1;
183}
184
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200185static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200186{
Harald Welte7f93cea2009-02-23 00:02:59 +0000187 int i;
188
Harald Welte5b8ed432009-12-24 12:20:20 +0100189 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200190 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200191 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100192 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000193}
194
Harald Weltee8bd9e82011-08-10 23:26:33 +0200195static void lchan_act_tmr_cb(void *data)
196{
197 struct gsm_lchan *lchan = data;
198
Holger Hans Peter Freyther1411c062012-12-06 19:00:35 +0100199 LOGP(DRSL, LOGL_ERROR, "%s Timeout during activation!\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200200 gsm_lchan_name(lchan));
201
Daniel Willmann513da172011-08-11 04:44:12 +0200202 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
203 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200204}
205
206static void lchan_deact_tmr_cb(void *data)
207{
208 struct gsm_lchan *lchan = data;
209
Holger Hans Peter Freyther1411c062012-12-06 19:00:35 +0100210 LOGP(DRSL, LOGL_ERROR, "%s Timeout during deactivation!\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200211 gsm_lchan_name(lchan));
212
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100213 do_lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200214}
215
216
Harald Welte52b1f982008-12-23 20:25:15 +0000217/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200218int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
219 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000220{
221 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000222 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000223
224 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
225 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
226 dh->chan_nr = RSL_CHAN_BCCH;
227
228 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
229 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
230
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200231 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000232
233 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000234}
235
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200236int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
237 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000238{
239 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000240 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000241
242 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
243 ch->msg_discr = ABIS_RSL_MDISC_TRX;
244 ch->msg_type = RSL_MT_SACCH_FILL;
245
246 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000247 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000248
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200249 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000250
251 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000252}
253
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200254int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
255 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100256{
257 struct abis_rsl_dchan_hdr *dh;
258 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200259 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100260
261 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
262 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
263 dh->chan_nr = chan_nr;
264
265 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
266 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
267
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200268 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100269
270 return abis_rsl_sendmsg(msg);
271}
272
Harald Weltefcd24452009-06-20 18:15:19 +0200273int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
274{
275 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200276 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200277 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200278
279 db = abs(db);
280 if (db > 30)
281 return -EINVAL;
282
Harald Welteeab33352009-06-27 03:09:08 +0200283 msg = rsl_msgb_alloc();
284
Harald Weltefcd24452009-06-20 18:15:19 +0200285 lchan->bs_power = db/2;
286 if (fpc)
287 lchan->bs_power |= 0x10;
288
289 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
290 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
291 dh->chan_nr = chan_nr;
292
293 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
294
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200295 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200296
297 return abis_rsl_sendmsg(msg);
298}
299
Harald Weltefcd24452009-06-20 18:15:19 +0200300int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
301{
302 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200303 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200304 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200305 int ctl_lvl;
306
Harald Welte66b6a8d2009-08-09 14:45:18 +0200307 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200308 if (ctl_lvl < 0)
309 return ctl_lvl;
310
Harald Welteeab33352009-06-27 03:09:08 +0200311 msg = rsl_msgb_alloc();
312
Harald Weltefcd24452009-06-20 18:15:19 +0200313 lchan->ms_power = ctl_lvl;
314
315 if (fpc)
316 lchan->ms_power |= 0x20;
317
318 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
319 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
320 dh->chan_nr = chan_nr;
321
322 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
323
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200324 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200325
326 return abis_rsl_sendmsg(msg);
327}
328
Harald Welte9943c5b2009-07-29 15:41:29 +0200329static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
330 struct gsm_lchan *lchan)
331{
Holger Hans Peter Freythere1145cf2013-03-09 17:50:10 +0100332 memset(cm, 0, sizeof(*cm));
Harald Welte9943c5b2009-07-29 15:41:29 +0200333
334 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800335 if (lchan->ts->trx->bts->network->dtx_enabled)
336 cm->dtx_dtu = 0x03;
337 else
338 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200339
340 /* set TCH Speech/Data */
341 cm->spd_ind = lchan->rsl_cmode;
342
Harald Welte1a79d362009-11-27 08:55:16 +0100343 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
344 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100345 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100346 "but tch_mode != signalling\n");
347
Harald Welte9943c5b2009-07-29 15:41:29 +0200348 switch (lchan->type) {
349 case GSM_LCHAN_SDCCH:
350 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
351 break;
352 case GSM_LCHAN_TCH_F:
353 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
354 break;
355 case GSM_LCHAN_TCH_H:
356 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
357 break;
358 case GSM_LCHAN_NONE:
359 case GSM_LCHAN_UNKNOWN:
360 default:
361 return -EINVAL;
362 }
363
364 switch (lchan->tch_mode) {
365 case GSM48_CMODE_SIGN:
366 cm->chan_rate = 0;
367 break;
368 case GSM48_CMODE_SPEECH_V1:
369 cm->chan_rate = RSL_CMOD_SP_GSM1;
370 break;
371 case GSM48_CMODE_SPEECH_EFR:
372 cm->chan_rate = RSL_CMOD_SP_GSM2;
373 break;
374 case GSM48_CMODE_SPEECH_AMR:
375 cm->chan_rate = RSL_CMOD_SP_GSM3;
376 break;
377 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200378 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200379 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200380 switch (lchan->csd_mode) {
381 case LCHAN_CSD_M_NT:
382 /* non-transparent CSD with RLP */
383 switch (lchan->tch_mode) {
384 case GSM48_CMODE_DATA_14k5:
385 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
386 break;
387 case GSM48_CMODE_DATA_12k0:
388 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
389 break;
390 case GSM48_CMODE_DATA_6k0:
391 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
392 break;
393 default:
394 return -EINVAL;
395 }
396 break;
397 /* transparent data services below */
398 case LCHAN_CSD_M_T_1200_75:
399 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
400 break;
401 case LCHAN_CSD_M_T_600:
402 cm->chan_rate = RSL_CMOD_CSD_T_600;
403 break;
404 case LCHAN_CSD_M_T_1200:
405 cm->chan_rate = RSL_CMOD_CSD_T_1200;
406 break;
407 case LCHAN_CSD_M_T_2400:
408 cm->chan_rate = RSL_CMOD_CSD_T_2400;
409 break;
410 case LCHAN_CSD_M_T_9600:
411 cm->chan_rate = RSL_CMOD_CSD_T_9600;
412 break;
413 case LCHAN_CSD_M_T_14400:
414 cm->chan_rate = RSL_CMOD_CSD_T_14400;
415 break;
416 case LCHAN_CSD_M_T_29000:
417 cm->chan_rate = RSL_CMOD_CSD_T_29000;
418 break;
419 case LCHAN_CSD_M_T_32000:
420 cm->chan_rate = RSL_CMOD_CSD_T_32000;
421 break;
422 default:
423 return -EINVAL;
424 }
Harald Welte9943c5b2009-07-29 15:41:29 +0200425 default:
426 return -EINVAL;
427 }
428
429 return 0;
430}
431
Harald Welte52b1f982008-12-23 20:25:15 +0000432/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000433#if 0
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200434int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
435 uint8_t act_type,
Harald Welte52b1f982008-12-23 20:25:15 +0000436 struct rsl_ie_chan_mode *chan_mode,
437 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200438 uint8_t bs_power, uint8_t ms_power,
439 uint8_t ta)
Harald Welte52b1f982008-12-23 20:25:15 +0000440{
441 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000442 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000443
444 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
445 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
446 dh->chan_nr = chan_nr;
447
448 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
449 /* For compatibility with Phase 1 */
450 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200451 (uint8_t *) chan_mode);
Harald Welte52b1f982008-12-23 20:25:15 +0000452 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200453 (uint8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000454#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000455 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200456 (uint8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000457#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000458 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000459 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
460 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
461
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200462 msg->dst = trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000463
Harald Welte8470bf22008-12-25 23:28:35 +0000464 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000465}
Harald Welteddab3c72009-02-28 13:19:15 +0000466#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000467
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200468int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
469 uint8_t ta, uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000470{
471 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200472 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200473 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200474 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000475
Harald Weltef6093a42011-06-25 10:02:33 +0200476 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000477 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200478 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000479
Harald Welte9943c5b2009-07-29 15:41:29 +0200480 rc = channel_mode_from_lchan(&cm, lchan);
481 if (rc < 0)
482 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000483
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800484 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200485 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000486
Harald Welteeab33352009-06-27 03:09:08 +0200487 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000488 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
489 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
490 dh->chan_nr = chan_nr;
491
492 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000493 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200494 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800495
496 /*
497 * The Channel Identification is needed for Phase1 phones
498 * and it contains the GSM48 Channel Description and the
499 * Mobile Allocation. The GSM 08.58 asks for the Mobile
500 * Allocation to have a length of zero. We are using the
501 * msgb_l3len to calculate the length of both messages.
502 */
laforge694a5cf2010-06-20 21:38:19 +0200503 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200504 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200505 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800506
507 if (lchan->ts->hopping.enabled)
508 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
509 lchan->ts->hopping.ma_data);
510 else
511 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800512
513 /* update the calculated size */
514 msg->l3h = len + 1;
515 *len = msgb_l3len(msg);
516
Harald Welte08d91a52009-08-30 15:37:11 +0900517 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200518 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900519 rc = build_encr_info(encr_info, lchan);
520 if (rc > 0)
521 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
522 }
523
Harald Welte8d77b952009-12-17 00:31:10 +0100524 switch (act_type) {
525 case RSL_ACT_INTER_ASYNC:
526 case RSL_ACT_INTER_SYNC:
527 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
528 break;
529 default:
530 break;
531 }
532
Harald Welted4c9bf32009-02-15 16:56:18 +0000533 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
534 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000535 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
536
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100537 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
538 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200539 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100540
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200541 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000542
Harald Welte4b634542008-12-27 01:55:51 +0000543 return abis_rsl_sendmsg(msg);
544}
545
Harald Welte470abb72009-07-29 11:38:15 +0200546/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000547int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
548{
549 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200550 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200551 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000552
Harald Weltef6093a42011-06-25 10:02:33 +0200553 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000554 struct rsl_ie_chan_mode cm;
555
Harald Welte9943c5b2009-07-29 15:41:29 +0200556 rc = channel_mode_from_lchan(&cm, lchan);
557 if (rc < 0)
558 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000559
Harald Welteeab33352009-06-27 03:09:08 +0200560 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000561 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
562 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
563 dh->chan_nr = chan_nr;
564
565 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200566 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900567
568 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200569 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900570 rc = build_encr_info(encr_info, lchan);
571 if (rc > 0)
572 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
573 }
574
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100575 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
576 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200577 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100578 }
579
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200580 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900581
582 return abis_rsl_sendmsg(msg);
583}
584
585/* Chapter 8.4.6: Send the encryption command with given L3 info */
586int rsl_encryption_cmd(struct msgb *msg)
587{
588 struct abis_rsl_dchan_hdr *dh;
589 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200590 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200591 uint8_t encr_info[MAX_A5_KEY_LEN+2];
592 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900593 int rc;
594
595 /* First push the L3 IE tag and length */
596 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
597
598 /* then the link identifier (SAPI0, main sign link) */
599 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
600
601 /* then encryption information */
602 rc = build_encr_info(encr_info, lchan);
603 if (rc <= 0)
604 return rc;
605 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
606
607 /* and finally the DCHAN header */
608 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
609 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
610 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000611
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200612 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000613
614 return abis_rsl_sendmsg(msg);
615}
616
Harald Welte115d1032009-08-10 11:43:22 +0200617/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200618int rsl_deact_sacch(struct gsm_lchan *lchan)
619{
620 struct abis_rsl_dchan_hdr *dh;
621 struct msgb *msg = rsl_msgb_alloc();
622
623 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
624 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200625 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200626
627 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200628 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200629
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100630 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200631
632 return abis_rsl_sendmsg(msg);
633}
634
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800635static void error_timeout_cb(void *data)
636{
637 struct gsm_lchan *lchan = data;
638 if (lchan->state != LCHAN_S_REL_ERR) {
639 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
640 gsm_lchan_name(lchan), lchan->state);
641 return;
642 }
643
644 /* go back to the none state */
645 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800646 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800647}
648
Harald Weltefd355a32011-03-04 13:41:31 +0100649static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
650
Harald Welte115d1032009-08-10 11:43:22 +0200651/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100652static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
653 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000654{
655 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800656 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100657 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000658
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100659 /* Stop timers that should lead to a channel release */
660 osmo_timer_del(&lchan->T3109);
661
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800662 if (lchan->state == LCHAN_S_REL_ERR) {
663 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
664 gsm_lchan_name(lchan));
665 return -1;
666 }
667
668 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000669 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
670 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200671 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000672
Harald Welte8470bf22008-12-25 23:28:35 +0000673 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200674 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000675
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800676 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
677
678 if (error) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200679 struct e1inp_sign_link *sign_link = msg->dst;
680
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100681 /*
682 * FIXME: GSM 04.08 gives us two options for the abnormal
683 * chanel release. This can be either like in the non-existent
684 * sub-lcuase 3.5.1 or for the main signalling link deactivate
685 * the SACCH, start timer T3109 and consider the channel as
686 * released.
687 *
688 * This code is doing the later for all raido links and not
689 * only the main link. Right now all SAPIs are released on the
690 * local end, the SACCH will be de-activated and right now the
691 * T3111 will be started. First T3109 should be started and then
692 * the T3111.
693 *
694 * TODO: Move this out of the function.
695 */
696
697 /*
698 * sacch de-activate and "local end release"
699 */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100700 if (deact_sacch == SACCH_DEACTIVATE)
701 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100702 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
703
704 /*
705 * TODO: start T3109 now.
706 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800707 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800708 lchan->error_timer.data = lchan;
709 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200710 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200711 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800712 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000713
Harald Weltee8bd9e82011-08-10 23:26:33 +0200714 /* Start another timer or assume the BTS sends a ACK/NACK? */
715 lchan->act_timer.cb = lchan_deact_tmr_cb;
716 lchan->act_timer.data = lchan;
717 osmo_timer_schedule(&lchan->act_timer, 4, 0);
718
Harald Weltefd355a32011-03-04 13:41:31 +0100719 rc = abis_rsl_sendmsg(msg);
720
Harald Welte115d1032009-08-10 11:43:22 +0200721 /* BTS will respond by RF CHAN REL ACK */
Harald Welte26d79072011-01-14 23:18:59 +0100722#ifdef HSL_SR_1_0
Harald Weltefd355a32011-03-04 13:41:31 +0100723 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
724 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
725 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte26d79072011-01-14 23:18:59 +0100726#endif
Harald Weltefd355a32011-03-04 13:41:31 +0100727
728 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000729}
730
Harald Welte64bb7542011-01-14 14:16:16 +0100731static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
732{
733
734 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
735
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100736 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200737 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100738 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200739
Harald Welte64bb7542011-01-14 14:16:16 +0100740 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
741 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
742 gsm_lchan_name(lchan),
743 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100744 do_lchan_free(lchan);
Harald Welte64bb7542011-01-14 14:16:16 +0100745
746 return 0;
747}
748
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200749int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
750 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte52b1f982008-12-23 20:25:15 +0000751{
752 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000753 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000754
755 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
756 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
757 dh->chan_nr = RSL_CHAN_PCH_AGCH;
758
759 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000760 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000761 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
762
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200763 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000764
765 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000766}
767
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200768int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +0000769{
770 int i, len = strlen(str_in);
771
772 for (i = 0; i < len; i++) {
773 int num = str_in[i] - 0x30;
774 if (num < 0 || num > 9)
775 return -1;
776 if (i % 2 == 0)
777 bcd_out[i/2] = num;
778 else
779 bcd_out[i/2] |= (num << 4);
780 }
781
782 return 0;
783}
784
Harald Welte702d8702008-12-26 20:25:35 +0000785/* Chapter 8.5.6 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200786int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +0000787{
Harald Welte8470bf22008-12-25 23:28:35 +0000788 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000789 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200790 uint8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000791
792 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
793 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
794 dh->chan_nr = RSL_CHAN_PCH_AGCH;
795
Harald Welte362322e2009-02-15 14:36:38 +0000796 switch (bts->type) {
797 case GSM_BTS_TYPE_BS11:
798 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
799 break;
800 default:
801 /* If phase 2, construct a FULL_IMM_ASS_INFO */
802 pad_macblock(buf, val, len);
803 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
804 break;
805 }
Harald Welte52b1f982008-12-23 20:25:15 +0000806
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200807 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000808
809 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000810}
811
Harald Welte67fa91b2009-08-10 09:51:40 +0200812/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200813int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200814{
815 struct msgb *msg = rsl_msgb_alloc();
816 struct abis_rsl_dchan_hdr *dh;
817
818 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
819 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200820 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +0200821 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200822 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200823
Harald Welte5b8ed432009-12-24 12:20:20 +0100824 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200825 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200826
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200827 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +0200828
Harald Welte67fa91b2009-08-10 09:51:40 +0200829 return abis_rsl_sendmsg(msg);
830}
831
832
Harald Welte8470bf22008-12-25 23:28:35 +0000833/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000834/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200835int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000836{
Harald Welte8470bf22008-12-25 23:28:35 +0000837 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100838 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000839 return -EINVAL;
840 }
Harald Welte52b1f982008-12-23 20:25:15 +0000841
Harald Weltef6093a42011-06-25 10:02:33 +0200842 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100843 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000844
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200845 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000846
847 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000848}
849
Harald Welteedcc5272009-08-09 13:47:35 +0200850/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
851/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200852int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +0200853{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100854 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200855
Harald Weltef6093a42011-06-25 10:02:33 +0200856 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100857 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200858 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +0200859
Harald Weltefda74ee2012-04-26 19:42:19 +0200860 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
861 gsm_lchan_name(lchan), link_id);
862
Harald Welteedcc5272009-08-09 13:47:35 +0200863 return abis_rsl_sendmsg(msg);
864}
865
Harald Welted2dc1de2009-08-08 13:15:07 +0200866/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
867 This is what higher layers should call. The BTS then responds with
868 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
869 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
870 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100871int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
872 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +0200873{
Harald Welted2dc1de2009-08-08 13:15:07 +0200874
Harald Welte3c9c5f92010-03-04 10:33:10 +0100875 struct msgb *msg;
876
Harald Weltef6093a42011-06-25 10:02:33 +0200877 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100878 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800879 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100880 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +0200881
Harald Welte8e93b792009-12-29 10:44:17 +0100882 /* FIXME: start some timer in case we don't receive a REL ACK ? */
883
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200884 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +0200885
Harald Weltefda74ee2012-04-26 19:42:19 +0200886 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100887 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +0200888
Harald Welted2dc1de2009-08-08 13:15:07 +0200889 return abis_rsl_sendmsg(msg);
890}
891
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200892int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
893{
894 lchan->state = state;
895 return 0;
896}
897
Harald Welte702d8702008-12-26 20:25:35 +0000898/* Chapter 8.4.2: Channel Activate Acknowledge */
899static int rsl_rx_chan_act_ack(struct msgb *msg)
900{
901 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
902
903 /* BTS has confirmed channel activation, we now need
904 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000905 if (rslh->ie_chan != RSL_IE_CHAN_NR)
906 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100907
Harald Weltee8bd9e82011-08-10 23:26:33 +0200908 osmo_timer_del(&msg->lchan->act_timer);
909
Harald Welte8e93b792009-12-29 10:44:17 +0100910 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100911 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
912 gsm_lchan_name(msg->lchan),
913 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200914 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100915
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800916 if (msg->lchan->rqd_ref) {
917 rsl_send_imm_assignment(msg->lchan);
918 talloc_free(msg->lchan->rqd_ref);
919 msg->lchan->rqd_ref = NULL;
920 msg->lchan->rqd_ta = 0;
921 }
922
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100923 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100924
Harald Welte4b634542008-12-27 01:55:51 +0000925 return 0;
926}
Harald Welte702d8702008-12-26 20:25:35 +0000927
Harald Welte4b634542008-12-27 01:55:51 +0000928/* Chapter 8.4.3: Channel Activate NACK */
929static int rsl_rx_chan_act_nack(struct msgb *msg)
930{
Harald Welte6dab0552009-05-01 17:21:37 +0000931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
932 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000933
Harald Weltee8bd9e82011-08-10 23:26:33 +0200934 osmo_timer_del(&msg->lchan->act_timer);
935
Daniel Willmann6fc6a122011-08-11 04:54:23 +0200936 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100937 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100938
Harald Welte6dab0552009-05-01 17:21:37 +0000939 /* BTS has rejected channel activation ?!? */
940 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000941 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000942
943 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100944 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200945 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100946 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200947 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100948 msg->lchan->error_cause = *cause;
Harald Welte (local)3e460312009-12-27 18:12:29 +0100949 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100950 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200951 else
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100952 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200953
Harald Welte (local)3e460312009-12-27 18:12:29 +0100954 } else
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100955 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200956
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100957 LOGPC(DRSL, LOGL_ERROR, "\n");
958
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100959 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +0000960 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000961}
962
Harald Welte7f93cea2009-02-23 00:02:59 +0000963/* Chapter 8.4.4: Connection Failure Indication */
964static int rsl_rx_conn_fail(struct msgb *msg)
965{
966 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
967 struct tlv_parsed tp;
968
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100969 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100970 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100971 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000972
973 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
974
Harald Welte8830e072009-07-28 17:58:09 +0200975 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100976 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200977 TLVP_LEN(&tp, RSL_IE_CAUSE));
978
Harald Welte (local)fc057502009-12-26 22:33:09 +0100979 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000980 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +0200981 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100982 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Harald Welte7f93cea2009-02-23 00:02:59 +0000983}
984
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100985static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
986 const char *prefix)
987{
Harald Welte6739dfb2009-12-16 16:52:07 +0100988 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
989 prefix, rxlev2dbm(mru->full.rx_lev),
990 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100991 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
992 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
993}
994
Harald Welte0c1bd612012-07-02 17:12:08 +0200995static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100996{
Harald Welte6739dfb2009-12-16 16:52:07 +0100997 int i;
Harald Welte0c1bd612012-07-02 17:12:08 +0200998 char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +0100999
Harald Welte0c1bd612012-07-02 17:12:08 +02001000 if (lchan && lchan->conn && lchan->conn->subscr)
1001 name = subscr_name(lchan->conn->subscr);
1002
1003 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001004
1005 if (mr->flags & MEAS_REP_F_DL_DTX)
1006 DEBUGPC(DMEAS, "DTXd ");
1007
1008 print_meas_rep_uni(&mr->ul, "ul");
1009 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1010 if (mr->flags & MEAS_REP_F_MS_TO)
1011 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1012
1013 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +01001014 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001015 DEBUGPC(DMEAS, "L1_FPC=%u ",
1016 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1017 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1018 }
1019
1020 if (mr->flags & MEAS_REP_F_UL_DTX)
1021 DEBUGPC(DMEAS, "DTXu ");
1022 if (mr->flags & MEAS_REP_F_BA1)
1023 DEBUGPC(DMEAS, "BA1 ");
1024 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1025 DEBUGPC(DMEAS, "NOT VALID ");
1026 else
1027 print_meas_rep_uni(&mr->dl, "dl");
1028
1029 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001030 if (mr->num_cell == 7)
1031 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001032 for (i = 0; i < mr->num_cell; i++) {
1033 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001034 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1035 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001036 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001037}
1038
Harald Welte440fed02009-05-01 18:43:47 +00001039static int rsl_rx_meas_res(struct msgb *msg)
1040{
1041 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1042 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001043 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001044 uint8_t len;
1045 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001046 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001047
Harald Welteb8bfc562009-12-21 13:27:11 +01001048 /* check if this channel is actually active */
1049 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001050 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001051 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001052 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001053 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001054 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001055
Harald Welted12b0fd2009-12-15 21:36:05 +01001056 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001057 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001058
Harald Welte440fed02009-05-01 18:43:47 +00001059 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1060
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001061 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1062 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1063 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1064 return -EIO;
1065
1066 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001067 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001068
1069 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1070 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1071 if (len >= 3) {
1072 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001073 mr->flags |= MEAS_REP_F_DL_DTX;
1074 mr->ul.full.rx_lev = val[0] & 0x3f;
1075 mr->ul.sub.rx_lev = val[1] & 0x3f;
1076 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1077 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001078 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001079
Harald Welted12b0fd2009-12-15 21:36:05 +01001080 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001081
1082 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +00001083 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +01001084 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001085 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1086
Harald Weltefe9af262009-06-20 18:44:35 +02001087 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001088 struct e1inp_sign_link *sign_link = msg->dst;
1089
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001090 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001091 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001092 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001093 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001094 mr->flags |= MEAS_REP_F_FPC;
1095 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001096 /* BS11 and Nokia reports TA shifted by 2 bits */
1097 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1098 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001099 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001100 }
Harald Weltef7c43522009-06-09 20:24:21 +00001101 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001102 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001103 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001104 if (rc < 0)
1105 return rc;
1106 }
1107
Harald Welte0c1bd612012-07-02 17:12:08 +02001108 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001109
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001110 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001111
Harald Welte75d34a82009-05-23 06:11:13 +00001112 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001113}
1114
Harald Welted011e8b2009-11-29 22:45:52 +01001115/* Chapter 8.4.7 */
1116static int rsl_rx_hando_det(struct msgb *msg)
1117{
1118 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1119 struct tlv_parsed tp;
1120
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001121 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001122
1123 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1124
1125 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1126 DEBUGPC(DRSL, "access delay = %u\n",
1127 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1128 else
1129 DEBUGPC(DRSL, "\n");
1130
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001131 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001132
1133 return 0;
1134}
1135
Harald Welte52b1f982008-12-23 20:25:15 +00001136static int abis_rsl_rx_dchan(struct msgb *msg)
1137{
Harald Welte8470bf22008-12-25 23:28:35 +00001138 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1139 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001140 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001141 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001142
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001143 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001144 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001145
Harald Welte8470bf22008-12-25 23:28:35 +00001146 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001147 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001148 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001149 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001150 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001151 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001152 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001153 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001154 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001155 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001156 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001157 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001158 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001159 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001160 case RSL_MT_HANDO_DET:
1161 rc = rsl_rx_hando_det(msg);
1162 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001163 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001164 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001165 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001166 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001167 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001168 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001169 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001170 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001171 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001172 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001173 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001174 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001175 break;
1176 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001177 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001178 break;
1179 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001180 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001181 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001182 break;
1183 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001184 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001185 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001186 case RSL_MT_PHY_CONTEXT_CONF:
1187 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001188 case RSL_MT_TALKER_DET:
1189 case RSL_MT_LISTENER_DET:
1190 case RSL_MT_REMOTE_CODEC_CONF_REP:
1191 case RSL_MT_MR_CODEC_MOD_ACK:
1192 case RSL_MT_MR_CODEC_MOD_NACK:
1193 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001194 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1195 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001196 break;
1197 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001198 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1199 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001200 return -EINVAL;
1201 }
Harald Weltef325eb42009-02-19 17:07:39 +00001202
Harald Welte8470bf22008-12-25 23:28:35 +00001203 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001204}
1205
Harald Welte702d8702008-12-26 20:25:35 +00001206static int rsl_rx_error_rep(struct msgb *msg)
1207{
1208 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001209 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001210 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001211
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001212 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001213
1214 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1215
1216 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001217 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001218 TLVP_LEN(&tp, RSL_IE_CAUSE));
1219
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001220 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001221
1222 return 0;
1223}
1224
Harald Welte52b1f982008-12-23 20:25:15 +00001225static int abis_rsl_rx_trx(struct msgb *msg)
1226{
Harald Welte702d8702008-12-26 20:25:35 +00001227 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001228 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001229 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001230
1231 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001232 case RSL_MT_ERROR_REPORT:
1233 rc = rsl_rx_error_rep(msg);
1234 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001235 case RSL_MT_RF_RES_IND:
1236 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001237 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001238 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001239 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001240 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001241 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001242 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001243 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001244 case 0x42: /* Nokia specific: SI End ACK */
1245 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1246 break;
1247 case 0x43: /* Nokia specific: SI End NACK */
1248 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1249 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001250 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001251 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001252 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001253 return -EINVAL;
1254 }
Harald Welte8470bf22008-12-25 23:28:35 +00001255 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001256}
1257
Harald Welteb7e81162009-08-10 00:26:10 +02001258/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1259static void t3101_expired(void *data)
1260{
1261 struct gsm_lchan *lchan = data;
1262
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001263 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001264}
1265
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001266/* If T3111 expires, we will send the RF Channel Request */
1267static void t3111_expired(void *data)
1268{
1269 struct gsm_lchan *lchan = data;
1270
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001271 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1272}
1273
1274/* If T3109 expires the MS has not send a UA/UM do the error release */
1275static void t3109_expired(void *data)
1276{
1277 struct gsm_lchan *lchan = data;
1278
1279 LOGP(DRSL, LOGL_ERROR,
1280 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1281 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001282}
1283
laforgecfa4a012010-06-21 12:08:52 +02001284#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1285
Harald Welte2862dca2010-12-23 14:39:29 +01001286/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1287static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1288 unsigned int num_req_refs,
1289 struct gsm48_req_ref *rqd_refs,
1290 uint8_t wait_ind)
1291{
1292 uint8_t buf[GSM_MACBLOCK_LEN];
1293 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1294
1295 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1296 memset(iar, 0, sizeof(*iar));
1297 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001298 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Welte2862dca2010-12-23 14:39:29 +01001299 iar->page_mode = GSM48_PM_SAME;
1300
1301 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1302 iar->wait_ind1 = wait_ind;
1303
1304 if (num_req_refs >= 2)
1305 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1306 else
1307 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1308 iar->wait_ind2 = wait_ind;
1309
1310 if (num_req_refs >= 3)
1311 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1312 else
1313 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1314 iar->wait_ind3 = wait_ind;
1315
1316 if (num_req_refs >= 4)
1317 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1318 else
1319 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1320 iar->wait_ind4 = wait_ind;
1321
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001322 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1323 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1324
1325 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Welte2862dca2010-12-23 14:39:29 +01001326}
1327
Harald Welte8470bf22008-12-25 23:28:35 +00001328/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001329static int rsl_rx_chan_rqd(struct msgb *msg)
1330{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001331 struct e1inp_sign_link *sign_link = msg->dst;
1332 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001333 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1334 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001335 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001336 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001337 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001338 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001339 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001340
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001341 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001342 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001343
Harald Welte8470bf22008-12-25 23:28:35 +00001344 /* parse request reference to be used in immediate assign */
1345 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1346 return -EINVAL;
1347
1348 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1349
1350 /* parse access delay and use as TA */
1351 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1352 return -EINVAL;
1353 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1354
1355 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1356 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001357 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1358 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001359
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001360 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001361
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001362 /*
1363 * We want LOCATION UPDATES to succeed and will assign a TCH
1364 * if we have no SDCCH available.
1365 */
1366 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1367
Harald Welte8470bf22008-12-25 23:28:35 +00001368 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001369 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001370 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001371 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001372 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001373 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001374 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1375 if (bts->network->T3122)
1376 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001377 return -ENOMEM;
1378 }
1379
Harald Welte8e93b792009-12-29 10:44:17 +01001380 if (lchan->state != LCHAN_S_NONE)
1381 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001382 "in state %s\n", gsm_lchan_name(lchan),
1383 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001384
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001385 /* save the RACH data as we need it after the CHAN ACT ACK */
1386 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1387 if (!lchan->rqd_ref) {
1388 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1389 lchan_free(lchan);
1390 return -ENOMEM;
1391 }
1392
Holger Hans Peter Freytherc0a66742011-12-29 23:33:04 +01001393 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001394 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1395 lchan->rqd_ta = rqd_ta;
1396
Harald Welte8470bf22008-12-25 23:28:35 +00001397 arfcn = lchan->ts->trx->arfcn;
1398 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001399
Harald Welte08d91a52009-08-30 15:37:11 +09001400 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001401 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001402 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001403 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001404 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001405
Harald Weltee8bd9e82011-08-10 23:26:33 +02001406 /* Start another timer or assume the BTS sends a ACK/NACK? */
1407 lchan->act_timer.cb = lchan_act_tmr_cb;
1408 lchan->act_timer.data = lchan;
1409 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1410
Andreas Eversberg2957de92011-12-16 17:45:37 +01001411 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1412 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1413 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1414 rqd_ref->ra, rqd_ta);
1415
1416 /* BS11 requires TA shifted by 2 bits */
1417 if (bts->type == GSM_BTS_TYPE_BS11)
1418 rqd_ta <<= 2;
Harald Welte8d77b952009-12-17 00:31:10 +01001419 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001420
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001421 return 0;
1422}
1423
1424static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1425{
1426 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001427 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001428 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1429
Harald Welte52b1f982008-12-23 20:25:15 +00001430 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001431 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001432 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001433 ia->proto_discr = GSM48_PDISC_RR;
1434 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1435 ia->page_mode = GSM48_PM_SAME;
1436 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001437
Harald Welte8470bf22008-12-25 23:28:35 +00001438 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001439 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1440 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001441 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001442 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001443 } else {
laforge09108bf2010-06-20 15:18:46 +02001444 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1445 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001446 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001447 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1448 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001449
Harald Welteb7e81162009-08-10 00:26:10 +02001450 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1451 lchan->T3101.cb = t3101_expired;
1452 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001453 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001454
Harald Welte52b1f982008-12-23 20:25:15 +00001455 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001456 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001457}
1458
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001459/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001460static int rsl_rx_ccch_load(struct msgb *msg)
1461{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001462 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001463 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001464 struct ccch_signal_data sd;
1465
1466 sd.bts = sign_link->trx->bts;
1467 sd.rach_slot_count = -1;
1468 sd.rach_busy_count = -1;
1469 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001470
1471 switch (rslh->data[0]) {
1472 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001473 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1474 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001475 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001476 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001477 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001478 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1479 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001480 break;
1481 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001482 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001483 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1484 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1485 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1486 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001487 }
Harald Welteea280442009-02-02 22:29:56 +00001488 break;
1489 default:
1490 break;
1491 }
1492
1493 return 0;
1494}
1495
Harald Welte52b1f982008-12-23 20:25:15 +00001496static int abis_rsl_rx_cchan(struct msgb *msg)
1497{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001498 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001499 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001500 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001501
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001502 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +00001503
1504 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001505 case RSL_MT_CHAN_RQD:
1506 /* MS has requested a channel on the RACH */
1507 rc = rsl_rx_chan_rqd(msg);
1508 break;
Harald Welteea280442009-02-02 22:29:56 +00001509 case RSL_MT_CCCH_LOAD_IND:
1510 /* current load on the CCCH */
1511 rc = rsl_rx_ccch_load(msg);
1512 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001513 case RSL_MT_DELETE_IND:
1514 /* CCCH overloaded, IMM_ASSIGN was dropped */
1515 case RSL_MT_CBCH_LOAD_IND:
1516 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001517 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1518 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001519 break;
1520 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001521 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1522 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001523 return -EINVAL;
1524 }
Harald Welte8470bf22008-12-25 23:28:35 +00001525
1526 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001527}
1528
Harald Welte4b634542008-12-27 01:55:51 +00001529static int rsl_rx_rll_err_ind(struct msgb *msg)
1530{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001531 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001532 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001533 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00001534
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001535 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1536 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1537 LOGP(DRLL, LOGL_ERROR,
1538 "%s ERROR INDICATION without mandantory cause.\n",
1539 gsm_lchan_name(msg->lchan));
1540 return -1;
1541 }
1542
1543 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001544 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001545 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001546 rsl_rlm_cause_name(rlm_cause));
Harald Welteedcc5272009-08-09 13:47:35 +02001547
1548 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001549
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001550 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001551 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001552 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001553 }
Harald Welte81543bc2009-07-04 09:40:05 +02001554
Harald Welte4b634542008-12-27 01:55:51 +00001555 return 0;
1556}
Harald Weltef325eb42009-02-19 17:07:39 +00001557
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001558static void rsl_handle_release(struct gsm_lchan *lchan)
1559{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001560 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001561 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001562
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +01001563 /*
1564 * Maybe only one link/SAPI was releasd or the error handling
1565 * was activated. Just return now and let the other code handle
1566 * it.
1567 */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001568 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001569 return;
1570
1571 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1572 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1573 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001574 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001575 gsm_lchan_name(lchan), sapi);
1576 return;
1577 }
1578
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001579
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001580 /* Stop T3109 and wait for T3111 before re-using the channel */
1581 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001582 lchan->T3111.cb = t3111_expired;
1583 lchan->T3111.data = lchan;
1584 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001585 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001586}
1587
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001588/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001589 0x02, 0x06,
1590 0x01, 0x20,
1591 0x02, 0x00,
1592 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1593
1594static int abis_rsl_rx_rll(struct msgb *msg)
1595{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001596 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001597 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001598 int rc = 0;
1599 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001600 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001601
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001602 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001603 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001604 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001605
1606 switch (rllh->c.msg_type) {
1607 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001608 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001609 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001610 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1611 rllh->data[0] == RSL_IE_L3_INFO) {
1612 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001613 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001614 }
Harald Welte52b1f982008-12-23 20:25:15 +00001615 break;
1616 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001617 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001618 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001619 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001620 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001621 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001622 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1623 rllh->data[0] == RSL_IE_L3_INFO) {
1624 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001625 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001626 }
Harald Welte52b1f982008-12-23 20:25:15 +00001627 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001628 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001629 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001630 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001631 rll_indication(msg->lchan, rllh->link_id,
1632 BSC_RLLR_IND_EST_CONF);
1633 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001634 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001635 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001636 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001637 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001638 rll_indication(msg->lchan, rllh->link_id,
1639 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001640 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001641 break;
1642 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001643 /* BTS informs us of having received UA from MS,
1644 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001645 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001646 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001647 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001648 break;
1649 case RSL_MT_ERROR_IND:
1650 rc = rsl_rx_rll_err_ind(msg);
1651 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001652 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001653 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1654 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001655 break;
1656 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001657 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1658 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001659 }
Harald Welte8470bf22008-12-25 23:28:35 +00001660 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001661}
1662
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001663static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001664{
Harald Welte0603c9d2009-12-02 01:58:23 +05301665 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001666 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301667 switch (lchan->type) {
1668 case GSM_LCHAN_TCH_F:
1669 return 0x00;
1670 case GSM_LCHAN_TCH_H:
1671 return 0x03;
1672 default:
1673 break;
1674 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001675 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301676 switch (lchan->type) {
1677 case GSM_LCHAN_TCH_F:
1678 return 0x01;
1679 /* there's no half-rate EFR */
1680 default:
1681 break;
1682 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001683 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301684 switch (lchan->type) {
1685 case GSM_LCHAN_TCH_F:
1686 return 0x02;
1687 case GSM_LCHAN_TCH_H:
1688 return 0x05;
1689 default:
1690 break;
1691 }
1692 default:
1693 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001694 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001695 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301696 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001697 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001698}
1699
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001700static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01001701{
1702 switch (lchan->tch_mode) {
1703 case GSM48_CMODE_SPEECH_V1:
1704 switch (lchan->type) {
1705 case GSM_LCHAN_TCH_F:
1706 return RTP_PT_GSM_FULL;
1707 case GSM_LCHAN_TCH_H:
1708 return RTP_PT_GSM_HALF;
1709 default:
1710 break;
1711 }
1712 case GSM48_CMODE_SPEECH_EFR:
1713 switch (lchan->type) {
1714 case GSM_LCHAN_TCH_F:
1715 return RTP_PT_GSM_EFR;
1716 /* there's no half-rate EFR */
1717 default:
1718 break;
1719 }
1720 case GSM48_CMODE_SPEECH_AMR:
1721 switch (lchan->type) {
1722 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01001723 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02001724 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01001725 default:
1726 break;
1727 }
1728 default:
1729 break;
1730 }
1731 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1732 "tch_mode == 0x%02x\n & lchan_type == %d",
1733 lchan->tch_mode, lchan->type);
1734 return 0;
1735}
1736
Harald Welte75099262009-02-16 21:12:08 +00001737/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001738static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1739{
1740 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001741 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001742
1743 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001744 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001745 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1746 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1747 }
1748
1749 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001750 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001751 port = ntohs(port);
1752 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1753 lchan->abis_ip.bound_port = port;
1754 }
1755
1756 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001757 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001758 conn_id = ntohs(conn_id);
1759 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1760 lchan->abis_ip.conn_id = conn_id;
1761 }
1762
1763 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1764 lchan->abis_ip.rtp_payload2 =
1765 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1766 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1767 lchan->abis_ip.rtp_payload2);
1768 }
1769
1770 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1771 lchan->abis_ip.speech_mode =
1772 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1773 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1774 lchan->abis_ip.speech_mode);
1775 }
1776
1777 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001778 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001779 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1780 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1781 }
1782
1783 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001784 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001785 port = ntohs(port);
1786 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1787 lchan->abis_ip.connect_port = port;
1788 }
1789}
1790
Harald Welte647db842013-02-03 12:06:58 +01001791/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1792 * \param[in] lchan Logical Channel for which we issue CRCX
1793 */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001794int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001795{
1796 struct msgb *msg = rsl_msgb_alloc();
1797 struct abis_rsl_dchan_hdr *dh;
1798
1799 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001800 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001801 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001802 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001803
Harald Weltef4e79f22009-07-28 18:11:56 +02001804 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001805 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001806 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001807 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001808 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001809
Sylvain Munautb54dda42009-12-20 22:06:40 +01001810 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1811 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1812 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001813
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001814 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001815
1816 return abis_rsl_sendmsg(msg);
1817}
1818
Harald Welte647db842013-02-03 12:06:58 +01001819/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1820 * \param[in] lchan Logical Channel for which we issue MDCX
1821 * \param[in] ip Remote (MGW) IP address for RTP
1822 * \param[in] port Remote (MGW) UDP port number for RTP
1823 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1824 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001825int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1826 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001827{
1828 struct msgb *msg = rsl_msgb_alloc();
1829 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001830 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001831 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001832
1833 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001834 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001835 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001836 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001837
Harald Welte5e3d91b2009-12-19 16:42:06 +01001838 /* we need to store these now as MDCX_ACK does not return them :( */
1839 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1840 lchan->abis_ip.connect_port = port;
1841 lchan->abis_ip.connect_ip = ip;
1842
Harald Welte58ca5b72009-07-29 12:12:18 +02001843 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001844 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001845 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001846
Harald Weltef4e79f22009-07-28 18:11:56 +02001847 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001848 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1849 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1850 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1851 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001852
Harald Welte5e3d91b2009-12-19 16:42:06 +01001853 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1854 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001855 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001856 *att_ip = ia.s_addr;
1857 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1858 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001859 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001860 if (rtp_payload2)
1861 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001862
1863 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001864
1865 return abis_rsl_sendmsg(msg);
1866}
1867
Harald Weltea72273e2009-12-20 16:51:09 +01001868/* tell BTS to connect RTP stream to our local RTP socket */
1869int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1870{
1871 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1872 int rc;
1873
1874 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1875 ntohs(rs->rtp.sin_local.sin_port),
1876 /* FIXME: use RTP payload of bound socket, not BTS*/
1877 lchan->abis_ip.rtp_payload2);
1878
1879 return rc;
1880}
1881
Harald Welte53cd7ac2010-12-23 12:59:52 +01001882int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001883{
1884 struct msgb *msg = rsl_msgb_alloc();
1885 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001886 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08001887
1888 if (act)
1889 msg_type = RSL_MT_IPAC_PDCH_ACT;
1890 else
1891 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001892
1893 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001894 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001895 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001896 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001897
Harald Welte53cd7ac2010-12-23 12:59:52 +01001898 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001899 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001900
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001901 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02001902
1903 return abis_rsl_sendmsg(msg);
1904}
1905
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001906static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001907{
1908 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1909 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301910 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001911
1912 /* the BTS has acknowledged a local bind, it now tells us the IP
1913 * address and port number to which it has bound the given logical
1914 * channel */
1915
1916 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1917 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1918 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001919 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001920 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001921 return -EINVAL;
1922 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001923
Harald Welte5e3d91b2009-12-19 16:42:06 +01001924 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001925
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001926 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001927
Harald Welte75099262009-02-16 21:12:08 +00001928 return 0;
1929}
1930
Harald Welte5e3d91b2009-12-19 16:42:06 +01001931static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1932{
1933 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1934 struct tlv_parsed tv;
1935 struct gsm_lchan *lchan = msg->lchan;
1936
1937 /* the BTS has acknowledged a remote connect request and
1938 * it now tells us the IP address and port number to which it has
1939 * connected the given logical channel */
1940
1941 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1942 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001943 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001944
1945 return 0;
1946}
1947
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001948static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001949{
1950 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1951 struct tlv_parsed tv;
1952
1953 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001954
Harald Welte8830e072009-07-28 17:58:09 +02001955 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001956 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001957 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001958
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001959 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001960
Harald Welte75099262009-02-16 21:12:08 +00001961 return 0;
1962}
1963
1964static int abis_rsl_rx_ipacc(struct msgb *msg)
1965{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001966 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00001967 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001968 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001969 int rc = 0;
1970
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001971 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001972 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001973
1974 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001975 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001976 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001977 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001978 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001979 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001980 /* somehow the BTS was unable to bind the lchan to its local
1981 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001982 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001983 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001984 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001985 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001986 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001987 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001988 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001989 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001990 /* somehow the BTS was unable to connect the lchan to a remote
1991 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001992 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001993 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001994 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001995 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001996 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001997 break;
1998 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001999 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002000 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00002001 break;
2002 }
Harald Welte6dab0552009-05-01 17:21:37 +00002003 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00002004
2005 return rc;
2006}
2007
2008
Harald Welte52b1f982008-12-23 20:25:15 +00002009/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00002010int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00002011{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002012 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002013 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002014
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002015 if (!msg) {
2016 DEBUGP(DRSL, "Empty RSL msg?..\n");
2017 return -1;
2018 }
2019
2020 if (msgb_l2len(msg) < sizeof(*rslh)) {
2021 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02002022 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002023 return -1;
2024 }
2025
2026 rslh = msgb_l2(msg);
2027
Harald Welte52b1f982008-12-23 20:25:15 +00002028 switch (rslh->msg_discr & 0xfe) {
2029 case ABIS_RSL_MDISC_RLL:
2030 rc = abis_rsl_rx_rll(msg);
2031 break;
2032 case ABIS_RSL_MDISC_DED_CHAN:
2033 rc = abis_rsl_rx_dchan(msg);
2034 break;
2035 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00002036 rc = abis_rsl_rx_cchan(msg);
2037 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002038 case ABIS_RSL_MDISC_TRX:
2039 rc = abis_rsl_rx_trx(msg);
2040 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002041 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002042 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002043 rslh->msg_discr);
2044 break;
Harald Welte75099262009-02-16 21:12:08 +00002045 case ABIS_RSL_MDISC_IPACCESS:
2046 rc = abis_rsl_rx_ipacc(msg);
2047 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002048 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002049 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2050 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002051 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002052 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002053 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002054 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002055}
Holger Freyther3b72a892009-02-04 00:31:39 +00002056
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002057int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
2058 uint8_t cb_command, const uint8_t *data, int len)
2059{
2060 struct abis_rsl_dchan_hdr *dh;
2061 struct msgb *cb_cmd;
2062
2063 cb_cmd = rsl_msgb_alloc();
2064 if (!cb_cmd)
2065 return -1;
2066
2067 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
2068 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2069 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2070
2071 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2072 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2073
2074 cb_cmd->trx = bts->c0;
2075
2076 return abis_rsl_sendmsg(cb_cmd);
2077}
Dieter Spaar16646022011-07-28 00:01:50 +02002078
2079int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2080{
2081 struct abis_rsl_common_hdr *ch;
2082 struct msgb *msg = rsl_msgb_alloc();
2083
2084 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2085 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2086 ch->msg_type = 0x40; /* Nokia SI Begin */
2087
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002088 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002089
2090 return abis_rsl_sendmsg(msg);
2091}
2092
2093int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2094{
2095 struct abis_rsl_common_hdr *ch;
2096 struct msgb *msg = rsl_msgb_alloc();
2097
2098 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2099 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2100 ch->msg_type = 0x41; /* Nokia SI End */
2101
2102 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2103
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002104 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002105
2106 return abis_rsl_sendmsg(msg);
2107}
2108
2109int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2110{
2111 struct abis_rsl_common_hdr *ch;
2112 struct msgb *msg = rsl_msgb_alloc();
2113
2114 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2115 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2116 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2117
2118 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2119 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2120
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002121 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002122
2123 return abis_rsl_sendmsg(msg);
2124}
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01002125
2126/**
2127 * Release all allocated SAPIs starting from @param start and
2128 * release them with the given release mode. Once the release
2129 * confirmation arrives it will be attempted to release the
2130 * the RF channel.
2131 */
2132int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2133 enum rsl_rel_mode release_mode)
2134{
2135 int no_sapi = 1;
2136 int sapi;
2137
2138 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2139 uint8_t link_id;
2140 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2141 continue;
2142
2143 link_id = sapi;
2144 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2145 link_id |= 0x40;
2146 rsl_release_request(lchan, link_id, release_mode);
2147 no_sapi = 0;
2148 }
2149
2150 return no_sapi;
2151}
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002152
2153int rsl_start_t3109(struct gsm_lchan *lchan)
2154{
2155 struct gsm_bts *bts = lchan->ts->trx->bts;
2156
2157 /* Disabled, mostly legacy code */
2158 if (bts->network->T3109 == 0)
2159 return -1;
2160
2161 lchan->T3109.cb = t3109_expired;
2162 lchan->T3109.data = lchan;
2163 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2164 return 0;
2165}
Holger Hans Peter Freyther006e3d82012-12-25 23:45:14 +01002166
2167/**
2168 * \brief directly RF Channel Release the lchan
2169 *
2170 * When no SAPI was allocated, directly release the logical channel. This
2171 * should only be called from chan_alloc.c on channel release handling. In
2172 * case no SAPI was established the RF Channel can be directly released,
2173 */
2174int rsl_direct_rf_release(struct gsm_lchan *lchan)
2175{
2176 int i;
2177 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2178 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2179 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2180 gsm_lchan_name(lchan), i);
2181 return -1;
2182 }
2183 }
2184
2185 /* Now release it */
2186 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2187}