blob: b703c034fb053a528ecb797178edab20ffbd104d [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 Ayusoed5cacb2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010042#include <osmocom/gsm/rsl.h>
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
Daniel Willmann513da172011-08-11 04:44:12 +0200188 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
189 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200190}
191
192static void lchan_deact_tmr_cb(void *data)
193{
194 struct gsm_lchan *lchan = data;
195
196 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during deactivation!\n",
197 gsm_lchan_name(lchan));
198
Holger Hans Peter Freytherbbf21392012-01-14 21:56:37 +0100199 if (lchan->state != LCHAN_S_REL_ERR)
200 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Daniel Willmann513da172011-08-11 04:44:12 +0200201 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200202}
203
204
Harald Welte52b1f982008-12-23 20:25:15 +0000205/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200206int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
207 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000208{
209 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000210 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000211
212 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
213 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
214 dh->chan_nr = RSL_CHAN_BCCH;
215
216 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
217 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
218
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200219 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000220
221 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000222}
223
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200224int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
225 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000226{
227 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000228 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000229
230 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
231 ch->msg_discr = ABIS_RSL_MDISC_TRX;
232 ch->msg_type = RSL_MT_SACCH_FILL;
233
234 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000235 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000236
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200237 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000238
239 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000240}
241
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200242int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
243 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100244{
245 struct abis_rsl_dchan_hdr *dh;
246 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200247 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100248
249 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
250 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
251 dh->chan_nr = chan_nr;
252
253 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
254 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
255
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200256 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100257
258 return abis_rsl_sendmsg(msg);
259}
260
Harald Weltefcd24452009-06-20 18:15:19 +0200261int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
262{
263 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200264 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200265 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200266
267 db = abs(db);
268 if (db > 30)
269 return -EINVAL;
270
Harald Welteeab33352009-06-27 03:09:08 +0200271 msg = rsl_msgb_alloc();
272
Harald Weltefcd24452009-06-20 18:15:19 +0200273 lchan->bs_power = db/2;
274 if (fpc)
275 lchan->bs_power |= 0x10;
276
277 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
278 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
279 dh->chan_nr = chan_nr;
280
281 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
282
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200283 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200284
285 return abis_rsl_sendmsg(msg);
286}
287
Harald Weltefcd24452009-06-20 18:15:19 +0200288int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
289{
290 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200291 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200292 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200293 int ctl_lvl;
294
Harald Welte66b6a8d2009-08-09 14:45:18 +0200295 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200296 if (ctl_lvl < 0)
297 return ctl_lvl;
298
Harald Welteeab33352009-06-27 03:09:08 +0200299 msg = rsl_msgb_alloc();
300
Harald Weltefcd24452009-06-20 18:15:19 +0200301 lchan->ms_power = ctl_lvl;
302
303 if (fpc)
304 lchan->ms_power |= 0x20;
305
306 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
307 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
308 dh->chan_nr = chan_nr;
309
310 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
311
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200312 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200313
314 return abis_rsl_sendmsg(msg);
315}
316
Harald Welte9943c5b2009-07-29 15:41:29 +0200317static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
318 struct gsm_lchan *lchan)
319{
320 memset(cm, 0, sizeof(cm));
321
322 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800323 if (lchan->ts->trx->bts->network->dtx_enabled)
324 cm->dtx_dtu = 0x03;
325 else
326 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200327
328 /* set TCH Speech/Data */
329 cm->spd_ind = lchan->rsl_cmode;
330
Harald Welte1a79d362009-11-27 08:55:16 +0100331 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
332 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100333 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100334 "but tch_mode != signalling\n");
335
Harald Welte9943c5b2009-07-29 15:41:29 +0200336 switch (lchan->type) {
337 case GSM_LCHAN_SDCCH:
338 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
339 break;
340 case GSM_LCHAN_TCH_F:
341 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
342 break;
343 case GSM_LCHAN_TCH_H:
344 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
345 break;
346 case GSM_LCHAN_NONE:
347 case GSM_LCHAN_UNKNOWN:
348 default:
349 return -EINVAL;
350 }
351
352 switch (lchan->tch_mode) {
353 case GSM48_CMODE_SIGN:
354 cm->chan_rate = 0;
355 break;
356 case GSM48_CMODE_SPEECH_V1:
357 cm->chan_rate = RSL_CMOD_SP_GSM1;
358 break;
359 case GSM48_CMODE_SPEECH_EFR:
360 cm->chan_rate = RSL_CMOD_SP_GSM2;
361 break;
362 case GSM48_CMODE_SPEECH_AMR:
363 cm->chan_rate = RSL_CMOD_SP_GSM3;
364 break;
365 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200366 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200367 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200368 switch (lchan->csd_mode) {
369 case LCHAN_CSD_M_NT:
370 /* non-transparent CSD with RLP */
371 switch (lchan->tch_mode) {
372 case GSM48_CMODE_DATA_14k5:
373 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
374 break;
375 case GSM48_CMODE_DATA_12k0:
376 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
377 break;
378 case GSM48_CMODE_DATA_6k0:
379 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
380 break;
381 default:
382 return -EINVAL;
383 }
384 break;
385 /* transparent data services below */
386 case LCHAN_CSD_M_T_1200_75:
387 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
388 break;
389 case LCHAN_CSD_M_T_600:
390 cm->chan_rate = RSL_CMOD_CSD_T_600;
391 break;
392 case LCHAN_CSD_M_T_1200:
393 cm->chan_rate = RSL_CMOD_CSD_T_1200;
394 break;
395 case LCHAN_CSD_M_T_2400:
396 cm->chan_rate = RSL_CMOD_CSD_T_2400;
397 break;
398 case LCHAN_CSD_M_T_9600:
399 cm->chan_rate = RSL_CMOD_CSD_T_9600;
400 break;
401 case LCHAN_CSD_M_T_14400:
402 cm->chan_rate = RSL_CMOD_CSD_T_14400;
403 break;
404 case LCHAN_CSD_M_T_29000:
405 cm->chan_rate = RSL_CMOD_CSD_T_29000;
406 break;
407 case LCHAN_CSD_M_T_32000:
408 cm->chan_rate = RSL_CMOD_CSD_T_32000;
409 break;
410 default:
411 return -EINVAL;
412 }
Harald Welte9943c5b2009-07-29 15:41:29 +0200413 default:
414 return -EINVAL;
415 }
416
417 return 0;
418}
419
Harald Welte52b1f982008-12-23 20:25:15 +0000420/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000421#if 0
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200422int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
423 uint8_t act_type,
Harald Welte52b1f982008-12-23 20:25:15 +0000424 struct rsl_ie_chan_mode *chan_mode,
425 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200426 uint8_t bs_power, uint8_t ms_power,
427 uint8_t ta)
Harald Welte52b1f982008-12-23 20:25:15 +0000428{
429 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000430 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000431
432 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
433 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
434 dh->chan_nr = chan_nr;
435
436 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
437 /* For compatibility with Phase 1 */
438 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200439 (uint8_t *) chan_mode);
Harald Welte52b1f982008-12-23 20:25:15 +0000440 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200441 (uint8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000442#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000443 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200444 (uint8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000445#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000446 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000447 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
448 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
449
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200450 msg->dst = trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000451
Harald Welte8470bf22008-12-25 23:28:35 +0000452 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000453}
Harald Welteddab3c72009-02-28 13:19:15 +0000454#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000455
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200456int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
457 uint8_t ta, uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000458{
459 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200460 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200461 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200462 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000463
Harald Weltef6093a42011-06-25 10:02:33 +0200464 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000465 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200466 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000467
Harald Welte9943c5b2009-07-29 15:41:29 +0200468 rc = channel_mode_from_lchan(&cm, lchan);
469 if (rc < 0)
470 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000471
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800472 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200473 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000474
Harald Welteeab33352009-06-27 03:09:08 +0200475 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000476 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
477 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
478 dh->chan_nr = chan_nr;
479
480 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000481 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200482 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800483
484 /*
485 * The Channel Identification is needed for Phase1 phones
486 * and it contains the GSM48 Channel Description and the
487 * Mobile Allocation. The GSM 08.58 asks for the Mobile
488 * Allocation to have a length of zero. We are using the
489 * msgb_l3len to calculate the length of both messages.
490 */
laforge694a5cf2010-06-20 21:38:19 +0200491 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200492 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200493 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800494
495 if (lchan->ts->hopping.enabled)
496 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
497 lchan->ts->hopping.ma_data);
498 else
499 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800500
501 /* update the calculated size */
502 msg->l3h = len + 1;
503 *len = msgb_l3len(msg);
504
Harald Welte08d91a52009-08-30 15:37:11 +0900505 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200506 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900507 rc = build_encr_info(encr_info, lchan);
508 if (rc > 0)
509 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
510 }
511
Harald Welte8d77b952009-12-17 00:31:10 +0100512 switch (act_type) {
513 case RSL_ACT_INTER_ASYNC:
514 case RSL_ACT_INTER_SYNC:
515 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
516 break;
517 default:
518 break;
519 }
520
Harald Welted4c9bf32009-02-15 16:56:18 +0000521 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
522 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000523 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
524
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100525 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
526 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200527 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100528
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200529 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000530
Harald Welte4b634542008-12-27 01:55:51 +0000531 return abis_rsl_sendmsg(msg);
532}
533
Harald Welte470abb72009-07-29 11:38:15 +0200534/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000535int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
536{
537 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200538 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200539 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000540
Harald Weltef6093a42011-06-25 10:02:33 +0200541 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000542 struct rsl_ie_chan_mode cm;
543
Harald Welte9943c5b2009-07-29 15:41:29 +0200544 rc = channel_mode_from_lchan(&cm, lchan);
545 if (rc < 0)
546 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000547
Harald Welteeab33352009-06-27 03:09:08 +0200548 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000549 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
550 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
551 dh->chan_nr = chan_nr;
552
553 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200554 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900555
556 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200557 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900558 rc = build_encr_info(encr_info, lchan);
559 if (rc > 0)
560 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
561 }
562
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100563 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
564 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200565 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100566 }
567
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200568 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900569
570 return abis_rsl_sendmsg(msg);
571}
572
573/* Chapter 8.4.6: Send the encryption command with given L3 info */
574int rsl_encryption_cmd(struct msgb *msg)
575{
576 struct abis_rsl_dchan_hdr *dh;
577 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200578 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200579 uint8_t encr_info[MAX_A5_KEY_LEN+2];
580 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900581 int rc;
582
583 /* First push the L3 IE tag and length */
584 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
585
586 /* then the link identifier (SAPI0, main sign link) */
587 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
588
589 /* then encryption information */
590 rc = build_encr_info(encr_info, lchan);
591 if (rc <= 0)
592 return rc;
593 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
594
595 /* and finally the DCHAN header */
596 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
597 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
598 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000599
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200600 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000601
602 return abis_rsl_sendmsg(msg);
603}
604
Harald Welte115d1032009-08-10 11:43:22 +0200605/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200606int rsl_deact_sacch(struct gsm_lchan *lchan)
607{
608 struct abis_rsl_dchan_hdr *dh;
609 struct msgb *msg = rsl_msgb_alloc();
610
611 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
612 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200613 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200614
615 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200616 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200617
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100618 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200619
620 return abis_rsl_sendmsg(msg);
621}
622
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800623static void error_timeout_cb(void *data)
624{
625 struct gsm_lchan *lchan = data;
626 if (lchan->state != LCHAN_S_REL_ERR) {
627 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
628 gsm_lchan_name(lchan), lchan->state);
629 return;
630 }
631
632 /* go back to the none state */
633 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800634 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800635}
636
Harald Weltefd355a32011-03-04 13:41:31 +0100637static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
638
Harald Welte115d1032009-08-10 11:43:22 +0200639/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800640static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte52b1f982008-12-23 20:25:15 +0000641{
642 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800643 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100644 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000645
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800646 if (lchan->state == LCHAN_S_REL_ERR) {
647 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
648 gsm_lchan_name(lchan));
649 return -1;
650 }
651
652 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000653 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
654 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200655 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000656
Harald Welte8470bf22008-12-25 23:28:35 +0000657 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200658 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000659
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800660 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
661
662 if (error) {
663 /*
664 * the nanoBTS sends RLL release indications after the channel release. This can
665 * be a problem when we have reassigned the channel to someone else and then can
666 * not figure out who used this channel.
667 */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200668 struct e1inp_sign_link *sign_link = msg->dst;
669
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800670 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800671 lchan->error_timer.data = lchan;
672 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200673 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200674 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800675 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000676
Harald Weltee8bd9e82011-08-10 23:26:33 +0200677 /* Start another timer or assume the BTS sends a ACK/NACK? */
678 lchan->act_timer.cb = lchan_deact_tmr_cb;
679 lchan->act_timer.data = lchan;
680 osmo_timer_schedule(&lchan->act_timer, 4, 0);
681
Harald Weltefd355a32011-03-04 13:41:31 +0100682 rc = abis_rsl_sendmsg(msg);
683
Harald Welte115d1032009-08-10 11:43:22 +0200684 /* BTS will respond by RF CHAN REL ACK */
Harald Welte26d79072011-01-14 23:18:59 +0100685#ifdef HSL_SR_1_0
Harald Weltefd355a32011-03-04 13:41:31 +0100686 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
687 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
688 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte26d79072011-01-14 23:18:59 +0100689#endif
Harald Weltefd355a32011-03-04 13:41:31 +0100690
691 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000692}
693
Harald Welte64bb7542011-01-14 14:16:16 +0100694static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
695{
696
697 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
698
Harald Weltee8bd9e82011-08-10 23:26:33 +0200699 osmo_timer_del(&lchan->act_timer);
700
Harald Welte64bb7542011-01-14 14:16:16 +0100701 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
702 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
703 gsm_lchan_name(lchan),
704 gsm_lchans_name(lchan->state));
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200705 osmo_timer_del(&lchan->T3111);
Harald Welte64bb7542011-01-14 14:16:16 +0100706 /* we have an error timer pending to release that */
707 if (lchan->state != LCHAN_S_REL_ERR)
708 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
709 lchan_free(lchan);
710
711 return 0;
712}
713
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200714int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
715 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte52b1f982008-12-23 20:25:15 +0000716{
717 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000718 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000719
720 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
721 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
722 dh->chan_nr = RSL_CHAN_PCH_AGCH;
723
724 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000725 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000726 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
727
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200728 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000729
730 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000731}
732
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200733int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +0000734{
735 int i, len = strlen(str_in);
736
737 for (i = 0; i < len; i++) {
738 int num = str_in[i] - 0x30;
739 if (num < 0 || num > 9)
740 return -1;
741 if (i % 2 == 0)
742 bcd_out[i/2] = num;
743 else
744 bcd_out[i/2] |= (num << 4);
745 }
746
747 return 0;
748}
749
Harald Welte702d8702008-12-26 20:25:35 +0000750/* Chapter 8.5.6 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200751int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +0000752{
Harald Welte8470bf22008-12-25 23:28:35 +0000753 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000754 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200755 uint8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000756
757 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
758 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
759 dh->chan_nr = RSL_CHAN_PCH_AGCH;
760
Harald Welte362322e2009-02-15 14:36:38 +0000761 switch (bts->type) {
762 case GSM_BTS_TYPE_BS11:
763 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
764 break;
765 default:
766 /* If phase 2, construct a FULL_IMM_ASS_INFO */
767 pad_macblock(buf, val, len);
768 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
769 break;
770 }
Harald Welte52b1f982008-12-23 20:25:15 +0000771
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200772 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000773
774 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000775}
776
Harald Welte67fa91b2009-08-10 09:51:40 +0200777/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200778int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200779{
780 struct msgb *msg = rsl_msgb_alloc();
781 struct abis_rsl_dchan_hdr *dh;
782
783 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
784 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200785 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +0200786 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200787 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200788
Harald Welte5b8ed432009-12-24 12:20:20 +0100789 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200790 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200791
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200792 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +0200793
Harald Welte67fa91b2009-08-10 09:51:40 +0200794 return abis_rsl_sendmsg(msg);
795}
796
797
Harald Welte8470bf22008-12-25 23:28:35 +0000798/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000799/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200800int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000801{
Harald Welte8470bf22008-12-25 23:28:35 +0000802 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100803 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000804 return -EINVAL;
805 }
Harald Welte52b1f982008-12-23 20:25:15 +0000806
Harald Weltef6093a42011-06-25 10:02:33 +0200807 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100808 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000809
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200810 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000811
812 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000813}
814
Harald Welteedcc5272009-08-09 13:47:35 +0200815/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
816/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200817int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +0200818{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100819 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200820
Harald Weltef6093a42011-06-25 10:02:33 +0200821 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100822 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200823 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +0200824
Harald Weltefda74ee2012-04-26 19:42:19 +0200825 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
826 gsm_lchan_name(lchan), link_id);
827
Harald Welteedcc5272009-08-09 13:47:35 +0200828 return abis_rsl_sendmsg(msg);
829}
830
Harald Welted2dc1de2009-08-08 13:15:07 +0200831/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
832 This is what higher layers should call. The BTS then responds with
833 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
834 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
835 lchan_free() */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200836int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason)
Harald Welted2dc1de2009-08-08 13:15:07 +0200837{
Harald Welted2dc1de2009-08-08 13:15:07 +0200838
Harald Welte3c9c5f92010-03-04 10:33:10 +0100839 struct msgb *msg;
840
Harald Weltef6093a42011-06-25 10:02:33 +0200841 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100842 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800843 /* 0 is normal release, 1 is local end */
844 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
Harald Welted2dc1de2009-08-08 13:15:07 +0200845
Harald Welte8e93b792009-12-29 10:44:17 +0100846 /* FIXME: start some timer in case we don't receive a REL ACK ? */
847
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200848 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +0200849
Harald Weltefda74ee2012-04-26 19:42:19 +0200850 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
851 gsm_lchan_name(lchan), link_id, reason);
852
Harald Welted2dc1de2009-08-08 13:15:07 +0200853 return abis_rsl_sendmsg(msg);
854}
855
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200856int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
857{
858 lchan->state = state;
859 return 0;
860}
861
Harald Welte702d8702008-12-26 20:25:35 +0000862/* Chapter 8.4.2: Channel Activate Acknowledge */
863static int rsl_rx_chan_act_ack(struct msgb *msg)
864{
865 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
866
867 /* BTS has confirmed channel activation, we now need
868 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000869 if (rslh->ie_chan != RSL_IE_CHAN_NR)
870 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100871
Harald Weltee8bd9e82011-08-10 23:26:33 +0200872 osmo_timer_del(&msg->lchan->act_timer);
873
Harald Welte8e93b792009-12-29 10:44:17 +0100874 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100875 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
876 gsm_lchan_name(msg->lchan),
877 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200878 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100879
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800880 if (msg->lchan->rqd_ref) {
881 rsl_send_imm_assignment(msg->lchan);
882 talloc_free(msg->lchan->rqd_ref);
883 msg->lchan->rqd_ref = NULL;
884 msg->lchan->rqd_ta = 0;
885 }
886
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100887 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100888
Harald Welte4b634542008-12-27 01:55:51 +0000889 return 0;
890}
Harald Welte702d8702008-12-26 20:25:35 +0000891
Harald Welte4b634542008-12-27 01:55:51 +0000892/* Chapter 8.4.3: Channel Activate NACK */
893static int rsl_rx_chan_act_nack(struct msgb *msg)
894{
Harald Welte6dab0552009-05-01 17:21:37 +0000895 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
896 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000897
Harald Weltee8bd9e82011-08-10 23:26:33 +0200898 osmo_timer_del(&msg->lchan->act_timer);
899
Daniel Willmann6fc6a122011-08-11 04:54:23 +0200900 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100901 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100902
Harald Welte6dab0552009-05-01 17:21:37 +0000903 /* BTS has rejected channel activation ?!? */
904 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000905 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000906
907 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100908 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200909 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100910 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200911 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100912 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200913 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200914 else
915 rsl_rf_chan_release(msg->lchan, 1);
916
Harald Welte (local)3e460312009-12-27 18:12:29 +0100917 } else
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200918 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200919
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100920 LOGPC(DRSL, LOGL_ERROR, "\n");
921
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100922 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100923
Harald Welte3073a9f2009-08-09 19:50:08 +0200924 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000925 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000926}
927
Harald Welte7f93cea2009-02-23 00:02:59 +0000928/* Chapter 8.4.4: Connection Failure Indication */
929static int rsl_rx_conn_fail(struct msgb *msg)
930{
931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
932 struct tlv_parsed tp;
933
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100934 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100935 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100936 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000937
938 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
939
Harald Welte8830e072009-07-28 17:58:09 +0200940 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100941 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200942 TLVP_LEN(&tp, RSL_IE_CAUSE));
943
Harald Welte (local)fc057502009-12-26 22:33:09 +0100944 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000945 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +0200946 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800947 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte7f93cea2009-02-23 00:02:59 +0000948}
949
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100950static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
951 const char *prefix)
952{
Harald Welte6739dfb2009-12-16 16:52:07 +0100953 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
954 prefix, rxlev2dbm(mru->full.rx_lev),
955 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100956 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
957 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
958}
959
Harald Welte0c1bd612012-07-02 17:12:08 +0200960static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100961{
Harald Welte6739dfb2009-12-16 16:52:07 +0100962 int i;
Harald Welte0c1bd612012-07-02 17:12:08 +0200963 char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +0100964
Harald Welte0c1bd612012-07-02 17:12:08 +0200965 if (lchan && lchan->conn && lchan->conn->subscr)
966 name = subscr_name(lchan->conn->subscr);
967
968 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100969
970 if (mr->flags & MEAS_REP_F_DL_DTX)
971 DEBUGPC(DMEAS, "DTXd ");
972
973 print_meas_rep_uni(&mr->ul, "ul");
974 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
975 if (mr->flags & MEAS_REP_F_MS_TO)
976 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
977
978 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +0100979 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100980 DEBUGPC(DMEAS, "L1_FPC=%u ",
981 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
982 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
983 }
984
985 if (mr->flags & MEAS_REP_F_UL_DTX)
986 DEBUGPC(DMEAS, "DTXu ");
987 if (mr->flags & MEAS_REP_F_BA1)
988 DEBUGPC(DMEAS, "BA1 ");
989 if (!(mr->flags & MEAS_REP_F_DL_VALID))
990 DEBUGPC(DMEAS, "NOT VALID ");
991 else
992 print_meas_rep_uni(&mr->dl, "dl");
993
994 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +0100995 if (mr->num_cell == 7)
996 return;
Harald Welte6739dfb2009-12-16 16:52:07 +0100997 for (i = 0; i < mr->num_cell; i++) {
998 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +0100999 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1000 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001001 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001002}
1003
Harald Welte440fed02009-05-01 18:43:47 +00001004static int rsl_rx_meas_res(struct msgb *msg)
1005{
1006 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1007 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001008 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001009 uint8_t len;
1010 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001011 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001012
Harald Welteb8bfc562009-12-21 13:27:11 +01001013 /* check if this channel is actually active */
1014 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001015 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001016 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001017 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001018 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001019 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001020
Harald Welted12b0fd2009-12-15 21:36:05 +01001021 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001022 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001023
Harald Welte440fed02009-05-01 18:43:47 +00001024 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1025
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001026 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1027 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1028 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1029 return -EIO;
1030
1031 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001032 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001033
1034 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1035 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1036 if (len >= 3) {
1037 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001038 mr->flags |= MEAS_REP_F_DL_DTX;
1039 mr->ul.full.rx_lev = val[0] & 0x3f;
1040 mr->ul.sub.rx_lev = val[1] & 0x3f;
1041 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1042 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001043 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001044
Harald Welted12b0fd2009-12-15 21:36:05 +01001045 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001046
1047 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +00001048 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +01001049 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001050 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1051
Harald Weltefe9af262009-06-20 18:44:35 +02001052 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001053 struct e1inp_sign_link *sign_link = msg->dst;
1054
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001055 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001056 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001057 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001058 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001059 mr->flags |= MEAS_REP_F_FPC;
1060 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001061 /* BS11 and Nokia reports TA shifted by 2 bits */
1062 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1063 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001064 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001065 }
Harald Weltef7c43522009-06-09 20:24:21 +00001066 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001067 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001068 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001069 if (rc < 0)
1070 return rc;
1071 }
1072
Harald Welte0c1bd612012-07-02 17:12:08 +02001073 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001074
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001075 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001076
Harald Welte75d34a82009-05-23 06:11:13 +00001077 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001078}
1079
Harald Welted011e8b2009-11-29 22:45:52 +01001080/* Chapter 8.4.7 */
1081static int rsl_rx_hando_det(struct msgb *msg)
1082{
1083 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1084 struct tlv_parsed tp;
1085
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001086 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001087
1088 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1089
1090 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1091 DEBUGPC(DRSL, "access delay = %u\n",
1092 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1093 else
1094 DEBUGPC(DRSL, "\n");
1095
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001096 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001097
1098 return 0;
1099}
1100
Harald Welte52b1f982008-12-23 20:25:15 +00001101static int abis_rsl_rx_dchan(struct msgb *msg)
1102{
Harald Welte8470bf22008-12-25 23:28:35 +00001103 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1104 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001105 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001106 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001107
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001108 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001109 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001110
Harald Welte8470bf22008-12-25 23:28:35 +00001111 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001112 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001113 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001114 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001115 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001116 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001117 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001118 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001119 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001120 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001121 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001122 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001123 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001124 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001125 case RSL_MT_HANDO_DET:
1126 rc = rsl_rx_hando_det(msg);
1127 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001128 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001129 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001130 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001131 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001132 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001133 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001134 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001135 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001136 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001137 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001138 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001139 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001140 break;
1141 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001142 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001143 break;
1144 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001145 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001146 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001147 break;
1148 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001149 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001150 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001151 case RSL_MT_PHY_CONTEXT_CONF:
1152 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001153 case RSL_MT_TALKER_DET:
1154 case RSL_MT_LISTENER_DET:
1155 case RSL_MT_REMOTE_CODEC_CONF_REP:
1156 case RSL_MT_MR_CODEC_MOD_ACK:
1157 case RSL_MT_MR_CODEC_MOD_NACK:
1158 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001159 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1160 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001161 break;
1162 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001163 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1164 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001165 return -EINVAL;
1166 }
Harald Weltef325eb42009-02-19 17:07:39 +00001167
Harald Welte8470bf22008-12-25 23:28:35 +00001168 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001169}
1170
Harald Welte702d8702008-12-26 20:25:35 +00001171static int rsl_rx_error_rep(struct msgb *msg)
1172{
1173 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001174 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001175 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001176
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001177 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001178
1179 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1180
1181 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001182 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001183 TLVP_LEN(&tp, RSL_IE_CAUSE));
1184
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001185 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001186
1187 return 0;
1188}
1189
Harald Welte52b1f982008-12-23 20:25:15 +00001190static int abis_rsl_rx_trx(struct msgb *msg)
1191{
Harald Welte702d8702008-12-26 20:25:35 +00001192 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001193 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001194 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001195
1196 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001197 case RSL_MT_ERROR_REPORT:
1198 rc = rsl_rx_error_rep(msg);
1199 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001200 case RSL_MT_RF_RES_IND:
1201 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001202 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001203 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001204 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001205 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001206 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001207 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001208 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001209 case 0x42: /* Nokia specific: SI End ACK */
1210 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1211 break;
1212 case 0x43: /* Nokia specific: SI End NACK */
1213 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1214 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001215 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001216 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001217 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001218 return -EINVAL;
1219 }
Harald Welte8470bf22008-12-25 23:28:35 +00001220 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001221}
1222
Harald Welteb7e81162009-08-10 00:26:10 +02001223/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1224static void t3101_expired(void *data)
1225{
1226 struct gsm_lchan *lchan = data;
1227
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001228 rsl_rf_chan_release(lchan, 1);
Harald Welteb7e81162009-08-10 00:26:10 +02001229}
1230
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001231/* If T3111 expires, we will send the RF Channel Request */
1232static void t3111_expired(void *data)
1233{
1234 struct gsm_lchan *lchan = data;
1235
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001236 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001237}
1238
laforgecfa4a012010-06-21 12:08:52 +02001239#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1240
Harald Welte2862dca2010-12-23 14:39:29 +01001241/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1242static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1243 unsigned int num_req_refs,
1244 struct gsm48_req_ref *rqd_refs,
1245 uint8_t wait_ind)
1246{
1247 uint8_t buf[GSM_MACBLOCK_LEN];
1248 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1249
1250 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1251 memset(iar, 0, sizeof(*iar));
1252 iar->proto_discr = GSM48_PDISC_RR;
1253 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1254 iar->page_mode = GSM48_PM_SAME;
1255
1256 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1257 iar->wait_ind1 = wait_ind;
1258
1259 if (num_req_refs >= 2)
1260 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1261 else
1262 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1263 iar->wait_ind2 = wait_ind;
1264
1265 if (num_req_refs >= 3)
1266 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1267 else
1268 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1269 iar->wait_ind3 = wait_ind;
1270
1271 if (num_req_refs >= 4)
1272 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1273 else
1274 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1275 iar->wait_ind4 = wait_ind;
1276
1277 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1278}
1279
Harald Welte8470bf22008-12-25 23:28:35 +00001280/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001281static int rsl_rx_chan_rqd(struct msgb *msg)
1282{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001283 struct e1inp_sign_link *sign_link = msg->dst;
1284 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001285 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1286 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001287 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001288 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001289 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001290 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001291 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001292
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001293 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001294 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001295
Harald Welte8470bf22008-12-25 23:28:35 +00001296 /* parse request reference to be used in immediate assign */
1297 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1298 return -EINVAL;
1299
1300 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1301
1302 /* parse access delay and use as TA */
1303 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1304 return -EINVAL;
1305 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1306
1307 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1308 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001309 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1310 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001311
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001312 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001313
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001314 /*
1315 * We want LOCATION UPDATES to succeed and will assign a TCH
1316 * if we have no SDCCH available.
1317 */
1318 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1319
Harald Welte8470bf22008-12-25 23:28:35 +00001320 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001321 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001322 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001323 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001324 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001325 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001326 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1327 if (bts->network->T3122)
1328 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001329 return -ENOMEM;
1330 }
1331
Harald Welte8e93b792009-12-29 10:44:17 +01001332 if (lchan->state != LCHAN_S_NONE)
1333 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001334 "in state %s\n", gsm_lchan_name(lchan),
1335 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001336
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001337 /* save the RACH data as we need it after the CHAN ACT ACK */
1338 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1339 if (!lchan->rqd_ref) {
1340 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1341 lchan_free(lchan);
1342 return -ENOMEM;
1343 }
1344
Holger Hans Peter Freytherc0a66742011-12-29 23:33:04 +01001345 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001346 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1347 lchan->rqd_ta = rqd_ta;
1348
Harald Welte8470bf22008-12-25 23:28:35 +00001349 arfcn = lchan->ts->trx->arfcn;
1350 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001351
Harald Welte08d91a52009-08-30 15:37:11 +09001352 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001353 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001354 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001355 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001356 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001357
Harald Weltee8bd9e82011-08-10 23:26:33 +02001358 /* Start another timer or assume the BTS sends a ACK/NACK? */
1359 lchan->act_timer.cb = lchan_act_tmr_cb;
1360 lchan->act_timer.data = lchan;
1361 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1362
Andreas Eversberg2957de92011-12-16 17:45:37 +01001363 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1364 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1365 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1366 rqd_ref->ra, rqd_ta);
1367
1368 /* BS11 requires TA shifted by 2 bits */
1369 if (bts->type == GSM_BTS_TYPE_BS11)
1370 rqd_ta <<= 2;
Harald Welte8d77b952009-12-17 00:31:10 +01001371 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001372
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001373 return 0;
1374}
1375
1376static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1377{
1378 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001379 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001380 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1381
Harald Welte52b1f982008-12-23 20:25:15 +00001382 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001383 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001384 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001385 ia->proto_discr = GSM48_PDISC_RR;
1386 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1387 ia->page_mode = GSM48_PM_SAME;
1388 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001389
Harald Welte8470bf22008-12-25 23:28:35 +00001390 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001391 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1392 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001393 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001394 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001395 } else {
laforge09108bf2010-06-20 15:18:46 +02001396 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1397 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001398 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001399 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1400 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001401
Harald Welteb7e81162009-08-10 00:26:10 +02001402 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1403 lchan->T3101.cb = t3101_expired;
1404 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001405 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001406
Harald Welte52b1f982008-12-23 20:25:15 +00001407 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001408 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001409}
1410
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001411/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001412static int rsl_rx_ccch_load(struct msgb *msg)
1413{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001414 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001415 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001416 struct ccch_signal_data sd;
1417
1418 sd.bts = sign_link->trx->bts;
1419 sd.rach_slot_count = -1;
1420 sd.rach_busy_count = -1;
1421 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001422
1423 switch (rslh->data[0]) {
1424 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001425 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1426 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001427 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001428 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001429 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001430 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1431 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001432 break;
1433 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001434 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001435 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1436 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1437 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1438 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001439 }
Harald Welteea280442009-02-02 22:29:56 +00001440 break;
1441 default:
1442 break;
1443 }
1444
1445 return 0;
1446}
1447
Harald Welte52b1f982008-12-23 20:25:15 +00001448static int abis_rsl_rx_cchan(struct msgb *msg)
1449{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001450 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001451 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001452 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001453
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001454 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +00001455
1456 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001457 case RSL_MT_CHAN_RQD:
1458 /* MS has requested a channel on the RACH */
1459 rc = rsl_rx_chan_rqd(msg);
1460 break;
Harald Welteea280442009-02-02 22:29:56 +00001461 case RSL_MT_CCCH_LOAD_IND:
1462 /* current load on the CCCH */
1463 rc = rsl_rx_ccch_load(msg);
1464 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001465 case RSL_MT_DELETE_IND:
1466 /* CCCH overloaded, IMM_ASSIGN was dropped */
1467 case RSL_MT_CBCH_LOAD_IND:
1468 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001469 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1470 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001471 break;
1472 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001473 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1474 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001475 return -EINVAL;
1476 }
Harald Welte8470bf22008-12-25 23:28:35 +00001477
1478 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001479}
1480
Harald Welte4b634542008-12-27 01:55:51 +00001481static int rsl_rx_rll_err_ind(struct msgb *msg)
1482{
1483 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001484 uint8_t *rlm_cause = rllh->data;
Harald Welte4b634542008-12-27 01:55:51 +00001485
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001486 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001487 gsm_lchan_name(msg->lchan),
Harald Weltee95daf12010-03-25 12:13:02 +08001488 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteedcc5272009-08-09 13:47:35 +02001489
1490 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001491
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001492 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001493 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001494 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001495 }
Harald Welte81543bc2009-07-04 09:40:05 +02001496
Harald Welte4b634542008-12-27 01:55:51 +00001497 return 0;
1498}
Harald Weltef325eb42009-02-19 17:07:39 +00001499
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001500static void rsl_handle_release(struct gsm_lchan *lchan)
1501{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001502 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001503 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001504
1505 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001506 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001507 return;
1508
1509 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1510 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1511 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001512 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001513 gsm_lchan_name(lchan), sapi);
1514 return;
1515 }
1516
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001517
1518
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001519 /* wait a bit to send the RF Channel Release */
1520 lchan->T3111.cb = t3111_expired;
1521 lchan->T3111.data = lchan;
1522 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001523 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001524}
1525
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001526/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001527 0x02, 0x06,
1528 0x01, 0x20,
1529 0x02, 0x00,
1530 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1531
1532static int abis_rsl_rx_rll(struct msgb *msg)
1533{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001534 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001535 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001536 int rc = 0;
1537 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001538 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001539
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001540 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001541 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001542 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001543
1544 switch (rllh->c.msg_type) {
1545 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001546 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001547 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001548 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1549 rllh->data[0] == RSL_IE_L3_INFO) {
1550 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001551 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001552 }
Harald Welte52b1f982008-12-23 20:25:15 +00001553 break;
1554 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001555 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001556 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001557 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001558 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001559 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001560 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1561 rllh->data[0] == RSL_IE_L3_INFO) {
1562 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001563 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001564 }
Harald Welte52b1f982008-12-23 20:25:15 +00001565 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001566 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001567 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001568 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001569 rll_indication(msg->lchan, rllh->link_id,
1570 BSC_RLLR_IND_EST_CONF);
1571 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001572 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001573 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001574 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001575 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001576 rll_indication(msg->lchan, rllh->link_id,
1577 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001578 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001579 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte2d5b6382008-12-27 19:46:06 +00001580 break;
1581 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001582 /* BTS informs us of having received UA from MS,
1583 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001584 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001585 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001586 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001587 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte4b634542008-12-27 01:55:51 +00001588 break;
1589 case RSL_MT_ERROR_IND:
1590 rc = rsl_rx_rll_err_ind(msg);
1591 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001592 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001593 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1594 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001595 break;
1596 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001597 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1598 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001599 }
Harald Welte8470bf22008-12-25 23:28:35 +00001600 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001601}
1602
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001603static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001604{
Harald Welte0603c9d2009-12-02 01:58:23 +05301605 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001606 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301607 switch (lchan->type) {
1608 case GSM_LCHAN_TCH_F:
1609 return 0x00;
1610 case GSM_LCHAN_TCH_H:
1611 return 0x03;
1612 default:
1613 break;
1614 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001615 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301616 switch (lchan->type) {
1617 case GSM_LCHAN_TCH_F:
1618 return 0x01;
1619 /* there's no half-rate EFR */
1620 default:
1621 break;
1622 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001623 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301624 switch (lchan->type) {
1625 case GSM_LCHAN_TCH_F:
1626 return 0x02;
1627 case GSM_LCHAN_TCH_H:
1628 return 0x05;
1629 default:
1630 break;
1631 }
1632 default:
1633 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001634 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001635 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301636 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001637 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001638}
1639
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001640static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01001641{
1642 switch (lchan->tch_mode) {
1643 case GSM48_CMODE_SPEECH_V1:
1644 switch (lchan->type) {
1645 case GSM_LCHAN_TCH_F:
1646 return RTP_PT_GSM_FULL;
1647 case GSM_LCHAN_TCH_H:
1648 return RTP_PT_GSM_HALF;
1649 default:
1650 break;
1651 }
1652 case GSM48_CMODE_SPEECH_EFR:
1653 switch (lchan->type) {
1654 case GSM_LCHAN_TCH_F:
1655 return RTP_PT_GSM_EFR;
1656 /* there's no half-rate EFR */
1657 default:
1658 break;
1659 }
1660 case GSM48_CMODE_SPEECH_AMR:
1661 switch (lchan->type) {
1662 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01001663 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02001664 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01001665 default:
1666 break;
1667 }
1668 default:
1669 break;
1670 }
1671 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1672 "tch_mode == 0x%02x\n & lchan_type == %d",
1673 lchan->tch_mode, lchan->type);
1674 return 0;
1675}
1676
Harald Welte75099262009-02-16 21:12:08 +00001677/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001678static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1679{
1680 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001681 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001682
1683 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001684 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001685 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1686 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1687 }
1688
1689 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001690 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001691 port = ntohs(port);
1692 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1693 lchan->abis_ip.bound_port = port;
1694 }
1695
1696 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001697 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001698 conn_id = ntohs(conn_id);
1699 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1700 lchan->abis_ip.conn_id = conn_id;
1701 }
1702
1703 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1704 lchan->abis_ip.rtp_payload2 =
1705 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1706 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1707 lchan->abis_ip.rtp_payload2);
1708 }
1709
1710 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1711 lchan->abis_ip.speech_mode =
1712 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1713 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1714 lchan->abis_ip.speech_mode);
1715 }
1716
1717 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001718 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001719 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1720 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1721 }
1722
1723 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001724 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001725 port = ntohs(port);
1726 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1727 lchan->abis_ip.connect_port = port;
1728 }
1729}
1730
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001731int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001732{
1733 struct msgb *msg = rsl_msgb_alloc();
1734 struct abis_rsl_dchan_hdr *dh;
1735
1736 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001737 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001738 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001739 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001740
Harald Weltef4e79f22009-07-28 18:11:56 +02001741 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001742 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001743 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001744 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001745 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001746
Sylvain Munautb54dda42009-12-20 22:06:40 +01001747 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1748 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1749 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001750
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001751 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001752
1753 return abis_rsl_sendmsg(msg);
1754}
1755
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001756int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1757 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001758{
1759 struct msgb *msg = rsl_msgb_alloc();
1760 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001761 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001762 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001763
1764 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001765 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001766 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001767 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001768
Harald Welte5e3d91b2009-12-19 16:42:06 +01001769 /* we need to store these now as MDCX_ACK does not return them :( */
1770 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1771 lchan->abis_ip.connect_port = port;
1772 lchan->abis_ip.connect_ip = ip;
1773
Harald Welte58ca5b72009-07-29 12:12:18 +02001774 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001775 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001776 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001777
Harald Weltef4e79f22009-07-28 18:11:56 +02001778 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001779 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1780 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1781 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1782 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001783
Harald Welte5e3d91b2009-12-19 16:42:06 +01001784 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1785 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001786 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001787 *att_ip = ia.s_addr;
1788 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1789 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001790 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001791 if (rtp_payload2)
1792 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001793
1794 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001795
1796 return abis_rsl_sendmsg(msg);
1797}
1798
Harald Weltea72273e2009-12-20 16:51:09 +01001799/* tell BTS to connect RTP stream to our local RTP socket */
1800int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1801{
1802 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1803 int rc;
1804
1805 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1806 ntohs(rs->rtp.sin_local.sin_port),
1807 /* FIXME: use RTP payload of bound socket, not BTS*/
1808 lchan->abis_ip.rtp_payload2);
1809
1810 return rc;
1811}
1812
Harald Welte53cd7ac2010-12-23 12:59:52 +01001813int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001814{
1815 struct msgb *msg = rsl_msgb_alloc();
1816 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001817 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08001818
1819 if (act)
1820 msg_type = RSL_MT_IPAC_PDCH_ACT;
1821 else
1822 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001823
1824 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001825 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001826 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001827 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001828
Harald Welte53cd7ac2010-12-23 12:59:52 +01001829 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001830 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001831
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001832 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02001833
1834 return abis_rsl_sendmsg(msg);
1835}
1836
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001837static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001838{
1839 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1840 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301841 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001842
1843 /* the BTS has acknowledged a local bind, it now tells us the IP
1844 * address and port number to which it has bound the given logical
1845 * channel */
1846
1847 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1848 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1849 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001850 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001851 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001852 return -EINVAL;
1853 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001854
Harald Welte5e3d91b2009-12-19 16:42:06 +01001855 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001856
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001857 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001858
Harald Welte75099262009-02-16 21:12:08 +00001859 return 0;
1860}
1861
Harald Welte5e3d91b2009-12-19 16:42:06 +01001862static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1863{
1864 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1865 struct tlv_parsed tv;
1866 struct gsm_lchan *lchan = msg->lchan;
1867
1868 /* the BTS has acknowledged a remote connect request and
1869 * it now tells us the IP address and port number to which it has
1870 * connected the given logical channel */
1871
1872 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1873 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001874 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001875
1876 return 0;
1877}
1878
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001879static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001880{
1881 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1882 struct tlv_parsed tv;
1883
1884 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001885
Harald Welte8830e072009-07-28 17:58:09 +02001886 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001887 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001888 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001889
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001890 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001891
Harald Welte75099262009-02-16 21:12:08 +00001892 return 0;
1893}
1894
1895static int abis_rsl_rx_ipacc(struct msgb *msg)
1896{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001897 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00001898 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001899 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001900 int rc = 0;
1901
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001902 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001903 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001904
1905 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001906 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001907 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001908 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001909 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001910 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001911 /* somehow the BTS was unable to bind the lchan to its local
1912 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001913 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001914 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001915 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001916 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001917 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001918 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001919 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001920 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001921 /* somehow the BTS was unable to connect the lchan to a remote
1922 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001923 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001924 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001925 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001926 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001927 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001928 break;
1929 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001930 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001931 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001932 break;
1933 }
Harald Welte6dab0552009-05-01 17:21:37 +00001934 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001935
1936 return rc;
1937}
1938
1939
Harald Welte52b1f982008-12-23 20:25:15 +00001940/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001941int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001942{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001943 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00001944 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001945
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001946 if (!msg) {
1947 DEBUGP(DRSL, "Empty RSL msg?..\n");
1948 return -1;
1949 }
1950
1951 if (msgb_l2len(msg) < sizeof(*rslh)) {
1952 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02001953 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001954 return -1;
1955 }
1956
1957 rslh = msgb_l2(msg);
1958
Harald Welte52b1f982008-12-23 20:25:15 +00001959 switch (rslh->msg_discr & 0xfe) {
1960 case ABIS_RSL_MDISC_RLL:
1961 rc = abis_rsl_rx_rll(msg);
1962 break;
1963 case ABIS_RSL_MDISC_DED_CHAN:
1964 rc = abis_rsl_rx_dchan(msg);
1965 break;
1966 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001967 rc = abis_rsl_rx_cchan(msg);
1968 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001969 case ABIS_RSL_MDISC_TRX:
1970 rc = abis_rsl_rx_trx(msg);
1971 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001972 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001973 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00001974 rslh->msg_discr);
1975 break;
Harald Welte75099262009-02-16 21:12:08 +00001976 case ABIS_RSL_MDISC_IPACCESS:
1977 rc = abis_rsl_rx_ipacc(msg);
1978 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001979 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001980 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1981 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02001982 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00001983 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001984 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001985 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001986}
Holger Freyther3b72a892009-02-04 00:31:39 +00001987
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08001988int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1989 uint8_t cb_command, const uint8_t *data, int len)
1990{
1991 struct abis_rsl_dchan_hdr *dh;
1992 struct msgb *cb_cmd;
1993
1994 cb_cmd = rsl_msgb_alloc();
1995 if (!cb_cmd)
1996 return -1;
1997
1998 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1999 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2000 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2001
2002 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2003 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2004
2005 cb_cmd->trx = bts->c0;
2006
2007 return abis_rsl_sendmsg(cb_cmd);
2008}
Dieter Spaar16646022011-07-28 00:01:50 +02002009
2010int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2011{
2012 struct abis_rsl_common_hdr *ch;
2013 struct msgb *msg = rsl_msgb_alloc();
2014
2015 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2016 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2017 ch->msg_type = 0x40; /* Nokia SI Begin */
2018
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002019 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002020
2021 return abis_rsl_sendmsg(msg);
2022}
2023
2024int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2025{
2026 struct abis_rsl_common_hdr *ch;
2027 struct msgb *msg = rsl_msgb_alloc();
2028
2029 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2030 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2031 ch->msg_type = 0x41; /* Nokia SI End */
2032
2033 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2034
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002035 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002036
2037 return abis_rsl_sendmsg(msg);
2038}
2039
2040int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2041{
2042 struct abis_rsl_common_hdr *ch;
2043 struct msgb *msg = rsl_msgb_alloc();
2044
2045 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2046 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2047 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2048
2049 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2050 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2051
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002052 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002053
2054 return abis_rsl_sendmsg(msg);
2055}