blob: 8a326def9997fa7b38ad8c9af3a57a7d5c2add26 [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>
Harald Welte8470bf22008-12-25 23:28:35 +00005 *
Harald Welte52b1f982008-12-23 20:25:15 +00006 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01009 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
Harald Welte52b1f982008-12-23 20:25:15 +000011 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010016 * GNU Affero General Public License for more details.
Harald Welte52b1f982008-12-23 20:25:15 +000017 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010018 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte52b1f982008-12-23 20:25:15 +000020 *
21 */
22
23#include <stdio.h>
Harald Welte8470bf22008-12-25 23:28:35 +000024#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000025#include <errno.h>
Harald Welte75099262009-02-16 21:12:08 +000026#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000027#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000028
Harald Welte8470bf22008-12-25 23:28:35 +000029#include <openbsc/gsm_data.h>
30#include <openbsc/gsm_04_08.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010031#include <osmocom/gsm/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000032#include <openbsc/abis_rsl.h>
33#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020034#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000035#include <openbsc/debug.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010036#include <osmocom/gsm/tlv.h>
Holger Freyther392209c2009-02-10 00:06:19 +000037#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000038#include <openbsc/signal.h>
Harald Welte3c7dc6e2009-11-29 19:07:28 +010039#include <openbsc/meas_rep.h>
Harald Welte17f5bf62009-12-20 15:42:44 +010040#include <openbsc/rtp_proxy.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010041#include <osmocom/gsm/rsl.h>
Harald Welte52b1f982008-12-23 20:25:15 +000042
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010043#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080044
Harald Welte8470bf22008-12-25 23:28:35 +000045#define RSL_ALLOC_SIZE 1024
46#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000047
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +080048static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
49
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010050static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
51 struct gsm_meas_rep *resp)
52{
53 struct lchan_signal_data sig;
54 sig.lchan = lchan;
55 sig.mr = resp;
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +020056 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +010057}
58
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020059static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000060{
61 /* mask off the transparent bit ? */
62 msg_type &= 0xfe;
63
Harald Welte8470bf22008-12-25 23:28:35 +000064 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000065 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000066 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000067 if (msg_type >= 0x19 && msg_type <= 0x22)
68 return ABIS_RSL_MDISC_TRX;
69 else
70 return ABIS_RSL_MDISC_COM_CHAN;
71 }
Harald Welte2d5b6382008-12-27 19:46:06 +000072 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000073 return ABIS_RSL_MDISC_DED_CHAN;
74
75 return ABIS_RSL_MDISC_LOC;
76}
77
78static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020079 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000080{
81 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
82 dh->c.msg_type = msg_type;
83 dh->ie_chan = RSL_IE_CHAN_NR;
84}
85
Harald Welte8470bf22008-12-25 23:28:35 +000086/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020087struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte8470bf22008-12-25 23:28:35 +000088{
89 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020090 uint8_t ts_nr = chan_nr & 0x07;
91 uint8_t cbits = chan_nr >> 3;
92 uint8_t lch_idx;
Harald Welte8470bf22008-12-25 23:28:35 +000093 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
94
95 if (cbits == 0x01) {
96 lch_idx = 0; /* TCH/F */
Harald Weltea1499d02009-10-24 10:25:50 +020097 if (ts->pchan != GSM_PCHAN_TCH_F &&
98 ts->pchan != GSM_PCHAN_PDCH &&
99 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100100 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000101 chan_nr, ts->pchan);
102 } else if ((cbits & 0x1e) == 0x02) {
103 lch_idx = cbits & 0x1; /* TCH/H */
104 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100105 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000106 chan_nr, ts->pchan);
107 } else if ((cbits & 0x1c) == 0x04) {
108 lch_idx = cbits & 0x3; /* SDCCH/4 */
109 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100110 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000111 chan_nr, ts->pchan);
112 } else if ((cbits & 0x18) == 0x08) {
113 lch_idx = cbits & 0x7; /* SDCCH/8 */
114 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100115 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000116 chan_nr, ts->pchan);
117 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
118 lch_idx = 0;
119 if (ts->pchan != GSM_PCHAN_CCCH &&
120 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100121 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000122 chan_nr, ts->pchan);
123 /* FIXME: we should not return first sdcch4 !!! */
124 } else {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100125 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000126 return NULL;
127 }
128
129 lchan = &ts->lchan[lch_idx];
Harald Weltedc5062b2010-03-26 21:28:59 +0800130 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800131 if (lchan->conn)
132 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000133
134 return lchan;
135}
136
Harald Welte52b1f982008-12-23 20:25:15 +0000137/* 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 +0200138uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000139{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200140 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000141
142 ret = strtoull(imsi_str, NULL, 10);
143
144 return ret;
145}
146
Harald Welte8470bf22008-12-25 23:28:35 +0000147static struct msgb *rsl_msgb_alloc(void)
148{
Harald Welte966636f2009-06-26 19:39:35 +0200149 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
150 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000151}
152
Harald Welte362322e2009-02-15 14:36:38 +0000153#define MACBLOCK_SIZE 23
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200154static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000155{
156 memcpy(out, in, len);
157
158 if (len < MACBLOCK_SIZE)
159 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
160}
161
Harald Welte08d91a52009-08-30 15:37:11 +0900162/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200163static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900164{
165 *out++ = lchan->encr.alg_id & 0xff;
166 if (lchan->encr.key_len)
167 memcpy(out, lchan->encr.key, lchan->encr.key_len);
168 return lchan->encr.key_len + 1;
169}
170
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200171static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200172{
Harald Welte7f93cea2009-02-23 00:02:59 +0000173 int i;
174
Harald Welte5b8ed432009-12-24 12:20:20 +0100175 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200176 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200177 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100178 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000179}
180
Harald Weltee8bd9e82011-08-10 23:26:33 +0200181static void lchan_act_tmr_cb(void *data)
182{
183 struct gsm_lchan *lchan = data;
184
185 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during activation!\n",
186 gsm_lchan_name(lchan));
187
188 lchan->state = LCHAN_S_NONE;
189}
190
191static void lchan_deact_tmr_cb(void *data)
192{
193 struct gsm_lchan *lchan = data;
194
195 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during deactivation!\n",
196 gsm_lchan_name(lchan));
197
198 lchan->state = LCHAN_S_NONE;
199}
200
201
Harald Welte52b1f982008-12-23 20:25:15 +0000202/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200203int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
204 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000205{
206 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000207 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000208
209 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
210 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
211 dh->chan_nr = RSL_CHAN_BCCH;
212
213 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
214 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
215
Harald Weltee79769b2009-02-07 00:48:17 +0000216 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000217
218 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000219}
220
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200221int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
222 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000223{
224 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000225 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000226
227 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
228 ch->msg_discr = ABIS_RSL_MDISC_TRX;
229 ch->msg_type = RSL_MT_SACCH_FILL;
230
231 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000232 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000233
Harald Weltee79769b2009-02-07 00:48:17 +0000234 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000235
236 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000237}
238
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200239int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
240 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100241{
242 struct abis_rsl_dchan_hdr *dh;
243 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200244 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100245
246 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
247 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
248 dh->chan_nr = chan_nr;
249
250 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
251 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
252
253 msg->trx = lchan->ts->trx;
254
255 return abis_rsl_sendmsg(msg);
256}
257
Harald Weltefcd24452009-06-20 18:15:19 +0200258int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
259{
260 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200261 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200262 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200263
264 db = abs(db);
265 if (db > 30)
266 return -EINVAL;
267
Harald Welteeab33352009-06-27 03:09:08 +0200268 msg = rsl_msgb_alloc();
269
Harald Weltefcd24452009-06-20 18:15:19 +0200270 lchan->bs_power = db/2;
271 if (fpc)
272 lchan->bs_power |= 0x10;
273
274 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
275 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
276 dh->chan_nr = chan_nr;
277
278 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
279
280 msg->trx = lchan->ts->trx;
281
282 return abis_rsl_sendmsg(msg);
283}
284
Harald Weltefcd24452009-06-20 18:15:19 +0200285int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
286{
287 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200288 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200289 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200290 int ctl_lvl;
291
Harald Welte66b6a8d2009-08-09 14:45:18 +0200292 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200293 if (ctl_lvl < 0)
294 return ctl_lvl;
295
Harald Welteeab33352009-06-27 03:09:08 +0200296 msg = rsl_msgb_alloc();
297
Harald Weltefcd24452009-06-20 18:15:19 +0200298 lchan->ms_power = ctl_lvl;
299
300 if (fpc)
301 lchan->ms_power |= 0x20;
302
303 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
304 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
305 dh->chan_nr = chan_nr;
306
307 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
308
309 msg->trx = lchan->ts->trx;
310
311 return abis_rsl_sendmsg(msg);
312}
313
Harald Welte9943c5b2009-07-29 15:41:29 +0200314static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
315 struct gsm_lchan *lchan)
316{
317 memset(cm, 0, sizeof(cm));
318
319 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800320 if (lchan->ts->trx->bts->network->dtx_enabled)
321 cm->dtx_dtu = 0x03;
322 else
323 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200324
325 /* set TCH Speech/Data */
326 cm->spd_ind = lchan->rsl_cmode;
327
Harald Welte1a79d362009-11-27 08:55:16 +0100328 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
329 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100330 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100331 "but tch_mode != signalling\n");
332
Harald Welte9943c5b2009-07-29 15:41:29 +0200333 switch (lchan->type) {
334 case GSM_LCHAN_SDCCH:
335 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
336 break;
337 case GSM_LCHAN_TCH_F:
338 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
339 break;
340 case GSM_LCHAN_TCH_H:
341 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
342 break;
343 case GSM_LCHAN_NONE:
344 case GSM_LCHAN_UNKNOWN:
345 default:
346 return -EINVAL;
347 }
348
349 switch (lchan->tch_mode) {
350 case GSM48_CMODE_SIGN:
351 cm->chan_rate = 0;
352 break;
353 case GSM48_CMODE_SPEECH_V1:
354 cm->chan_rate = RSL_CMOD_SP_GSM1;
355 break;
356 case GSM48_CMODE_SPEECH_EFR:
357 cm->chan_rate = RSL_CMOD_SP_GSM2;
358 break;
359 case GSM48_CMODE_SPEECH_AMR:
360 cm->chan_rate = RSL_CMOD_SP_GSM3;
361 break;
362 case GSM48_CMODE_DATA_14k5:
363 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
364 break;
365 case GSM48_CMODE_DATA_12k0:
366 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
367 break;
368 case GSM48_CMODE_DATA_6k0:
369 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
370 break;
371 default:
372 return -EINVAL;
373 }
374
375 return 0;
376}
377
Harald Welte52b1f982008-12-23 20:25:15 +0000378/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000379#if 0
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200380int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
381 uint8_t act_type,
Harald Welte52b1f982008-12-23 20:25:15 +0000382 struct rsl_ie_chan_mode *chan_mode,
383 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200384 uint8_t bs_power, uint8_t ms_power,
385 uint8_t ta)
Harald Welte52b1f982008-12-23 20:25:15 +0000386{
387 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000388 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000389
390 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
391 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
392 dh->chan_nr = chan_nr;
393
394 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
395 /* For compatibility with Phase 1 */
396 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200397 (uint8_t *) chan_mode);
Harald Welte52b1f982008-12-23 20:25:15 +0000398 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200399 (uint8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000400#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000401 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200402 (uint8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000403#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000404 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000405 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
406 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
407
Harald Weltee79769b2009-02-07 00:48:17 +0000408 msg->trx = trx;
409
Harald Welte8470bf22008-12-25 23:28:35 +0000410 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000411}
Harald Welteddab3c72009-02-28 13:19:15 +0000412#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000413
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200414int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
415 uint8_t ta, uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000416{
417 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200418 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200419 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200420 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000421
Harald Weltef6093a42011-06-25 10:02:33 +0200422 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000423 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200424 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000425
Harald Welte9943c5b2009-07-29 15:41:29 +0200426 rc = channel_mode_from_lchan(&cm, lchan);
427 if (rc < 0)
428 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000429
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800430 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200431 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000432
Harald Welteeab33352009-06-27 03:09:08 +0200433 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000434 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
435 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
436 dh->chan_nr = chan_nr;
437
438 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000439 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200440 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800441
442 /*
443 * The Channel Identification is needed for Phase1 phones
444 * and it contains the GSM48 Channel Description and the
445 * Mobile Allocation. The GSM 08.58 asks for the Mobile
446 * Allocation to have a length of zero. We are using the
447 * msgb_l3len to calculate the length of both messages.
448 */
laforge694a5cf2010-06-20 21:38:19 +0200449 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200450 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200451 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800452
453 if (lchan->ts->hopping.enabled)
454 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
455 lchan->ts->hopping.ma_data);
456 else
457 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800458
459 /* update the calculated size */
460 msg->l3h = len + 1;
461 *len = msgb_l3len(msg);
462
Harald Welte08d91a52009-08-30 15:37:11 +0900463 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200464 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900465 rc = build_encr_info(encr_info, lchan);
466 if (rc > 0)
467 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
468 }
469
Harald Welte8d77b952009-12-17 00:31:10 +0100470 switch (act_type) {
471 case RSL_ACT_INTER_ASYNC:
472 case RSL_ACT_INTER_SYNC:
473 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
474 break;
475 default:
476 break;
477 }
478
Harald Welted4c9bf32009-02-15 16:56:18 +0000479 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
480 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000481 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
482
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100483 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
484 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200485 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100486
Harald Weltee79769b2009-02-07 00:48:17 +0000487 msg->trx = lchan->ts->trx;
488
Harald Welte4b634542008-12-27 01:55:51 +0000489 return abis_rsl_sendmsg(msg);
490}
491
Harald Welte470abb72009-07-29 11:38:15 +0200492/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000493int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
494{
495 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200496 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200497 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000498
Harald Weltef6093a42011-06-25 10:02:33 +0200499 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000500 struct rsl_ie_chan_mode cm;
501
Harald Welte9943c5b2009-07-29 15:41:29 +0200502 rc = channel_mode_from_lchan(&cm, lchan);
503 if (rc < 0)
504 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000505
Harald Welteeab33352009-06-27 03:09:08 +0200506 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000507 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
508 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
509 dh->chan_nr = chan_nr;
510
511 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200512 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900513
514 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200515 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900516 rc = build_encr_info(encr_info, lchan);
517 if (rc > 0)
518 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
519 }
520
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100521 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
522 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200523 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100524 }
525
Harald Welte08d91a52009-08-30 15:37:11 +0900526 msg->trx = lchan->ts->trx;
527
528 return abis_rsl_sendmsg(msg);
529}
530
531/* Chapter 8.4.6: Send the encryption command with given L3 info */
532int rsl_encryption_cmd(struct msgb *msg)
533{
534 struct abis_rsl_dchan_hdr *dh;
535 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200536 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200537 uint8_t encr_info[MAX_A5_KEY_LEN+2];
538 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900539 int rc;
540
541 /* First push the L3 IE tag and length */
542 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
543
544 /* then the link identifier (SAPI0, main sign link) */
545 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
546
547 /* then encryption information */
548 rc = build_encr_info(encr_info, lchan);
549 if (rc <= 0)
550 return rc;
551 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
552
553 /* and finally the DCHAN header */
554 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
555 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
556 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000557
558 msg->trx = lchan->ts->trx;
559
560 return abis_rsl_sendmsg(msg);
561}
562
Harald Welte115d1032009-08-10 11:43:22 +0200563/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200564int rsl_deact_sacch(struct gsm_lchan *lchan)
565{
566 struct abis_rsl_dchan_hdr *dh;
567 struct msgb *msg = rsl_msgb_alloc();
568
569 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
570 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200571 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200572
573 msg->lchan = lchan;
574 msg->trx = lchan->ts->trx;
575
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100576 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200577
578 return abis_rsl_sendmsg(msg);
579}
580
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800581static void error_timeout_cb(void *data)
582{
583 struct gsm_lchan *lchan = data;
584 if (lchan->state != LCHAN_S_REL_ERR) {
585 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
586 gsm_lchan_name(lchan), lchan->state);
587 return;
588 }
589
590 /* go back to the none state */
591 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800592 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800593}
594
Harald Weltefd355a32011-03-04 13:41:31 +0100595static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
596
Harald Welte115d1032009-08-10 11:43:22 +0200597/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800598static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte52b1f982008-12-23 20:25:15 +0000599{
600 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800601 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100602 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000603
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800604 if (lchan->state == LCHAN_S_REL_ERR) {
605 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
606 gsm_lchan_name(lchan));
607 return -1;
608 }
609
610 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000611 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
612 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200613 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000614
Harald Welte8470bf22008-12-25 23:28:35 +0000615 msg->lchan = lchan;
616 msg->trx = lchan->ts->trx;
617
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800618 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
619
620 if (error) {
621 /*
622 * the nanoBTS sends RLL release indications after the channel release. This can
623 * be a problem when we have reassigned the channel to someone else and then can
624 * not figure out who used this channel.
625 */
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800626 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800627 lchan->error_timer.data = lchan;
628 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200629 osmo_timer_schedule(&lchan->error_timer,
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800630 msg->trx->bts->network->T3111 + 2, 0);
631 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000632
Harald Weltee8bd9e82011-08-10 23:26:33 +0200633 /* Start another timer or assume the BTS sends a ACK/NACK? */
634 lchan->act_timer.cb = lchan_deact_tmr_cb;
635 lchan->act_timer.data = lchan;
636 osmo_timer_schedule(&lchan->act_timer, 4, 0);
637
Harald Weltefd355a32011-03-04 13:41:31 +0100638 rc = abis_rsl_sendmsg(msg);
639
Harald Welte115d1032009-08-10 11:43:22 +0200640 /* BTS will respond by RF CHAN REL ACK */
Harald Welte26d79072011-01-14 23:18:59 +0100641#ifdef HSL_SR_1_0
Harald Weltefd355a32011-03-04 13:41:31 +0100642 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
643 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
644 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte26d79072011-01-14 23:18:59 +0100645#endif
Harald Weltefd355a32011-03-04 13:41:31 +0100646
647 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000648}
649
Harald Welte64bb7542011-01-14 14:16:16 +0100650static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
651{
652
653 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
654
Harald Weltee8bd9e82011-08-10 23:26:33 +0200655 osmo_timer_del(&lchan->act_timer);
656
Harald Welte64bb7542011-01-14 14:16:16 +0100657 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
658 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
659 gsm_lchan_name(lchan),
660 gsm_lchans_name(lchan->state));
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200661 osmo_timer_del(&lchan->T3111);
Harald Welte64bb7542011-01-14 14:16:16 +0100662 /* we have an error timer pending to release that */
663 if (lchan->state != LCHAN_S_REL_ERR)
664 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
665 lchan_free(lchan);
666
667 return 0;
668}
669
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200670int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
671 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte52b1f982008-12-23 20:25:15 +0000672{
673 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000674 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000675
676 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
677 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
678 dh->chan_nr = RSL_CHAN_PCH_AGCH;
679
680 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000681 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000682 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
683
Harald Welte8470bf22008-12-25 23:28:35 +0000684 msg->trx = bts->c0;
685
686 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000687}
688
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200689int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +0000690{
691 int i, len = strlen(str_in);
692
693 for (i = 0; i < len; i++) {
694 int num = str_in[i] - 0x30;
695 if (num < 0 || num > 9)
696 return -1;
697 if (i % 2 == 0)
698 bcd_out[i/2] = num;
699 else
700 bcd_out[i/2] |= (num << 4);
701 }
702
703 return 0;
704}
705
Harald Welte702d8702008-12-26 20:25:35 +0000706/* Chapter 8.5.6 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200707int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +0000708{
Harald Welte8470bf22008-12-25 23:28:35 +0000709 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000710 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200711 uint8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000712
713 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
714 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
715 dh->chan_nr = RSL_CHAN_PCH_AGCH;
716
Harald Welte362322e2009-02-15 14:36:38 +0000717 switch (bts->type) {
718 case GSM_BTS_TYPE_BS11:
719 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
720 break;
721 default:
722 /* If phase 2, construct a FULL_IMM_ASS_INFO */
723 pad_macblock(buf, val, len);
724 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
725 break;
726 }
Harald Welte52b1f982008-12-23 20:25:15 +0000727
Harald Welte8470bf22008-12-25 23:28:35 +0000728 msg->trx = bts->c0;
729
730 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000731}
732
Harald Welte67fa91b2009-08-10 09:51:40 +0200733/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200734int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200735{
736 struct msgb *msg = rsl_msgb_alloc();
737 struct abis_rsl_dchan_hdr *dh;
738
739 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
740 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200741 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +0200742 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200743 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200744
Harald Welte5b8ed432009-12-24 12:20:20 +0100745 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200746 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200747
748 msg->trx = lchan->ts->trx;
749
Harald Welte67fa91b2009-08-10 09:51:40 +0200750 return abis_rsl_sendmsg(msg);
751}
752
753
Harald Welte8470bf22008-12-25 23:28:35 +0000754/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000755/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200756int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000757{
Harald Welte8470bf22008-12-25 23:28:35 +0000758 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100759 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000760 return -EINVAL;
761 }
Harald Welte52b1f982008-12-23 20:25:15 +0000762
Harald Weltef6093a42011-06-25 10:02:33 +0200763 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100764 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000765
Harald Welte8470bf22008-12-25 23:28:35 +0000766 msg->trx = msg->lchan->ts->trx;
767
768 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000769}
770
Harald Welteedcc5272009-08-09 13:47:35 +0200771/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
772/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200773int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +0200774{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100775 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200776
Harald Weltef6093a42011-06-25 10:02:33 +0200777 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100778 link_id, 0);
Harald Welteedcc5272009-08-09 13:47:35 +0200779 msg->trx = lchan->ts->trx;
780
781 return abis_rsl_sendmsg(msg);
782}
783
Harald Welted2dc1de2009-08-08 13:15:07 +0200784/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
785 This is what higher layers should call. The BTS then responds with
786 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
787 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
788 lchan_free() */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200789int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason)
Harald Welted2dc1de2009-08-08 13:15:07 +0200790{
Harald Welted2dc1de2009-08-08 13:15:07 +0200791
Harald Welte3c9c5f92010-03-04 10:33:10 +0100792 struct msgb *msg;
793
Harald Weltef6093a42011-06-25 10:02:33 +0200794 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100795 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800796 /* 0 is normal release, 1 is local end */
797 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
Harald Welted2dc1de2009-08-08 13:15:07 +0200798
Harald Welte8e93b792009-12-29 10:44:17 +0100799 /* FIXME: start some timer in case we don't receive a REL ACK ? */
800
Harald Welted2dc1de2009-08-08 13:15:07 +0200801 msg->trx = lchan->ts->trx;
802
803 return abis_rsl_sendmsg(msg);
804}
805
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200806int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
807{
808 lchan->state = state;
809 return 0;
810}
811
Harald Welte702d8702008-12-26 20:25:35 +0000812/* Chapter 8.4.2: Channel Activate Acknowledge */
813static int rsl_rx_chan_act_ack(struct msgb *msg)
814{
815 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
816
817 /* BTS has confirmed channel activation, we now need
818 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000819 if (rslh->ie_chan != RSL_IE_CHAN_NR)
820 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100821
Harald Weltee8bd9e82011-08-10 23:26:33 +0200822 osmo_timer_del(&msg->lchan->act_timer);
823
Harald Welte8e93b792009-12-29 10:44:17 +0100824 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100825 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
826 gsm_lchan_name(msg->lchan),
827 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200828 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100829
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800830 if (msg->lchan->rqd_ref) {
831 rsl_send_imm_assignment(msg->lchan);
832 talloc_free(msg->lchan->rqd_ref);
833 msg->lchan->rqd_ref = NULL;
834 msg->lchan->rqd_ta = 0;
835 }
836
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100837 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100838
Harald Welte4b634542008-12-27 01:55:51 +0000839 return 0;
840}
Harald Welte702d8702008-12-26 20:25:35 +0000841
Harald Welte4b634542008-12-27 01:55:51 +0000842/* Chapter 8.4.3: Channel Activate NACK */
843static int rsl_rx_chan_act_nack(struct msgb *msg)
844{
Harald Welte6dab0552009-05-01 17:21:37 +0000845 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
846 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000847
Harald Weltee8bd9e82011-08-10 23:26:33 +0200848 osmo_timer_del(&msg->lchan->act_timer);
849
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100850 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100851 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100852
Harald Welte6dab0552009-05-01 17:21:37 +0000853 /* BTS has rejected channel activation ?!? */
854 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000855 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000856
857 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100858 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200859 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100860 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200861 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100862 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200863 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100864 } else
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200865 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200866
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100867 LOGPC(DRSL, LOGL_ERROR, "\n");
868
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100869 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100870
Harald Welte3073a9f2009-08-09 19:50:08 +0200871 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000872 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000873}
874
Harald Welte7f93cea2009-02-23 00:02:59 +0000875/* Chapter 8.4.4: Connection Failure Indication */
876static int rsl_rx_conn_fail(struct msgb *msg)
877{
878 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
879 struct tlv_parsed tp;
880
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100881 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100882 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100883 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000884
885 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
886
Harald Welte8830e072009-07-28 17:58:09 +0200887 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100888 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200889 TLVP_LEN(&tp, RSL_IE_CAUSE));
890
Harald Welte (local)fc057502009-12-26 22:33:09 +0100891 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000892 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +0200893 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800894 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte7f93cea2009-02-23 00:02:59 +0000895}
896
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100897static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
898 const char *prefix)
899{
Harald Welte6739dfb2009-12-16 16:52:07 +0100900 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
901 prefix, rxlev2dbm(mru->full.rx_lev),
902 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100903 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
904 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
905}
906
907static void print_meas_rep(struct gsm_meas_rep *mr)
908{
Harald Welte6739dfb2009-12-16 16:52:07 +0100909 int i;
910
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100911 DEBUGP(DMEAS, "MEASUREMENT RESULT NR=%d ", mr->nr);
912
913 if (mr->flags & MEAS_REP_F_DL_DTX)
914 DEBUGPC(DMEAS, "DTXd ");
915
916 print_meas_rep_uni(&mr->ul, "ul");
917 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
918 if (mr->flags & MEAS_REP_F_MS_TO)
919 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
920
921 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +0100922 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100923 DEBUGPC(DMEAS, "L1_FPC=%u ",
924 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
925 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
926 }
927
928 if (mr->flags & MEAS_REP_F_UL_DTX)
929 DEBUGPC(DMEAS, "DTXu ");
930 if (mr->flags & MEAS_REP_F_BA1)
931 DEBUGPC(DMEAS, "BA1 ");
932 if (!(mr->flags & MEAS_REP_F_DL_VALID))
933 DEBUGPC(DMEAS, "NOT VALID ");
934 else
935 print_meas_rep_uni(&mr->dl, "dl");
936
937 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +0100938 if (mr->num_cell == 7)
939 return;
Harald Welte6739dfb2009-12-16 16:52:07 +0100940 for (i = 0; i < mr->num_cell; i++) {
941 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +0100942 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
943 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +0100944 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100945}
946
Harald Welte440fed02009-05-01 18:43:47 +0000947static int rsl_rx_meas_res(struct msgb *msg)
948{
949 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
950 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +0100951 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200952 uint8_t len;
953 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100954 int rc;
Harald Welte440fed02009-05-01 18:43:47 +0000955
Harald Welteb8bfc562009-12-21 13:27:11 +0100956 /* check if this channel is actually active */
957 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +0100958 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +0800959 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +0100960 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +0100961 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +0100962 }
Harald Welteb8bfc562009-12-21 13:27:11 +0100963
Harald Welted12b0fd2009-12-15 21:36:05 +0100964 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +0100965 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +0100966
Harald Welte440fed02009-05-01 18:43:47 +0000967 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
968
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100969 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
970 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
971 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
972 return -EIO;
973
974 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +0100975 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100976
977 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
978 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
979 if (len >= 3) {
980 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +0100981 mr->flags |= MEAS_REP_F_DL_DTX;
982 mr->ul.full.rx_lev = val[0] & 0x3f;
983 mr->ul.sub.rx_lev = val[1] & 0x3f;
984 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
985 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +0000986 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100987
Harald Welted12b0fd2009-12-15 21:36:05 +0100988 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100989
990 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +0000991 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +0100992 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100993 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
994
Harald Weltefe9af262009-06-20 18:44:35 +0200995 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100996 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +0100997 mr->flags |= MEAS_REP_F_MS_L1;
998 mr->ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100999 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001000 mr->flags |= MEAS_REP_F_FPC;
1001 mr->ms_l1.ta = val[1];
Harald Weltefe9af262009-06-20 18:44:35 +02001002 }
Harald Weltef7c43522009-06-09 20:24:21 +00001003 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001004 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001005 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001006 if (rc < 0)
1007 return rc;
1008 }
1009
Harald Welted12b0fd2009-12-15 21:36:05 +01001010 print_meas_rep(mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001011
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001012 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001013
Harald Welte75d34a82009-05-23 06:11:13 +00001014 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001015}
1016
Harald Welted011e8b2009-11-29 22:45:52 +01001017/* Chapter 8.4.7 */
1018static int rsl_rx_hando_det(struct msgb *msg)
1019{
1020 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1021 struct tlv_parsed tp;
1022
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001023 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001024
1025 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1026
1027 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1028 DEBUGPC(DRSL, "access delay = %u\n",
1029 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1030 else
1031 DEBUGPC(DRSL, "\n");
1032
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001033 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001034
1035 return 0;
1036}
1037
Harald Welte52b1f982008-12-23 20:25:15 +00001038static int abis_rsl_rx_dchan(struct msgb *msg)
1039{
Harald Welte8470bf22008-12-25 23:28:35 +00001040 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1041 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001042 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +00001043
Harald Welte8470bf22008-12-25 23:28:35 +00001044 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001045 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001046
Harald Welte8470bf22008-12-25 23:28:35 +00001047 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001048 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001049 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001050 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001051 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001052 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001053 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001054 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001055 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001056 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001057 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001058 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001059 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001060 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001061 case RSL_MT_HANDO_DET:
1062 rc = rsl_rx_hando_det(msg);
1063 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001064 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001065 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001066 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001067 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001068 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001069 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001070 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001071 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001072 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001073 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001074 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001075 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001076 break;
1077 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001078 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001079 break;
1080 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001081 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001082 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001083 break;
1084 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001085 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001086 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001087 case RSL_MT_PHY_CONTEXT_CONF:
1088 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001089 case RSL_MT_TALKER_DET:
1090 case RSL_MT_LISTENER_DET:
1091 case RSL_MT_REMOTE_CODEC_CONF_REP:
1092 case RSL_MT_MR_CODEC_MOD_ACK:
1093 case RSL_MT_MR_CODEC_MOD_NACK:
1094 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001095 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1096 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001097 break;
1098 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001099 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1100 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001101 return -EINVAL;
1102 }
Harald Weltef325eb42009-02-19 17:07:39 +00001103
Harald Welte8470bf22008-12-25 23:28:35 +00001104 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001105}
1106
Harald Welte702d8702008-12-26 20:25:35 +00001107static int rsl_rx_error_rep(struct msgb *msg)
1108{
1109 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001110 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001111
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001112 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001113
1114 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1115
1116 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001117 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001118 TLVP_LEN(&tp, RSL_IE_CAUSE));
1119
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001120 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001121
1122 return 0;
1123}
1124
Harald Welte52b1f982008-12-23 20:25:15 +00001125static int abis_rsl_rx_trx(struct msgb *msg)
1126{
Harald Welte702d8702008-12-26 20:25:35 +00001127 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001128 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001129
1130 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001131 case RSL_MT_ERROR_REPORT:
1132 rc = rsl_rx_error_rep(msg);
1133 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001134 case RSL_MT_RF_RES_IND:
1135 /* interference on idle channels of TRX */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001136 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001137 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001138 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001139 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001140 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
1141 gsm_trx_name(msg->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001142 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001143 case 0x42: /* Nokia specific: SI End ACK */
1144 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1145 break;
1146 case 0x43: /* Nokia specific: SI End NACK */
1147 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1148 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001149 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001150 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
1151 "type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001152 return -EINVAL;
1153 }
Harald Welte8470bf22008-12-25 23:28:35 +00001154 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001155}
1156
Harald Welteb7e81162009-08-10 00:26:10 +02001157/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1158static void t3101_expired(void *data)
1159{
1160 struct gsm_lchan *lchan = data;
1161
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001162 rsl_rf_chan_release(lchan, 1);
Harald Welteb7e81162009-08-10 00:26:10 +02001163}
1164
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001165/* If T3111 expires, we will send the RF Channel Request */
1166static void t3111_expired(void *data)
1167{
1168 struct gsm_lchan *lchan = data;
1169
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001170 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001171}
1172
laforgecfa4a012010-06-21 12:08:52 +02001173#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1174
Harald Welte2862dca2010-12-23 14:39:29 +01001175/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1176static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1177 unsigned int num_req_refs,
1178 struct gsm48_req_ref *rqd_refs,
1179 uint8_t wait_ind)
1180{
1181 uint8_t buf[GSM_MACBLOCK_LEN];
1182 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1183
1184 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1185 memset(iar, 0, sizeof(*iar));
1186 iar->proto_discr = GSM48_PDISC_RR;
1187 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1188 iar->page_mode = GSM48_PM_SAME;
1189
1190 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1191 iar->wait_ind1 = wait_ind;
1192
1193 if (num_req_refs >= 2)
1194 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1195 else
1196 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1197 iar->wait_ind2 = wait_ind;
1198
1199 if (num_req_refs >= 3)
1200 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1201 else
1202 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1203 iar->wait_ind3 = wait_ind;
1204
1205 if (num_req_refs >= 4)
1206 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1207 else
1208 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1209 iar->wait_ind4 = wait_ind;
1210
1211 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1212}
1213
Harald Welte8470bf22008-12-25 23:28:35 +00001214/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001215static int rsl_rx_chan_rqd(struct msgb *msg)
1216{
Harald Welte702d8702008-12-26 20:25:35 +00001217 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001218 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1219 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001220 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001221 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001222 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001223 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001224 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001225
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001226 uint16_t arfcn;
1227 uint8_t ts_number, subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001228
Harald Welte8470bf22008-12-25 23:28:35 +00001229 /* parse request reference to be used in immediate assign */
1230 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1231 return -EINVAL;
1232
1233 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1234
1235 /* parse access delay and use as TA */
1236 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1237 return -EINVAL;
1238 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1239
1240 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1241 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001242 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1243 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001244
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001245 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001246
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001247 /*
1248 * We want LOCATION UPDATES to succeed and will assign a TCH
1249 * if we have no SDCCH available.
1250 */
1251 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1252
Harald Welte8470bf22008-12-25 23:28:35 +00001253 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001254 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001255 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001256 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001257 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001258 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001259 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1260 if (bts->network->T3122)
1261 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001262 return -ENOMEM;
1263 }
1264
Harald Welte8e93b792009-12-29 10:44:17 +01001265 if (lchan->state != LCHAN_S_NONE)
1266 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001267 "in state %s\n", gsm_lchan_name(lchan),
1268 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +02001269 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Harald Welte (local)3e460312009-12-27 18:12:29 +01001270
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001271 /* save the RACH data as we need it after the CHAN ACT ACK */
1272 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1273 if (!lchan->rqd_ref) {
1274 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1275 lchan_free(lchan);
1276 return -ENOMEM;
1277 }
1278
1279 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1280 lchan->rqd_ta = rqd_ta;
1281
Harald Welte8470bf22008-12-25 23:28:35 +00001282 ts_number = lchan->ts->nr;
1283 arfcn = lchan->ts->trx->arfcn;
1284 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001285
Harald Welte08d91a52009-08-30 15:37:11 +09001286 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001287 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001288 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001289 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001290 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001291
Harald Weltee8bd9e82011-08-10 23:26:33 +02001292 /* Start another timer or assume the BTS sends a ACK/NACK? */
1293 lchan->act_timer.cb = lchan_act_tmr_cb;
1294 lchan->act_timer.data = lchan;
1295 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1296
Harald Welte8d77b952009-12-17 00:31:10 +01001297 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001298
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001299 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1300 "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
1301 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1302 rqd_ref->ra);
1303 return 0;
1304}
1305
1306static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1307{
1308 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001309 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001310 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1311
Harald Welte52b1f982008-12-23 20:25:15 +00001312 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001313 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001314 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001315 ia->proto_discr = GSM48_PDISC_RR;
1316 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1317 ia->page_mode = GSM48_PM_SAME;
1318 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001319
Harald Welte8470bf22008-12-25 23:28:35 +00001320 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001321 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1322 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001323 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001324 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001325 } else {
laforge09108bf2010-06-20 15:18:46 +02001326 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1327 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001328 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001329 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1330 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001331
Harald Welteb7e81162009-08-10 00:26:10 +02001332 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1333 lchan->T3101.cb = t3101_expired;
1334 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001335 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001336
Harald Welte52b1f982008-12-23 20:25:15 +00001337 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001338 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001339}
1340
Harald Welteea280442009-02-02 22:29:56 +00001341/* MS has requested a channel on the RACH */
1342static int rsl_rx_ccch_load(struct msgb *msg)
1343{
1344 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001345 uint16_t pg_buf_space;
1346 uint16_t rach_slot_count = -1;
1347 uint16_t rach_busy_count = -1;
1348 uint16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001349
1350 switch (rslh->data[0]) {
1351 case RSL_IE_PAGING_LOAD:
1352 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Harald Welte38e9c822010-04-19 10:24:07 +02001353 if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
1354 /* paging load below configured threshold, use 50 as default */
1355 pg_buf_space = 50;
1356 }
Holger Freyther392209c2009-02-10 00:06:19 +00001357 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001358 break;
1359 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001360 if (msg->data_len >= 7) {
1361 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1362 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1363 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1364 }
Harald Welteea280442009-02-02 22:29:56 +00001365 break;
1366 default:
1367 break;
1368 }
1369
1370 return 0;
1371}
1372
Harald Welte52b1f982008-12-23 20:25:15 +00001373static int abis_rsl_rx_cchan(struct msgb *msg)
1374{
Harald Welteea280442009-02-02 22:29:56 +00001375 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001376 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001377
Harald Welte8470bf22008-12-25 23:28:35 +00001378 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1379
1380 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001381 case RSL_MT_CHAN_RQD:
1382 /* MS has requested a channel on the RACH */
1383 rc = rsl_rx_chan_rqd(msg);
1384 break;
Harald Welteea280442009-02-02 22:29:56 +00001385 case RSL_MT_CCCH_LOAD_IND:
1386 /* current load on the CCCH */
1387 rc = rsl_rx_ccch_load(msg);
1388 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001389 case RSL_MT_DELETE_IND:
1390 /* CCCH overloaded, IMM_ASSIGN was dropped */
1391 case RSL_MT_CBCH_LOAD_IND:
1392 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001393 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1394 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001395 break;
1396 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001397 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1398 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001399 return -EINVAL;
1400 }
Harald Welte8470bf22008-12-25 23:28:35 +00001401
1402 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001403}
1404
Harald Welte4b634542008-12-27 01:55:51 +00001405static int rsl_rx_rll_err_ind(struct msgb *msg)
1406{
1407 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001408 uint8_t *rlm_cause = rllh->data;
Harald Welte4b634542008-12-27 01:55:51 +00001409
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001410 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001411 gsm_lchan_name(msg->lchan),
Harald Weltee95daf12010-03-25 12:13:02 +08001412 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteedcc5272009-08-09 13:47:35 +02001413
1414 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001415
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001416 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001417 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001418 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001419 }
Harald Welte81543bc2009-07-04 09:40:05 +02001420
Harald Welte4b634542008-12-27 01:55:51 +00001421 return 0;
1422}
Harald Weltef325eb42009-02-19 17:07:39 +00001423
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001424static void rsl_handle_release(struct gsm_lchan *lchan)
1425{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001426 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001427 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001428
1429 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001430 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001431 return;
1432
1433 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1434 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1435 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001436 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001437 gsm_lchan_name(lchan), sapi);
1438 return;
1439 }
1440
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001441
1442
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001443 /* wait a bit to send the RF Channel Release */
1444 lchan->T3111.cb = t3111_expired;
1445 lchan->T3111.data = lchan;
1446 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001447 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001448}
1449
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001450/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001451 0x02, 0x06,
1452 0x01, 0x20,
1453 0x02, 0x00,
1454 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1455
1456static int abis_rsl_rx_rll(struct msgb *msg)
1457{
1458 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001459 int rc = 0;
1460 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001461 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001462
1463 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001464 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001465 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001466
1467 switch (rllh->c.msg_type) {
1468 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001469 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001470 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001471 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1472 rllh->data[0] == RSL_IE_L3_INFO) {
1473 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001474 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001475 }
Harald Welte52b1f982008-12-23 20:25:15 +00001476 break;
1477 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001478 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001479 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001480 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001481 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001482 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001483 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1484 rllh->data[0] == RSL_IE_L3_INFO) {
1485 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001486 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001487 }
Harald Welte52b1f982008-12-23 20:25:15 +00001488 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001489 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001490 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001491 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001492 rll_indication(msg->lchan, rllh->link_id,
1493 BSC_RLLR_IND_EST_CONF);
1494 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001495 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001496 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001497 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001498 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001499 rll_indication(msg->lchan, rllh->link_id,
1500 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001501 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001502 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte2d5b6382008-12-27 19:46:06 +00001503 break;
1504 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001505 /* BTS informs us of having received UA from MS,
1506 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001507 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001508 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001509 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001510 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte4b634542008-12-27 01:55:51 +00001511 break;
1512 case RSL_MT_ERROR_IND:
1513 rc = rsl_rx_rll_err_ind(msg);
1514 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001515 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001516 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1517 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001518 break;
1519 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001520 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1521 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001522 }
Harald Welte8470bf22008-12-25 23:28:35 +00001523 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001524}
1525
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001526static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001527{
Harald Welte0603c9d2009-12-02 01:58:23 +05301528 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001529 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301530 switch (lchan->type) {
1531 case GSM_LCHAN_TCH_F:
1532 return 0x00;
1533 case GSM_LCHAN_TCH_H:
1534 return 0x03;
1535 default:
1536 break;
1537 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001538 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301539 switch (lchan->type) {
1540 case GSM_LCHAN_TCH_F:
1541 return 0x01;
1542 /* there's no half-rate EFR */
1543 default:
1544 break;
1545 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001546 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301547 switch (lchan->type) {
1548 case GSM_LCHAN_TCH_F:
1549 return 0x02;
1550 case GSM_LCHAN_TCH_H:
1551 return 0x05;
1552 default:
1553 break;
1554 }
1555 default:
1556 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001557 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001558 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301559 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001560 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001561}
1562
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001563static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01001564{
Holger Hans Peter Freyther8cc59032010-11-14 21:09:08 +01001565 struct gsm_network *net = lchan->ts->trx->bts->network;
1566
1567 /* allow to hardcode the rtp payload */
1568 if (net->hardcoded_rtp_payload != 0)
1569 return net->hardcoded_rtp_payload;
1570
Sylvain Munautb54dda42009-12-20 22:06:40 +01001571 switch (lchan->tch_mode) {
1572 case GSM48_CMODE_SPEECH_V1:
1573 switch (lchan->type) {
1574 case GSM_LCHAN_TCH_F:
1575 return RTP_PT_GSM_FULL;
1576 case GSM_LCHAN_TCH_H:
1577 return RTP_PT_GSM_HALF;
1578 default:
1579 break;
1580 }
1581 case GSM48_CMODE_SPEECH_EFR:
1582 switch (lchan->type) {
1583 case GSM_LCHAN_TCH_F:
1584 return RTP_PT_GSM_EFR;
1585 /* there's no half-rate EFR */
1586 default:
1587 break;
1588 }
1589 case GSM48_CMODE_SPEECH_AMR:
1590 switch (lchan->type) {
1591 case GSM_LCHAN_TCH_F:
1592 return RTP_PT_AMR_FULL;
1593 case GSM_LCHAN_TCH_H:
1594 return RTP_PT_AMR_HALF;
1595 default:
1596 break;
1597 }
1598 default:
1599 break;
1600 }
1601 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1602 "tch_mode == 0x%02x\n & lchan_type == %d",
1603 lchan->tch_mode, lchan->type);
1604 return 0;
1605}
1606
Harald Welte75099262009-02-16 21:12:08 +00001607/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001608static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1609{
1610 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001611 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001612
1613 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001614 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001615 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1616 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1617 }
1618
1619 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001620 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001621 port = ntohs(port);
1622 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1623 lchan->abis_ip.bound_port = port;
1624 }
1625
1626 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001627 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001628 conn_id = ntohs(conn_id);
1629 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1630 lchan->abis_ip.conn_id = conn_id;
1631 }
1632
1633 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1634 lchan->abis_ip.rtp_payload2 =
1635 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1636 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1637 lchan->abis_ip.rtp_payload2);
1638 }
1639
1640 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1641 lchan->abis_ip.speech_mode =
1642 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1643 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1644 lchan->abis_ip.speech_mode);
1645 }
1646
1647 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001648 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001649 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1650 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1651 }
1652
1653 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001654 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001655 port = ntohs(port);
1656 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1657 lchan->abis_ip.connect_port = port;
1658 }
1659}
1660
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001661int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001662{
1663 struct msgb *msg = rsl_msgb_alloc();
1664 struct abis_rsl_dchan_hdr *dh;
1665
1666 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001667 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001668 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001669 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001670
Harald Weltef4e79f22009-07-28 18:11:56 +02001671 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001672 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001673 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001674 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001675 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001676
Sylvain Munautb54dda42009-12-20 22:06:40 +01001677 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1678 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1679 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001680
Harald Welte75099262009-02-16 21:12:08 +00001681 msg->trx = lchan->ts->trx;
1682
1683 return abis_rsl_sendmsg(msg);
1684}
1685
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001686int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1687 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001688{
1689 struct msgb *msg = rsl_msgb_alloc();
1690 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001691 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001692 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001693
1694 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001695 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001696 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001697 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001698
Harald Welte5e3d91b2009-12-19 16:42:06 +01001699 /* we need to store these now as MDCX_ACK does not return them :( */
1700 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1701 lchan->abis_ip.connect_port = port;
1702 lchan->abis_ip.connect_ip = ip;
1703
Harald Welte58ca5b72009-07-29 12:12:18 +02001704 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001705 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001706 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001707
Harald Weltef4e79f22009-07-28 18:11:56 +02001708 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001709 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1710 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1711 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1712 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001713
Harald Welte5e3d91b2009-12-19 16:42:06 +01001714 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1715 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001716 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001717 *att_ip = ia.s_addr;
1718 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1719 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001720 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001721 if (rtp_payload2)
1722 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1723
Harald Welte75099262009-02-16 21:12:08 +00001724 msg->trx = lchan->ts->trx;
1725
1726 return abis_rsl_sendmsg(msg);
1727}
1728
Harald Weltea72273e2009-12-20 16:51:09 +01001729/* tell BTS to connect RTP stream to our local RTP socket */
1730int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1731{
1732 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1733 int rc;
1734
1735 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1736 ntohs(rs->rtp.sin_local.sin_port),
1737 /* FIXME: use RTP payload of bound socket, not BTS*/
1738 lchan->abis_ip.rtp_payload2);
1739
1740 return rc;
1741}
1742
Harald Welte53cd7ac2010-12-23 12:59:52 +01001743int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001744{
1745 struct msgb *msg = rsl_msgb_alloc();
1746 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001747 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08001748
1749 if (act)
1750 msg_type = RSL_MT_IPAC_PDCH_ACT;
1751 else
1752 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001753
1754 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001755 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001756 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001757 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001758
Harald Welte53cd7ac2010-12-23 12:59:52 +01001759 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001760 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001761
Harald Welte53cd7ac2010-12-23 12:59:52 +01001762 msg->trx = ts->trx;
Harald Welte9c880c92009-10-24 10:29:22 +02001763
1764 return abis_rsl_sendmsg(msg);
1765}
1766
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001767static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001768{
1769 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1770 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301771 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001772
1773 /* the BTS has acknowledged a local bind, it now tells us the IP
1774 * address and port number to which it has bound the given logical
1775 * channel */
1776
1777 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1778 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1779 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001780 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001781 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001782 return -EINVAL;
1783 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001784
Harald Welte5e3d91b2009-12-19 16:42:06 +01001785 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001786
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001787 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001788
Harald Welte75099262009-02-16 21:12:08 +00001789 return 0;
1790}
1791
Harald Welte5e3d91b2009-12-19 16:42:06 +01001792static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1793{
1794 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1795 struct tlv_parsed tv;
1796 struct gsm_lchan *lchan = msg->lchan;
1797
1798 /* the BTS has acknowledged a remote connect request and
1799 * it now tells us the IP address and port number to which it has
1800 * connected the given logical channel */
1801
1802 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1803 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001804 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001805
1806 return 0;
1807}
1808
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001809static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001810{
1811 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1812 struct tlv_parsed tv;
1813
1814 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001815
Harald Welte8830e072009-07-28 17:58:09 +02001816 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001817 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001818 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001819
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001820 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001821
Harald Welte75099262009-02-16 21:12:08 +00001822 return 0;
1823}
1824
1825static int abis_rsl_rx_ipacc(struct msgb *msg)
1826{
1827 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001828 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001829 int rc = 0;
1830
1831 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001832 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001833
1834 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001835 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001836 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001837 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001838 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001839 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001840 /* somehow the BTS was unable to bind the lchan to its local
1841 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001842 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001843 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001844 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001845 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001846 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001847 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001848 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001849 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001850 /* somehow the BTS was unable to connect the lchan to a remote
1851 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001852 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001853 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001854 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001855 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001856 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001857 break;
1858 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001859 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001860 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001861 break;
1862 }
Harald Welte6dab0552009-05-01 17:21:37 +00001863 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001864
1865 return rc;
1866}
1867
1868
Harald Welte52b1f982008-12-23 20:25:15 +00001869/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001870int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001871{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001872 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00001873 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001874
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001875 if (!msg) {
1876 DEBUGP(DRSL, "Empty RSL msg?..\n");
1877 return -1;
1878 }
1879
1880 if (msgb_l2len(msg) < sizeof(*rslh)) {
1881 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
1882 return -1;
1883 }
1884
1885 rslh = msgb_l2(msg);
1886
Harald Welte52b1f982008-12-23 20:25:15 +00001887 switch (rslh->msg_discr & 0xfe) {
1888 case ABIS_RSL_MDISC_RLL:
1889 rc = abis_rsl_rx_rll(msg);
1890 break;
1891 case ABIS_RSL_MDISC_DED_CHAN:
1892 rc = abis_rsl_rx_dchan(msg);
1893 break;
1894 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001895 rc = abis_rsl_rx_cchan(msg);
1896 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001897 case ABIS_RSL_MDISC_TRX:
1898 rc = abis_rsl_rx_trx(msg);
1899 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001900 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001901 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00001902 rslh->msg_discr);
1903 break;
Harald Welte75099262009-02-16 21:12:08 +00001904 case ABIS_RSL_MDISC_IPACCESS:
1905 rc = abis_rsl_rx_ipacc(msg);
1906 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001907 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001908 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1909 "0x%02x\n", rslh->msg_discr);
Harald Welte52b1f982008-12-23 20:25:15 +00001910 return -EINVAL;
1911 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001912 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001913 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001914}
Holger Freyther3b72a892009-02-04 00:31:39 +00001915
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08001916int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1917 uint8_t cb_command, const uint8_t *data, int len)
1918{
1919 struct abis_rsl_dchan_hdr *dh;
1920 struct msgb *cb_cmd;
1921
1922 cb_cmd = rsl_msgb_alloc();
1923 if (!cb_cmd)
1924 return -1;
1925
1926 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1927 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
1928 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
1929
1930 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
1931 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
1932
1933 cb_cmd->trx = bts->c0;
1934
1935 return abis_rsl_sendmsg(cb_cmd);
1936}
Dieter Spaar16646022011-07-28 00:01:50 +02001937
1938int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
1939{
1940 struct abis_rsl_common_hdr *ch;
1941 struct msgb *msg = rsl_msgb_alloc();
1942
1943 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
1944 ch->msg_discr = ABIS_RSL_MDISC_TRX;
1945 ch->msg_type = 0x40; /* Nokia SI Begin */
1946
1947 msg->trx = trx;
1948
1949 return abis_rsl_sendmsg(msg);
1950}
1951
1952int rsl_nokia_si_end(struct gsm_bts_trx *trx)
1953{
1954 struct abis_rsl_common_hdr *ch;
1955 struct msgb *msg = rsl_msgb_alloc();
1956
1957 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
1958 ch->msg_discr = ABIS_RSL_MDISC_TRX;
1959 ch->msg_type = 0x41; /* Nokia SI End */
1960
1961 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
1962
1963 msg->trx = trx;
1964
1965 return abis_rsl_sendmsg(msg);
1966}
1967
1968int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
1969{
1970 struct abis_rsl_common_hdr *ch;
1971 struct msgb *msg = rsl_msgb_alloc();
1972
1973 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
1974 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1975 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
1976
1977 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
1978 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
1979
1980 msg->trx = trx;
1981
1982 return abis_rsl_sendmsg(msg);
1983}