blob: 6f50cee16c0a0e61cd7d8b09b3cbcb3dd6eab722 [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 Freyther93599a22012-12-06 19:09:58 +010059static void do_lchan_free(struct gsm_lchan *lchan)
60{
61 /* we have an error timer pending to release that */
62 if (lchan->state != LCHAN_S_REL_ERR)
63 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
64 lchan_free(lchan);
65}
66
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020067static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000068{
69 /* mask off the transparent bit ? */
70 msg_type &= 0xfe;
71
Harald Welte8470bf22008-12-25 23:28:35 +000072 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +000073 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +000074 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +000075 if (msg_type >= 0x19 && msg_type <= 0x22)
76 return ABIS_RSL_MDISC_TRX;
77 else
78 return ABIS_RSL_MDISC_COM_CHAN;
79 }
Harald Welte2d5b6382008-12-27 19:46:06 +000080 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +000081 return ABIS_RSL_MDISC_DED_CHAN;
82
83 return ABIS_RSL_MDISC_LOC;
84}
85
86static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020087 uint8_t msg_type)
Harald Welte52b1f982008-12-23 20:25:15 +000088{
89 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
90 dh->c.msg_type = msg_type;
91 dh->ie_chan = RSL_IE_CHAN_NR;
92}
93
Harald Welte8470bf22008-12-25 23:28:35 +000094/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020095struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte8470bf22008-12-25 23:28:35 +000096{
97 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +020098 uint8_t ts_nr = chan_nr & 0x07;
99 uint8_t cbits = chan_nr >> 3;
100 uint8_t lch_idx;
Harald Welte8470bf22008-12-25 23:28:35 +0000101 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
102
103 if (cbits == 0x01) {
104 lch_idx = 0; /* TCH/F */
Harald Weltea1499d02009-10-24 10:25:50 +0200105 if (ts->pchan != GSM_PCHAN_TCH_F &&
106 ts->pchan != GSM_PCHAN_PDCH &&
107 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100108 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000109 chan_nr, ts->pchan);
110 } else if ((cbits & 0x1e) == 0x02) {
111 lch_idx = cbits & 0x1; /* TCH/H */
112 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100113 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000114 chan_nr, ts->pchan);
115 } else if ((cbits & 0x1c) == 0x04) {
116 lch_idx = cbits & 0x3; /* SDCCH/4 */
117 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100118 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000119 chan_nr, ts->pchan);
120 } else if ((cbits & 0x18) == 0x08) {
121 lch_idx = cbits & 0x7; /* SDCCH/8 */
122 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100123 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000124 chan_nr, ts->pchan);
125 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
126 lch_idx = 0;
127 if (ts->pchan != GSM_PCHAN_CCCH &&
128 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100129 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte8470bf22008-12-25 23:28:35 +0000130 chan_nr, ts->pchan);
131 /* FIXME: we should not return first sdcch4 !!! */
132 } else {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100133 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000134 return NULL;
135 }
136
137 lchan = &ts->lchan[lch_idx];
Harald Weltedc5062b2010-03-26 21:28:59 +0800138 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther2412a072010-06-28 15:47:12 +0800139 if (lchan->conn)
140 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte8470bf22008-12-25 23:28:35 +0000141
142 return lchan;
143}
144
Harald Welte52b1f982008-12-23 20:25:15 +0000145/* 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 +0200146uint64_t str_to_imsi(const char *imsi_str)
Harald Welte52b1f982008-12-23 20:25:15 +0000147{
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200148 uint64_t ret;
Harald Welte52b1f982008-12-23 20:25:15 +0000149
150 ret = strtoull(imsi_str, NULL, 10);
151
152 return ret;
153}
154
Harald Welte8470bf22008-12-25 23:28:35 +0000155static struct msgb *rsl_msgb_alloc(void)
156{
Harald Welte966636f2009-06-26 19:39:35 +0200157 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
158 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000159}
160
Harald Welte362322e2009-02-15 14:36:38 +0000161#define MACBLOCK_SIZE 23
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200162static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte362322e2009-02-15 14:36:38 +0000163{
164 memcpy(out, in, len);
165
166 if (len < MACBLOCK_SIZE)
167 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
168}
169
Harald Welte08d91a52009-08-30 15:37:11 +0900170/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200171static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welte08d91a52009-08-30 15:37:11 +0900172{
173 *out++ = lchan->encr.alg_id & 0xff;
174 if (lchan->encr.key_len)
175 memcpy(out, lchan->encr.key, lchan->encr.key_len);
176 return lchan->encr.key_len + 1;
177}
178
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200179static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Welte8830e072009-07-28 17:58:09 +0200180{
Harald Welte7f93cea2009-02-23 00:02:59 +0000181 int i;
182
Harald Welte5b8ed432009-12-24 12:20:20 +0100183 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Welte8830e072009-07-28 17:58:09 +0200184 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200185 for (i = 1; i < cause_len-1; i++)
Harald Welte5b8ed432009-12-24 12:20:20 +0100186 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000187}
188
Harald Weltee8bd9e82011-08-10 23:26:33 +0200189static void lchan_act_tmr_cb(void *data)
190{
191 struct gsm_lchan *lchan = data;
192
Holger Hans Peter Freyther1411c062012-12-06 19:00:35 +0100193 LOGP(DRSL, LOGL_ERROR, "%s Timeout during activation!\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200194 gsm_lchan_name(lchan));
195
Daniel Willmann513da172011-08-11 04:44:12 +0200196 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
197 lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200198}
199
200static void lchan_deact_tmr_cb(void *data)
201{
202 struct gsm_lchan *lchan = data;
203
Holger Hans Peter Freyther1411c062012-12-06 19:00:35 +0100204 LOGP(DRSL, LOGL_ERROR, "%s Timeout during deactivation!\n",
Harald Weltee8bd9e82011-08-10 23:26:33 +0200205 gsm_lchan_name(lchan));
206
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100207 do_lchan_free(lchan);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200208}
209
210
Harald Welte52b1f982008-12-23 20:25:15 +0000211/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200212int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
213 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000214{
215 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000216 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000217
218 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
219 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
220 dh->chan_nr = RSL_CHAN_BCCH;
221
222 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
223 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
224
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200225 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000226
227 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000228}
229
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200230int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
231 const uint8_t *data, int len)
Harald Welte52b1f982008-12-23 20:25:15 +0000232{
233 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000234 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000235
236 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
237 ch->msg_discr = ABIS_RSL_MDISC_TRX;
238 ch->msg_type = RSL_MT_SACCH_FILL;
239
240 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000241 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000242
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200243 msg->dst = trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000244
245 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000246}
247
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200248int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
249 const uint8_t *data, int len)
Harald Welte7a69cf02011-01-13 23:16:03 +0100250{
251 struct abis_rsl_dchan_hdr *dh;
252 struct msgb *msg = rsl_msgb_alloc();
Harald Weltef6093a42011-06-25 10:02:33 +0200253 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte7a69cf02011-01-13 23:16:03 +0100254
255 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
256 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
257 dh->chan_nr = chan_nr;
258
259 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
260 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
261
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200262 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte7a69cf02011-01-13 23:16:03 +0100263
264 return abis_rsl_sendmsg(msg);
265}
266
Harald Weltefcd24452009-06-20 18:15:19 +0200267int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
268{
269 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200270 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200271 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200272
273 db = abs(db);
274 if (db > 30)
275 return -EINVAL;
276
Harald Welteeab33352009-06-27 03:09:08 +0200277 msg = rsl_msgb_alloc();
278
Harald Weltefcd24452009-06-20 18:15:19 +0200279 lchan->bs_power = db/2;
280 if (fpc)
281 lchan->bs_power |= 0x10;
282
283 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
284 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
285 dh->chan_nr = chan_nr;
286
287 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
288
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200289 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200290
291 return abis_rsl_sendmsg(msg);
292}
293
Harald Weltefcd24452009-06-20 18:15:19 +0200294int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
295{
296 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200297 struct msgb *msg;
Harald Weltef6093a42011-06-25 10:02:33 +0200298 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Weltefcd24452009-06-20 18:15:19 +0200299 int ctl_lvl;
300
Harald Welte66b6a8d2009-08-09 14:45:18 +0200301 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200302 if (ctl_lvl < 0)
303 return ctl_lvl;
304
Harald Welteeab33352009-06-27 03:09:08 +0200305 msg = rsl_msgb_alloc();
306
Harald Weltefcd24452009-06-20 18:15:19 +0200307 lchan->ms_power = ctl_lvl;
308
309 if (fpc)
310 lchan->ms_power |= 0x20;
311
312 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
313 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
314 dh->chan_nr = chan_nr;
315
316 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
317
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200318 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltefcd24452009-06-20 18:15:19 +0200319
320 return abis_rsl_sendmsg(msg);
321}
322
Harald Welte9943c5b2009-07-29 15:41:29 +0200323static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
324 struct gsm_lchan *lchan)
325{
326 memset(cm, 0, sizeof(cm));
327
328 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +0800329 if (lchan->ts->trx->bts->network->dtx_enabled)
330 cm->dtx_dtu = 0x03;
331 else
332 cm->dtx_dtu = 0x00;
Harald Welte9943c5b2009-07-29 15:41:29 +0200333
334 /* set TCH Speech/Data */
335 cm->spd_ind = lchan->rsl_cmode;
336
Harald Welte1a79d362009-11-27 08:55:16 +0100337 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
338 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100339 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte1a79d362009-11-27 08:55:16 +0100340 "but tch_mode != signalling\n");
341
Harald Welte9943c5b2009-07-29 15:41:29 +0200342 switch (lchan->type) {
343 case GSM_LCHAN_SDCCH:
344 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
345 break;
346 case GSM_LCHAN_TCH_F:
347 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
348 break;
349 case GSM_LCHAN_TCH_H:
350 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
351 break;
352 case GSM_LCHAN_NONE:
353 case GSM_LCHAN_UNKNOWN:
354 default:
355 return -EINVAL;
356 }
357
358 switch (lchan->tch_mode) {
359 case GSM48_CMODE_SIGN:
360 cm->chan_rate = 0;
361 break;
362 case GSM48_CMODE_SPEECH_V1:
363 cm->chan_rate = RSL_CMOD_SP_GSM1;
364 break;
365 case GSM48_CMODE_SPEECH_EFR:
366 cm->chan_rate = RSL_CMOD_SP_GSM2;
367 break;
368 case GSM48_CMODE_SPEECH_AMR:
369 cm->chan_rate = RSL_CMOD_SP_GSM3;
370 break;
371 case GSM48_CMODE_DATA_14k5:
Harald Welte9943c5b2009-07-29 15:41:29 +0200372 case GSM48_CMODE_DATA_12k0:
Harald Welte9943c5b2009-07-29 15:41:29 +0200373 case GSM48_CMODE_DATA_6k0:
Harald Weltee4227982012-08-24 15:33:56 +0200374 switch (lchan->csd_mode) {
375 case LCHAN_CSD_M_NT:
376 /* non-transparent CSD with RLP */
377 switch (lchan->tch_mode) {
378 case GSM48_CMODE_DATA_14k5:
379 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
380 break;
381 case GSM48_CMODE_DATA_12k0:
382 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
383 break;
384 case GSM48_CMODE_DATA_6k0:
385 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
386 break;
387 default:
388 return -EINVAL;
389 }
390 break;
391 /* transparent data services below */
392 case LCHAN_CSD_M_T_1200_75:
393 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
394 break;
395 case LCHAN_CSD_M_T_600:
396 cm->chan_rate = RSL_CMOD_CSD_T_600;
397 break;
398 case LCHAN_CSD_M_T_1200:
399 cm->chan_rate = RSL_CMOD_CSD_T_1200;
400 break;
401 case LCHAN_CSD_M_T_2400:
402 cm->chan_rate = RSL_CMOD_CSD_T_2400;
403 break;
404 case LCHAN_CSD_M_T_9600:
405 cm->chan_rate = RSL_CMOD_CSD_T_9600;
406 break;
407 case LCHAN_CSD_M_T_14400:
408 cm->chan_rate = RSL_CMOD_CSD_T_14400;
409 break;
410 case LCHAN_CSD_M_T_29000:
411 cm->chan_rate = RSL_CMOD_CSD_T_29000;
412 break;
413 case LCHAN_CSD_M_T_32000:
414 cm->chan_rate = RSL_CMOD_CSD_T_32000;
415 break;
416 default:
417 return -EINVAL;
418 }
Harald Welte9943c5b2009-07-29 15:41:29 +0200419 default:
420 return -EINVAL;
421 }
422
423 return 0;
424}
425
Harald Welte52b1f982008-12-23 20:25:15 +0000426/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000427#if 0
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200428int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
429 uint8_t act_type,
Harald Welte52b1f982008-12-23 20:25:15 +0000430 struct rsl_ie_chan_mode *chan_mode,
431 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200432 uint8_t bs_power, uint8_t ms_power,
433 uint8_t ta)
Harald Welte52b1f982008-12-23 20:25:15 +0000434{
435 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000436 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000437
438 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
439 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
440 dh->chan_nr = chan_nr;
441
442 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
443 /* For compatibility with Phase 1 */
444 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200445 (uint8_t *) chan_mode);
Harald Welte52b1f982008-12-23 20:25:15 +0000446 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200447 (uint8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000448#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000449 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200450 (uint8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000451#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000452 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000453 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
454 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
455
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200456 msg->dst = trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000457
Harald Welte8470bf22008-12-25 23:28:35 +0000458 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000459}
Harald Welteddab3c72009-02-28 13:19:15 +0000460#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000461
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200462int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
463 uint8_t ta, uint8_t ho_ref)
Harald Welte4b634542008-12-27 01:55:51 +0000464{
465 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200466 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200467 int rc;
Harald Welte93d50e62010-06-29 17:53:45 +0200468 uint8_t *len;
Harald Welte4b634542008-12-27 01:55:51 +0000469
Harald Weltef6093a42011-06-25 10:02:33 +0200470 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000471 struct rsl_ie_chan_mode cm;
laforge694a5cf2010-06-20 21:38:19 +0200472 struct gsm48_chan_desc cd;
Harald Welte4b634542008-12-27 01:55:51 +0000473
Harald Welte9943c5b2009-07-29 15:41:29 +0200474 rc = channel_mode_from_lchan(&cm, lchan);
475 if (rc < 0)
476 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000477
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800478 memset(&cd, 0, sizeof(cd));
laforge694a5cf2010-06-20 21:38:19 +0200479 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000480
Harald Welteeab33352009-06-27 03:09:08 +0200481 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000482 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
483 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
484 dh->chan_nr = chan_nr;
485
486 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte4b634542008-12-27 01:55:51 +0000487 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200488 (uint8_t *) &cm);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800489
490 /*
491 * The Channel Identification is needed for Phase1 phones
492 * and it contains the GSM48 Channel Description and the
493 * Mobile Allocation. The GSM 08.58 asks for the Mobile
494 * Allocation to have a length of zero. We are using the
495 * msgb_l3len to calculate the length of both messages.
496 */
laforge694a5cf2010-06-20 21:38:19 +0200497 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Welte93d50e62010-06-29 17:53:45 +0200498 len = msgb_put(msg, 1);
Dieter Spaareabb6e32011-07-27 23:40:33 +0200499 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther0379c6d2010-06-30 12:06:20 +0800500
501 if (lchan->ts->hopping.enabled)
502 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
503 lchan->ts->hopping.ma_data);
504 else
505 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freythere38bd6c2010-06-30 11:56:43 +0800506
507 /* update the calculated size */
508 msg->l3h = len + 1;
509 *len = msgb_l3len(msg);
510
Harald Welte08d91a52009-08-30 15:37:11 +0900511 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200512 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900513 rc = build_encr_info(encr_info, lchan);
514 if (rc > 0)
515 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
516 }
517
Harald Welte8d77b952009-12-17 00:31:10 +0100518 switch (act_type) {
519 case RSL_ACT_INTER_ASYNC:
520 case RSL_ACT_INTER_SYNC:
521 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
522 break;
523 default:
524 break;
525 }
526
Harald Welted4c9bf32009-02-15 16:56:18 +0000527 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
528 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000529 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
530
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100531 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
532 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200533 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther93b6c652010-01-28 04:45:05 +0100534
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200535 msg->dst = lchan->ts->trx->rsl_link;
Harald Weltee79769b2009-02-07 00:48:17 +0000536
Harald Welte4b634542008-12-27 01:55:51 +0000537 return abis_rsl_sendmsg(msg);
538}
539
Harald Welte470abb72009-07-29 11:38:15 +0200540/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000541int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
542{
543 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200544 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200545 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000546
Harald Weltef6093a42011-06-25 10:02:33 +0200547 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteda783762009-02-18 03:29:53 +0000548 struct rsl_ie_chan_mode cm;
549
Harald Welte9943c5b2009-07-29 15:41:29 +0200550 rc = channel_mode_from_lchan(&cm, lchan);
551 if (rc < 0)
552 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000553
Harald Welteeab33352009-06-27 03:09:08 +0200554 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000555 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
556 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
557 dh->chan_nr = chan_nr;
558
559 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200560 (uint8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900561
562 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200563 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welte08d91a52009-08-30 15:37:11 +0900564 rc = build_encr_info(encr_info, lchan);
565 if (rc > 0)
566 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
567 }
568
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100569 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
570 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200571 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100572 }
573
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200574 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte08d91a52009-08-30 15:37:11 +0900575
576 return abis_rsl_sendmsg(msg);
577}
578
579/* Chapter 8.4.6: Send the encryption command with given L3 info */
580int rsl_encryption_cmd(struct msgb *msg)
581{
582 struct abis_rsl_dchan_hdr *dh;
583 struct gsm_lchan *lchan = msg->lchan;
Harald Weltef6093a42011-06-25 10:02:33 +0200584 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200585 uint8_t encr_info[MAX_A5_KEY_LEN+2];
586 uint8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900587 int rc;
588
589 /* First push the L3 IE tag and length */
590 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
591
592 /* then the link identifier (SAPI0, main sign link) */
593 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
594
595 /* then encryption information */
596 rc = build_encr_info(encr_info, lchan);
597 if (rc <= 0)
598 return rc;
599 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
600
601 /* and finally the DCHAN header */
602 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
603 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
604 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000605
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200606 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteda783762009-02-18 03:29:53 +0000607
608 return abis_rsl_sendmsg(msg);
609}
610
Harald Welte115d1032009-08-10 11:43:22 +0200611/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200612int rsl_deact_sacch(struct gsm_lchan *lchan)
613{
614 struct abis_rsl_dchan_hdr *dh;
615 struct msgb *msg = rsl_msgb_alloc();
616
617 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
618 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltef6093a42011-06-25 10:02:33 +0200619 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteae0f2362009-07-19 18:36:49 +0200620
621 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200622 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteae0f2362009-07-19 18:36:49 +0200623
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100624 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteae0f2362009-07-19 18:36:49 +0200625
626 return abis_rsl_sendmsg(msg);
627}
628
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800629static void error_timeout_cb(void *data)
630{
631 struct gsm_lchan *lchan = data;
632 if (lchan->state != LCHAN_S_REL_ERR) {
633 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
634 gsm_lchan_name(lchan), lchan->state);
635 return;
636 }
637
638 /* go back to the none state */
639 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800640 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800641}
642
Harald Weltefd355a32011-03-04 13:41:31 +0100643static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
644
Harald Welte115d1032009-08-10 11:43:22 +0200645/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800646static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte52b1f982008-12-23 20:25:15 +0000647{
648 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800649 struct msgb *msg;
Harald Weltefd355a32011-03-04 13:41:31 +0100650 int rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000651
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800652 if (lchan->state == LCHAN_S_REL_ERR) {
653 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
654 gsm_lchan_name(lchan));
655 return -1;
656 }
657
658 msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000659 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
660 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltef6093a42011-06-25 10:02:33 +0200661 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000662
Harald Welte8470bf22008-12-25 23:28:35 +0000663 msg->lchan = lchan;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200664 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000665
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800666 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
667
668 if (error) {
669 /*
670 * the nanoBTS sends RLL release indications after the channel release. This can
671 * be a problem when we have reassigned the channel to someone else and then can
672 * not figure out who used this channel.
673 */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200674 struct e1inp_sign_link *sign_link = msg->dst;
675
Holger Hans Peter Freyther44752d92010-06-08 11:53:33 +0800676 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800677 lchan->error_timer.data = lchan;
678 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200679 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200680 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800681 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000682
Harald Weltee8bd9e82011-08-10 23:26:33 +0200683 /* Start another timer or assume the BTS sends a ACK/NACK? */
684 lchan->act_timer.cb = lchan_deact_tmr_cb;
685 lchan->act_timer.data = lchan;
686 osmo_timer_schedule(&lchan->act_timer, 4, 0);
687
Harald Weltefd355a32011-03-04 13:41:31 +0100688 rc = abis_rsl_sendmsg(msg);
689
Harald Welte115d1032009-08-10 11:43:22 +0200690 /* BTS will respond by RF CHAN REL ACK */
Harald Welte26d79072011-01-14 23:18:59 +0100691#ifdef HSL_SR_1_0
Harald Weltefd355a32011-03-04 13:41:31 +0100692 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
693 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
694 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte26d79072011-01-14 23:18:59 +0100695#endif
Harald Weltefd355a32011-03-04 13:41:31 +0100696
697 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +0000698}
699
Harald Welte64bb7542011-01-14 14:16:16 +0100700static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
701{
702
703 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
704
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100705 /* Stop all pending timers */
Harald Weltee8bd9e82011-08-10 23:26:33 +0200706 osmo_timer_del(&lchan->act_timer);
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100707 osmo_timer_del(&lchan->T3111);
Harald Weltee8bd9e82011-08-10 23:26:33 +0200708
Harald Welte64bb7542011-01-14 14:16:16 +0100709 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
710 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
711 gsm_lchan_name(lchan),
712 gsm_lchans_name(lchan->state));
Holger Hans Peter Freyther93599a22012-12-06 19:09:58 +0100713 do_lchan_free(lchan);
Harald Welte64bb7542011-01-14 14:16:16 +0100714
715 return 0;
716}
717
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200718int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
719 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte52b1f982008-12-23 20:25:15 +0000720{
721 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000722 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000723
724 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
725 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
726 dh->chan_nr = RSL_CHAN_PCH_AGCH;
727
728 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000729 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000730 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
731
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200732 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000733
734 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000735}
736
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200737int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte52b1f982008-12-23 20:25:15 +0000738{
739 int i, len = strlen(str_in);
740
741 for (i = 0; i < len; i++) {
742 int num = str_in[i] - 0x30;
743 if (num < 0 || num > 9)
744 return -1;
745 if (i % 2 == 0)
746 bcd_out[i/2] = num;
747 else
748 bcd_out[i/2] |= (num << 4);
749 }
750
751 return 0;
752}
753
Harald Welte702d8702008-12-26 20:25:35 +0000754/* Chapter 8.5.6 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200755int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte52b1f982008-12-23 20:25:15 +0000756{
Harald Welte8470bf22008-12-25 23:28:35 +0000757 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000758 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200759 uint8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000760
761 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
762 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
763 dh->chan_nr = RSL_CHAN_PCH_AGCH;
764
Harald Welte362322e2009-02-15 14:36:38 +0000765 switch (bts->type) {
766 case GSM_BTS_TYPE_BS11:
767 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
768 break;
769 default:
770 /* If phase 2, construct a FULL_IMM_ASS_INFO */
771 pad_macblock(buf, val, len);
772 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
773 break;
774 }
Harald Welte52b1f982008-12-23 20:25:15 +0000775
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200776 msg->dst = bts->c0->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000777
778 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000779}
780
Harald Welte67fa91b2009-08-10 09:51:40 +0200781/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200782int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200783{
784 struct msgb *msg = rsl_msgb_alloc();
785 struct abis_rsl_dchan_hdr *dh;
786
787 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
788 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200789 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +0200790 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200791 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200792
Harald Welte5b8ed432009-12-24 12:20:20 +0100793 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200794 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte3c456d02009-08-10 11:26:14 +0200795
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200796 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte3c456d02009-08-10 11:26:14 +0200797
Harald Welte67fa91b2009-08-10 09:51:40 +0200798 return abis_rsl_sendmsg(msg);
799}
800
801
Harald Welte8470bf22008-12-25 23:28:35 +0000802/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000803/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200804int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000805{
Harald Welte8470bf22008-12-25 23:28:35 +0000806 if (msg->lchan == NULL) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100807 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte8470bf22008-12-25 23:28:35 +0000808 return -EINVAL;
809 }
Harald Welte52b1f982008-12-23 20:25:15 +0000810
Harald Weltef6093a42011-06-25 10:02:33 +0200811 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100812 link_id, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000813
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200814 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte8470bf22008-12-25 23:28:35 +0000815
816 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000817}
818
Harald Welteedcc5272009-08-09 13:47:35 +0200819/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
820/* Chapter 8.3.1 */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200821int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteedcc5272009-08-09 13:47:35 +0200822{
Harald Welte3c9c5f92010-03-04 10:33:10 +0100823 struct msgb *msg;
Harald Welteedcc5272009-08-09 13:47:35 +0200824
Harald Weltef6093a42011-06-25 10:02:33 +0200825 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100826 link_id, 0);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200827 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteedcc5272009-08-09 13:47:35 +0200828
Harald Weltefda74ee2012-04-26 19:42:19 +0200829 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
830 gsm_lchan_name(lchan), link_id);
831
Harald Welteedcc5272009-08-09 13:47:35 +0200832 return abis_rsl_sendmsg(msg);
833}
834
Harald Welted2dc1de2009-08-08 13:15:07 +0200835/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
836 This is what higher layers should call. The BTS then responds with
837 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
838 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
839 lchan_free() */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100840int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
841 enum rsl_rel_mode release_mode)
Harald Welted2dc1de2009-08-08 13:15:07 +0200842{
Harald Welted2dc1de2009-08-08 13:15:07 +0200843
Harald Welte3c9c5f92010-03-04 10:33:10 +0100844 struct msgb *msg;
845
Harald Weltef6093a42011-06-25 10:02:33 +0200846 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Welte3c9c5f92010-03-04 10:33:10 +0100847 link_id, 0);
Holger Hans Peter Freyther4f5848d2010-06-08 11:57:45 +0800848 /* 0 is normal release, 1 is local end */
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100849 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
Harald Welted2dc1de2009-08-08 13:15:07 +0200850
Harald Welte8e93b792009-12-29 10:44:17 +0100851 /* FIXME: start some timer in case we don't receive a REL ACK ? */
852
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +0200853 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dc1de2009-08-08 13:15:07 +0200854
Harald Weltefda74ee2012-04-26 19:42:19 +0200855 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
Holger Hans Peter Freyther5ca825e2012-12-06 12:01:38 +0100856 gsm_lchan_name(lchan), link_id, release_mode);
Harald Weltefda74ee2012-04-26 19:42:19 +0200857
Harald Welted2dc1de2009-08-08 13:15:07 +0200858 return abis_rsl_sendmsg(msg);
859}
860
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200861int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
862{
863 lchan->state = state;
864 return 0;
865}
866
Harald Welte702d8702008-12-26 20:25:35 +0000867/* Chapter 8.4.2: Channel Activate Acknowledge */
868static int rsl_rx_chan_act_ack(struct msgb *msg)
869{
870 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
871
872 /* BTS has confirmed channel activation, we now need
873 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000874 if (rslh->ie_chan != RSL_IE_CHAN_NR)
875 return -EINVAL;
Harald Welted011e8b2009-11-29 22:45:52 +0100876
Harald Weltee8bd9e82011-08-10 23:26:33 +0200877 osmo_timer_del(&msg->lchan->act_timer);
878
Harald Welte8e93b792009-12-29 10:44:17 +0100879 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welte1887f9d2009-12-29 10:52:38 +0100880 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
881 gsm_lchan_name(msg->lchan),
882 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200883 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welteb8bfc562009-12-21 13:27:11 +0100884
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +0800885 if (msg->lchan->rqd_ref) {
886 rsl_send_imm_assignment(msg->lchan);
887 talloc_free(msg->lchan->rqd_ref);
888 msg->lchan->rqd_ref = NULL;
889 msg->lchan->rqd_ta = 0;
890 }
891
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100892 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100893
Harald Welte4b634542008-12-27 01:55:51 +0000894 return 0;
895}
Harald Welte702d8702008-12-26 20:25:35 +0000896
Harald Welte4b634542008-12-27 01:55:51 +0000897/* Chapter 8.4.3: Channel Activate NACK */
898static int rsl_rx_chan_act_nack(struct msgb *msg)
899{
Harald Welte6dab0552009-05-01 17:21:37 +0000900 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
901 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000902
Harald Weltee8bd9e82011-08-10 23:26:33 +0200903 osmo_timer_del(&msg->lchan->act_timer);
904
Daniel Willmann6fc6a122011-08-11 04:54:23 +0200905 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100906 gsm_lchan_name(msg->lchan));
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100907
Harald Welte6dab0552009-05-01 17:21:37 +0000908 /* BTS has rejected channel activation ?!? */
909 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000910 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000911
912 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100913 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200914 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)3e460312009-12-27 18:12:29 +0100915 print_rsl_cause(LOGL_ERROR, cause,
Harald Welte8830e072009-07-28 17:58:09 +0200916 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)3e460312009-12-27 18:12:29 +0100917 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200918 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Daniel Willmann7ddc3182011-08-11 04:47:11 +0200919 else
920 rsl_rf_chan_release(msg->lchan, 1);
921
Harald Welte (local)3e460312009-12-27 18:12:29 +0100922 } else
Holger Hans Peter Freyther74419492010-04-10 00:12:31 +0200923 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200924
Harald Welte (local)91b603d2009-12-27 11:48:11 +0100925 LOGPC(DRSL, LOGL_ERROR, "\n");
926
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +0100927 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +0100928
Harald Welte3073a9f2009-08-09 19:50:08 +0200929 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000930 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000931}
932
Harald Welte7f93cea2009-02-23 00:02:59 +0000933/* Chapter 8.4.4: Connection Failure Indication */
934static int rsl_rx_conn_fail(struct msgb *msg)
935{
936 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
937 struct tlv_parsed tp;
938
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100939 /* FIXME: print which channel */
Harald Welte (local)fc057502009-12-26 22:33:09 +0100940 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +0100941 gsm_lchan_name(msg->lchan));
Harald Welte7f93cea2009-02-23 00:02:59 +0000942
943 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
944
Harald Welte8830e072009-07-28 17:58:09 +0200945 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +0100946 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +0200947 TLVP_LEN(&tp, RSL_IE_CAUSE));
948
Harald Welte (local)fc057502009-12-26 22:33:09 +0100949 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000950 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +0200951 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +0800952 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte7f93cea2009-02-23 00:02:59 +0000953}
954
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100955static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
956 const char *prefix)
957{
Harald Welte6739dfb2009-12-16 16:52:07 +0100958 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
959 prefix, rxlev2dbm(mru->full.rx_lev),
960 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100961 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
962 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
963}
964
Harald Welte0c1bd612012-07-02 17:12:08 +0200965static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100966{
Harald Welte6739dfb2009-12-16 16:52:07 +0100967 int i;
Harald Welte0c1bd612012-07-02 17:12:08 +0200968 char *name = "";
Harald Welte6739dfb2009-12-16 16:52:07 +0100969
Harald Welte0c1bd612012-07-02 17:12:08 +0200970 if (lchan && lchan->conn && lchan->conn->subscr)
971 name = subscr_name(lchan->conn->subscr);
972
973 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100974
975 if (mr->flags & MEAS_REP_F_DL_DTX)
976 DEBUGPC(DMEAS, "DTXd ");
977
978 print_meas_rep_uni(&mr->ul, "ul");
979 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
980 if (mr->flags & MEAS_REP_F_MS_TO)
981 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
982
983 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte6739dfb2009-12-16 16:52:07 +0100984 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Welte3c7dc6e2009-11-29 19:07:28 +0100985 DEBUGPC(DMEAS, "L1_FPC=%u ",
986 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
987 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
988 }
989
990 if (mr->flags & MEAS_REP_F_UL_DTX)
991 DEBUGPC(DMEAS, "DTXu ");
992 if (mr->flags & MEAS_REP_F_BA1)
993 DEBUGPC(DMEAS, "BA1 ");
994 if (!(mr->flags & MEAS_REP_F_DL_VALID))
995 DEBUGPC(DMEAS, "NOT VALID ");
996 else
997 print_meas_rep_uni(&mr->dl, "dl");
998
999 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte479015b2009-12-19 18:33:05 +01001000 if (mr->num_cell == 7)
1001 return;
Harald Welte6739dfb2009-12-16 16:52:07 +01001002 for (i = 0; i < mr->num_cell; i++) {
1003 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte303e5e02009-12-25 23:02:22 +01001004 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1005 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte6739dfb2009-12-16 16:52:07 +01001006 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001007}
1008
Harald Welte440fed02009-05-01 18:43:47 +00001009static int rsl_rx_meas_res(struct msgb *msg)
1010{
1011 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1012 struct tlv_parsed tp;
Harald Welted12b0fd2009-12-15 21:36:05 +01001013 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001014 uint8_t len;
1015 const uint8_t *val;
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001016 int rc;
Harald Welte440fed02009-05-01 18:43:47 +00001017
Harald Welteb8bfc562009-12-21 13:27:11 +01001018 /* check if this channel is actually active */
1019 /* FIXME: maybe this check should be way more generic/centralized */
Harald Welte8e93b792009-12-29 10:44:17 +01001020 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freytherc44db4a2010-07-29 14:50:57 +08001021 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Welte8e93b792009-12-29 10:44:17 +01001022 gsm_lchan_name(msg->lchan));
Harald Welteb8bfc562009-12-21 13:27:11 +01001023 return 0;
Harald Welte8e93b792009-12-29 10:44:17 +01001024 }
Harald Welteb8bfc562009-12-21 13:27:11 +01001025
Harald Welted12b0fd2009-12-15 21:36:05 +01001026 memset(mr, 0, sizeof(*mr));
Harald Welte33e65972009-12-16 23:29:34 +01001027 mr->lchan = msg->lchan;
Harald Weltedbb1d882009-11-30 19:16:47 +01001028
Harald Welte440fed02009-05-01 18:43:47 +00001029 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1030
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001031 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1032 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1033 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1034 return -EIO;
1035
1036 /* Mandatory Parts */
Harald Welted12b0fd2009-12-15 21:36:05 +01001037 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001038
1039 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1040 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1041 if (len >= 3) {
1042 if (val[0] & 0x40)
Harald Welted12b0fd2009-12-15 21:36:05 +01001043 mr->flags |= MEAS_REP_F_DL_DTX;
1044 mr->ul.full.rx_lev = val[0] & 0x3f;
1045 mr->ul.sub.rx_lev = val[1] & 0x3f;
1046 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1047 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte440fed02009-05-01 18:43:47 +00001048 }
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001049
Harald Welted12b0fd2009-12-15 21:36:05 +01001050 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001051
1052 /* Optional Parts */
Harald Welte440fed02009-05-01 18:43:47 +00001053 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welted12b0fd2009-12-15 21:36:05 +01001054 mr->ms_timing_offset =
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001055 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1056
Harald Weltefe9af262009-06-20 18:44:35 +02001057 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001058 struct e1inp_sign_link *sign_link = msg->dst;
1059
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001060 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001061 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001062 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001063 if (val[0] & 0x04)
Harald Welted12b0fd2009-12-15 21:36:05 +01001064 mr->flags |= MEAS_REP_F_FPC;
1065 mr->ms_l1.ta = val[1];
Andreas Eversberg3365cd12011-12-24 11:49:05 +01001066 /* BS11 and Nokia reports TA shifted by 2 bits */
1067 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1068 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg2957de92011-12-16 17:45:37 +01001069 mr->ms_l1.ta >>= 2;
Harald Weltefe9af262009-06-20 18:44:35 +02001070 }
Harald Weltef7c43522009-06-09 20:24:21 +00001071 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001072 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welted12b0fd2009-12-15 21:36:05 +01001073 rc = gsm48_parse_meas_rep(mr, msg);
Harald Welte3c7dc6e2009-11-29 19:07:28 +01001074 if (rc < 0)
1075 return rc;
1076 }
1077
Harald Welte0c1bd612012-07-02 17:12:08 +02001078 print_meas_rep(msg->lchan, mr);
Harald Welte60d68f12009-06-05 20:07:43 +00001079
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001080 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Weltedbb1d882009-11-30 19:16:47 +01001081
Harald Welte75d34a82009-05-23 06:11:13 +00001082 return 0;
Harald Welte440fed02009-05-01 18:43:47 +00001083}
1084
Harald Welted011e8b2009-11-29 22:45:52 +01001085/* Chapter 8.4.7 */
1086static int rsl_rx_hando_det(struct msgb *msg)
1087{
1088 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1089 struct tlv_parsed tp;
1090
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001091 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welted011e8b2009-11-29 22:45:52 +01001092
1093 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1094
1095 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1096 DEBUGPC(DRSL, "access delay = %u\n",
1097 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1098 else
1099 DEBUGPC(DRSL, "\n");
1100
Holger Hans Peter Freyther08eebd52010-12-27 13:28:20 +01001101 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welted011e8b2009-11-29 22:45:52 +01001102
1103 return 0;
1104}
1105
Harald Welte52b1f982008-12-23 20:25:15 +00001106static int abis_rsl_rx_dchan(struct msgb *msg)
1107{
Harald Welte8470bf22008-12-25 23:28:35 +00001108 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1109 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001110 char *ts_name;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001111 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001112
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001113 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001114 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltef325eb42009-02-19 17:07:39 +00001115
Harald Welte8470bf22008-12-25 23:28:35 +00001116 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001117 case RSL_MT_CHAN_ACTIV_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001118 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte4b634542008-12-27 01:55:51 +00001119 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001120 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001121 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte4b634542008-12-27 01:55:51 +00001122 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001123 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001124 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001125 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001126 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001127 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001128 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001129 break;
Harald Welted011e8b2009-11-29 22:45:52 +01001130 case RSL_MT_HANDO_DET:
1131 rc = rsl_rx_hando_det(msg);
1132 break;
Harald Welte2d5b6382008-12-27 19:46:06 +00001133 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte64bb7542011-01-14 14:16:16 +01001134 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001135 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001136 case RSL_MT_MODE_MODIFY_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001137 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001138 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001139 case RSL_MT_MODE_MODIFY_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001140 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welteda783762009-02-18 03:29:53 +00001141 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001142 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001143 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001144 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001145 break;
1146 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001147 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001148 break;
1149 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001150 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte4563eab2010-03-28 14:42:09 +08001151 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welte9c880c92009-10-24 10:29:22 +02001152 break;
1153 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001154 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welte9c880c92009-10-24 10:29:22 +02001155 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001156 case RSL_MT_PHY_CONTEXT_CONF:
1157 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001158 case RSL_MT_TALKER_DET:
1159 case RSL_MT_LISTENER_DET:
1160 case RSL_MT_REMOTE_CODEC_CONF_REP:
1161 case RSL_MT_MR_CODEC_MOD_ACK:
1162 case RSL_MT_MR_CODEC_MOD_NACK:
1163 case RSL_MT_MR_CODEC_MOD_PER:
Harald Welte5b8ed432009-12-24 12:20:20 +01001164 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1165 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001166 break;
1167 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001168 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1169 ts_name, rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001170 return -EINVAL;
1171 }
Harald Weltef325eb42009-02-19 17:07:39 +00001172
Harald Welte8470bf22008-12-25 23:28:35 +00001173 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001174}
1175
Harald Welte702d8702008-12-26 20:25:35 +00001176static int rsl_rx_error_rep(struct msgb *msg)
1177{
1178 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001179 struct tlv_parsed tp;
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001180 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte702d8702008-12-26 20:25:35 +00001181
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001182 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Welte8830e072009-07-28 17:58:09 +02001183
1184 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1185
1186 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001187 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001188 TLVP_LEN(&tp, RSL_IE_CAUSE));
1189
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001190 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001191
1192 return 0;
1193}
1194
Harald Welte52b1f982008-12-23 20:25:15 +00001195static int abis_rsl_rx_trx(struct msgb *msg)
1196{
Harald Welte702d8702008-12-26 20:25:35 +00001197 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001198 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte8470bf22008-12-25 23:28:35 +00001199 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001200
1201 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001202 case RSL_MT_ERROR_REPORT:
1203 rc = rsl_rx_error_rep(msg);
1204 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001205 case RSL_MT_RF_RES_IND:
1206 /* interference on idle channels of TRX */
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001207 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte8f5e2392009-02-03 12:57:37 +00001208 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001209 case RSL_MT_OVERLOAD:
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001210 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001211 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001212 gsm_trx_name(sign_link->trx));
Harald Welte52b1f982008-12-23 20:25:15 +00001213 break;
Dieter Spaar16646022011-07-28 00:01:50 +02001214 case 0x42: /* Nokia specific: SI End ACK */
1215 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1216 break;
1217 case 0x43: /* Nokia specific: SI End NACK */
1218 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1219 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001220 default:
Harald Welte (local)d48f4eb2009-12-28 23:14:22 +01001221 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001222 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001223 return -EINVAL;
1224 }
Harald Welte8470bf22008-12-25 23:28:35 +00001225 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001226}
1227
Harald Welteb7e81162009-08-10 00:26:10 +02001228/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1229static void t3101_expired(void *data)
1230{
1231 struct gsm_lchan *lchan = data;
1232
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001233 rsl_rf_chan_release(lchan, 1);
Harald Welteb7e81162009-08-10 00:26:10 +02001234}
1235
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001236/* If T3111 expires, we will send the RF Channel Request */
1237static void t3111_expired(void *data)
1238{
1239 struct gsm_lchan *lchan = data;
1240
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001241 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001242}
1243
laforgecfa4a012010-06-21 12:08:52 +02001244#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1245
Harald Welte2862dca2010-12-23 14:39:29 +01001246/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1247static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1248 unsigned int num_req_refs,
1249 struct gsm48_req_ref *rqd_refs,
1250 uint8_t wait_ind)
1251{
1252 uint8_t buf[GSM_MACBLOCK_LEN];
1253 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1254
1255 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1256 memset(iar, 0, sizeof(*iar));
1257 iar->proto_discr = GSM48_PDISC_RR;
1258 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1259 iar->page_mode = GSM48_PM_SAME;
1260
1261 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1262 iar->wait_ind1 = wait_ind;
1263
1264 if (num_req_refs >= 2)
1265 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1266 else
1267 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1268 iar->wait_ind2 = wait_ind;
1269
1270 if (num_req_refs >= 3)
1271 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1272 else
1273 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1274 iar->wait_ind3 = wait_ind;
1275
1276 if (num_req_refs >= 4)
1277 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1278 else
1279 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1280 iar->wait_ind4 = wait_ind;
1281
1282 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1283}
1284
Harald Welte8470bf22008-12-25 23:28:35 +00001285/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001286static int rsl_rx_chan_rqd(struct msgb *msg)
1287{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001288 struct e1inp_sign_link *sign_link = msg->dst;
1289 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001290 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1291 struct gsm48_req_ref *rqd_ref;
Harald Welte8470bf22008-12-25 23:28:35 +00001292 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001293 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001294 struct gsm_lchan *lchan;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001295 uint8_t rqd_ta;
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001296 int is_lu;
Harald Welte8470bf22008-12-25 23:28:35 +00001297
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001298 uint16_t arfcn;
Holger Hans Peter Freytherc6d0a172012-02-03 20:10:13 +01001299 uint8_t subch;
Harald Welte52b1f982008-12-23 20:25:15 +00001300
Harald Welte8470bf22008-12-25 23:28:35 +00001301 /* parse request reference to be used in immediate assign */
1302 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1303 return -EINVAL;
1304
1305 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1306
1307 /* parse access delay and use as TA */
1308 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1309 return -EINVAL;
1310 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1311
1312 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1313 * request reference RA */
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001314 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1315 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001316
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001317 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte24ff6ee2009-12-22 00:41:05 +01001318
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001319 /*
1320 * We want LOCATION UPDATES to succeed and will assign a TCH
1321 * if we have no SDCCH available.
1322 */
1323 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1324
Harald Welte8470bf22008-12-25 23:28:35 +00001325 /* check availability / allocate channel */
Holger Hans Peter Freyther457c2a82010-09-06 08:58:42 +08001326 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte8470bf22008-12-25 23:28:35 +00001327 if (!lchan) {
Harald Welte (local)2f5df852009-12-27 13:48:09 +01001328 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)ccd88452009-12-27 18:05:25 +01001329 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001330 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Welte2862dca2010-12-23 14:39:29 +01001331 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1332 if (bts->network->T3122)
1333 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte8470bf22008-12-25 23:28:35 +00001334 return -ENOMEM;
1335 }
1336
Harald Welte8e93b792009-12-29 10:44:17 +01001337 if (lchan->state != LCHAN_S_NONE)
1338 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welte1887f9d2009-12-29 10:52:38 +01001339 "in state %s\n", gsm_lchan_name(lchan),
1340 gsm_lchans_name(lchan->state));
Harald Welte (local)3e460312009-12-27 18:12:29 +01001341
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001342 /* save the RACH data as we need it after the CHAN ACT ACK */
1343 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1344 if (!lchan->rqd_ref) {
1345 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1346 lchan_free(lchan);
1347 return -ENOMEM;
1348 }
1349
Holger Hans Peter Freytherc0a66742011-12-29 23:33:04 +01001350 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001351 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1352 lchan->rqd_ta = rqd_ta;
1353
Harald Welte8470bf22008-12-25 23:28:35 +00001354 arfcn = lchan->ts->trx->arfcn;
1355 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001356
Harald Welte08d91a52009-08-30 15:37:11 +09001357 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001358 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001359 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001360 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001361 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001362
Harald Weltee8bd9e82011-08-10 23:26:33 +02001363 /* Start another timer or assume the BTS sends a ACK/NACK? */
1364 lchan->act_timer.cb = lchan_act_tmr_cb;
1365 lchan->act_timer.data = lchan;
1366 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1367
Andreas Eversberg2957de92011-12-16 17:45:37 +01001368 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1369 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1370 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1371 rqd_ref->ra, rqd_ta);
1372
1373 /* BS11 requires TA shifted by 2 bits */
1374 if (bts->type == GSM_BTS_TYPE_BS11)
1375 rqd_ta <<= 2;
Harald Welte8d77b952009-12-17 00:31:10 +01001376 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte52b1f982008-12-23 20:25:15 +00001377
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001378 return 0;
1379}
1380
1381static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1382{
1383 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001384 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001385 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1386
Harald Welte52b1f982008-12-23 20:25:15 +00001387 /* create IMMEDIATE ASSIGN 04.08 messge */
laforge09108bf2010-06-20 15:18:46 +02001388 memset(ia, 0, sizeof(*ia));
laforgecfa4a012010-06-21 12:08:52 +02001389 /* we set ia->l2_plen once we know the length of the MA below */
laforge09108bf2010-06-20 15:18:46 +02001390 ia->proto_discr = GSM48_PDISC_RR;
1391 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1392 ia->page_mode = GSM48_PM_SAME;
1393 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea39b0f22010-06-14 22:26:10 +02001394
Harald Welte8470bf22008-12-25 23:28:35 +00001395 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freyther5ba05f42010-06-22 12:11:59 +08001396 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1397 ia->timing_advance = lchan->rqd_ta;
Harald Weltea39b0f22010-06-14 22:26:10 +02001398 if (!lchan->ts->hopping.enabled) {
laforge09108bf2010-06-20 15:18:46 +02001399 ia->mob_alloc_len = 0;
Harald Weltea39b0f22010-06-14 22:26:10 +02001400 } else {
laforge09108bf2010-06-20 15:18:46 +02001401 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1402 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea39b0f22010-06-14 22:26:10 +02001403 }
Harald Weltea1d39a22010-06-28 18:41:27 +02001404 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1405 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte52b1f982008-12-23 20:25:15 +00001406
Harald Welteb7e81162009-08-10 00:26:10 +02001407 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1408 lchan->T3101.cb = t3101_expired;
1409 lchan->T3101.data = lchan;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001410 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001411
Harald Welte52b1f982008-12-23 20:25:15 +00001412 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001413 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte52b1f982008-12-23 20:25:15 +00001414}
1415
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001416/* current load on the CCCH */
Harald Welteea280442009-02-02 22:29:56 +00001417static int rsl_rx_ccch_load(struct msgb *msg)
1418{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001419 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001420 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001421 struct ccch_signal_data sd;
1422
1423 sd.bts = sign_link->trx->bts;
1424 sd.rach_slot_count = -1;
1425 sd.rach_busy_count = -1;
1426 sd.rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001427
1428 switch (rslh->data[0]) {
1429 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001430 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1431 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte38e9c822010-04-19 10:24:07 +02001432 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001433 sd.pg_buf_space = 50;
Harald Welte38e9c822010-04-19 10:24:07 +02001434 }
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001435 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1436 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welteea280442009-02-02 22:29:56 +00001437 break;
1438 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001439 if (msg->data_len >= 7) {
Holger Hans Peter Freyther54fa2c72012-02-03 20:26:25 +01001440 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1441 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1442 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1443 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Holger Freyther8c563cf2009-02-03 20:08:51 +00001444 }
Harald Welteea280442009-02-02 22:29:56 +00001445 break;
1446 default:
1447 break;
1448 }
1449
1450 return 0;
1451}
1452
Harald Welte52b1f982008-12-23 20:25:15 +00001453static int abis_rsl_rx_cchan(struct msgb *msg)
1454{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001455 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welteea280442009-02-02 22:29:56 +00001456 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001457 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001458
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001459 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +00001460
1461 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001462 case RSL_MT_CHAN_RQD:
1463 /* MS has requested a channel on the RACH */
1464 rc = rsl_rx_chan_rqd(msg);
1465 break;
Harald Welteea280442009-02-02 22:29:56 +00001466 case RSL_MT_CCCH_LOAD_IND:
1467 /* current load on the CCCH */
1468 rc = rsl_rx_ccch_load(msg);
1469 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001470 case RSL_MT_DELETE_IND:
1471 /* CCCH overloaded, IMM_ASSIGN was dropped */
1472 case RSL_MT_CBCH_LOAD_IND:
1473 /* current load on the CBCH */
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001474 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1475 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001476 break;
1477 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001478 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1479 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001480 return -EINVAL;
1481 }
Harald Welte8470bf22008-12-25 23:28:35 +00001482
1483 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001484}
1485
Harald Welte4b634542008-12-27 01:55:51 +00001486static int rsl_rx_rll_err_ind(struct msgb *msg)
1487{
1488 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001489 uint8_t *rlm_cause = rllh->data;
Harald Welte4b634542008-12-27 01:55:51 +00001490
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001491 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001492 gsm_lchan_name(msg->lchan),
Harald Weltee95daf12010-03-25 12:13:02 +08001493 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteedcc5272009-08-09 13:47:35 +02001494
1495 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)9538efc2009-12-26 23:55:00 +01001496
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001497 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayusodfb342c2011-05-06 12:13:10 +02001498 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther4b4dd102010-05-31 21:38:24 +08001499 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther3ba36d52010-04-17 06:48:29 +02001500 }
Harald Welte81543bc2009-07-04 09:40:05 +02001501
Harald Welte4b634542008-12-27 01:55:51 +00001502 return 0;
1503}
Harald Weltef325eb42009-02-19 17:07:39 +00001504
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001505static void rsl_handle_release(struct gsm_lchan *lchan)
1506{
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001507 int sapi;
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001508 struct gsm_bts *bts;
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001509
1510 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001511 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001512 return;
1513
1514 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1515 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1516 continue;
Harald Welte3a3c2772010-12-24 12:51:07 +01001517 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001518 gsm_lchan_name(lchan), sapi);
1519 return;
1520 }
1521
Holger Hans Peter Freytherd7fd3062010-04-08 22:47:44 +02001522
1523
Holger Hans Peter Freytherf30c0dc2010-05-31 21:33:15 +08001524 /* wait a bit to send the RF Channel Release */
1525 lchan->T3111.cb = t3111_expired;
1526 lchan->T3111.data = lchan;
1527 bts = lchan->ts->trx->bts;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001528 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001529}
1530
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001531/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte52b1f982008-12-23 20:25:15 +00001532 0x02, 0x06,
1533 0x01, 0x20,
1534 0x02, 0x00,
1535 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1536
1537static int abis_rsl_rx_rll(struct msgb *msg)
1538{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001539 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte52b1f982008-12-23 20:25:15 +00001540 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001541 int rc = 0;
1542 char *ts_name;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001543 uint8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001544
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001545 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001546 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte5b8ed432009-12-24 12:20:20 +01001547 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001548
1549 switch (rllh->c.msg_type) {
1550 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001551 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001552 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001553 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1554 rllh->data[0] == RSL_IE_L3_INFO) {
1555 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001556 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001557 }
Harald Welte52b1f982008-12-23 20:25:15 +00001558 break;
1559 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001560 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001561 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001562 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001563 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001564 if (msgb_l2len(msg) >
Harald Welte4a543e82009-02-28 13:17:55 +00001565 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1566 rllh->data[0] == RSL_IE_L3_INFO) {
1567 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001568 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001569 }
Harald Welte52b1f982008-12-23 20:25:15 +00001570 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001571 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001572 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001573 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001574 rll_indication(msg->lchan, rllh->link_id,
1575 BSC_RLLR_IND_EST_CONF);
1576 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001577 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001578 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001579 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001580 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001581 rll_indication(msg->lchan, rllh->link_id,
1582 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001583 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001584 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte2d5b6382008-12-27 19:46:06 +00001585 break;
1586 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001587 /* BTS informs us of having received UA from MS,
1588 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001589 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001590 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freytherdbc5fae2010-04-08 22:39:34 +02001591 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther4b85a322010-07-29 17:09:36 +08001592 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte4b634542008-12-27 01:55:51 +00001593 break;
1594 case RSL_MT_ERROR_IND:
1595 rc = rsl_rx_rll_err_ind(msg);
1596 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001597 case RSL_MT_UNIT_DATA_IND:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001598 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1599 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001600 break;
1601 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001602 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1603 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001604 }
Harald Welte8470bf22008-12-25 23:28:35 +00001605 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001606}
1607
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001608static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Weltef4e79f22009-07-28 18:11:56 +02001609{
Harald Welte0603c9d2009-12-02 01:58:23 +05301610 switch (lchan->tch_mode) {
Harald Weltef4e79f22009-07-28 18:11:56 +02001611 case GSM48_CMODE_SPEECH_V1:
Harald Welte0603c9d2009-12-02 01:58:23 +05301612 switch (lchan->type) {
1613 case GSM_LCHAN_TCH_F:
1614 return 0x00;
1615 case GSM_LCHAN_TCH_H:
1616 return 0x03;
1617 default:
1618 break;
1619 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001620 case GSM48_CMODE_SPEECH_EFR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301621 switch (lchan->type) {
1622 case GSM_LCHAN_TCH_F:
1623 return 0x01;
1624 /* there's no half-rate EFR */
1625 default:
1626 break;
1627 }
Harald Weltef4e79f22009-07-28 18:11:56 +02001628 case GSM48_CMODE_SPEECH_AMR:
Harald Welte0603c9d2009-12-02 01:58:23 +05301629 switch (lchan->type) {
1630 case GSM_LCHAN_TCH_F:
1631 return 0x02;
1632 case GSM_LCHAN_TCH_H:
1633 return 0x05;
1634 default:
1635 break;
1636 }
1637 default:
1638 break;
Harald Weltef4e79f22009-07-28 18:11:56 +02001639 }
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001640 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welte0603c9d2009-12-02 01:58:23 +05301641 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001642 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001643}
1644
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001645static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munautb54dda42009-12-20 22:06:40 +01001646{
1647 switch (lchan->tch_mode) {
1648 case GSM48_CMODE_SPEECH_V1:
1649 switch (lchan->type) {
1650 case GSM_LCHAN_TCH_F:
1651 return RTP_PT_GSM_FULL;
1652 case GSM_LCHAN_TCH_H:
1653 return RTP_PT_GSM_HALF;
1654 default:
1655 break;
1656 }
1657 case GSM48_CMODE_SPEECH_EFR:
1658 switch (lchan->type) {
1659 case GSM_LCHAN_TCH_F:
1660 return RTP_PT_GSM_EFR;
1661 /* there's no half-rate EFR */
1662 default:
1663 break;
1664 }
1665 case GSM48_CMODE_SPEECH_AMR:
1666 switch (lchan->type) {
1667 case GSM_LCHAN_TCH_F:
Sylvain Munautb54dda42009-12-20 22:06:40 +01001668 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freythered999b22011-07-21 10:24:46 +02001669 return RTP_PT_AMR;
Sylvain Munautb54dda42009-12-20 22:06:40 +01001670 default:
1671 break;
1672 }
1673 default:
1674 break;
1675 }
1676 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1677 "tch_mode == 0x%02x\n & lchan_type == %d",
1678 lchan->tch_mode, lchan->type);
1679 return 0;
1680}
1681
Harald Welte75099262009-02-16 21:12:08 +00001682/* ip.access specific RSL extensions */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001683static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1684{
1685 struct in_addr ip;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001686 uint16_t port, conn_id;
Harald Welte5e3d91b2009-12-19 16:42:06 +01001687
1688 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001689 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001690 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1691 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1692 }
1693
1694 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001695 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001696 port = ntohs(port);
1697 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1698 lchan->abis_ip.bound_port = port;
1699 }
1700
1701 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001702 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001703 conn_id = ntohs(conn_id);
1704 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1705 lchan->abis_ip.conn_id = conn_id;
1706 }
1707
1708 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1709 lchan->abis_ip.rtp_payload2 =
1710 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1711 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1712 lchan->abis_ip.rtp_payload2);
1713 }
1714
1715 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1716 lchan->abis_ip.speech_mode =
1717 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1718 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1719 lchan->abis_ip.speech_mode);
1720 }
1721
1722 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001723 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001724 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1725 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1726 }
1727
1728 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001729 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001730 port = ntohs(port);
1731 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1732 lchan->abis_ip.connect_port = port;
1733 }
1734}
1735
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001736int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001737{
1738 struct msgb *msg = rsl_msgb_alloc();
1739 struct abis_rsl_dchan_hdr *dh;
1740
1741 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001742 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001743 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001744 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001745
Harald Weltef4e79f22009-07-28 18:11:56 +02001746 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001747 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001748 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001749 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001750 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001751
Sylvain Munautb54dda42009-12-20 22:06:40 +01001752 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1753 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1754 lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001755
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001756 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001757
1758 return abis_rsl_sendmsg(msg);
1759}
1760
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001761int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1762 uint8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001763{
1764 struct msgb *msg = rsl_msgb_alloc();
1765 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001766 uint32_t *att_ip;
Harald Weltef4e79f22009-07-28 18:11:56 +02001767 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001768
1769 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001770 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001771 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltef6093a42011-06-25 10:02:33 +02001772 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte75099262009-02-16 21:12:08 +00001773
Harald Welte5e3d91b2009-12-19 16:42:06 +01001774 /* we need to store these now as MDCX_ACK does not return them :( */
1775 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1776 lchan->abis_ip.connect_port = port;
1777 lchan->abis_ip.connect_ip = ip;
1778
Harald Welte58ca5b72009-07-29 12:12:18 +02001779 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Welte5e3d91b2009-12-19 16:42:06 +01001780 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001781 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Welte58ca5b72009-07-29 12:12:18 +02001782
Harald Weltef4e79f22009-07-28 18:11:56 +02001783 ia.s_addr = htonl(ip);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001784 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1785 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1786 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1787 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001788
Harald Welte5e3d91b2009-12-19 16:42:06 +01001789 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1790 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001791 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Welte5e3d91b2009-12-19 16:42:06 +01001792 *att_ip = ia.s_addr;
1793 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1794 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munautb54dda42009-12-20 22:06:40 +01001795 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Weltef4e79f22009-07-28 18:11:56 +02001796 if (rtp_payload2)
1797 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001798
1799 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte75099262009-02-16 21:12:08 +00001800
1801 return abis_rsl_sendmsg(msg);
1802}
1803
Harald Weltea72273e2009-12-20 16:51:09 +01001804/* tell BTS to connect RTP stream to our local RTP socket */
1805int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1806{
1807 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1808 int rc;
1809
1810 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1811 ntohs(rs->rtp.sin_local.sin_port),
1812 /* FIXME: use RTP payload of bound socket, not BTS*/
1813 lchan->abis_ip.rtp_payload2);
1814
1815 return rc;
1816}
1817
Harald Welte53cd7ac2010-12-23 12:59:52 +01001818int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welte9c880c92009-10-24 10:29:22 +02001819{
1820 struct msgb *msg = rsl_msgb_alloc();
1821 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +02001822 uint8_t msg_type;
Harald Welte4563eab2010-03-28 14:42:09 +08001823
1824 if (act)
1825 msg_type = RSL_MT_IPAC_PDCH_ACT;
1826 else
1827 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welte9c880c92009-10-24 10:29:22 +02001828
1829 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte4563eab2010-03-28 14:42:09 +08001830 init_dchan_hdr(dh, msg_type);
Harald Welte9c880c92009-10-24 10:29:22 +02001831 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltef6093a42011-06-25 10:02:33 +02001832 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welte9c880c92009-10-24 10:29:22 +02001833
Harald Welte53cd7ac2010-12-23 12:59:52 +01001834 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte4563eab2010-03-28 14:42:09 +08001835 act ? "" : "DE");
Harald Welte9c880c92009-10-24 10:29:22 +02001836
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001837 msg->dst = ts->trx->rsl_link;
Harald Welte9c880c92009-10-24 10:29:22 +02001838
1839 return abis_rsl_sendmsg(msg);
1840}
1841
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001842static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001843{
1844 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1845 struct tlv_parsed tv;
Harald Welte2c828992009-12-02 01:56:49 +05301846 struct gsm_lchan *lchan = msg->lchan;
Harald Welte75099262009-02-16 21:12:08 +00001847
1848 /* the BTS has acknowledged a local bind, it now tells us the IP
1849 * address and port number to which it has bound the given logical
1850 * channel */
1851
1852 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1853 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1854 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001855 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001856 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001857 return -EINVAL;
1858 }
Harald Welte17f5bf62009-12-20 15:42:44 +01001859
Harald Welte5e3d91b2009-12-19 16:42:06 +01001860 ipac_parse_rtp(lchan, &tv);
Harald Welte17f5bf62009-12-20 15:42:44 +01001861
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001862 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001863
Harald Welte75099262009-02-16 21:12:08 +00001864 return 0;
1865}
1866
Harald Welte5e3d91b2009-12-19 16:42:06 +01001867static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1868{
1869 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1870 struct tlv_parsed tv;
1871 struct gsm_lchan *lchan = msg->lchan;
1872
1873 /* the BTS has acknowledged a remote connect request and
1874 * it now tells us the IP address and port number to which it has
1875 * connected the given logical channel */
1876
1877 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1878 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001879 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001880
1881 return 0;
1882}
1883
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001884static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001885{
1886 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1887 struct tlv_parsed tv;
1888
1889 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001890
Harald Welte8830e072009-07-28 17:58:09 +02001891 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Welte5b8ed432009-12-24 12:20:20 +01001892 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Welte8830e072009-07-28 17:58:09 +02001893 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001894
Pablo Neira Ayusobbc5b992011-05-06 12:12:31 +02001895 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001896
Harald Welte75099262009-02-16 21:12:08 +00001897 return 0;
1898}
1899
1900static int abis_rsl_rx_ipacc(struct msgb *msg)
1901{
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001902 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte75099262009-02-16 21:12:08 +00001903 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Welte5b8ed432009-12-24 12:20:20 +01001904 char *ts_name;
Harald Welte75099262009-02-16 21:12:08 +00001905 int rc = 0;
1906
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02001907 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)19ef62a2009-12-27 18:16:36 +01001908 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte75099262009-02-16 21:12:08 +00001909
1910 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001911 case RSL_MT_IPAC_CRCX_ACK:
Harald Welte5b8ed432009-12-24 12:20:20 +01001912 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001913 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001914 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001915 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001916 /* somehow the BTS was unable to bind the lchan to its local
1917 * port?!? */
Harald Welte5b8ed432009-12-24 12:20:20 +01001918 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001919 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001920 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001921 /* the BTS tells us that a connect operation was successful */
Harald Welte5b8ed432009-12-24 12:20:20 +01001922 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Welte5e3d91b2009-12-19 16:42:06 +01001923 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001924 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001925 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001926 /* somehow the BTS was unable to connect the lchan to a remote
1927 * port */
Harald Welte5b8ed432009-12-24 12:20:20 +01001928 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte75099262009-02-16 21:12:08 +00001929 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001930 case RSL_MT_IPAC_DLCX_IND:
Harald Welte5b8ed432009-12-24 12:20:20 +01001931 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001932 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001933 break;
1934 default:
Harald Welte5b8ed432009-12-24 12:20:20 +01001935 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001936 rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001937 break;
1938 }
Harald Welte6dab0552009-05-01 17:21:37 +00001939 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001940
1941 return rc;
1942}
1943
1944
Harald Welte52b1f982008-12-23 20:25:15 +00001945/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001946int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001947{
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001948 struct abis_rsl_common_hdr *rslh;
Harald Welte8f5e2392009-02-03 12:57:37 +00001949 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001950
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001951 if (!msg) {
1952 DEBUGP(DRSL, "Empty RSL msg?..\n");
1953 return -1;
1954 }
1955
1956 if (msgb_l2len(msg) < sizeof(*rslh)) {
1957 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltef25b55e2012-05-31 20:22:34 +02001958 msgb_free(msg);
Holger Hans Peter Freyther19bab732009-11-20 15:14:01 +01001959 return -1;
1960 }
1961
1962 rslh = msgb_l2(msg);
1963
Harald Welte52b1f982008-12-23 20:25:15 +00001964 switch (rslh->msg_discr & 0xfe) {
1965 case ABIS_RSL_MDISC_RLL:
1966 rc = abis_rsl_rx_rll(msg);
1967 break;
1968 case ABIS_RSL_MDISC_DED_CHAN:
1969 rc = abis_rsl_rx_dchan(msg);
1970 break;
1971 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001972 rc = abis_rsl_rx_cchan(msg);
1973 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001974 case ABIS_RSL_MDISC_TRX:
1975 rc = abis_rsl_rx_trx(msg);
1976 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001977 case ABIS_RSL_MDISC_LOC:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001978 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte8f5e2392009-02-03 12:57:37 +00001979 rslh->msg_discr);
1980 break;
Harald Welte75099262009-02-16 21:12:08 +00001981 case ABIS_RSL_MDISC_IPACCESS:
1982 rc = abis_rsl_rx_ipacc(msg);
1983 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001984 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001985 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1986 "0x%02x\n", rslh->msg_discr);
Harald Weltef25b55e2012-05-31 20:22:34 +02001987 rc = -EINVAL;
Harald Welte52b1f982008-12-23 20:25:15 +00001988 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001989 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001990 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001991}
Holger Freyther3b72a892009-02-04 00:31:39 +00001992
Holger Hans Peter Freyther8cb4a0f2010-07-21 15:54:32 +08001993int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1994 uint8_t cb_command, const uint8_t *data, int len)
1995{
1996 struct abis_rsl_dchan_hdr *dh;
1997 struct msgb *cb_cmd;
1998
1999 cb_cmd = rsl_msgb_alloc();
2000 if (!cb_cmd)
2001 return -1;
2002
2003 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
2004 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2005 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2006
2007 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2008 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2009
2010 cb_cmd->trx = bts->c0;
2011
2012 return abis_rsl_sendmsg(cb_cmd);
2013}
Dieter Spaar16646022011-07-28 00:01:50 +02002014
2015int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2016{
2017 struct abis_rsl_common_hdr *ch;
2018 struct msgb *msg = rsl_msgb_alloc();
2019
2020 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2021 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2022 ch->msg_type = 0x40; /* Nokia SI Begin */
2023
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002024 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002025
2026 return abis_rsl_sendmsg(msg);
2027}
2028
2029int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2030{
2031 struct abis_rsl_common_hdr *ch;
2032 struct msgb *msg = rsl_msgb_alloc();
2033
2034 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2035 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2036 ch->msg_type = 0x41; /* Nokia SI End */
2037
2038 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2039
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002040 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002041
2042 return abis_rsl_sendmsg(msg);
2043}
2044
2045int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2046{
2047 struct abis_rsl_common_hdr *ch;
2048 struct msgb *msg = rsl_msgb_alloc();
2049
2050 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2051 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2052 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2053
2054 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2055 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2056
Pablo Neira Ayuso7abecfc2011-08-17 22:43:54 +02002057 msg->dst = trx->rsl_link;
Dieter Spaar16646022011-07-28 00:01:50 +02002058
2059 return abis_rsl_sendmsg(msg);
2060}