blob: 7aae590fc71ec568b79ea48d1cebc2569c162d49 [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 Freyther21776242013-05-01 18:44:04 +0200199 LOGP(DRSL, LOGL_ERROR,
200 "%s Timeout during activation. Marked as broken.\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200201 gsm_lchan_name(lchan));
202
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200203 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
Daniel Willmann513da172011-08-11 04:44:12 +0200204 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200205}
206
207static void lchan_deact_tmr_cb(void *data)
208{
209 struct gsm_lchan *lchan = data;
210
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200211 LOGP(DRSL, LOGL_ERROR,
212 "%s Timeout during deactivation! Marked as broken.\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200213 gsm_lchan_name(lchan));
214
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200215 rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
216 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200217}
218
219
Harald Welte52b1f982008-12-23 20:25:15 +0000220/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200221int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
222 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000223{
224 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000225 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000226
227 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
228 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
229 dh->chan_nr = RSL_CHAN_BCCH;
230
231 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
232 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
233
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200234 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000235
236 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000237}
238
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200239int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
240 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000241{
242 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000243 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000244
245 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
246 ch->msg_discr = ABIS_RSL_MDISC_TRX;
247 ch->msg_type = RSL_MT_SACCH_FILL;
248
249 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000250 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000251
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200252 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000253
254 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000255}
256
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200257int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
258 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100259{
260 struct abis_rsl_dchan_hdr *dh;
261 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200262 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100263
264 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
265 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
266 dh->chan_nr = chan_nr;
267
268 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
269 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
270
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200271 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100272
273 return abis_rsl_sendmsg(msg);
274}
275
Harald Weltefcd24452009-06-20 18:15:19 +0200276int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
277{
278 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200279 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200280 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200281
282 db = abs(db);
283 if (db > 30)
284 return -EINVAL;
285
Harald Welteeab33352009-06-27 03:09:08 +0200286 msg = rsl_msgb_alloc();
287
Harald Weltefcd24452009-06-20 18:15:19 +0200288 lchan->bs_power = db/2;
289 if (fpc)
290 lchan->bs_power |= 0x10;
291
292 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
293 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
294 dh->chan_nr = chan_nr;
295
296 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
297
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200298 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200299
300 return abis_rsl_sendmsg(msg);
301}
302
Harald Weltefcd24452009-06-20 18:15:19 +0200303int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
304{
305 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200306 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200307 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200308 int ctl_lvl;
309
Harald Welte66b6a8d2009-08-09 14:45:18 +0200310 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200311 if (ctl_lvl < 0)
312 return ctl_lvl;
313
Harald Welteeab33352009-06-27 03:09:08 +0200314 msg = rsl_msgb_alloc();
315
Harald Weltefcd24452009-06-20 18:15:19 +0200316 lchan->ms_power = ctl_lvl;
317
318 if (fpc)
319 lchan->ms_power |= 0x20;
320
321 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
322 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
323 dh->chan_nr = chan_nr;
324
325 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
326
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200327 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200328
329 return abis_rsl_sendmsg(msg);
330}
331
Harald Welte9943c5b2009-07-29 15:41:29 +0200332static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
333 struct gsm_lchan *lchan)
334{
Holger Hans Peter Freythere1145cf2013-03-09 17:50:10 +0100335 memset(cm, 0, sizeof(*cm));
Harald Welte9943c5b2009-07-29 15:41:29 +0200336
337 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800338 if (lchan->ts->trx->bts->network->dtx_enabled)
339 cm->dtx_dtu = 0x03;
340 else
341 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200342
343 /* set TCH Speech/Data */
344 cm->spd_ind = lchan->rsl_cmode;
345
Harald Welte1a79d362009-11-27 08:55:16 +0100346 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
347 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100348 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100349 "but tch_mode != signalling\n");
350
Harald Welte9943c5b2009-07-29 15:41:29 +0200351 switch (lchan->type) {
352 case GSM_LCHAN_SDCCH:
353 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
354 break;
355 case GSM_LCHAN_TCH_F:
356 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
357 break;
358 case GSM_LCHAN_TCH_H:
359 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
360 break;
361 case GSM_LCHAN_NONE:
362 case GSM_LCHAN_UNKNOWN:
363 default:
364 return -EINVAL;
365 }
366
367 switch (lchan->tch_mode) {
368 case GSM48_CMODE_SIGN:
369 cm->chan_rate = 0;
370 break;
371 case GSM48_CMODE_SPEECH_V1:
372 cm->chan_rate = RSL_CMOD_SP_GSM1;
373 break;
374 case GSM48_CMODE_SPEECH_EFR:
375 cm->chan_rate = RSL_CMOD_SP_GSM2;
376 break;
377 case GSM48_CMODE_SPEECH_AMR:
378 cm->chan_rate = RSL_CMOD_SP_GSM3;
379 break;
380 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200381 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200382 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200383 switch (lchan->csd_mode) {
384 case LCHAN_CSD_M_NT:
385 /* non-transparent CSD with RLP */
386 switch (lchan->tch_mode) {
387 case GSM48_CMODE_DATA_14k5:
388 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
389 break;
390 case GSM48_CMODE_DATA_12k0:
391 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
392 break;
393 case GSM48_CMODE_DATA_6k0:
394 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
395 break;
396 default:
397 return -EINVAL;
398 }
399 break;
400 /* transparent data services below */
401 case LCHAN_CSD_M_T_1200_75:
402 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
403 break;
404 case LCHAN_CSD_M_T_600:
405 cm->chan_rate = RSL_CMOD_CSD_T_600;
406 break;
407 case LCHAN_CSD_M_T_1200:
408 cm->chan_rate = RSL_CMOD_CSD_T_1200;
409 break;
410 case LCHAN_CSD_M_T_2400:
411 cm->chan_rate = RSL_CMOD_CSD_T_2400;
412 break;
413 case LCHAN_CSD_M_T_9600:
414 cm->chan_rate = RSL_CMOD_CSD_T_9600;
415 break;
416 case LCHAN_CSD_M_T_14400:
417 cm->chan_rate = RSL_CMOD_CSD_T_14400;
418 break;
419 case LCHAN_CSD_M_T_29000:
420 cm->chan_rate = RSL_CMOD_CSD_T_29000;
421 break;
422 case LCHAN_CSD_M_T_32000:
423 cm->chan_rate = RSL_CMOD_CSD_T_32000;
424 break;
425 default:
426 return -EINVAL;
427 }
Harald Welte9943c5b2009-07-29 15:41:29 +0200428 default:
429 return -EINVAL;
430 }
431
432 return 0;
433}
434
Harald Welte52b1f982008-12-23 20:25:15 +0000435/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000436#if 0
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200437int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
438 uint8_t act_type,
Harald Welte52b1f982008-12-23 20:25:15 +0000439 struct rsl_ie_chan_mode *chan_mode,
440 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200441 uint8_t bs_power, uint8_t ms_power,
442 uint8_t ta)
Harald Welte52b1f982008-12-23 20:25:15 +0000443{
444 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000445 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000446
447 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
448 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
449 dh->chan_nr = chan_nr;
450
451 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
452 /* For compatibility with Phase 1 */
453 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200454 (uint8_t *) chan_mode);
Harald Welte52b1f982008-12-23 20:25:15 +0000455 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200456 (uint8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000457#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000458 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200459 (uint8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000460#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000461 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000462 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
463 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
464
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200465 msg->dst = trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000466
Harald Welte8470bf22008-12-25 23:28:35 +0000467 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000468}
Harald Welteddab3c72009-02-28 13:19:15 +0000469#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000470
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200471int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
472 uint8_t ta, uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000473{
474 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200475 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200476 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200477 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000478
Harald Weltef6093a42011-06-25 10:02:33 +0200479 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000480 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200481 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000482
Harald Welte9943c5b2009-07-29 15:41:29 +0200483 rc = channel_mode_from_lchan(&cm, lchan);
484 if (rc < 0)
485 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000486
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800487 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200488 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000489
Harald Welteeab33352009-06-27 03:09:08 +0200490 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000491 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
492 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
493 dh->chan_nr = chan_nr;
494
495 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000496 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200497 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800498
499 /*
500 * The Channel Identification is needed for Phase1 phones
501 * and it contains the GSM48 Channel Description and the
502 * Mobile Allocation. The GSM 08.58 asks for the Mobile
503 * Allocation to have a length of zero. We are using the
504 * msgb_l3len to calculate the length of both messages.
505 */
laforge694a5cf2010-06-20 21:38:19 +0200506 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200507 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200508 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800509
510 if (lchan->ts->hopping.enabled)
511 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
512 lchan->ts->hopping.ma_data);
513 else
514 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800515
516 /* update the calculated size */
517 msg->l3h = len + 1;
518 *len = msgb_l3len(msg);
519
Harald Welte08d91a52009-08-30 15:37:11 +0900520 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200521 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900522 rc = build_encr_info(encr_info, lchan);
523 if (rc > 0)
524 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
525 }
526
Harald Welte8d77b952009-12-17 00:31:10 +0100527 switch (act_type) {
528 case RSL_ACT_INTER_ASYNC:
529 case RSL_ACT_INTER_SYNC:
530 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
531 break;
532 default:
533 break;
534 }
535
Harald Welted4c9bf32009-02-15 16:56:18 +0000536 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
537 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000538 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
539
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100540 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
541 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200542 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100543
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200544 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000545
Harald Welte4b634542008-12-27 01:55:51 +0000546 return abis_rsl_sendmsg(msg);
547}
548
Harald Welte470abb72009-07-29 11:38:15 +0200549/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000550int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
551{
552 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200553 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200554 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000555
Harald Weltef6093a42011-06-25 10:02:33 +0200556 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000557 struct rsl_ie_chan_mode cm;
558
Harald Welte9943c5b2009-07-29 15:41:29 +0200559 rc = channel_mode_from_lchan(&cm, lchan);
560 if (rc < 0)
561 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000562
Harald Welteeab33352009-06-27 03:09:08 +0200563 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000564 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
565 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
566 dh->chan_nr = chan_nr;
567
568 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200569 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900570
571 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200572 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900573 rc = build_encr_info(encr_info, lchan);
574 if (rc > 0)
575 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
576 }
577
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100578 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
579 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200580 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100581 }
582
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200583 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900584
585 return abis_rsl_sendmsg(msg);
586}
587
588/* Chapter 8.4.6: Send the encryption command with given L3 info */
589int rsl_encryption_cmd(struct msgb *msg)
590{
591 struct abis_rsl_dchan_hdr *dh;
592 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200593 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200594 uint8_t encr_info[MAX_A5_KEY_LEN+2];
595 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900596 int rc;
597
598 /* First push the L3 IE tag and length */
599 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
600
601 /* then the link identifier (SAPI0, main sign link) */
602 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
603
604 /* then encryption information */
605 rc = build_encr_info(encr_info, lchan);
606 if (rc <= 0)
607 return rc;
608 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
609
610 /* and finally the DCHAN header */
611 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
612 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
613 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000614
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200615 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000616
617 return abis_rsl_sendmsg(msg);
618}
619
Harald Welte115d1032009-08-10 11:43:22 +0200620/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200621int rsl_deact_sacch(struct gsm_lchan *lchan)
622{
623 struct abis_rsl_dchan_hdr *dh;
624 struct msgb *msg = rsl_msgb_alloc();
625
626 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
627 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200628 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200629
630 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200631 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200632
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100633 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200634
635 return abis_rsl_sendmsg(msg);
636}
637
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800638static void error_timeout_cb(void *data)
639{
640 struct gsm_lchan *lchan = data;
641 if (lchan->state != LCHAN_S_REL_ERR) {
642 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
643 gsm_lchan_name(lchan), lchan->state);
644 return;
645 }
646
647 /* go back to the none state */
648 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800649 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800650}
651
Harald Weltefd355a32011-03-04 13:41:31 +0100652static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
653
Harald Welte115d1032009-08-10 11:43:22 +0200654/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100655static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
656 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000657{
658 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800659 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100660 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000661
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100662 /* Stop timers that should lead to a channel release */
663 osmo_timer_del(&lchan->T3109);
664
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800665 if (lchan->state == LCHAN_S_REL_ERR) {
666 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
667 gsm_lchan_name(lchan));
668 return -1;
669 }
670
671 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000672 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
673 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200674 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000675
Harald Welte8470bf22008-12-25 23:28:35 +0000676 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200677 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000678
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800679 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
680
681 if (error) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200682 struct e1inp_sign_link *sign_link = msg->dst;
683
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100684 /*
685 * FIXME: GSM 04.08 gives us two options for the abnormal
686 * chanel release. This can be either like in the non-existent
687 * sub-lcuase 3.5.1 or for the main signalling link deactivate
688 * the SACCH, start timer T3109 and consider the channel as
689 * released.
690 *
691 * This code is doing the later for all raido links and not
692 * only the main link. Right now all SAPIs are released on the
693 * local end, the SACCH will be de-activated and right now the
694 * T3111 will be started. First T3109 should be started and then
695 * the T3111.
696 *
697 * TODO: Move this out of the function.
698 */
699
700 /*
701 * sacch de-activate and "local end release"
702 */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100703 if (deact_sacch == SACCH_DEACTIVATE)
704 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100705 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
706
707 /*
708 * TODO: start T3109 now.
709 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800710 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800711 lchan->error_timer.data = lchan;
712 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200713 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200714 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800715 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000716
Harald Weltee8bd9e82011-08-10 23:26:33 +0200717 /* Start another timer or assume the BTS sends a ACK/NACK? */
718 lchan->act_timer.cb = lchan_deact_tmr_cb;
719 lchan->act_timer.data = lchan;
720 osmo_timer_schedule(&lchan->act_timer, 4, 0);
721
Harald Weltefd355a32011-03-04 13:41:31 +0100722 rc = abis_rsl_sendmsg(msg);
723
Harald Welte115d1032009-08-10 11:43:22 +0200724 /* BTS will respond by RF CHAN REL ACK */
Harald Welte26d79072011-01-14 23:18:59 +0100725#ifdef HSL_SR_1_0
Harald Weltefd355a32011-03-04 13:41:31 +0100726 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
727 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
728 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte26d79072011-01-14 23:18:59 +0100729#endif
Harald Weltefd355a32011-03-04 13:41:31 +0100730
731 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000732}
733
Harald Welte64bb7542011-01-14 14:16:16 +0100734static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
735{
736
737 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
738
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100739 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200740 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100741 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200742
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200743 if (lchan->state == LCHAN_S_BROKEN) {
744 /* we are leaving this channel broken for now */
745 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK for broken channel.\n",
746 gsm_lchan_name(lchan));
747 return 0;
748 }
749
Harald Welte64bb7542011-01-14 14:16:16 +0100750 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
751 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
752 gsm_lchan_name(lchan),
753 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100754 do_lchan_free(lchan);
Harald Welte64bb7542011-01-14 14:16:16 +0100755
756 return 0;
757}
758
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200759int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
760 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte52b1f982008-12-23 20:25:15 +0000761{
762 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000763 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000764
765 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
766 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
767 dh->chan_nr = RSL_CHAN_PCH_AGCH;
768
769 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000770 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000771 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
772
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200773 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000774
775 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000776}
777
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200778int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +0000779{
780 int i, len = strlen(str_in);
781
782 for (i = 0; i < len; i++) {
783 int num = str_in[i] - 0x30;
784 if (num < 0 || num > 9)
785 return -1;
786 if (i % 2 == 0)
787 bcd_out[i/2] = num;
788 else
789 bcd_out[i/2] |= (num << 4);
790 }
791
792 return 0;
793}
794
Harald Welte702d8702008-12-26 20:25:35 +0000795/* Chapter 8.5.6 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200796int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +0000797{
Harald Welte8470bf22008-12-25 23:28:35 +0000798 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000799 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200800 uint8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000801
802 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
803 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
804 dh->chan_nr = RSL_CHAN_PCH_AGCH;
805
Harald Welte362322e2009-02-15 14:36:38 +0000806 switch (bts->type) {
807 case GSM_BTS_TYPE_BS11:
808 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
809 break;
810 default:
811 /* If phase 2, construct a FULL_IMM_ASS_INFO */
812 pad_macblock(buf, val, len);
813 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
814 break;
815 }
Harald Welte52b1f982008-12-23 20:25:15 +0000816
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200817 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000818
819 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000820}
821
Harald Welte67fa91b2009-08-10 09:51:40 +0200822/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200823int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200824{
825 struct msgb *msg = rsl_msgb_alloc();
826 struct abis_rsl_dchan_hdr *dh;
827
828 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
829 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200830 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +0200831 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200832 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200833
Harald Welte5b8ed432009-12-24 12:20:20 +0100834 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200835 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200836
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200837 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +0200838
Harald Welte67fa91b2009-08-10 09:51:40 +0200839 return abis_rsl_sendmsg(msg);
840}
841
842
Harald Welte8470bf22008-12-25 23:28:35 +0000843/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000844/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200845int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000846{
Harald Welte8470bf22008-12-25 23:28:35 +0000847 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100848 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000849 return -EINVAL;
850 }
Harald Welte52b1f982008-12-23 20:25:15 +0000851
Harald Weltef6093a42011-06-25 10:02:33 +0200852 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100853 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000854
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200855 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000856
857 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000858}
859
Harald Welteedcc5272009-08-09 13:47:35 +0200860/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
861/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200862int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +0200863{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100864 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200865
Harald Weltef6093a42011-06-25 10:02:33 +0200866 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100867 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200868 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +0200869
Harald Weltefda74ee2012-04-26 19:42:19 +0200870 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
871 gsm_lchan_name(lchan), link_id);
872
Harald Welteedcc5272009-08-09 13:47:35 +0200873 return abis_rsl_sendmsg(msg);
874}
875
Harald Welted2dc1de2009-08-08 13:15:07 +0200876/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
877 This is what higher layers should call. The BTS then responds with
878 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
879 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
880 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100881int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
882 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +0200883{
Harald Welted2dc1de2009-08-08 13:15:07 +0200884
Harald Welte3c9c5f92010-03-04 10:33:10 +0100885 struct msgb *msg;
886
Harald Weltef6093a42011-06-25 10:02:33 +0200887 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100888 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800889 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100890 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +0200891
Harald Welte8e93b792009-12-29 10:44:17 +0100892 /* FIXME: start some timer in case we don't receive a REL ACK ? */
893
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200894 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +0200895
Harald Weltefda74ee2012-04-26 19:42:19 +0200896 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100897 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +0200898
Harald Welted2dc1de2009-08-08 13:15:07 +0200899 return abis_rsl_sendmsg(msg);
900}
901
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200902int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
903{
904 lchan->state = state;
905 return 0;
906}
907
Harald Welte702d8702008-12-26 20:25:35 +0000908/* Chapter 8.4.2: Channel Activate Acknowledge */
909static int rsl_rx_chan_act_ack(struct msgb *msg)
910{
911 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
912
913 /* BTS has confirmed channel activation, we now need
914 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000915 if (rslh->ie_chan != RSL_IE_CHAN_NR)
916 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100917
Harald Weltee8bd9e82011-08-10 23:26:33 +0200918 osmo_timer_del(&msg->lchan->act_timer);
919
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200920 if (msg->lchan->state == LCHAN_S_BROKEN) {
921 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel.\n",
922 gsm_lchan_name(msg->lchan));
923 return 0;
924 }
925
Harald Welte8e93b792009-12-29 10:44:17 +0100926 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100927 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
928 gsm_lchan_name(msg->lchan),
929 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200930 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100931
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800932 if (msg->lchan->rqd_ref) {
933 rsl_send_imm_assignment(msg->lchan);
934 talloc_free(msg->lchan->rqd_ref);
935 msg->lchan->rqd_ref = NULL;
936 msg->lchan->rqd_ta = 0;
937 }
938
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100939 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100940
Harald Welte4b634542008-12-27 01:55:51 +0000941 return 0;
942}
Harald Welte702d8702008-12-26 20:25:35 +0000943
Harald Welte4b634542008-12-27 01:55:51 +0000944/* Chapter 8.4.3: Channel Activate NACK */
945static int rsl_rx_chan_act_nack(struct msgb *msg)
946{
Harald Welte6dab0552009-05-01 17:21:37 +0000947 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
948 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000949
Harald Weltee8bd9e82011-08-10 23:26:33 +0200950 osmo_timer_del(&msg->lchan->act_timer);
951
Holger Hans Peter Freyther21776242013-05-01 18:44:04 +0200952 if (msg->lchan->state == LCHAN_S_BROKEN) {
953 LOGP(DRSL, LOGL_ERROR,
954 "%s CHANNEL ACTIVATE NACK for broken channel.\n",
955 gsm_lchan_name(msg->lchan));
956 return -1;
957 }
958
Daniel Willmann6fc6a122011-08-11 04:54:23 +0200959 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100960 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100961
Harald Welte6dab0552009-05-01 17:21:37 +0000962 /* BTS has rejected channel activation ?!? */
963 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000964 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000965
966 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100967 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200968 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100969 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200970 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100971 msg->lchan->error_cause = *cause;
Harald Welte (local)3e460312009-12-27 18:12:29 +0100972 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100973 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200974 else
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100975 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200976
Harald Welte (local)3e460312009-12-27 18:12:29 +0100977 } else
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100978 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200979
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100980 LOGPC(DRSL, LOGL_ERROR, "\n");
981
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100982 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +0000983 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000984}
985
Harald Welte7f93cea2009-02-23 00:02:59 +0000986/* Chapter 8.4.4: Connection Failure Indication */
987static int rsl_rx_conn_fail(struct msgb *msg)
988{
989 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
990 struct tlv_parsed tp;
991
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100992 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100993 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100994 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000995
996 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
997
Harald Welte8830e072009-07-28 17:58:09 +0200998 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100999 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001000 TLVP_LEN(&tp, RSL_IE_CAUSE));
1001
Harald Welte (local)fc057502009-12-26 22:33:09 +01001002 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +00001003 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001004 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001005 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Harald Welte7f93cea2009-02-23 00:02:59 +00001006}
1007
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001008static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
1009 const char *prefix)
1010{
Harald Welte6739dfb2009-12-16 16:52:07 +01001011 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
1012 prefix, rxlev2dbm(mru->full.rx_lev),
1013 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001014 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
1015 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
1016}
1017
Harald Welte0c1bd612012-07-02 17:12:08 +02001018static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001019{
Harald Welte6739dfb2009-12-16 16:52:07 +01001020 int i;
Harald Welte0c1bd612012-07-02 17:12:08 +02001021 char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +01001022
Harald Welte0c1bd612012-07-02 17:12:08 +02001023 if (lchan && lchan->conn && lchan->conn->subscr)
1024 name = subscr_name(lchan->conn->subscr);
1025
1026 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001027
1028 if (mr->flags & MEAS_REP_F_DL_DTX)
1029 DEBUGPC(DMEAS, "DTXd ");
1030
1031 print_meas_rep_uni(&mr->ul, "ul");
1032 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1033 if (mr->flags & MEAS_REP_F_MS_TO)
1034 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1035
1036 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +01001037 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001038 DEBUGPC(DMEAS, "L1_FPC=%u ",
1039 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1040 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1041 }
1042
1043 if (mr->flags & MEAS_REP_F_UL_DTX)
1044 DEBUGPC(DMEAS, "DTXu ");
1045 if (mr->flags & MEAS_REP_F_BA1)
1046 DEBUGPC(DMEAS, "BA1 ");
1047 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1048 DEBUGPC(DMEAS, "NOT VALID ");
1049 else
1050 print_meas_rep_uni(&mr->dl, "dl");
1051
1052 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001053 if (mr->num_cell == 7)
1054 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001055 for (i = 0; i < mr->num_cell; i++) {
1056 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001057 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1058 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001059 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001060}
1061
Harald Welte440fed02009-05-01 18:43:47 +00001062static int rsl_rx_meas_res(struct msgb *msg)
1063{
1064 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1065 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001066 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001067 uint8_t len;
1068 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001069 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001070
Harald Welteb8bfc562009-12-21 13:27:11 +01001071 /* check if this channel is actually active */
1072 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001073 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001074 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001075 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001076 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001077 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001078
Harald Welted12b0fd2009-12-15 21:36:05 +01001079 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001080 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001081
Harald Welte440fed02009-05-01 18:43:47 +00001082 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1083
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001084 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1085 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1086 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1087 return -EIO;
1088
1089 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001090 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001091
1092 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1093 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1094 if (len >= 3) {
1095 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001096 mr->flags |= MEAS_REP_F_DL_DTX;
1097 mr->ul.full.rx_lev = val[0] & 0x3f;
1098 mr->ul.sub.rx_lev = val[1] & 0x3f;
1099 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1100 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001101 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001102
Harald Welted12b0fd2009-12-15 21:36:05 +01001103 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001104
1105 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +00001106 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +01001107 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001108 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1109
Harald Weltefe9af262009-06-20 18:44:35 +02001110 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001111 struct e1inp_sign_link *sign_link = msg->dst;
1112
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001113 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001114 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001115 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001116 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001117 mr->flags |= MEAS_REP_F_FPC;
1118 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001119 /* BS11 and Nokia reports TA shifted by 2 bits */
1120 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1121 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001122 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001123 }
Harald Weltef7c43522009-06-09 20:24:21 +00001124 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001125 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001126 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001127 if (rc < 0)
1128 return rc;
1129 }
1130
Harald Welte0c1bd612012-07-02 17:12:08 +02001131 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001132
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001133 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001134
Harald Welte75d34a82009-05-23 06:11:13 +00001135 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001136}
1137
Harald Welted011e8b2009-11-29 22:45:52 +01001138/* Chapter 8.4.7 */
1139static int rsl_rx_hando_det(struct msgb *msg)
1140{
1141 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1142 struct tlv_parsed tp;
1143
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001144 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001145
1146 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1147
1148 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1149 DEBUGPC(DRSL, "access delay = %u\n",
1150 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1151 else
1152 DEBUGPC(DRSL, "\n");
1153
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001154 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001155
1156 return 0;
1157}
1158
Harald Welte52b1f982008-12-23 20:25:15 +00001159static int abis_rsl_rx_dchan(struct msgb *msg)
1160{
Harald Welte8470bf22008-12-25 23:28:35 +00001161 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1162 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001163 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001164 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001165
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001166 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001167 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001168
Harald Welte8470bf22008-12-25 23:28:35 +00001169 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001170 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001171 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001172 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001173 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001174 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001175 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001176 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001177 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001178 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001179 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001180 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001181 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001182 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001183 case RSL_MT_HANDO_DET:
1184 rc = rsl_rx_hando_det(msg);
1185 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001186 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001187 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001188 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001189 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001190 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001191 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001192 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001193 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001194 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001195 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001196 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001197 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001198 break;
1199 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001200 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001201 break;
1202 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001203 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001204 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001205 break;
1206 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001207 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001208 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001209 case RSL_MT_PHY_CONTEXT_CONF:
1210 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001211 case RSL_MT_TALKER_DET:
1212 case RSL_MT_LISTENER_DET:
1213 case RSL_MT_REMOTE_CODEC_CONF_REP:
1214 case RSL_MT_MR_CODEC_MOD_ACK:
1215 case RSL_MT_MR_CODEC_MOD_NACK:
1216 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001217 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1218 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001219 break;
1220 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001221 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1222 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001223 return -EINVAL;
1224 }
Harald Weltef325eb42009-02-19 17:07:39 +00001225
Harald Welte8470bf22008-12-25 23:28:35 +00001226 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001227}
1228
Harald Welte702d8702008-12-26 20:25:35 +00001229static int rsl_rx_error_rep(struct msgb *msg)
1230{
1231 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001232 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001233 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001234
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001235 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001236
1237 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1238
1239 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001240 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001241 TLVP_LEN(&tp, RSL_IE_CAUSE));
1242
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001243 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001244
1245 return 0;
1246}
1247
Harald Welte52b1f982008-12-23 20:25:15 +00001248static int abis_rsl_rx_trx(struct msgb *msg)
1249{
Harald Welte702d8702008-12-26 20:25:35 +00001250 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001251 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001252 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001253
1254 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001255 case RSL_MT_ERROR_REPORT:
1256 rc = rsl_rx_error_rep(msg);
1257 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001258 case RSL_MT_RF_RES_IND:
1259 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001260 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001261 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001262 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001263 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001264 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001265 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001266 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001267 case 0x42: /* Nokia specific: SI End ACK */
1268 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1269 break;
1270 case 0x43: /* Nokia specific: SI End NACK */
1271 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1272 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001273 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001274 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001275 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001276 return -EINVAL;
1277 }
Harald Welte8470bf22008-12-25 23:28:35 +00001278 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001279}
1280
Harald Welteb7e81162009-08-10 00:26:10 +02001281/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1282static void t3101_expired(void *data)
1283{
1284 struct gsm_lchan *lchan = data;
1285
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001286 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001287}
1288
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001289/* If T3111 expires, we will send the RF Channel Request */
1290static void t3111_expired(void *data)
1291{
1292 struct gsm_lchan *lchan = data;
1293
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001294 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1295}
1296
1297/* If T3109 expires the MS has not send a UA/UM do the error release */
1298static void t3109_expired(void *data)
1299{
1300 struct gsm_lchan *lchan = data;
1301
1302 LOGP(DRSL, LOGL_ERROR,
1303 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1304 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001305}
1306
laforgecfa4a012010-06-21 12:08:52 +02001307#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1308
Harald Welte2862dca2010-12-23 14:39:29 +01001309/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1310static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1311 unsigned int num_req_refs,
1312 struct gsm48_req_ref *rqd_refs,
1313 uint8_t wait_ind)
1314{
1315 uint8_t buf[GSM_MACBLOCK_LEN];
1316 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1317
1318 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1319 memset(iar, 0, sizeof(*iar));
1320 iar->proto_discr = GSM48_PDISC_RR;
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001321 iar->msg_type = GSM48_MT_RR_IMM_ASS_REJ;
Harald Welte2862dca2010-12-23 14:39:29 +01001322 iar->page_mode = GSM48_PM_SAME;
1323
1324 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1325 iar->wait_ind1 = wait_ind;
1326
1327 if (num_req_refs >= 2)
1328 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1329 else
1330 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1331 iar->wait_ind2 = wait_ind;
1332
1333 if (num_req_refs >= 3)
1334 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1335 else
1336 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1337 iar->wait_ind3 = wait_ind;
1338
1339 if (num_req_refs >= 4)
1340 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1341 else
1342 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1343 iar->wait_ind4 = wait_ind;
1344
Andreas Eversberg75e13a42013-02-07 11:51:16 +01001345 /* we need to subtract 1 byte from sizeof(*iar) since ia includes the l2_plen field */
1346 iar->l2_plen = GSM48_LEN2PLEN((sizeof(*iar)-1));
1347
1348 return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
Harald Welte2862dca2010-12-23 14:39:29 +01001349}
1350
Harald Welte8470bf22008-12-25 23:28:35 +00001351/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001352static int rsl_rx_chan_rqd(struct msgb *msg)
1353{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001354 struct e1inp_sign_link *sign_link = msg->dst;
1355 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001356 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1357 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001358 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001359 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001360 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001361 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001362 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001363
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001364 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001365 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001366
Harald Welte8470bf22008-12-25 23:28:35 +00001367 /* parse request reference to be used in immediate assign */
1368 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1369 return -EINVAL;
1370
1371 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1372
1373 /* parse access delay and use as TA */
1374 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1375 return -EINVAL;
1376 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1377
1378 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1379 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001380 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1381 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001382
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001383 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001384
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001385 /*
1386 * We want LOCATION UPDATES to succeed and will assign a TCH
1387 * if we have no SDCCH available.
1388 */
1389 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1390
Harald Welte8470bf22008-12-25 23:28:35 +00001391 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001392 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001393 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001394 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001395 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001396 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001397 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1398 if (bts->network->T3122)
1399 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001400 return -ENOMEM;
1401 }
1402
Harald Welte8e93b792009-12-29 10:44:17 +01001403 if (lchan->state != LCHAN_S_NONE)
1404 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001405 "in state %s\n", gsm_lchan_name(lchan),
1406 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001407
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001408 /* save the RACH data as we need it after the CHAN ACT ACK */
1409 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1410 if (!lchan->rqd_ref) {
1411 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1412 lchan_free(lchan);
1413 return -ENOMEM;
1414 }
1415
Holger Hans Peter Freytherc0a66742011-12-29 23:33:04 +01001416 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001417 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1418 lchan->rqd_ta = rqd_ta;
1419
Harald Welte8470bf22008-12-25 23:28:35 +00001420 arfcn = lchan->ts->trx->arfcn;
1421 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001422
Harald Welte08d91a52009-08-30 15:37:11 +09001423 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001424 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001425 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001426 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001427 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001428
Harald Weltee8bd9e82011-08-10 23:26:33 +02001429 /* Start another timer or assume the BTS sends a ACK/NACK? */
1430 lchan->act_timer.cb = lchan_act_tmr_cb;
1431 lchan->act_timer.data = lchan;
1432 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1433
Andreas Eversberg2957de92011-12-16 17:45:37 +01001434 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1435 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1436 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1437 rqd_ref->ra, rqd_ta);
1438
1439 /* BS11 requires TA shifted by 2 bits */
1440 if (bts->type == GSM_BTS_TYPE_BS11)
1441 rqd_ta <<= 2;
Harald Welte8d77b952009-12-17 00:31:10 +01001442 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001443
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001444 return 0;
1445}
1446
1447static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1448{
1449 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001450 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001451 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1452
Harald Welte52b1f982008-12-23 20:25:15 +00001453 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001454 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001455 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001456 ia->proto_discr = GSM48_PDISC_RR;
1457 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1458 ia->page_mode = GSM48_PM_SAME;
1459 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001460
Harald Welte8470bf22008-12-25 23:28:35 +00001461 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001462 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1463 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001464 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001465 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001466 } else {
laforge09108bf2010-06-20 15:18:46 +02001467 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1468 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001469 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001470 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1471 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001472
Harald Welteb7e81162009-08-10 00:26:10 +02001473 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1474 lchan->T3101.cb = t3101_expired;
1475 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001476 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001477
Harald Welte52b1f982008-12-23 20:25:15 +00001478 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001479 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001480}
1481
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001482/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001483static int rsl_rx_ccch_load(struct msgb *msg)
1484{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001485 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001486 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001487 struct ccch_signal_data sd;
1488
1489 sd.bts = sign_link->trx->bts;
1490 sd.rach_slot_count = -1;
1491 sd.rach_busy_count = -1;
1492 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001493
1494 switch (rslh->data[0]) {
1495 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001496 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1497 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001498 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001499 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001500 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001501 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1502 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001503 break;
1504 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001505 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001506 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1507 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1508 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1509 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001510 }
Harald Welteea280442009-02-02 22:29:56 +00001511 break;
1512 default:
1513 break;
1514 }
1515
1516 return 0;
1517}
1518
Harald Welte52b1f982008-12-23 20:25:15 +00001519static int abis_rsl_rx_cchan(struct msgb *msg)
1520{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001521 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001522 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001523 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001524
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001525 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +00001526
1527 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001528 case RSL_MT_CHAN_RQD:
1529 /* MS has requested a channel on the RACH */
1530 rc = rsl_rx_chan_rqd(msg);
1531 break;
Harald Welteea280442009-02-02 22:29:56 +00001532 case RSL_MT_CCCH_LOAD_IND:
1533 /* current load on the CCCH */
1534 rc = rsl_rx_ccch_load(msg);
1535 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001536 case RSL_MT_DELETE_IND:
1537 /* CCCH overloaded, IMM_ASSIGN was dropped */
1538 case RSL_MT_CBCH_LOAD_IND:
1539 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001540 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1541 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001542 break;
1543 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001544 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1545 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001546 return -EINVAL;
1547 }
Harald Welte8470bf22008-12-25 23:28:35 +00001548
1549 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001550}
1551
Harald Welte4b634542008-12-27 01:55:51 +00001552static int rsl_rx_rll_err_ind(struct msgb *msg)
1553{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001554 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001555 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001556 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00001557
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001558 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1559 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1560 LOGP(DRLL, LOGL_ERROR,
1561 "%s ERROR INDICATION without mandantory cause.\n",
1562 gsm_lchan_name(msg->lchan));
1563 return -1;
1564 }
1565
1566 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001567 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001568 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001569 rsl_rlm_cause_name(rlm_cause));
Harald Welteedcc5272009-08-09 13:47:35 +02001570
1571 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001572
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001573 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001574 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001575 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001576 }
Harald Welte81543bc2009-07-04 09:40:05 +02001577
Harald Welte4b634542008-12-27 01:55:51 +00001578 return 0;
1579}
Harald Weltef325eb42009-02-19 17:07:39 +00001580
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001581static void rsl_handle_release(struct gsm_lchan *lchan)
1582{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001583 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001584 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001585
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +01001586 /*
1587 * Maybe only one link/SAPI was releasd or the error handling
1588 * was activated. Just return now and let the other code handle
1589 * it.
1590 */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001591 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001592 return;
1593
1594 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1595 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1596 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001597 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001598 gsm_lchan_name(lchan), sapi);
1599 return;
1600 }
1601
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001602
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001603 /* Stop T3109 and wait for T3111 before re-using the channel */
1604 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001605 lchan->T3111.cb = t3111_expired;
1606 lchan->T3111.data = lchan;
1607 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001608 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001609}
1610
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001611/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001612 0x02, 0x06,
1613 0x01, 0x20,
1614 0x02, 0x00,
1615 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1616
1617static int abis_rsl_rx_rll(struct msgb *msg)
1618{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001619 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001620 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001621 int rc = 0;
1622 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001623 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001624
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001625 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001626 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001627 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001628
1629 switch (rllh->c.msg_type) {
1630 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001631 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001632 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001633 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1634 rllh->data[0] == RSL_IE_L3_INFO) {
1635 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001636 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001637 }
Harald Welte52b1f982008-12-23 20:25:15 +00001638 break;
1639 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001640 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001641 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001642 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001643 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001644 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001645 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1646 rllh->data[0] == RSL_IE_L3_INFO) {
1647 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001648 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001649 }
Harald Welte52b1f982008-12-23 20:25:15 +00001650 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001651 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001652 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001653 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001654 rll_indication(msg->lchan, rllh->link_id,
1655 BSC_RLLR_IND_EST_CONF);
1656 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001657 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001658 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001659 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001660 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001661 rll_indication(msg->lchan, rllh->link_id,
1662 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001663 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001664 break;
1665 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001666 /* BTS informs us of having received UA from MS,
1667 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001668 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001669 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001670 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001671 break;
1672 case RSL_MT_ERROR_IND:
1673 rc = rsl_rx_rll_err_ind(msg);
1674 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001675 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001676 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1677 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001678 break;
1679 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001680 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1681 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001682 }
Harald Welte8470bf22008-12-25 23:28:35 +00001683 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001684}
1685
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001686static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001687{
Harald Welte0603c9d2009-12-02 01:58:23 +05301688 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001689 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301690 switch (lchan->type) {
1691 case GSM_LCHAN_TCH_F:
1692 return 0x00;
1693 case GSM_LCHAN_TCH_H:
1694 return 0x03;
1695 default:
1696 break;
1697 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001698 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301699 switch (lchan->type) {
1700 case GSM_LCHAN_TCH_F:
1701 return 0x01;
1702 /* there's no half-rate EFR */
1703 default:
1704 break;
1705 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001706 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301707 switch (lchan->type) {
1708 case GSM_LCHAN_TCH_F:
1709 return 0x02;
1710 case GSM_LCHAN_TCH_H:
1711 return 0x05;
1712 default:
1713 break;
1714 }
1715 default:
1716 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001717 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001718 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301719 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001720 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001721}
1722
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001723static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01001724{
1725 switch (lchan->tch_mode) {
1726 case GSM48_CMODE_SPEECH_V1:
1727 switch (lchan->type) {
1728 case GSM_LCHAN_TCH_F:
1729 return RTP_PT_GSM_FULL;
1730 case GSM_LCHAN_TCH_H:
1731 return RTP_PT_GSM_HALF;
1732 default:
1733 break;
1734 }
1735 case GSM48_CMODE_SPEECH_EFR:
1736 switch (lchan->type) {
1737 case GSM_LCHAN_TCH_F:
1738 return RTP_PT_GSM_EFR;
1739 /* there's no half-rate EFR */
1740 default:
1741 break;
1742 }
1743 case GSM48_CMODE_SPEECH_AMR:
1744 switch (lchan->type) {
1745 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01001746 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02001747 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01001748 default:
1749 break;
1750 }
1751 default:
1752 break;
1753 }
1754 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1755 "tch_mode == 0x%02x\n & lchan_type == %d",
1756 lchan->tch_mode, lchan->type);
1757 return 0;
1758}
1759
Harald Welte75099262009-02-16 21:12:08 +00001760/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001761static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1762{
1763 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001764 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001765
1766 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001767 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001768 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1769 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1770 }
1771
1772 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001773 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001774 port = ntohs(port);
1775 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1776 lchan->abis_ip.bound_port = port;
1777 }
1778
1779 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001780 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001781 conn_id = ntohs(conn_id);
1782 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1783 lchan->abis_ip.conn_id = conn_id;
1784 }
1785
1786 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1787 lchan->abis_ip.rtp_payload2 =
1788 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1789 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1790 lchan->abis_ip.rtp_payload2);
1791 }
1792
1793 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1794 lchan->abis_ip.speech_mode =
1795 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1796 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1797 lchan->abis_ip.speech_mode);
1798 }
1799
1800 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001801 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001802 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1803 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1804 }
1805
1806 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001807 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001808 port = ntohs(port);
1809 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1810 lchan->abis_ip.connect_port = port;
1811 }
1812}
1813
Harald Welte647db842013-02-03 12:06:58 +01001814/*! \brief Issue IPA RSL CRCX to configure RTP on BTS side
1815 * \param[in] lchan Logical Channel for which we issue CRCX
1816 */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001817int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001818{
1819 struct msgb *msg = rsl_msgb_alloc();
1820 struct abis_rsl_dchan_hdr *dh;
1821
1822 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001823 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001824 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001825 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001826
Harald Weltef4e79f22009-07-28 18:11:56 +02001827 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001828 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001829 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001830 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001831 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001832
Sylvain Munautb54dda42009-12-20 22:06:40 +01001833 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1834 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1835 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001836
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001837 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001838
1839 return abis_rsl_sendmsg(msg);
1840}
1841
Harald Welte647db842013-02-03 12:06:58 +01001842/*! \brief Issue IPA RSL MDCX to configure MGW-side of RTP
1843 * \param[in] lchan Logical Channel for which we issue MDCX
1844 * \param[in] ip Remote (MGW) IP address for RTP
1845 * \param[in] port Remote (MGW) UDP port number for RTP
1846 * \param[in] rtp_payload2 Contents of RTP PAYLOAD 2 IE
1847 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001848int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1849 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001850{
1851 struct msgb *msg = rsl_msgb_alloc();
1852 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001853 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001854 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001855
1856 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001857 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001858 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001859 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001860
Harald Welte5e3d91b2009-12-19 16:42:06 +01001861 /* we need to store these now as MDCX_ACK does not return them :( */
1862 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1863 lchan->abis_ip.connect_port = port;
1864 lchan->abis_ip.connect_ip = ip;
1865
Harald Welte58ca5b72009-07-29 12:12:18 +02001866 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001867 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001868 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001869
Harald Weltef4e79f22009-07-28 18:11:56 +02001870 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001871 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1872 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1873 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1874 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001875
Harald Welte5e3d91b2009-12-19 16:42:06 +01001876 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1877 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001878 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001879 *att_ip = ia.s_addr;
1880 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1881 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001882 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001883 if (rtp_payload2)
1884 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001885
1886 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001887
1888 return abis_rsl_sendmsg(msg);
1889}
1890
Harald Weltea72273e2009-12-20 16:51:09 +01001891/* tell BTS to connect RTP stream to our local RTP socket */
1892int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1893{
1894 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1895 int rc;
1896
1897 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1898 ntohs(rs->rtp.sin_local.sin_port),
1899 /* FIXME: use RTP payload of bound socket, not BTS*/
1900 lchan->abis_ip.rtp_payload2);
1901
1902 return rc;
1903}
1904
Harald Welte53cd7ac2010-12-23 12:59:52 +01001905int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001906{
1907 struct msgb *msg = rsl_msgb_alloc();
1908 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001909 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08001910
1911 if (act)
1912 msg_type = RSL_MT_IPAC_PDCH_ACT;
1913 else
1914 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001915
1916 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001917 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001918 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001919 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001920
Harald Welte53cd7ac2010-12-23 12:59:52 +01001921 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001922 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001923
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001924 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02001925
1926 return abis_rsl_sendmsg(msg);
1927}
1928
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001929static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001930{
1931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1932 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301933 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001934
1935 /* the BTS has acknowledged a local bind, it now tells us the IP
1936 * address and port number to which it has bound the given logical
1937 * channel */
1938
1939 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1940 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1941 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001942 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001943 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001944 return -EINVAL;
1945 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001946
Harald Welte5e3d91b2009-12-19 16:42:06 +01001947 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001948
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001949 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001950
Harald Welte75099262009-02-16 21:12:08 +00001951 return 0;
1952}
1953
Harald Welte5e3d91b2009-12-19 16:42:06 +01001954static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1955{
1956 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1957 struct tlv_parsed tv;
1958 struct gsm_lchan *lchan = msg->lchan;
1959
1960 /* the BTS has acknowledged a remote connect request and
1961 * it now tells us the IP address and port number to which it has
1962 * connected the given logical channel */
1963
1964 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1965 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001966 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001967
1968 return 0;
1969}
1970
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001971static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001972{
1973 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1974 struct tlv_parsed tv;
1975
1976 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001977
Harald Welte8830e072009-07-28 17:58:09 +02001978 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001979 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001980 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001981
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001982 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001983
Harald Welte75099262009-02-16 21:12:08 +00001984 return 0;
1985}
1986
1987static int abis_rsl_rx_ipacc(struct msgb *msg)
1988{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001989 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00001990 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001991 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001992 int rc = 0;
1993
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001994 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001995 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001996
1997 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001998 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001999 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002000 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002001 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002002 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002003 /* somehow the BTS was unable to bind the lchan to its local
2004 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01002005 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002006 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002007 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00002008 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01002009 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01002010 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00002011 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002012 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00002013 /* somehow the BTS was unable to connect the lchan to a remote
2014 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01002015 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00002016 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002017 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01002018 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01002019 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00002020 break;
2021 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01002022 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002023 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00002024 break;
2025 }
Harald Welte6dab0552009-05-01 17:21:37 +00002026 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00002027
2028 return rc;
2029}
2030
2031
Harald Welte52b1f982008-12-23 20:25:15 +00002032/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00002033int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00002034{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002035 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002036 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002037
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002038 if (!msg) {
2039 DEBUGP(DRSL, "Empty RSL msg?..\n");
2040 return -1;
2041 }
2042
2043 if (msgb_l2len(msg) < sizeof(*rslh)) {
2044 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02002045 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002046 return -1;
2047 }
2048
2049 rslh = msgb_l2(msg);
2050
Harald Welte52b1f982008-12-23 20:25:15 +00002051 switch (rslh->msg_discr & 0xfe) {
2052 case ABIS_RSL_MDISC_RLL:
2053 rc = abis_rsl_rx_rll(msg);
2054 break;
2055 case ABIS_RSL_MDISC_DED_CHAN:
2056 rc = abis_rsl_rx_dchan(msg);
2057 break;
2058 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00002059 rc = abis_rsl_rx_cchan(msg);
2060 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002061 case ABIS_RSL_MDISC_TRX:
2062 rc = abis_rsl_rx_trx(msg);
2063 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002064 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002065 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002066 rslh->msg_discr);
2067 break;
Harald Welte75099262009-02-16 21:12:08 +00002068 case ABIS_RSL_MDISC_IPACCESS:
2069 rc = abis_rsl_rx_ipacc(msg);
2070 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002071 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002072 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2073 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002074 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002075 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002076 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002077 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002078}
Holger Freyther3b72a892009-02-04 00:31:39 +00002079
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002080int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
2081 uint8_t cb_command, const uint8_t *data, int len)
2082{
2083 struct abis_rsl_dchan_hdr *dh;
2084 struct msgb *cb_cmd;
2085
2086 cb_cmd = rsl_msgb_alloc();
2087 if (!cb_cmd)
2088 return -1;
2089
2090 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
2091 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2092 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2093
2094 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2095 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2096
2097 cb_cmd->trx = bts->c0;
2098
2099 return abis_rsl_sendmsg(cb_cmd);
2100}
Dieter Spaar16646022011-07-28 00:01:50 +02002101
2102int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2103{
2104 struct abis_rsl_common_hdr *ch;
2105 struct msgb *msg = rsl_msgb_alloc();
2106
2107 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2108 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2109 ch->msg_type = 0x40; /* Nokia SI Begin */
2110
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002111 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002112
2113 return abis_rsl_sendmsg(msg);
2114}
2115
2116int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2117{
2118 struct abis_rsl_common_hdr *ch;
2119 struct msgb *msg = rsl_msgb_alloc();
2120
2121 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2122 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2123 ch->msg_type = 0x41; /* Nokia SI End */
2124
2125 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2126
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002127 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002128
2129 return abis_rsl_sendmsg(msg);
2130}
2131
2132int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2133{
2134 struct abis_rsl_common_hdr *ch;
2135 struct msgb *msg = rsl_msgb_alloc();
2136
2137 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2138 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2139 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2140
2141 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2142 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2143
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002144 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002145
2146 return abis_rsl_sendmsg(msg);
2147}
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01002148
2149/**
2150 * Release all allocated SAPIs starting from @param start and
2151 * release them with the given release mode. Once the release
2152 * confirmation arrives it will be attempted to release the
2153 * the RF channel.
2154 */
2155int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2156 enum rsl_rel_mode release_mode)
2157{
2158 int no_sapi = 1;
2159 int sapi;
2160
2161 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2162 uint8_t link_id;
2163 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2164 continue;
2165
2166 link_id = sapi;
2167 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2168 link_id |= 0x40;
2169 rsl_release_request(lchan, link_id, release_mode);
2170 no_sapi = 0;
2171 }
2172
2173 return no_sapi;
2174}
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002175
2176int rsl_start_t3109(struct gsm_lchan *lchan)
2177{
2178 struct gsm_bts *bts = lchan->ts->trx->bts;
2179
2180 /* Disabled, mostly legacy code */
2181 if (bts->network->T3109 == 0)
2182 return -1;
2183
2184 lchan->T3109.cb = t3109_expired;
2185 lchan->T3109.data = lchan;
2186 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2187 return 0;
2188}
Holger Hans Peter Freyther006e3d82012-12-25 23:45:14 +01002189
2190/**
2191 * \brief directly RF Channel Release the lchan
2192 *
2193 * When no SAPI was allocated, directly release the logical channel. This
2194 * should only be called from chan_alloc.c on channel release handling. In
2195 * case no SAPI was established the RF Channel can be directly released,
2196 */
2197int rsl_direct_rf_release(struct gsm_lchan *lchan)
2198{
2199 int i;
2200 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2201 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2202 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2203 gsm_lchan_name(lchan), i);
2204 return -1;
2205 }
2206 }
2207
2208 /* Now release it */
2209 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2210}