blob: 03ad8da9c80b99ad2b7c2708ece24ba3625ae75c [file] [log] [blame]
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte52b1f982008-12-23 20:25:15 +00002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Welte3c9c5f92010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01005 * (C) 2012 by Holger Hans Peter Freyther
Harald Welte8470bf22008-12-25 23:28:35 +00006 *
Harald Welte52b1f982008-12-23 20:25:15 +00007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte52b1f982008-12-23 20:25:15 +000012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte52b1f982008-12-23 20:25:15 +000021 *
22 */
23
24#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
Harald Welte75099262009-02-16 21:12:08 +000027#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000028#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Harald Welte8470bf22008-12-25 23:28:35 +000030#include <openbsc/gsm_data.h>
31#include <openbsc/gsm_04_08.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010032#include <osmocom/gsm/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000033#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000036#include <openbsc/debug.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010037#include <osmocom/gsm/tlv.h>
Holger Freyther392209c2009-02-10 00:06:19 +000038#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000039#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010040#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010041#include <openbsc/rtp_proxy.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020042#include <osmocom/abis/e1_input.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010043#include <osmocom/gsm/rsl.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080045
Harald Welte8470bf22008-12-25 23:28:35 +000046#define RSL_ALLOC_SIZE 1024
47#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000048
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +010049enum sacch_deact {
50 SACCH_NONE,
51 SACCH_DEACTIVATE,
52};
53
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080054static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
55
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010056static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
57 struct gsm_meas_rep *resp)
58{
59 struct lchan_signal_data sig;
60 sig.lchan = lchan;
61 sig.mr = resp;
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +020062 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010063}
64
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +010065static void do_lchan_free(struct gsm_lchan *lchan)
66{
67 /* we have an error timer pending to release that */
68 if (lchan->state != LCHAN_S_REL_ERR)
69 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
70 lchan_free(lchan);
71}
72
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020073static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000074{
75 /* mask off the transparent bit ? */
76 msg_type &= 0xfe;
77
Harald Welte8470bf22008-12-25 23:28:35 +000078 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000079 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000080 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000081 if (msg_type >= 0x19 && msg_type <= 0x22)
82 return ABIS_RSL_MDISC_TRX;
83 else
84 return ABIS_RSL_MDISC_COM_CHAN;
85 }
Harald Welte2d5b6382008-12-27 19:46:06 +000086 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000087 return ABIS_RSL_MDISC_DED_CHAN;
88
89 return ABIS_RSL_MDISC_LOC;
90}
91
92static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020093 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000094{
95 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
96 dh->c.msg_type = msg_type;
97 dh->ie_chan = RSL_IE_CHAN_NR;
98}
99
Harald Welte8470bf22008-12-25 23:28:35 +0000100/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200101struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte8470bf22008-12-25 23:28:35 +0000102{
103 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200104 uint8_t ts_nr = chan_nr & 0x07;
105 uint8_t cbits = chan_nr >> 3;
106 uint8_t lch_idx;
Harald Welte8470bf22008-12-25 23:28:35 +0000107 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
108
109 if (cbits == 0x01) {
110 lch_idx = 0; /* TCH/F */
Harald Weltea1499d02009-10-24 10:25:50 +0200111 if (ts->pchan != GSM_PCHAN_TCH_F &&
112 ts->pchan != GSM_PCHAN_PDCH &&
113 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100114 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000115 chan_nr, ts->pchan);
116 } else if ((cbits & 0x1e) == 0x02) {
117 lch_idx = cbits & 0x1; /* TCH/H */
118 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100119 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000120 chan_nr, ts->pchan);
121 } else if ((cbits & 0x1c) == 0x04) {
122 lch_idx = cbits & 0x3; /* SDCCH/4 */
123 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100124 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000125 chan_nr, ts->pchan);
126 } else if ((cbits & 0x18) == 0x08) {
127 lch_idx = cbits & 0x7; /* SDCCH/8 */
128 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100129 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000130 chan_nr, ts->pchan);
131 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
132 lch_idx = 0;
133 if (ts->pchan != GSM_PCHAN_CCCH &&
134 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100135 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000136 chan_nr, ts->pchan);
137 /* FIXME: we should not return first sdcch4 !!! */
138 } else {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100139 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000140 return NULL;
141 }
142
143 lchan = &ts->lchan[lch_idx];
Harald Weltedc5062b2010-03-26 21:28:59 +0800144 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800145 if (lchan->conn)
146 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000147
148 return lchan;
149}
150
Harald Welte52b1f982008-12-23 20:25:15 +0000151/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200152uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000153{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200154 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000155
156 ret = strtoull(imsi_str, NULL, 10);
157
158 return ret;
159}
160
Harald Welte8470bf22008-12-25 23:28:35 +0000161static struct msgb *rsl_msgb_alloc(void)
162{
Harald Welte966636f2009-06-26 19:39:35 +0200163 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
164 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000165}
166
Harald Welte362322e2009-02-15 14:36:38 +0000167#define MACBLOCK_SIZE 23
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200168static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000169{
170 memcpy(out, in, len);
171
172 if (len < MACBLOCK_SIZE)
173 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
174}
175
Harald Welte08d91a52009-08-30 15:37:11 +0900176/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200177static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900178{
179 *out++ = lchan->encr.alg_id & 0xff;
180 if (lchan->encr.key_len)
181 memcpy(out, lchan->encr.key, lchan->encr.key_len);
182 return lchan->encr.key_len + 1;
183}
184
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200185static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200186{
Harald Welte7f93cea2009-02-23 00:02:59 +0000187 int i;
188
Harald Welte5b8ed432009-12-24 12:20:20 +0100189 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200190 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200191 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100192 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000193}
194
Harald Weltee8bd9e82011-08-10 23:26:33 +0200195static void lchan_act_tmr_cb(void *data)
196{
197 struct gsm_lchan *lchan = data;
198
Holger Hans Peter Freyther1411c062012-12-06 19:00:35 +0100199 LOGP(DRSL, LOGL_ERROR, "%s Timeout during activation!\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200200 gsm_lchan_name(lchan));
201
Daniel Willmann513da172011-08-11 04:44:12 +0200202 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
203 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200204}
205
206static void lchan_deact_tmr_cb(void *data)
207{
208 struct gsm_lchan *lchan = data;
209
Holger Hans Peter Freyther1411c062012-12-06 19:00:35 +0100210 LOGP(DRSL, LOGL_ERROR, "%s Timeout during deactivation!\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200211 gsm_lchan_name(lchan));
212
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100213 do_lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200214}
215
216
Harald Welte52b1f982008-12-23 20:25:15 +0000217/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200218int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
219 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000220{
221 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000222 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000223
224 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
225 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
226 dh->chan_nr = RSL_CHAN_BCCH;
227
228 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
229 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
230
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200231 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000232
233 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000234}
235
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200236int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
237 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000238{
239 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000240 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000241
242 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
243 ch->msg_discr = ABIS_RSL_MDISC_TRX;
244 ch->msg_type = RSL_MT_SACCH_FILL;
245
246 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000247 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000248
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200249 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000250
251 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000252}
253
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200254int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
255 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100256{
257 struct abis_rsl_dchan_hdr *dh;
258 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200259 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100260
261 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
262 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
263 dh->chan_nr = chan_nr;
264
265 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
266 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
267
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200268 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100269
270 return abis_rsl_sendmsg(msg);
271}
272
Harald Weltefcd24452009-06-20 18:15:19 +0200273int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
274{
275 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200276 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200277 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200278
279 db = abs(db);
280 if (db > 30)
281 return -EINVAL;
282
Harald Welteeab33352009-06-27 03:09:08 +0200283 msg = rsl_msgb_alloc();
284
Harald Weltefcd24452009-06-20 18:15:19 +0200285 lchan->bs_power = db/2;
286 if (fpc)
287 lchan->bs_power |= 0x10;
288
289 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
290 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
291 dh->chan_nr = chan_nr;
292
293 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
294
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200295 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200296
297 return abis_rsl_sendmsg(msg);
298}
299
Harald Weltefcd24452009-06-20 18:15:19 +0200300int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
301{
302 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200303 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200304 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200305 int ctl_lvl;
306
Harald Welte66b6a8d2009-08-09 14:45:18 +0200307 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200308 if (ctl_lvl < 0)
309 return ctl_lvl;
310
Harald Welteeab33352009-06-27 03:09:08 +0200311 msg = rsl_msgb_alloc();
312
Harald Weltefcd24452009-06-20 18:15:19 +0200313 lchan->ms_power = ctl_lvl;
314
315 if (fpc)
316 lchan->ms_power |= 0x20;
317
318 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
319 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
320 dh->chan_nr = chan_nr;
321
322 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
323
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200324 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200325
326 return abis_rsl_sendmsg(msg);
327}
328
Harald Welte9943c5b2009-07-29 15:41:29 +0200329static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
330 struct gsm_lchan *lchan)
331{
332 memset(cm, 0, sizeof(cm));
333
334 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800335 if (lchan->ts->trx->bts->network->dtx_enabled)
336 cm->dtx_dtu = 0x03;
337 else
338 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200339
340 /* set TCH Speech/Data */
341 cm->spd_ind = lchan->rsl_cmode;
342
Harald Welte1a79d362009-11-27 08:55:16 +0100343 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
344 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100345 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100346 "but tch_mode != signalling\n");
347
Harald Welte9943c5b2009-07-29 15:41:29 +0200348 switch (lchan->type) {
349 case GSM_LCHAN_SDCCH:
350 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
351 break;
352 case GSM_LCHAN_TCH_F:
353 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
354 break;
355 case GSM_LCHAN_TCH_H:
356 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
357 break;
358 case GSM_LCHAN_NONE:
359 case GSM_LCHAN_UNKNOWN:
360 default:
361 return -EINVAL;
362 }
363
364 switch (lchan->tch_mode) {
365 case GSM48_CMODE_SIGN:
366 cm->chan_rate = 0;
367 break;
368 case GSM48_CMODE_SPEECH_V1:
369 cm->chan_rate = RSL_CMOD_SP_GSM1;
370 break;
371 case GSM48_CMODE_SPEECH_EFR:
372 cm->chan_rate = RSL_CMOD_SP_GSM2;
373 break;
374 case GSM48_CMODE_SPEECH_AMR:
375 cm->chan_rate = RSL_CMOD_SP_GSM3;
376 break;
377 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200378 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200379 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200380 switch (lchan->csd_mode) {
381 case LCHAN_CSD_M_NT:
382 /* non-transparent CSD with RLP */
383 switch (lchan->tch_mode) {
384 case GSM48_CMODE_DATA_14k5:
385 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
386 break;
387 case GSM48_CMODE_DATA_12k0:
388 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
389 break;
390 case GSM48_CMODE_DATA_6k0:
391 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
392 break;
393 default:
394 return -EINVAL;
395 }
396 break;
397 /* transparent data services below */
398 case LCHAN_CSD_M_T_1200_75:
399 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
400 break;
401 case LCHAN_CSD_M_T_600:
402 cm->chan_rate = RSL_CMOD_CSD_T_600;
403 break;
404 case LCHAN_CSD_M_T_1200:
405 cm->chan_rate = RSL_CMOD_CSD_T_1200;
406 break;
407 case LCHAN_CSD_M_T_2400:
408 cm->chan_rate = RSL_CMOD_CSD_T_2400;
409 break;
410 case LCHAN_CSD_M_T_9600:
411 cm->chan_rate = RSL_CMOD_CSD_T_9600;
412 break;
413 case LCHAN_CSD_M_T_14400:
414 cm->chan_rate = RSL_CMOD_CSD_T_14400;
415 break;
416 case LCHAN_CSD_M_T_29000:
417 cm->chan_rate = RSL_CMOD_CSD_T_29000;
418 break;
419 case LCHAN_CSD_M_T_32000:
420 cm->chan_rate = RSL_CMOD_CSD_T_32000;
421 break;
422 default:
423 return -EINVAL;
424 }
Harald Welte9943c5b2009-07-29 15:41:29 +0200425 default:
426 return -EINVAL;
427 }
428
429 return 0;
430}
431
Harald Welte52b1f982008-12-23 20:25:15 +0000432/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000433#if 0
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200434int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
435 uint8_t act_type,
Harald Welte52b1f982008-12-23 20:25:15 +0000436 struct rsl_ie_chan_mode *chan_mode,
437 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200438 uint8_t bs_power, uint8_t ms_power,
439 uint8_t ta)
Harald Welte52b1f982008-12-23 20:25:15 +0000440{
441 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000442 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000443
444 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
445 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
446 dh->chan_nr = chan_nr;
447
448 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
449 /* For compatibility with Phase 1 */
450 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200451 (uint8_t *) chan_mode);
Harald Welte52b1f982008-12-23 20:25:15 +0000452 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200453 (uint8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000454#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000455 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200456 (uint8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000457#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000458 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000459 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
460 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
461
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200462 msg->dst = trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000463
Harald Welte8470bf22008-12-25 23:28:35 +0000464 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000465}
Harald Welteddab3c72009-02-28 13:19:15 +0000466#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000467
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200468int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
469 uint8_t ta, uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000470{
471 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200472 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200473 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200474 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000475
Harald Weltef6093a42011-06-25 10:02:33 +0200476 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000477 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200478 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000479
Harald Welte9943c5b2009-07-29 15:41:29 +0200480 rc = channel_mode_from_lchan(&cm, lchan);
481 if (rc < 0)
482 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000483
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800484 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200485 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000486
Harald Welteeab33352009-06-27 03:09:08 +0200487 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000488 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
489 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
490 dh->chan_nr = chan_nr;
491
492 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000493 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200494 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800495
496 /*
497 * The Channel Identification is needed for Phase1 phones
498 * and it contains the GSM48 Channel Description and the
499 * Mobile Allocation. The GSM 08.58 asks for the Mobile
500 * Allocation to have a length of zero. We are using the
501 * msgb_l3len to calculate the length of both messages.
502 */
laforge694a5cf2010-06-20 21:38:19 +0200503 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200504 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200505 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800506
507 if (lchan->ts->hopping.enabled)
508 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
509 lchan->ts->hopping.ma_data);
510 else
511 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800512
513 /* update the calculated size */
514 msg->l3h = len + 1;
515 *len = msgb_l3len(msg);
516
Harald Welte08d91a52009-08-30 15:37:11 +0900517 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200518 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900519 rc = build_encr_info(encr_info, lchan);
520 if (rc > 0)
521 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
522 }
523
Harald Welte8d77b952009-12-17 00:31:10 +0100524 switch (act_type) {
525 case RSL_ACT_INTER_ASYNC:
526 case RSL_ACT_INTER_SYNC:
527 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
528 break;
529 default:
530 break;
531 }
532
Harald Welted4c9bf32009-02-15 16:56:18 +0000533 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
534 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000535 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
536
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100537 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
538 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200539 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100540
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200541 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000542
Harald Welte4b634542008-12-27 01:55:51 +0000543 return abis_rsl_sendmsg(msg);
544}
545
Harald Welte470abb72009-07-29 11:38:15 +0200546/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000547int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
548{
549 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200550 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200551 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000552
Harald Weltef6093a42011-06-25 10:02:33 +0200553 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000554 struct rsl_ie_chan_mode cm;
555
Harald Welte9943c5b2009-07-29 15:41:29 +0200556 rc = channel_mode_from_lchan(&cm, lchan);
557 if (rc < 0)
558 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000559
Harald Welteeab33352009-06-27 03:09:08 +0200560 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000561 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
562 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
563 dh->chan_nr = chan_nr;
564
565 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200566 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900567
568 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200569 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900570 rc = build_encr_info(encr_info, lchan);
571 if (rc > 0)
572 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
573 }
574
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100575 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
576 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200577 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100578 }
579
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200580 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900581
582 return abis_rsl_sendmsg(msg);
583}
584
585/* Chapter 8.4.6: Send the encryption command with given L3 info */
586int rsl_encryption_cmd(struct msgb *msg)
587{
588 struct abis_rsl_dchan_hdr *dh;
589 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200590 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200591 uint8_t encr_info[MAX_A5_KEY_LEN+2];
592 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900593 int rc;
594
595 /* First push the L3 IE tag and length */
596 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
597
598 /* then the link identifier (SAPI0, main sign link) */
599 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
600
601 /* then encryption information */
602 rc = build_encr_info(encr_info, lchan);
603 if (rc <= 0)
604 return rc;
605 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
606
607 /* and finally the DCHAN header */
608 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
609 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
610 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000611
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200612 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000613
614 return abis_rsl_sendmsg(msg);
615}
616
Harald Welte115d1032009-08-10 11:43:22 +0200617/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200618int rsl_deact_sacch(struct gsm_lchan *lchan)
619{
620 struct abis_rsl_dchan_hdr *dh;
621 struct msgb *msg = rsl_msgb_alloc();
622
623 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
624 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200625 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200626
627 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200628 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200629
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100630 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200631
632 return abis_rsl_sendmsg(msg);
633}
634
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800635static void error_timeout_cb(void *data)
636{
637 struct gsm_lchan *lchan = data;
638 if (lchan->state != LCHAN_S_REL_ERR) {
639 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
640 gsm_lchan_name(lchan), lchan->state);
641 return;
642 }
643
644 /* go back to the none state */
645 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800646 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800647}
648
Harald Weltefd355a32011-03-04 13:41:31 +0100649static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
650
Harald Welte115d1032009-08-10 11:43:22 +0200651/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100652static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
653 enum sacch_deact deact_sacch)
Harald Welte52b1f982008-12-23 20:25:15 +0000654{
655 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800656 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100657 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000658
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100659 /* Stop timers that should lead to a channel release */
660 osmo_timer_del(&lchan->T3109);
661
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800662 if (lchan->state == LCHAN_S_REL_ERR) {
663 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
664 gsm_lchan_name(lchan));
665 return -1;
666 }
667
668 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000669 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
670 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200671 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000672
Harald Welte8470bf22008-12-25 23:28:35 +0000673 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200674 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000675
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800676 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
677
678 if (error) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200679 struct e1inp_sign_link *sign_link = msg->dst;
680
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100681 /*
682 * FIXME: GSM 04.08 gives us two options for the abnormal
683 * chanel release. This can be either like in the non-existent
684 * sub-lcuase 3.5.1 or for the main signalling link deactivate
685 * the SACCH, start timer T3109 and consider the channel as
686 * released.
687 *
688 * This code is doing the later for all raido links and not
689 * only the main link. Right now all SAPIs are released on the
690 * local end, the SACCH will be de-activated and right now the
691 * T3111 will be started. First T3109 should be started and then
692 * the T3111.
693 *
694 * TODO: Move this out of the function.
695 */
696
697 /*
698 * sacch de-activate and "local end release"
699 */
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100700 if (deact_sacch == SACCH_DEACTIVATE)
701 rsl_deact_sacch(lchan);
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +0100702 rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
703
704 /*
705 * TODO: start T3109 now.
706 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800707 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800708 lchan->error_timer.data = lchan;
709 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200710 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200711 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800712 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000713
Harald Weltee8bd9e82011-08-10 23:26:33 +0200714 /* Start another timer or assume the BTS sends a ACK/NACK? */
715 lchan->act_timer.cb = lchan_deact_tmr_cb;
716 lchan->act_timer.data = lchan;
717 osmo_timer_schedule(&lchan->act_timer, 4, 0);
718
Harald Weltefd355a32011-03-04 13:41:31 +0100719 rc = abis_rsl_sendmsg(msg);
720
Harald Welte115d1032009-08-10 11:43:22 +0200721 /* BTS will respond by RF CHAN REL ACK */
Harald Welte26d79072011-01-14 23:18:59 +0100722#ifdef HSL_SR_1_0
Harald Weltefd355a32011-03-04 13:41:31 +0100723 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
724 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
725 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte26d79072011-01-14 23:18:59 +0100726#endif
Harald Weltefd355a32011-03-04 13:41:31 +0100727
728 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000729}
730
Harald Welte64bb7542011-01-14 14:16:16 +0100731static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
732{
733
734 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
735
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100736 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200737 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100738 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200739
Harald Welte64bb7542011-01-14 14:16:16 +0100740 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
741 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
742 gsm_lchan_name(lchan),
743 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100744 do_lchan_free(lchan);
Harald Welte64bb7542011-01-14 14:16:16 +0100745
746 return 0;
747}
748
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200749int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
750 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte52b1f982008-12-23 20:25:15 +0000751{
752 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000753 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000754
755 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
756 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
757 dh->chan_nr = RSL_CHAN_PCH_AGCH;
758
759 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000760 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000761 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
762
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200763 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000764
765 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000766}
767
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200768int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +0000769{
770 int i, len = strlen(str_in);
771
772 for (i = 0; i < len; i++) {
773 int num = str_in[i] - 0x30;
774 if (num < 0 || num > 9)
775 return -1;
776 if (i % 2 == 0)
777 bcd_out[i/2] = num;
778 else
779 bcd_out[i/2] |= (num << 4);
780 }
781
782 return 0;
783}
784
Harald Welte702d8702008-12-26 20:25:35 +0000785/* Chapter 8.5.6 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200786int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +0000787{
Harald Welte8470bf22008-12-25 23:28:35 +0000788 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000789 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200790 uint8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000791
792 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
793 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
794 dh->chan_nr = RSL_CHAN_PCH_AGCH;
795
Harald Welte362322e2009-02-15 14:36:38 +0000796 switch (bts->type) {
797 case GSM_BTS_TYPE_BS11:
798 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
799 break;
800 default:
801 /* If phase 2, construct a FULL_IMM_ASS_INFO */
802 pad_macblock(buf, val, len);
803 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
804 break;
805 }
Harald Welte52b1f982008-12-23 20:25:15 +0000806
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200807 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000808
809 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000810}
811
Harald Welte67fa91b2009-08-10 09:51:40 +0200812/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200813int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200814{
815 struct msgb *msg = rsl_msgb_alloc();
816 struct abis_rsl_dchan_hdr *dh;
817
818 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
819 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200820 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +0200821 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200822 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200823
Harald Welte5b8ed432009-12-24 12:20:20 +0100824 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200825 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200826
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200827 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +0200828
Harald Welte67fa91b2009-08-10 09:51:40 +0200829 return abis_rsl_sendmsg(msg);
830}
831
832
Harald Welte8470bf22008-12-25 23:28:35 +0000833/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000834/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200835int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000836{
Harald Welte8470bf22008-12-25 23:28:35 +0000837 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100838 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000839 return -EINVAL;
840 }
Harald Welte52b1f982008-12-23 20:25:15 +0000841
Harald Weltef6093a42011-06-25 10:02:33 +0200842 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100843 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000844
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200845 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000846
847 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000848}
849
Harald Welteedcc5272009-08-09 13:47:35 +0200850/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
851/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200852int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +0200853{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100854 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200855
Harald Weltef6093a42011-06-25 10:02:33 +0200856 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100857 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200858 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +0200859
Harald Weltefda74ee2012-04-26 19:42:19 +0200860 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
861 gsm_lchan_name(lchan), link_id);
862
Harald Welteedcc5272009-08-09 13:47:35 +0200863 return abis_rsl_sendmsg(msg);
864}
865
Harald Welted2dc1de2009-08-08 13:15:07 +0200866/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
867 This is what higher layers should call. The BTS then responds with
868 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
869 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
870 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100871int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
872 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +0200873{
Harald Welted2dc1de2009-08-08 13:15:07 +0200874
Harald Welte3c9c5f92010-03-04 10:33:10 +0100875 struct msgb *msg;
876
Harald Weltef6093a42011-06-25 10:02:33 +0200877 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100878 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800879 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100880 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +0200881
Harald Welte8e93b792009-12-29 10:44:17 +0100882 /* FIXME: start some timer in case we don't receive a REL ACK ? */
883
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200884 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +0200885
Harald Weltefda74ee2012-04-26 19:42:19 +0200886 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100887 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +0200888
Harald Welted2dc1de2009-08-08 13:15:07 +0200889 return abis_rsl_sendmsg(msg);
890}
891
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200892int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
893{
894 lchan->state = state;
895 return 0;
896}
897
Harald Welte702d8702008-12-26 20:25:35 +0000898/* Chapter 8.4.2: Channel Activate Acknowledge */
899static int rsl_rx_chan_act_ack(struct msgb *msg)
900{
901 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
902
903 /* BTS has confirmed channel activation, we now need
904 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000905 if (rslh->ie_chan != RSL_IE_CHAN_NR)
906 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100907
Harald Weltee8bd9e82011-08-10 23:26:33 +0200908 osmo_timer_del(&msg->lchan->act_timer);
909
Harald Welte8e93b792009-12-29 10:44:17 +0100910 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100911 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
912 gsm_lchan_name(msg->lchan),
913 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200914 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100915
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800916 if (msg->lchan->rqd_ref) {
917 rsl_send_imm_assignment(msg->lchan);
918 talloc_free(msg->lchan->rqd_ref);
919 msg->lchan->rqd_ref = NULL;
920 msg->lchan->rqd_ta = 0;
921 }
922
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100923 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100924
Harald Welte4b634542008-12-27 01:55:51 +0000925 return 0;
926}
Harald Welte702d8702008-12-26 20:25:35 +0000927
Harald Welte4b634542008-12-27 01:55:51 +0000928/* Chapter 8.4.3: Channel Activate NACK */
929static int rsl_rx_chan_act_nack(struct msgb *msg)
930{
Harald Welte6dab0552009-05-01 17:21:37 +0000931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
932 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000933
Harald Weltee8bd9e82011-08-10 23:26:33 +0200934 osmo_timer_del(&msg->lchan->act_timer);
935
Daniel Willmann6fc6a122011-08-11 04:54:23 +0200936 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100937 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100938
Harald Welte6dab0552009-05-01 17:21:37 +0000939 /* BTS has rejected channel activation ?!? */
940 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000941 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000942
943 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100944 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200945 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100946 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200947 TLVP_LEN(&tp, RSL_IE_CAUSE));
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100948 msg->lchan->error_cause = *cause;
Harald Welte (local)3e460312009-12-27 18:12:29 +0100949 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100950 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200951 else
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100952 rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200953
Harald Welte (local)3e460312009-12-27 18:12:29 +0100954 } else
Holger Hans Peter Freyther638da512012-12-06 19:25:06 +0100955 rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200956
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100957 LOGPC(DRSL, LOGL_ERROR, "\n");
958
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100959 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte4b634542008-12-27 01:55:51 +0000960 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000961}
962
Harald Welte7f93cea2009-02-23 00:02:59 +0000963/* Chapter 8.4.4: Connection Failure Indication */
964static int rsl_rx_conn_fail(struct msgb *msg)
965{
966 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
967 struct tlv_parsed tp;
968
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100969 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100970 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100971 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000972
973 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
974
Harald Welte8830e072009-07-28 17:58:09 +0200975 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100976 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200977 TLVP_LEN(&tp, RSL_IE_CAUSE));
978
Harald Welte (local)fc057502009-12-26 22:33:09 +0100979 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000980 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +0200981 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +0100982 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Harald Welte7f93cea2009-02-23 00:02:59 +0000983}
984
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100985static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
986 const char *prefix)
987{
Harald Welte6739dfb2009-12-16 16:52:07 +0100988 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
989 prefix, rxlev2dbm(mru->full.rx_lev),
990 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100991 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
992 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
993}
994
Harald Welte0c1bd612012-07-02 17:12:08 +0200995static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100996{
Harald Welte6739dfb2009-12-16 16:52:07 +0100997 int i;
Harald Welte0c1bd612012-07-02 17:12:08 +0200998 char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +0100999
Harald Welte0c1bd612012-07-02 17:12:08 +02001000 if (lchan && lchan->conn && lchan->conn->subscr)
1001 name = subscr_name(lchan->conn->subscr);
1002
1003 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001004
1005 if (mr->flags & MEAS_REP_F_DL_DTX)
1006 DEBUGPC(DMEAS, "DTXd ");
1007
1008 print_meas_rep_uni(&mr->ul, "ul");
1009 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
1010 if (mr->flags & MEAS_REP_F_MS_TO)
1011 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
1012
1013 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +01001014 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001015 DEBUGPC(DMEAS, "L1_FPC=%u ",
1016 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
1017 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
1018 }
1019
1020 if (mr->flags & MEAS_REP_F_UL_DTX)
1021 DEBUGPC(DMEAS, "DTXu ");
1022 if (mr->flags & MEAS_REP_F_BA1)
1023 DEBUGPC(DMEAS, "BA1 ");
1024 if (!(mr->flags & MEAS_REP_F_DL_VALID))
1025 DEBUGPC(DMEAS, "NOT VALID ");
1026 else
1027 print_meas_rep_uni(&mr->dl, "dl");
1028
1029 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001030 if (mr->num_cell == 7)
1031 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001032 for (i = 0; i < mr->num_cell; i++) {
1033 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001034 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1035 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001036 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001037}
1038
Harald Welte440fed02009-05-01 18:43:47 +00001039static int rsl_rx_meas_res(struct msgb *msg)
1040{
1041 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1042 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001043 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001044 uint8_t len;
1045 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001046 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001047
Harald Welteb8bfc562009-12-21 13:27:11 +01001048 /* check if this channel is actually active */
1049 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001050 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001051 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001052 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001053 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001054 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001055
Harald Welted12b0fd2009-12-15 21:36:05 +01001056 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001057 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001058
Harald Welte440fed02009-05-01 18:43:47 +00001059 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1060
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001061 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1062 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1063 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1064 return -EIO;
1065
1066 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001067 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001068
1069 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1070 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1071 if (len >= 3) {
1072 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001073 mr->flags |= MEAS_REP_F_DL_DTX;
1074 mr->ul.full.rx_lev = val[0] & 0x3f;
1075 mr->ul.sub.rx_lev = val[1] & 0x3f;
1076 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1077 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001078 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001079
Harald Welted12b0fd2009-12-15 21:36:05 +01001080 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001081
1082 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +00001083 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +01001084 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001085 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1086
Harald Weltefe9af262009-06-20 18:44:35 +02001087 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001088 struct e1inp_sign_link *sign_link = msg->dst;
1089
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001090 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001091 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001092 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001093 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001094 mr->flags |= MEAS_REP_F_FPC;
1095 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001096 /* BS11 and Nokia reports TA shifted by 2 bits */
1097 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1098 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001099 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001100 }
Harald Weltef7c43522009-06-09 20:24:21 +00001101 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001102 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001103 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001104 if (rc < 0)
1105 return rc;
1106 }
1107
Harald Welte0c1bd612012-07-02 17:12:08 +02001108 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001109
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001110 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001111
Harald Welte75d34a82009-05-23 06:11:13 +00001112 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001113}
1114
Harald Welted011e8b2009-11-29 22:45:52 +01001115/* Chapter 8.4.7 */
1116static int rsl_rx_hando_det(struct msgb *msg)
1117{
1118 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1119 struct tlv_parsed tp;
1120
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001121 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001122
1123 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1124
1125 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1126 DEBUGPC(DRSL, "access delay = %u\n",
1127 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1128 else
1129 DEBUGPC(DRSL, "\n");
1130
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001131 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001132
1133 return 0;
1134}
1135
Harald Welte52b1f982008-12-23 20:25:15 +00001136static int abis_rsl_rx_dchan(struct msgb *msg)
1137{
Harald Welte8470bf22008-12-25 23:28:35 +00001138 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1139 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001140 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001141 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001142
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001143 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001144 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001145
Harald Welte8470bf22008-12-25 23:28:35 +00001146 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001147 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001148 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001149 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001150 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001151 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001152 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001153 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001154 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001155 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001156 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001157 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001158 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001159 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001160 case RSL_MT_HANDO_DET:
1161 rc = rsl_rx_hando_det(msg);
1162 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001163 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001164 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001165 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001166 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001167 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001168 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001169 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001170 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001171 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001172 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001173 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001174 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001175 break;
1176 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001177 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001178 break;
1179 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001180 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001181 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001182 break;
1183 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001184 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001185 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001186 case RSL_MT_PHY_CONTEXT_CONF:
1187 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001188 case RSL_MT_TALKER_DET:
1189 case RSL_MT_LISTENER_DET:
1190 case RSL_MT_REMOTE_CODEC_CONF_REP:
1191 case RSL_MT_MR_CODEC_MOD_ACK:
1192 case RSL_MT_MR_CODEC_MOD_NACK:
1193 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001194 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1195 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001196 break;
1197 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001198 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1199 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001200 return -EINVAL;
1201 }
Harald Weltef325eb42009-02-19 17:07:39 +00001202
Harald Welte8470bf22008-12-25 23:28:35 +00001203 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001204}
1205
Harald Welte702d8702008-12-26 20:25:35 +00001206static int rsl_rx_error_rep(struct msgb *msg)
1207{
1208 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001209 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001210 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001211
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001212 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001213
1214 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1215
1216 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001217 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001218 TLVP_LEN(&tp, RSL_IE_CAUSE));
1219
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001220 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001221
1222 return 0;
1223}
1224
Harald Welte52b1f982008-12-23 20:25:15 +00001225static int abis_rsl_rx_trx(struct msgb *msg)
1226{
Harald Welte702d8702008-12-26 20:25:35 +00001227 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001228 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001229 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001230
1231 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001232 case RSL_MT_ERROR_REPORT:
1233 rc = rsl_rx_error_rep(msg);
1234 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001235 case RSL_MT_RF_RES_IND:
1236 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001237 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001238 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001239 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001240 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001241 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001242 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001243 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001244 case 0x42: /* Nokia specific: SI End ACK */
1245 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1246 break;
1247 case 0x43: /* Nokia specific: SI End NACK */
1248 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1249 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001250 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001251 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001252 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001253 return -EINVAL;
1254 }
Harald Welte8470bf22008-12-25 23:28:35 +00001255 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001256}
1257
Harald Welteb7e81162009-08-10 00:26:10 +02001258/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1259static void t3101_expired(void *data)
1260{
1261 struct gsm_lchan *lchan = data;
1262
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001263 rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
Harald Welteb7e81162009-08-10 00:26:10 +02001264}
1265
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001266/* If T3111 expires, we will send the RF Channel Request */
1267static void t3111_expired(void *data)
1268{
1269 struct gsm_lchan *lchan = data;
1270
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001271 rsl_rf_chan_release(lchan, 0, SACCH_NONE);
1272}
1273
1274/* If T3109 expires the MS has not send a UA/UM do the error release */
1275static void t3109_expired(void *data)
1276{
1277 struct gsm_lchan *lchan = data;
1278
1279 LOGP(DRSL, LOGL_ERROR,
1280 "%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
1281 rsl_rf_chan_release(lchan, 1, SACCH_NONE);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001282}
1283
laforgecfa4a012010-06-21 12:08:52 +02001284#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1285
Harald Welte2862dca2010-12-23 14:39:29 +01001286/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1287static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1288 unsigned int num_req_refs,
1289 struct gsm48_req_ref *rqd_refs,
1290 uint8_t wait_ind)
1291{
1292 uint8_t buf[GSM_MACBLOCK_LEN];
1293 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1294
1295 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1296 memset(iar, 0, sizeof(*iar));
1297 iar->proto_discr = GSM48_PDISC_RR;
1298 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1299 iar->page_mode = GSM48_PM_SAME;
1300
1301 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1302 iar->wait_ind1 = wait_ind;
1303
1304 if (num_req_refs >= 2)
1305 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1306 else
1307 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1308 iar->wait_ind2 = wait_ind;
1309
1310 if (num_req_refs >= 3)
1311 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1312 else
1313 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1314 iar->wait_ind3 = wait_ind;
1315
1316 if (num_req_refs >= 4)
1317 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1318 else
1319 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1320 iar->wait_ind4 = wait_ind;
1321
1322 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1323}
1324
Harald Welte8470bf22008-12-25 23:28:35 +00001325/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001326static int rsl_rx_chan_rqd(struct msgb *msg)
1327{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001328 struct e1inp_sign_link *sign_link = msg->dst;
1329 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001330 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1331 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001332 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001333 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001334 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001335 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001336 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001337
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001338 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001339 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001340
Harald Welte8470bf22008-12-25 23:28:35 +00001341 /* parse request reference to be used in immediate assign */
1342 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1343 return -EINVAL;
1344
1345 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1346
1347 /* parse access delay and use as TA */
1348 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1349 return -EINVAL;
1350 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1351
1352 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1353 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001354 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1355 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001356
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001357 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001358
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001359 /*
1360 * We want LOCATION UPDATES to succeed and will assign a TCH
1361 * if we have no SDCCH available.
1362 */
1363 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1364
Harald Welte8470bf22008-12-25 23:28:35 +00001365 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001366 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001367 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001368 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001369 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001370 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001371 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1372 if (bts->network->T3122)
1373 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001374 return -ENOMEM;
1375 }
1376
Harald Welte8e93b792009-12-29 10:44:17 +01001377 if (lchan->state != LCHAN_S_NONE)
1378 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001379 "in state %s\n", gsm_lchan_name(lchan),
1380 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001381
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001382 /* save the RACH data as we need it after the CHAN ACT ACK */
1383 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1384 if (!lchan->rqd_ref) {
1385 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1386 lchan_free(lchan);
1387 return -ENOMEM;
1388 }
1389
Holger Hans Peter Freytherc0a66742011-12-29 23:33:04 +01001390 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001391 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1392 lchan->rqd_ta = rqd_ta;
1393
Harald Welte8470bf22008-12-25 23:28:35 +00001394 arfcn = lchan->ts->trx->arfcn;
1395 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001396
Harald Welte08d91a52009-08-30 15:37:11 +09001397 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001398 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001399 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001400 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001401 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001402
Harald Weltee8bd9e82011-08-10 23:26:33 +02001403 /* Start another timer or assume the BTS sends a ACK/NACK? */
1404 lchan->act_timer.cb = lchan_act_tmr_cb;
1405 lchan->act_timer.data = lchan;
1406 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1407
Andreas Eversberg2957de92011-12-16 17:45:37 +01001408 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1409 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1410 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1411 rqd_ref->ra, rqd_ta);
1412
1413 /* BS11 requires TA shifted by 2 bits */
1414 if (bts->type == GSM_BTS_TYPE_BS11)
1415 rqd_ta <<= 2;
Harald Welte8d77b952009-12-17 00:31:10 +01001416 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001417
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001418 return 0;
1419}
1420
1421static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1422{
1423 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001424 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001425 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1426
Harald Welte52b1f982008-12-23 20:25:15 +00001427 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001428 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001429 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001430 ia->proto_discr = GSM48_PDISC_RR;
1431 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1432 ia->page_mode = GSM48_PM_SAME;
1433 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001434
Harald Welte8470bf22008-12-25 23:28:35 +00001435 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001436 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1437 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001438 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001439 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001440 } else {
laforge09108bf2010-06-20 15:18:46 +02001441 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1442 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001443 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001444 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1445 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001446
Harald Welteb7e81162009-08-10 00:26:10 +02001447 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1448 lchan->T3101.cb = t3101_expired;
1449 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001450 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001451
Harald Welte52b1f982008-12-23 20:25:15 +00001452 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001453 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001454}
1455
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001456/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001457static int rsl_rx_ccch_load(struct msgb *msg)
1458{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001459 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001460 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001461 struct ccch_signal_data sd;
1462
1463 sd.bts = sign_link->trx->bts;
1464 sd.rach_slot_count = -1;
1465 sd.rach_busy_count = -1;
1466 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001467
1468 switch (rslh->data[0]) {
1469 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001470 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1471 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001472 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001473 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001474 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001475 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1476 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001477 break;
1478 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001479 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001480 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1481 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1482 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1483 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001484 }
Harald Welteea280442009-02-02 22:29:56 +00001485 break;
1486 default:
1487 break;
1488 }
1489
1490 return 0;
1491}
1492
Harald Welte52b1f982008-12-23 20:25:15 +00001493static int abis_rsl_rx_cchan(struct msgb *msg)
1494{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001495 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001496 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001497 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001498
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001499 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +00001500
1501 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001502 case RSL_MT_CHAN_RQD:
1503 /* MS has requested a channel on the RACH */
1504 rc = rsl_rx_chan_rqd(msg);
1505 break;
Harald Welteea280442009-02-02 22:29:56 +00001506 case RSL_MT_CCCH_LOAD_IND:
1507 /* current load on the CCCH */
1508 rc = rsl_rx_ccch_load(msg);
1509 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001510 case RSL_MT_DELETE_IND:
1511 /* CCCH overloaded, IMM_ASSIGN was dropped */
1512 case RSL_MT_CBCH_LOAD_IND:
1513 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001514 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1515 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001516 break;
1517 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001518 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1519 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001520 return -EINVAL;
1521 }
Harald Welte8470bf22008-12-25 23:28:35 +00001522
1523 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001524}
1525
Harald Welte4b634542008-12-27 01:55:51 +00001526static int rsl_rx_rll_err_ind(struct msgb *msg)
1527{
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001528 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +00001529 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001530 uint8_t rlm_cause;
Harald Welte4b634542008-12-27 01:55:51 +00001531
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001532 rsl_tlv_parse(&tp, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
1533 if (!TLVP_PRESENT(&tp, RSL_IE_RLM_CAUSE)) {
1534 LOGP(DRLL, LOGL_ERROR,
1535 "%s ERROR INDICATION without mandantory cause.\n",
1536 gsm_lchan_name(msg->lchan));
1537 return -1;
1538 }
1539
1540 rlm_cause = *TLVP_VAL(&tp, RSL_IE_RLM_CAUSE);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001541 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001542 gsm_lchan_name(msg->lchan),
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001543 rsl_rlm_cause_name(rlm_cause));
Harald Welteedcc5272009-08-09 13:47:35 +02001544
1545 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001546
Holger Hans Peter Freyther164ee302013-01-16 21:07:43 +01001547 if (rlm_cause == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001548 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001549 return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001550 }
Harald Welte81543bc2009-07-04 09:40:05 +02001551
Harald Welte4b634542008-12-27 01:55:51 +00001552 return 0;
1553}
Harald Weltef325eb42009-02-19 17:07:39 +00001554
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001555static void rsl_handle_release(struct gsm_lchan *lchan)
1556{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001557 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001558 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001559
Holger Hans Peter Freyther9d50a272011-12-28 12:11:40 +01001560 /*
1561 * Maybe only one link/SAPI was releasd or the error handling
1562 * was activated. Just return now and let the other code handle
1563 * it.
1564 */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001565 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001566 return;
1567
1568 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1569 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1570 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001571 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001572 gsm_lchan_name(lchan), sapi);
1573 return;
1574 }
1575
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001576
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01001577 /* Stop T3109 and wait for T3111 before re-using the channel */
1578 osmo_timer_del(&lchan->T3109);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001579 lchan->T3111.cb = t3111_expired;
1580 lchan->T3111.data = lchan;
1581 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001582 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001583}
1584
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001585/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001586 0x02, 0x06,
1587 0x01, 0x20,
1588 0x02, 0x00,
1589 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1590
1591static int abis_rsl_rx_rll(struct msgb *msg)
1592{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001593 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001594 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001595 int rc = 0;
1596 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001597 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001598
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001599 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001600 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001601 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001602
1603 switch (rllh->c.msg_type) {
1604 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001605 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001606 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001607 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1608 rllh->data[0] == RSL_IE_L3_INFO) {
1609 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001610 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001611 }
Harald Welte52b1f982008-12-23 20:25:15 +00001612 break;
1613 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001614 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001615 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001616 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001617 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001618 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001619 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1620 rllh->data[0] == RSL_IE_L3_INFO) {
1621 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001622 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001623 }
Harald Welte52b1f982008-12-23 20:25:15 +00001624 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001625 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001626 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001627 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001628 rll_indication(msg->lchan, rllh->link_id,
1629 BSC_RLLR_IND_EST_CONF);
1630 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001631 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001632 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001633 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001634 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001635 rll_indication(msg->lchan, rllh->link_id,
1636 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001637 rsl_handle_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001638 break;
1639 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001640 /* BTS informs us of having received UA from MS,
1641 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001642 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001643 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001644 rsl_handle_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001645 break;
1646 case RSL_MT_ERROR_IND:
1647 rc = rsl_rx_rll_err_ind(msg);
1648 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001649 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001650 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1651 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001652 break;
1653 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001654 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1655 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001656 }
Harald Welte8470bf22008-12-25 23:28:35 +00001657 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001658}
1659
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001660static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001661{
Harald Welte0603c9d2009-12-02 01:58:23 +05301662 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001663 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301664 switch (lchan->type) {
1665 case GSM_LCHAN_TCH_F:
1666 return 0x00;
1667 case GSM_LCHAN_TCH_H:
1668 return 0x03;
1669 default:
1670 break;
1671 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001672 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301673 switch (lchan->type) {
1674 case GSM_LCHAN_TCH_F:
1675 return 0x01;
1676 /* there's no half-rate EFR */
1677 default:
1678 break;
1679 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001680 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301681 switch (lchan->type) {
1682 case GSM_LCHAN_TCH_F:
1683 return 0x02;
1684 case GSM_LCHAN_TCH_H:
1685 return 0x05;
1686 default:
1687 break;
1688 }
1689 default:
1690 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001691 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001692 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301693 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001694 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001695}
1696
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001697static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01001698{
1699 switch (lchan->tch_mode) {
1700 case GSM48_CMODE_SPEECH_V1:
1701 switch (lchan->type) {
1702 case GSM_LCHAN_TCH_F:
1703 return RTP_PT_GSM_FULL;
1704 case GSM_LCHAN_TCH_H:
1705 return RTP_PT_GSM_HALF;
1706 default:
1707 break;
1708 }
1709 case GSM48_CMODE_SPEECH_EFR:
1710 switch (lchan->type) {
1711 case GSM_LCHAN_TCH_F:
1712 return RTP_PT_GSM_EFR;
1713 /* there's no half-rate EFR */
1714 default:
1715 break;
1716 }
1717 case GSM48_CMODE_SPEECH_AMR:
1718 switch (lchan->type) {
1719 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01001720 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02001721 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01001722 default:
1723 break;
1724 }
1725 default:
1726 break;
1727 }
1728 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1729 "tch_mode == 0x%02x\n & lchan_type == %d",
1730 lchan->tch_mode, lchan->type);
1731 return 0;
1732}
1733
Harald Welte75099262009-02-16 21:12:08 +00001734/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001735static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1736{
1737 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001738 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001739
1740 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001741 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001742 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1743 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1744 }
1745
1746 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001747 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001748 port = ntohs(port);
1749 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1750 lchan->abis_ip.bound_port = port;
1751 }
1752
1753 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001754 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001755 conn_id = ntohs(conn_id);
1756 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1757 lchan->abis_ip.conn_id = conn_id;
1758 }
1759
1760 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1761 lchan->abis_ip.rtp_payload2 =
1762 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1763 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1764 lchan->abis_ip.rtp_payload2);
1765 }
1766
1767 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1768 lchan->abis_ip.speech_mode =
1769 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1770 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1771 lchan->abis_ip.speech_mode);
1772 }
1773
1774 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001775 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001776 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1777 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1778 }
1779
1780 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001781 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001782 port = ntohs(port);
1783 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1784 lchan->abis_ip.connect_port = port;
1785 }
1786}
1787
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001788int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001789{
1790 struct msgb *msg = rsl_msgb_alloc();
1791 struct abis_rsl_dchan_hdr *dh;
1792
1793 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001794 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001795 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001796 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001797
Harald Weltef4e79f22009-07-28 18:11:56 +02001798 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001799 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001800 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001801 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001802 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001803
Sylvain Munautb54dda42009-12-20 22:06:40 +01001804 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1805 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1806 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001807
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001808 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001809
1810 return abis_rsl_sendmsg(msg);
1811}
1812
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001813int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1814 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001815{
1816 struct msgb *msg = rsl_msgb_alloc();
1817 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001818 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001819 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001820
1821 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001822 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001823 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001824 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001825
Harald Welte5e3d91b2009-12-19 16:42:06 +01001826 /* we need to store these now as MDCX_ACK does not return them :( */
1827 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1828 lchan->abis_ip.connect_port = port;
1829 lchan->abis_ip.connect_ip = ip;
1830
Harald Welte58ca5b72009-07-29 12:12:18 +02001831 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001832 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001833 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001834
Harald Weltef4e79f22009-07-28 18:11:56 +02001835 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001836 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1837 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1838 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1839 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001840
Harald Welte5e3d91b2009-12-19 16:42:06 +01001841 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1842 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001843 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001844 *att_ip = ia.s_addr;
1845 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1846 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001847 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001848 if (rtp_payload2)
1849 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001850
1851 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001852
1853 return abis_rsl_sendmsg(msg);
1854}
1855
Harald Weltea72273e2009-12-20 16:51:09 +01001856/* tell BTS to connect RTP stream to our local RTP socket */
1857int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1858{
1859 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1860 int rc;
1861
1862 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1863 ntohs(rs->rtp.sin_local.sin_port),
1864 /* FIXME: use RTP payload of bound socket, not BTS*/
1865 lchan->abis_ip.rtp_payload2);
1866
1867 return rc;
1868}
1869
Harald Welte53cd7ac2010-12-23 12:59:52 +01001870int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001871{
1872 struct msgb *msg = rsl_msgb_alloc();
1873 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001874 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08001875
1876 if (act)
1877 msg_type = RSL_MT_IPAC_PDCH_ACT;
1878 else
1879 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001880
1881 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001882 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001883 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001884 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001885
Harald Welte53cd7ac2010-12-23 12:59:52 +01001886 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001887 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001888
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001889 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02001890
1891 return abis_rsl_sendmsg(msg);
1892}
1893
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001894static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001895{
1896 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1897 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301898 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001899
1900 /* the BTS has acknowledged a local bind, it now tells us the IP
1901 * address and port number to which it has bound the given logical
1902 * channel */
1903
1904 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1905 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1906 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001907 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001908 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001909 return -EINVAL;
1910 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001911
Harald Welte5e3d91b2009-12-19 16:42:06 +01001912 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001913
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001914 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001915
Harald Welte75099262009-02-16 21:12:08 +00001916 return 0;
1917}
1918
Harald Welte5e3d91b2009-12-19 16:42:06 +01001919static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1920{
1921 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1922 struct tlv_parsed tv;
1923 struct gsm_lchan *lchan = msg->lchan;
1924
1925 /* the BTS has acknowledged a remote connect request and
1926 * it now tells us the IP address and port number to which it has
1927 * connected the given logical channel */
1928
1929 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1930 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001931 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001932
1933 return 0;
1934}
1935
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001936static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001937{
1938 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1939 struct tlv_parsed tv;
1940
1941 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001942
Harald Welte8830e072009-07-28 17:58:09 +02001943 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001944 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001945 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001946
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001947 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001948
Harald Welte75099262009-02-16 21:12:08 +00001949 return 0;
1950}
1951
1952static int abis_rsl_rx_ipacc(struct msgb *msg)
1953{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001954 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00001955 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001956 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001957 int rc = 0;
1958
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001959 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001960 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001961
1962 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001963 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001964 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001965 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001966 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001967 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001968 /* somehow the BTS was unable to bind the lchan to its local
1969 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001970 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001971 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001972 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001973 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001974 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001975 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001976 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001977 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001978 /* somehow the BTS was unable to connect the lchan to a remote
1979 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001980 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001981 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001982 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001983 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001984 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001985 break;
1986 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001987 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001988 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001989 break;
1990 }
Harald Welte6dab0552009-05-01 17:21:37 +00001991 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001992
1993 return rc;
1994}
1995
1996
Harald Welte52b1f982008-12-23 20:25:15 +00001997/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001998int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001999{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002000 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00002001 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00002002
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002003 if (!msg) {
2004 DEBUGP(DRSL, "Empty RSL msg?..\n");
2005 return -1;
2006 }
2007
2008 if (msgb_l2len(msg) < sizeof(*rslh)) {
2009 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02002010 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01002011 return -1;
2012 }
2013
2014 rslh = msgb_l2(msg);
2015
Harald Welte52b1f982008-12-23 20:25:15 +00002016 switch (rslh->msg_discr & 0xfe) {
2017 case ABIS_RSL_MDISC_RLL:
2018 rc = abis_rsl_rx_rll(msg);
2019 break;
2020 case ABIS_RSL_MDISC_DED_CHAN:
2021 rc = abis_rsl_rx_dchan(msg);
2022 break;
2023 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00002024 rc = abis_rsl_rx_cchan(msg);
2025 break;
Harald Welte8470bf22008-12-25 23:28:35 +00002026 case ABIS_RSL_MDISC_TRX:
2027 rc = abis_rsl_rx_trx(msg);
2028 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002029 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002030 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00002031 rslh->msg_discr);
2032 break;
Harald Welte75099262009-02-16 21:12:08 +00002033 case ABIS_RSL_MDISC_IPACCESS:
2034 rc = abis_rsl_rx_ipacc(msg);
2035 break;
Harald Welte52b1f982008-12-23 20:25:15 +00002036 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01002037 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
2038 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02002039 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00002040 }
Harald Welte4f4a3902008-12-26 00:04:49 +00002041 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00002042 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00002043}
Holger Freyther3b72a892009-02-04 00:31:39 +00002044
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08002045int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
2046 uint8_t cb_command, const uint8_t *data, int len)
2047{
2048 struct abis_rsl_dchan_hdr *dh;
2049 struct msgb *cb_cmd;
2050
2051 cb_cmd = rsl_msgb_alloc();
2052 if (!cb_cmd)
2053 return -1;
2054
2055 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
2056 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2057 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2058
2059 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2060 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2061
2062 cb_cmd->trx = bts->c0;
2063
2064 return abis_rsl_sendmsg(cb_cmd);
2065}
Dieter Spaar16646022011-07-28 00:01:50 +02002066
2067int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2068{
2069 struct abis_rsl_common_hdr *ch;
2070 struct msgb *msg = rsl_msgb_alloc();
2071
2072 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2073 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2074 ch->msg_type = 0x40; /* Nokia SI Begin */
2075
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002076 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002077
2078 return abis_rsl_sendmsg(msg);
2079}
2080
2081int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2082{
2083 struct abis_rsl_common_hdr *ch;
2084 struct msgb *msg = rsl_msgb_alloc();
2085
2086 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2087 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2088 ch->msg_type = 0x41; /* Nokia SI End */
2089
2090 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2091
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002092 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002093
2094 return abis_rsl_sendmsg(msg);
2095}
2096
2097int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2098{
2099 struct abis_rsl_common_hdr *ch;
2100 struct msgb *msg = rsl_msgb_alloc();
2101
2102 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2103 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2104 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2105
2106 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2107 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2108
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002109 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002110
2111 return abis_rsl_sendmsg(msg);
2112}
Holger Hans Peter Freyther85825352011-12-27 22:24:17 +01002113
2114/**
2115 * Release all allocated SAPIs starting from @param start and
2116 * release them with the given release mode. Once the release
2117 * confirmation arrives it will be attempted to release the
2118 * the RF channel.
2119 */
2120int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
2121 enum rsl_rel_mode release_mode)
2122{
2123 int no_sapi = 1;
2124 int sapi;
2125
2126 for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
2127 uint8_t link_id;
2128 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
2129 continue;
2130
2131 link_id = sapi;
2132 if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
2133 link_id |= 0x40;
2134 rsl_release_request(lchan, link_id, release_mode);
2135 no_sapi = 0;
2136 }
2137
2138 return no_sapi;
2139}
Holger Hans Peter Freytherb3489392011-12-28 16:21:05 +01002140
2141int rsl_start_t3109(struct gsm_lchan *lchan)
2142{
2143 struct gsm_bts *bts = lchan->ts->trx->bts;
2144
2145 /* Disabled, mostly legacy code */
2146 if (bts->network->T3109 == 0)
2147 return -1;
2148
2149 lchan->T3109.cb = t3109_expired;
2150 lchan->T3109.data = lchan;
2151 osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
2152 return 0;
2153}
Holger Hans Peter Freyther006e3d82012-12-25 23:45:14 +01002154
2155/**
2156 * \brief directly RF Channel Release the lchan
2157 *
2158 * When no SAPI was allocated, directly release the logical channel. This
2159 * should only be called from chan_alloc.c on channel release handling. In
2160 * case no SAPI was established the RF Channel can be directly released,
2161 */
2162int rsl_direct_rf_release(struct gsm_lchan *lchan)
2163{
2164 int i;
2165 for (i = 0; i < ARRAY_SIZE(lchan->sapis); ++i) {
2166 if (lchan->sapis[i] != LCHAN_SAPI_UNUSED) {
2167 LOGP(DRSL, LOGL_ERROR, "%s SAPI(%d) still allocated.\n",
2168 gsm_lchan_name(lchan), i);
2169 return -1;
2170 }
2171 }
2172
2173 /* Now release it */
2174 return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
2175}