blob: b703c034fb053a528ecb797178edab20ffbd104d [file] [log] [blame]
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001/* GSM Radio Signalling Link messages on the A-bis interface
Harald Welte59b04682009-06-10 05:40:52 +08002 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
Harald Weltea22d36b2010-03-04 10:33:10 +01004/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte59b04682009-06-10 05:40:52 +08005 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
Harald Welte0e3e88e2011-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 Welte59b04682009-06-10 05:40:52 +080011 * (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 Welte0e3e88e2011-01-01 15:25:50 +010016 * GNU Affero General Public License for more details.
Harald Welte59b04682009-06-10 05:40:52 +080017 *
Harald Welte0e3e88e2011-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 Welte59b04682009-06-10 05:40:52 +080020 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <errno.h>
Harald Welte59b04682009-06-10 05:40:52 +080026#include <netinet/in.h>
27#include <arpa/inet.h>
28
29#include <openbsc/gsm_data.h>
30#include <openbsc/gsm_04_08.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010031#include <osmocom/gsm/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080032#include <openbsc/abis_rsl.h>
33#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020034#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080035#include <openbsc/debug.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010036#include <osmocom/gsm/tlv.h>
Harald Welte59b04682009-06-10 05:40:52 +080037#include <openbsc/paging.h>
38#include <openbsc/signal.h>
Harald Weltec20bd1d2009-11-29 19:07:28 +010039#include <openbsc/meas_rep.h>
Harald Welte50517742009-12-20 15:42:44 +010040#include <openbsc/rtp_proxy.h>
Pablo Neira Ayuso42e41df2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010042#include <osmocom/gsm/rsl.h>
Pablo Neira Ayusodd5fff42011-03-22 16:47:59 +010043#include <osmocom/core/talloc.h>
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080044
Harald Welte59b04682009-06-10 05:40:52 +080045#define RSL_ALLOC_SIZE 1024
46#define RSL_ALLOC_HEADROOM 128
47
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +080048static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
49
Holger Hans Peter Freyther645b3832010-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 Ayusoef717c62011-05-06 12:12:31 +020056 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +010057}
58
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020059static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080060{
61 /* mask off the transparent bit ? */
62 msg_type &= 0xfe;
63
64 if ((msg_type & 0xf0) == 0x00)
65 return ABIS_RSL_MDISC_RLL;
66 if ((msg_type & 0xf0) == 0x10) {
67 if (msg_type >= 0x19 && msg_type <= 0x22)
68 return ABIS_RSL_MDISC_TRX;
69 else
70 return ABIS_RSL_MDISC_COM_CHAN;
71 }
72 if ((msg_type & 0xe0) == 0x20)
73 return ABIS_RSL_MDISC_DED_CHAN;
74
75 return ABIS_RSL_MDISC_LOC;
76}
77
78static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020079 uint8_t msg_type)
Harald Welte59b04682009-06-10 05:40:52 +080080{
81 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
82 dh->c.msg_type = msg_type;
83 dh->ie_chan = RSL_IE_CHAN_NR;
84}
85
Harald Welte59b04682009-06-10 05:40:52 +080086/* determine logical channel based on TRX and channel number IE */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020087struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Harald Welte59b04682009-06-10 05:40:52 +080088{
89 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +020090 uint8_t ts_nr = chan_nr & 0x07;
91 uint8_t cbits = chan_nr >> 3;
92 uint8_t lch_idx;
Harald Welte59b04682009-06-10 05:40:52 +080093 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
94
95 if (cbits == 0x01) {
96 lch_idx = 0; /* TCH/F */
Harald Welte37884ed2009-10-24 10:25:50 +020097 if (ts->pchan != GSM_PCHAN_TCH_F &&
98 ts->pchan != GSM_PCHAN_PDCH &&
99 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100100 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800101 chan_nr, ts->pchan);
102 } else if ((cbits & 0x1e) == 0x02) {
103 lch_idx = cbits & 0x1; /* TCH/H */
104 if (ts->pchan != GSM_PCHAN_TCH_H)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100105 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800106 chan_nr, ts->pchan);
107 } else if ((cbits & 0x1c) == 0x04) {
108 lch_idx = cbits & 0x3; /* SDCCH/4 */
109 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100110 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800111 chan_nr, ts->pchan);
112 } else if ((cbits & 0x18) == 0x08) {
113 lch_idx = cbits & 0x7; /* SDCCH/8 */
114 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100115 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800116 chan_nr, ts->pchan);
117 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
118 lch_idx = 0;
119 if (ts->pchan != GSM_PCHAN_CCCH &&
120 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100121 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
Harald Welte59b04682009-06-10 05:40:52 +0800122 chan_nr, ts->pchan);
123 /* FIXME: we should not return first sdcch4 !!! */
124 } else {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100125 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800126 return NULL;
127 }
128
129 lchan = &ts->lchan[lch_idx];
Harald Welte51d2a592010-03-26 21:28:59 +0800130 log_set_context(BSC_CTX_LCHAN, lchan);
Holger Hans Peter Freyther1a95fa82010-06-28 15:47:12 +0800131 if (lchan->conn)
132 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800133
134 return lchan;
135}
136
Harald Welte59b04682009-06-10 05:40:52 +0800137/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200138uint64_t str_to_imsi(const char *imsi_str)
Harald Welte59b04682009-06-10 05:40:52 +0800139{
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200140 uint64_t ret;
Harald Welte59b04682009-06-10 05:40:52 +0800141
142 ret = strtoull(imsi_str, NULL, 10);
143
144 return ret;
145}
146
Harald Welte59b04682009-06-10 05:40:52 +0800147static struct msgb *rsl_msgb_alloc(void)
148{
Harald Welte9cfc9352009-06-26 19:39:35 +0200149 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
150 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800151}
152
153#define MACBLOCK_SIZE 23
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200154static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800155{
156 memcpy(out, in, len);
157
158 if (len < MACBLOCK_SIZE)
159 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
160}
161
Harald Welted2dd9de2009-08-30 15:37:11 +0900162/* Chapter 9.3.7: Encryption Information */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200163static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Harald Welted2dd9de2009-08-30 15:37:11 +0900164{
165 *out++ = lchan->encr.alg_id & 0xff;
166 if (lchan->encr.key_len)
167 memcpy(out, lchan->encr.key, lchan->encr.key_len);
168 return lchan->encr.key_len + 1;
169}
170
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200171static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Harald Weltef1a168d2009-07-28 17:58:09 +0200172{
Harald Welte59b04682009-06-10 05:40:52 +0800173 int i;
174
Harald Weltede4477a2009-12-24 12:20:20 +0100175 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
Harald Weltef1a168d2009-07-28 17:58:09 +0200176 cause_v[0], rsl_err_name(cause_v[0]));
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200177 for (i = 1; i < cause_len-1; i++)
Harald Weltede4477a2009-12-24 12:20:20 +0100178 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800179}
180
Harald Welte32951ea2011-08-10 23:26:33 +0200181static void lchan_act_tmr_cb(void *data)
182{
183 struct gsm_lchan *lchan = data;
184
185 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during activation!\n",
186 gsm_lchan_name(lchan));
187
Daniel Willmann2731e732011-08-11 04:44:12 +0200188 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
189 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200190}
191
192static void lchan_deact_tmr_cb(void *data)
193{
194 struct gsm_lchan *lchan = data;
195
196 LOGP(DRSL, LOGL_NOTICE, "%s Timeout during deactivation!\n",
197 gsm_lchan_name(lchan));
198
Holger Hans Peter Freyther7a663792012-01-14 21:56:37 +0100199 if (lchan->state != LCHAN_S_REL_ERR)
200 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Daniel Willmann2731e732011-08-11 04:44:12 +0200201 lchan_free(lchan);
Harald Welte32951ea2011-08-10 23:26:33 +0200202}
203
204
Harald Welte59b04682009-06-10 05:40:52 +0800205/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200206int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
207 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800208{
209 struct abis_rsl_dchan_hdr *dh;
210 struct msgb *msg = rsl_msgb_alloc();
211
212 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
213 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
214 dh->chan_nr = RSL_CHAN_BCCH;
215
216 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
217 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
218
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200219 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800220
221 return abis_rsl_sendmsg(msg);
222}
223
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200224int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
225 const uint8_t *data, int len)
Harald Welte59b04682009-06-10 05:40:52 +0800226{
227 struct abis_rsl_common_hdr *ch;
228 struct msgb *msg = rsl_msgb_alloc();
229
230 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
231 ch->msg_discr = ABIS_RSL_MDISC_TRX;
232 ch->msg_type = RSL_MT_SACCH_FILL;
233
234 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
235 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
236
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200237 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800238
239 return abis_rsl_sendmsg(msg);
240}
241
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200242int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
243 const uint8_t *data, int len)
Harald Welte10b7d8f2011-01-13 23:16:03 +0100244{
245 struct abis_rsl_dchan_hdr *dh;
246 struct msgb *msg = rsl_msgb_alloc();
Harald Weltee6d51f92011-06-25 10:02:33 +0200247 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte10b7d8f2011-01-13 23:16:03 +0100248
249 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
250 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
251 dh->chan_nr = chan_nr;
252
253 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
254 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
255
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200256 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte10b7d8f2011-01-13 23:16:03 +0100257
258 return abis_rsl_sendmsg(msg);
259}
260
Harald Welte91afe4c2009-06-20 18:15:19 +0200261int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
262{
263 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200264 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200265 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200266
267 db = abs(db);
268 if (db > 30)
269 return -EINVAL;
270
Harald Welteed831842009-06-27 03:09:08 +0200271 msg = rsl_msgb_alloc();
272
Harald Welte91afe4c2009-06-20 18:15:19 +0200273 lchan->bs_power = db/2;
274 if (fpc)
275 lchan->bs_power |= 0x10;
276
277 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
278 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
279 dh->chan_nr = chan_nr;
280
281 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
282
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200283 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200284
285 return abis_rsl_sendmsg(msg);
286}
287
Harald Welte91afe4c2009-06-20 18:15:19 +0200288int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
289{
290 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200291 struct msgb *msg;
Harald Weltee6d51f92011-06-25 10:02:33 +0200292 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte91afe4c2009-06-20 18:15:19 +0200293 int ctl_lvl;
294
Harald Weltec4dcda02009-08-09 14:45:18 +0200295 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200296 if (ctl_lvl < 0)
297 return ctl_lvl;
298
Harald Welteed831842009-06-27 03:09:08 +0200299 msg = rsl_msgb_alloc();
300
Harald Welte91afe4c2009-06-20 18:15:19 +0200301 lchan->ms_power = ctl_lvl;
302
303 if (fpc)
304 lchan->ms_power |= 0x20;
305
306 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
307 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
308 dh->chan_nr = chan_nr;
309
310 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
311
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200312 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte91afe4c2009-06-20 18:15:19 +0200313
314 return abis_rsl_sendmsg(msg);
315}
316
Harald Welte39274f42009-07-29 15:41:29 +0200317static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
318 struct gsm_lchan *lchan)
319{
320 memset(cm, 0, sizeof(cm));
321
322 /* FIXME: what to do with data calls ? */
Holger Hans Peter Freyther21d63ff2010-09-06 09:25:48 +0800323 if (lchan->ts->trx->bts->network->dtx_enabled)
324 cm->dtx_dtu = 0x03;
325 else
326 cm->dtx_dtu = 0x00;
Harald Welte39274f42009-07-29 15:41:29 +0200327
328 /* set TCH Speech/Data */
329 cm->spd_ind = lchan->rsl_cmode;
330
Harald Welte951e3512009-11-27 08:55:16 +0100331 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
332 lchan->tch_mode != GSM48_CMODE_SIGN)
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100333 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
Harald Welte951e3512009-11-27 08:55:16 +0100334 "but tch_mode != signalling\n");
335
Harald Welte39274f42009-07-29 15:41:29 +0200336 switch (lchan->type) {
337 case GSM_LCHAN_SDCCH:
338 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
339 break;
340 case GSM_LCHAN_TCH_F:
341 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
342 break;
343 case GSM_LCHAN_TCH_H:
344 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
345 break;
346 case GSM_LCHAN_NONE:
347 case GSM_LCHAN_UNKNOWN:
348 default:
349 return -EINVAL;
350 }
351
352 switch (lchan->tch_mode) {
353 case GSM48_CMODE_SIGN:
354 cm->chan_rate = 0;
355 break;
356 case GSM48_CMODE_SPEECH_V1:
357 cm->chan_rate = RSL_CMOD_SP_GSM1;
358 break;
359 case GSM48_CMODE_SPEECH_EFR:
360 cm->chan_rate = RSL_CMOD_SP_GSM2;
361 break;
362 case GSM48_CMODE_SPEECH_AMR:
363 cm->chan_rate = RSL_CMOD_SP_GSM3;
364 break;
365 case GSM48_CMODE_DATA_14k5:
Harald Welte39274f42009-07-29 15:41:29 +0200366 case GSM48_CMODE_DATA_12k0:
Harald Welte39274f42009-07-29 15:41:29 +0200367 case GSM48_CMODE_DATA_6k0:
Harald Weltee75a47d2012-08-24 15:33:56 +0200368 switch (lchan->csd_mode) {
369 case LCHAN_CSD_M_NT:
370 /* non-transparent CSD with RLP */
371 switch (lchan->tch_mode) {
372 case GSM48_CMODE_DATA_14k5:
373 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
374 break;
375 case GSM48_CMODE_DATA_12k0:
376 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
377 break;
378 case GSM48_CMODE_DATA_6k0:
379 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
380 break;
381 default:
382 return -EINVAL;
383 }
384 break;
385 /* transparent data services below */
386 case LCHAN_CSD_M_T_1200_75:
387 cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
388 break;
389 case LCHAN_CSD_M_T_600:
390 cm->chan_rate = RSL_CMOD_CSD_T_600;
391 break;
392 case LCHAN_CSD_M_T_1200:
393 cm->chan_rate = RSL_CMOD_CSD_T_1200;
394 break;
395 case LCHAN_CSD_M_T_2400:
396 cm->chan_rate = RSL_CMOD_CSD_T_2400;
397 break;
398 case LCHAN_CSD_M_T_9600:
399 cm->chan_rate = RSL_CMOD_CSD_T_9600;
400 break;
401 case LCHAN_CSD_M_T_14400:
402 cm->chan_rate = RSL_CMOD_CSD_T_14400;
403 break;
404 case LCHAN_CSD_M_T_29000:
405 cm->chan_rate = RSL_CMOD_CSD_T_29000;
406 break;
407 case LCHAN_CSD_M_T_32000:
408 cm->chan_rate = RSL_CMOD_CSD_T_32000;
409 break;
410 default:
411 return -EINVAL;
412 }
Harald Welte39274f42009-07-29 15:41:29 +0200413 default:
414 return -EINVAL;
415 }
416
417 return 0;
418}
419
Harald Welte59b04682009-06-10 05:40:52 +0800420/* Chapter 8.4.1 */
421#if 0
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200422int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
423 uint8_t act_type,
Harald Welte59b04682009-06-10 05:40:52 +0800424 struct rsl_ie_chan_mode *chan_mode,
425 struct rsl_ie_chan_ident *chan_ident,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200426 uint8_t bs_power, uint8_t ms_power,
427 uint8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800428{
429 struct abis_rsl_dchan_hdr *dh;
430 struct msgb *msg = rsl_msgb_alloc();
431
432 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
433 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
434 dh->chan_nr = chan_nr;
435
436 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
437 /* For compatibility with Phase 1 */
438 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200439 (uint8_t *) chan_mode);
Harald Welte59b04682009-06-10 05:40:52 +0800440 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200441 (uint8_t *) chan_ident);
Harald Welte59b04682009-06-10 05:40:52 +0800442#if 0
443 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200444 (uint8_t *) &encr_info);
Harald Welte59b04682009-06-10 05:40:52 +0800445#endif
446 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
447 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
448 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
449
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200450 msg->dst = trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800451
452 return abis_rsl_sendmsg(msg);
453}
454#endif
455
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200456int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
457 uint8_t ta, uint8_t ho_ref)
Harald Welte59b04682009-06-10 05:40:52 +0800458{
459 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200460 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200461 int rc;
Harald Weltedea24e92010-06-29 17:53:45 +0200462 uint8_t *len;
Harald Welte59b04682009-06-10 05:40:52 +0800463
Harald Weltee6d51f92011-06-25 10:02:33 +0200464 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800465 struct rsl_ie_chan_mode cm;
laforgef723cf02010-06-20 21:38:19 +0200466 struct gsm48_chan_desc cd;
Harald Welte59b04682009-06-10 05:40:52 +0800467
Harald Welte39274f42009-07-29 15:41:29 +0200468 rc = channel_mode_from_lchan(&cm, lchan);
469 if (rc < 0)
470 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800471
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800472 memset(&cd, 0, sizeof(cd));
laforgef723cf02010-06-20 21:38:19 +0200473 gsm48_lchan2chan_desc(&cd, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800474
Harald Welteed831842009-06-27 03:09:08 +0200475 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800476 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
477 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
478 dh->chan_nr = chan_nr;
479
480 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
Harald Welte59b04682009-06-10 05:40:52 +0800481 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200482 (uint8_t *) &cm);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800483
484 /*
485 * The Channel Identification is needed for Phase1 phones
486 * and it contains the GSM48 Channel Description and the
487 * Mobile Allocation. The GSM 08.58 asks for the Mobile
488 * Allocation to have a length of zero. We are using the
489 * msgb_l3len to calculate the length of both messages.
490 */
laforgef723cf02010-06-20 21:38:19 +0200491 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
Harald Weltedea24e92010-06-29 17:53:45 +0200492 len = msgb_put(msg, 1);
Dieter Spaar18a55f62011-07-27 23:40:33 +0200493 msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
Holger Hans Peter Freyther4cab4422010-06-30 12:06:20 +0800494
495 if (lchan->ts->hopping.enabled)
496 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
497 lchan->ts->hopping.ma_data);
498 else
499 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
Holger Hans Peter Freyther11b01402010-06-30 11:56:43 +0800500
501 /* update the calculated size */
502 msg->l3h = len + 1;
503 *len = msgb_l3len(msg);
504
Harald Welted2dd9de2009-08-30 15:37:11 +0900505 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200506 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900507 rc = build_encr_info(encr_info, lchan);
508 if (rc > 0)
509 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
510 }
511
Harald Welteb90d7bd2009-12-17 00:31:10 +0100512 switch (act_type) {
513 case RSL_ACT_INTER_ASYNC:
514 case RSL_ACT_INTER_SYNC:
515 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
516 break;
517 default:
518 break;
519 }
520
Harald Welte59b04682009-06-10 05:40:52 +0800521 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
522 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
523 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
524
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100525 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
526 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200527 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther6fe8ab92010-01-28 04:45:05 +0100528
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200529 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800530
531 return abis_rsl_sendmsg(msg);
532}
533
Harald Welte8e770492009-07-29 11:38:15 +0200534/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800535int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
536{
537 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200538 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200539 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800540
Harald Weltee6d51f92011-06-25 10:02:33 +0200541 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800542 struct rsl_ie_chan_mode cm;
543
Harald Welte39274f42009-07-29 15:41:29 +0200544 rc = channel_mode_from_lchan(&cm, lchan);
545 if (rc < 0)
546 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800547
Harald Welteed831842009-06-27 03:09:08 +0200548 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800549 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
550 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
551 dh->chan_nr = chan_nr;
552
553 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200554 (uint8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900555
556 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200557 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Harald Welted2dd9de2009-08-30 15:37:11 +0900558 rc = build_encr_info(encr_info, lchan);
559 if (rc > 0)
560 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
561 }
562
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100563 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
564 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200565 (uint8_t *) &lchan->mr_conf);
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100566 }
567
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200568 msg->dst = lchan->ts->trx->rsl_link;
Harald Welted2dd9de2009-08-30 15:37:11 +0900569
570 return abis_rsl_sendmsg(msg);
571}
572
573/* Chapter 8.4.6: Send the encryption command with given L3 info */
574int rsl_encryption_cmd(struct msgb *msg)
575{
576 struct abis_rsl_dchan_hdr *dh;
577 struct gsm_lchan *lchan = msg->lchan;
Harald Weltee6d51f92011-06-25 10:02:33 +0200578 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200579 uint8_t encr_info[MAX_A5_KEY_LEN+2];
580 uint8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900581 int rc;
582
583 /* First push the L3 IE tag and length */
584 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
585
586 /* then the link identifier (SAPI0, main sign link) */
587 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
588
589 /* then encryption information */
590 rc = build_encr_info(encr_info, lchan);
591 if (rc <= 0)
592 return rc;
593 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
594
595 /* and finally the DCHAN header */
596 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
597 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
598 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800599
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200600 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800601
602 return abis_rsl_sendmsg(msg);
603}
604
Harald Welte85a163c2009-08-10 11:43:22 +0200605/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200606int rsl_deact_sacch(struct gsm_lchan *lchan)
607{
608 struct abis_rsl_dchan_hdr *dh;
609 struct msgb *msg = rsl_msgb_alloc();
610
611 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
612 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Harald Weltee6d51f92011-06-25 10:02:33 +0200613 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welteafe3c232009-07-19 18:36:49 +0200614
615 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200616 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteafe3c232009-07-19 18:36:49 +0200617
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100618 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
Harald Welteafe3c232009-07-19 18:36:49 +0200619
620 return abis_rsl_sendmsg(msg);
621}
622
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800623static void error_timeout_cb(void *data)
624{
625 struct gsm_lchan *lchan = data;
626 if (lchan->state != LCHAN_S_REL_ERR) {
627 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
628 gsm_lchan_name(lchan), lchan->state);
629 return;
630 }
631
632 /* go back to the none state */
633 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800634 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800635}
636
Harald Welte08011e22011-03-04 13:41:31 +0100637static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
638
Harald Welte85a163c2009-08-10 11:43:22 +0200639/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800640static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
Harald Welte59b04682009-06-10 05:40:52 +0800641{
642 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800643 struct msgb *msg;
Harald Welte08011e22011-03-04 13:41:31 +0100644 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800645
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800646 if (lchan->state == LCHAN_S_REL_ERR) {
647 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
648 gsm_lchan_name(lchan));
649 return -1;
650 }
651
652 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800653 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
654 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Weltee6d51f92011-06-25 10:02:33 +0200655 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800656
657 msg->lchan = lchan;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200658 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800659
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800660 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
661
662 if (error) {
663 /*
664 * the nanoBTS sends RLL release indications after the channel release. This can
665 * be a problem when we have reassigned the channel to someone else and then can
666 * not figure out who used this channel.
667 */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200668 struct e1inp_sign_link *sign_link = msg->dst;
669
Holger Hans Peter Freyther456fb9d2010-06-08 11:53:33 +0800670 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800671 lchan->error_timer.data = lchan;
672 lchan->error_timer.cb = error_timeout_cb;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +0200673 osmo_timer_schedule(&lchan->error_timer,
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200674 sign_link->trx->bts->network->T3111 + 2, 0);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800675 }
Harald Welte59b04682009-06-10 05:40:52 +0800676
Harald Welte32951ea2011-08-10 23:26:33 +0200677 /* Start another timer or assume the BTS sends a ACK/NACK? */
678 lchan->act_timer.cb = lchan_deact_tmr_cb;
679 lchan->act_timer.data = lchan;
680 osmo_timer_schedule(&lchan->act_timer, 4, 0);
681
Harald Welte08011e22011-03-04 13:41:31 +0100682 rc = abis_rsl_sendmsg(msg);
683
Harald Welte85a163c2009-08-10 11:43:22 +0200684 /* BTS will respond by RF CHAN REL ACK */
Harald Welte6bddd822011-01-14 23:18:59 +0100685#ifdef HSL_SR_1_0
Harald Welte08011e22011-03-04 13:41:31 +0100686 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
687 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
688 rc = rsl_rx_rf_chan_rel_ack(lchan);
Harald Welte6bddd822011-01-14 23:18:59 +0100689#endif
Harald Welte08011e22011-03-04 13:41:31 +0100690
691 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800692}
693
Harald Welte9773f6c2011-01-14 14:16:16 +0100694static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
695{
696
697 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
698
Harald Welte32951ea2011-08-10 23:26:33 +0200699 osmo_timer_del(&lchan->act_timer);
700
Harald Welte9773f6c2011-01-14 14:16:16 +0100701 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
702 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
703 gsm_lchan_name(lchan),
704 gsm_lchans_name(lchan->state));
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +0200705 osmo_timer_del(&lchan->T3111);
Harald Welte9773f6c2011-01-14 14:16:16 +0100706 /* we have an error timer pending to release that */
707 if (lchan->state != LCHAN_S_REL_ERR)
708 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
709 lchan_free(lchan);
710
711 return 0;
712}
713
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200714int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
715 uint8_t *ms_ident, uint8_t chan_needed)
Harald Welte59b04682009-06-10 05:40:52 +0800716{
717 struct abis_rsl_dchan_hdr *dh;
718 struct msgb *msg = rsl_msgb_alloc();
719
720 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
721 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
722 dh->chan_nr = RSL_CHAN_PCH_AGCH;
723
724 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
725 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
726 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
727
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200728 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800729
730 return abis_rsl_sendmsg(msg);
731}
732
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200733int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Harald Welte59b04682009-06-10 05:40:52 +0800734{
735 int i, len = strlen(str_in);
736
737 for (i = 0; i < len; i++) {
738 int num = str_in[i] - 0x30;
739 if (num < 0 || num > 9)
740 return -1;
741 if (i % 2 == 0)
742 bcd_out[i/2] = num;
743 else
744 bcd_out[i/2] |= (num << 4);
745 }
746
747 return 0;
748}
749
750/* Chapter 8.5.6 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200751int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Harald Welte59b04682009-06-10 05:40:52 +0800752{
753 struct msgb *msg = rsl_msgb_alloc();
754 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200755 uint8_t buf[MACBLOCK_SIZE];
Harald Welte59b04682009-06-10 05:40:52 +0800756
757 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
758 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
759 dh->chan_nr = RSL_CHAN_PCH_AGCH;
760
761 switch (bts->type) {
762 case GSM_BTS_TYPE_BS11:
763 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
764 break;
765 default:
766 /* If phase 2, construct a FULL_IMM_ASS_INFO */
767 pad_macblock(buf, val, len);
768 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
769 break;
770 }
771
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200772 msg->dst = bts->c0->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800773
774 return abis_rsl_sendmsg(msg);
775}
776
Harald Welte4684e632009-08-10 09:51:40 +0200777/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200778int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200779{
780 struct msgb *msg = rsl_msgb_alloc();
781 struct abis_rsl_dchan_hdr *dh;
782
783 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
784 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200785 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +0200786 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200787 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200788
Harald Weltede4477a2009-12-24 12:20:20 +0100789 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200790 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Harald Welte874a5b42009-08-10 11:26:14 +0200791
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200792 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte874a5b42009-08-10 11:26:14 +0200793
Harald Welte4684e632009-08-10 09:51:40 +0200794 return abis_rsl_sendmsg(msg);
795}
796
797
Harald Welte59b04682009-06-10 05:40:52 +0800798/* Send "DATA REQUEST" message with given L3 Info payload */
799/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200800int rsl_data_request(struct msgb *msg, uint8_t link_id)
Harald Welte59b04682009-06-10 05:40:52 +0800801{
Harald Welte59b04682009-06-10 05:40:52 +0800802 if (msg->lchan == NULL) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100803 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
Harald Welte59b04682009-06-10 05:40:52 +0800804 return -EINVAL;
805 }
806
Harald Weltee6d51f92011-06-25 10:02:33 +0200807 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100808 link_id, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800809
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200810 msg->dst = msg->lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +0800811
812 return abis_rsl_sendmsg(msg);
813}
814
Harald Welteed9a5ab2009-08-09 13:47:35 +0200815/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
816/* Chapter 8.3.1 */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200817int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Harald Welteed9a5ab2009-08-09 13:47:35 +0200818{
Harald Weltea22d36b2010-03-04 10:33:10 +0100819 struct msgb *msg;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200820
Harald Weltee6d51f92011-06-25 10:02:33 +0200821 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100822 link_id, 0);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200823 msg->dst = lchan->ts->trx->rsl_link;
Harald Welteed9a5ab2009-08-09 13:47:35 +0200824
Harald Welte17091bd2012-04-26 19:42:19 +0200825 DEBUGP(DRLL, "%s RSL RLL ESTABLISH REQ (link_id=0x%02x)\n",
826 gsm_lchan_name(lchan), link_id);
827
Harald Welteed9a5ab2009-08-09 13:47:35 +0200828 return abis_rsl_sendmsg(msg);
829}
830
Harald Welte0f2e3c12009-08-08 13:15:07 +0200831/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
832 This is what higher layers should call. The BTS then responds with
833 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
834 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
835 lchan_free() */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200836int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason)
Harald Welte0f2e3c12009-08-08 13:15:07 +0200837{
Harald Welte0f2e3c12009-08-08 13:15:07 +0200838
Harald Weltea22d36b2010-03-04 10:33:10 +0100839 struct msgb *msg;
840
Harald Weltee6d51f92011-06-25 10:02:33 +0200841 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Harald Weltea22d36b2010-03-04 10:33:10 +0100842 link_id, 0);
Holger Hans Peter Freytherbcea9a72010-06-08 11:57:45 +0800843 /* 0 is normal release, 1 is local end */
844 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
Harald Welte0f2e3c12009-08-08 13:15:07 +0200845
Harald Weltec88a4432009-12-29 10:44:17 +0100846 /* FIXME: start some timer in case we don't receive a REL ACK ? */
847
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +0200848 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte0f2e3c12009-08-08 13:15:07 +0200849
Harald Welte17091bd2012-04-26 19:42:19 +0200850 DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
851 gsm_lchan_name(lchan), link_id, reason);
852
Harald Welte0f2e3c12009-08-08 13:15:07 +0200853 return abis_rsl_sendmsg(msg);
854}
855
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200856int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
857{
858 lchan->state = state;
859 return 0;
860}
861
Harald Welte59b04682009-06-10 05:40:52 +0800862/* Chapter 8.4.2: Channel Activate Acknowledge */
863static int rsl_rx_chan_act_ack(struct msgb *msg)
864{
865 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
866
867 /* BTS has confirmed channel activation, we now need
868 * to assign the activated channel to the MS */
869 if (rslh->ie_chan != RSL_IE_CHAN_NR)
870 return -EINVAL;
Harald Welte6720a432009-11-29 22:45:52 +0100871
Harald Welte32951ea2011-08-10 23:26:33 +0200872 osmo_timer_del(&msg->lchan->act_timer);
873
Harald Weltec88a4432009-12-29 10:44:17 +0100874 if (msg->lchan->state != LCHAN_S_ACT_REQ)
Harald Welteab2534c2009-12-29 10:52:38 +0100875 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
876 gsm_lchan_name(msg->lchan),
877 gsm_lchans_name(msg->lchan->state));
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200878 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
Harald Welte4baa9c52009-12-21 13:27:11 +0100879
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +0800880 if (msg->lchan->rqd_ref) {
881 rsl_send_imm_assignment(msg->lchan);
882 talloc_free(msg->lchan->rqd_ref);
883 msg->lchan->rqd_ref = NULL;
884 msg->lchan->rqd_ta = 0;
885 }
886
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100887 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100888
Harald Welte59b04682009-06-10 05:40:52 +0800889 return 0;
890}
891
892/* Chapter 8.4.3: Channel Activate NACK */
893static int rsl_rx_chan_act_nack(struct msgb *msg)
894{
895 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
896 struct tlv_parsed tp;
897
Harald Welte32951ea2011-08-10 23:26:33 +0200898 osmo_timer_del(&msg->lchan->act_timer);
899
Daniel Willmann9e9d44c2011-08-11 04:54:23 +0200900 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100901 gsm_lchan_name(msg->lchan));
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100902
Harald Welte59b04682009-06-10 05:40:52 +0800903 /* BTS has rejected channel activation ?!? */
904 if (dh->ie_chan != RSL_IE_CHAN_NR)
905 return -EINVAL;
906
907 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100908 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +0200909 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100910 print_rsl_cause(LOGL_ERROR, cause,
Harald Weltef1a168d2009-07-28 17:58:09 +0200911 TLVP_LEN(&tp, RSL_IE_CAUSE));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100912 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200913 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Daniel Willmann245ee032011-08-11 04:47:11 +0200914 else
915 rsl_rf_chan_release(msg->lchan, 1);
916
Harald Welte (local)c3be50c2009-12-27 18:12:29 +0100917 } else
Holger Hans Peter Freyther68914a02010-04-10 00:12:31 +0200918 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200919
Harald Welte (local)ed6d7622009-12-27 11:48:11 +0100920 LOGPC(DRSL, LOGL_ERROR, "\n");
921
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +0100922 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +0100923
Harald Weltecddb9802009-08-09 19:50:08 +0200924 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800925 return 0;
926}
927
928/* Chapter 8.4.4: Connection Failure Indication */
929static int rsl_rx_conn_fail(struct msgb *msg)
930{
931 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
932 struct tlv_parsed tp;
933
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100934 /* FIXME: print which channel */
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100935 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +0100936 gsm_lchan_name(msg->lchan));
Harald Welte59b04682009-06-10 05:40:52 +0800937
938 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
939
Harald Weltef1a168d2009-07-28 17:58:09 +0200940 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +0100941 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +0200942 TLVP_LEN(&tp, RSL_IE_CAUSE));
943
Harald Welte (local)4bd76642009-12-26 22:33:09 +0100944 LOGPC(DRSL, LOGL_NOTICE, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800945 /* FIXME: only free it after channel release ACK */
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +0200946 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +0800947 return rsl_rf_chan_release(msg->lchan, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800948}
949
Harald Weltec20bd1d2009-11-29 19:07:28 +0100950static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
951 const char *prefix)
952{
Harald Welte0e4fa782009-12-16 16:52:07 +0100953 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
954 prefix, rxlev2dbm(mru->full.rx_lev),
955 prefix, rxlev2dbm(mru->sub.rx_lev));
Harald Weltec20bd1d2009-11-29 19:07:28 +0100956 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
957 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
958}
959
Harald Welte50290cc2012-07-02 17:12:08 +0200960static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
Harald Weltec20bd1d2009-11-29 19:07:28 +0100961{
Harald Welte0e4fa782009-12-16 16:52:07 +0100962 int i;
Harald Welte50290cc2012-07-02 17:12:08 +0200963 char *name = "";
Harald Welte0e4fa782009-12-16 16:52:07 +0100964
Harald Welte50290cc2012-07-02 17:12:08 +0200965 if (lchan && lchan->conn && lchan->conn->subscr)
966 name = subscr_name(lchan->conn->subscr);
967
968 DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100969
970 if (mr->flags & MEAS_REP_F_DL_DTX)
971 DEBUGPC(DMEAS, "DTXd ");
972
973 print_meas_rep_uni(&mr->ul, "ul");
974 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
975 if (mr->flags & MEAS_REP_F_MS_TO)
976 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
977
978 if (mr->flags & MEAS_REP_F_MS_L1) {
Harald Welte0e4fa782009-12-16 16:52:07 +0100979 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
Harald Weltec20bd1d2009-11-29 19:07:28 +0100980 DEBUGPC(DMEAS, "L1_FPC=%u ",
981 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
982 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
983 }
984
985 if (mr->flags & MEAS_REP_F_UL_DTX)
986 DEBUGPC(DMEAS, "DTXu ");
987 if (mr->flags & MEAS_REP_F_BA1)
988 DEBUGPC(DMEAS, "BA1 ");
989 if (!(mr->flags & MEAS_REP_F_DL_VALID))
990 DEBUGPC(DMEAS, "NOT VALID ");
991 else
992 print_meas_rep_uni(&mr->dl, "dl");
993
994 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
Harald Welte0b833f82009-12-19 18:33:05 +0100995 if (mr->num_cell == 7)
996 return;
Harald Welte0e4fa782009-12-16 16:52:07 +0100997 for (i = 0; i < mr->num_cell; i++) {
998 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
Harald Welte350c2d32009-12-25 23:02:22 +0100999 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
1000 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
Harald Welte0e4fa782009-12-16 16:52:07 +01001001 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001002}
1003
Harald Welte59b04682009-06-10 05:40:52 +08001004static int rsl_rx_meas_res(struct msgb *msg)
1005{
1006 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1007 struct tlv_parsed tp;
Harald Weltef9476812009-12-15 21:36:05 +01001008 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001009 uint8_t len;
1010 const uint8_t *val;
Harald Weltec20bd1d2009-11-29 19:07:28 +01001011 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001012
Harald Welte4baa9c52009-12-21 13:27:11 +01001013 /* check if this channel is actually active */
1014 /* FIXME: maybe this check should be way more generic/centralized */
Harald Weltec88a4432009-12-29 10:44:17 +01001015 if (msg->lchan->state != LCHAN_S_ACTIVE) {
Holger Hans Peter Freyther67a2e292010-07-29 14:50:57 +08001016 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
Harald Weltec88a4432009-12-29 10:44:17 +01001017 gsm_lchan_name(msg->lchan));
Harald Welte4baa9c52009-12-21 13:27:11 +01001018 return 0;
Harald Weltec88a4432009-12-29 10:44:17 +01001019 }
Harald Welte4baa9c52009-12-21 13:27:11 +01001020
Harald Weltef9476812009-12-15 21:36:05 +01001021 memset(mr, 0, sizeof(*mr));
Harald Welteaa0efa12009-12-16 23:29:34 +01001022 mr->lchan = msg->lchan;
Harald Welte4efcc542009-11-30 19:16:47 +01001023
Harald Welte59b04682009-06-10 05:40:52 +08001024 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1025
Harald Weltec20bd1d2009-11-29 19:07:28 +01001026 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
1027 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
1028 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
1029 return -EIO;
1030
1031 /* Mandatory Parts */
Harald Weltef9476812009-12-15 21:36:05 +01001032 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001033
1034 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
1035 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
1036 if (len >= 3) {
1037 if (val[0] & 0x40)
Harald Weltef9476812009-12-15 21:36:05 +01001038 mr->flags |= MEAS_REP_F_DL_DTX;
1039 mr->ul.full.rx_lev = val[0] & 0x3f;
1040 mr->ul.sub.rx_lev = val[1] & 0x3f;
1041 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
1042 mr->ul.sub.rx_qual = val[2] & 0x7;
Harald Welte59b04682009-06-10 05:40:52 +08001043 }
Harald Weltec20bd1d2009-11-29 19:07:28 +01001044
Harald Weltef9476812009-12-15 21:36:05 +01001045 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001046
1047 /* Optional Parts */
Harald Welte59b04682009-06-10 05:40:52 +08001048 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Weltef9476812009-12-15 21:36:05 +01001049 mr->ms_timing_offset =
Harald Weltec20bd1d2009-11-29 19:07:28 +01001050 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
1051
Harald Weltea1467eb2009-06-20 18:44:35 +02001052 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001053 struct e1inp_sign_link *sign_link = msg->dst;
1054
Harald Weltec20bd1d2009-11-29 19:07:28 +01001055 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001056 mr->flags |= MEAS_REP_F_MS_L1;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001057 mr->ms_l1.pwr = ms_pwr_dbm(sign_link->trx->bts->band, val[0] >> 3);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001058 if (val[0] & 0x04)
Harald Weltef9476812009-12-15 21:36:05 +01001059 mr->flags |= MEAS_REP_F_FPC;
1060 mr->ms_l1.ta = val[1];
Andreas Eversbergfe56cf82011-12-24 11:49:05 +01001061 /* BS11 and Nokia reports TA shifted by 2 bits */
1062 if (msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_BS11
1063 || msg->lchan->ts->trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE)
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001064 mr->ms_l1.ta >>= 2;
Harald Weltea1467eb2009-06-20 18:44:35 +02001065 }
Harald Welte59b04682009-06-10 05:40:52 +08001066 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001067 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Weltef9476812009-12-15 21:36:05 +01001068 rc = gsm48_parse_meas_rep(mr, msg);
Harald Weltec20bd1d2009-11-29 19:07:28 +01001069 if (rc < 0)
1070 return rc;
1071 }
1072
Harald Welte50290cc2012-07-02 17:12:08 +02001073 print_meas_rep(msg->lchan, mr);
Harald Welte59b04682009-06-10 05:40:52 +08001074
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001075 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
Harald Welte4efcc542009-11-30 19:16:47 +01001076
Harald Welte59b04682009-06-10 05:40:52 +08001077 return 0;
1078}
1079
Harald Welte6720a432009-11-29 22:45:52 +01001080/* Chapter 8.4.7 */
1081static int rsl_rx_hando_det(struct msgb *msg)
1082{
1083 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1084 struct tlv_parsed tp;
1085
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001086 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
Harald Welte6720a432009-11-29 22:45:52 +01001087
1088 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
1089
1090 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
1091 DEBUGPC(DRSL, "access delay = %u\n",
1092 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
1093 else
1094 DEBUGPC(DRSL, "\n");
1095
Holger Hans Peter Freyther645b3832010-12-27 13:28:20 +01001096 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
Harald Welte6720a432009-11-29 22:45:52 +01001097
1098 return 0;
1099}
1100
Harald Welte59b04682009-06-10 05:40:52 +08001101static int abis_rsl_rx_dchan(struct msgb *msg)
1102{
1103 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1104 int rc = 0;
1105 char *ts_name;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001106 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001107
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001108 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001109 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001110
Harald Welte59b04682009-06-10 05:40:52 +08001111 switch (rslh->c.msg_type) {
1112 case RSL_MT_CHAN_ACTIV_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001113 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001114 rc = rsl_rx_chan_act_ack(msg);
1115 break;
1116 case RSL_MT_CHAN_ACTIV_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001117 rc = rsl_rx_chan_act_nack(msg);
1118 break;
1119 case RSL_MT_CONN_FAIL:
1120 rc = rsl_rx_conn_fail(msg);
1121 break;
1122 case RSL_MT_MEAS_RES:
1123 rc = rsl_rx_meas_res(msg);
1124 break;
Harald Welte6720a432009-11-29 22:45:52 +01001125 case RSL_MT_HANDO_DET:
1126 rc = rsl_rx_hando_det(msg);
1127 break;
Harald Welte59b04682009-06-10 05:40:52 +08001128 case RSL_MT_RF_CHAN_REL_ACK:
Harald Welte9773f6c2011-01-14 14:16:16 +01001129 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001130 break;
1131 case RSL_MT_MODE_MODIFY_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001132 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001133 break;
1134 case RSL_MT_MODE_MODIFY_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001135 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001136 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001137 case RSL_MT_IPAC_PDCH_ACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001138 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001139 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001140 break;
1141 case RSL_MT_IPAC_PDCH_ACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001142 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001143 break;
1144 case RSL_MT_IPAC_PDCH_DEACT_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001145 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
Harald Welte2b361522010-03-28 14:42:09 +08001146 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
Harald Welteaed946e2009-10-24 10:29:22 +02001147 break;
1148 case RSL_MT_IPAC_PDCH_DEACT_NACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001149 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
Harald Welteaed946e2009-10-24 10:29:22 +02001150 break;
Harald Welte59b04682009-06-10 05:40:52 +08001151 case RSL_MT_PHY_CONTEXT_CONF:
1152 case RSL_MT_PREPROC_MEAS_RES:
1153 case RSL_MT_TALKER_DET:
1154 case RSL_MT_LISTENER_DET:
1155 case RSL_MT_REMOTE_CODEC_CONF_REP:
1156 case RSL_MT_MR_CODEC_MOD_ACK:
1157 case RSL_MT_MR_CODEC_MOD_NACK:
1158 case RSL_MT_MR_CODEC_MOD_PER:
Harald Weltede4477a2009-12-24 12:20:20 +01001159 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1160 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001161 break;
1162 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001163 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1164 ts_name, rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001165 return -EINVAL;
1166 }
1167
1168 return rc;
1169}
1170
1171static int rsl_rx_error_rep(struct msgb *msg)
1172{
1173 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001174 struct tlv_parsed tp;
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001175 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001176
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001177 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(sign_link->trx));
Harald Weltef1a168d2009-07-28 17:58:09 +02001178
1179 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1180
1181 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001182 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001183 TLVP_LEN(&tp, RSL_IE_CAUSE));
1184
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001185 LOGPC(DRSL, LOGL_ERROR, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001186
1187 return 0;
1188}
1189
1190static int abis_rsl_rx_trx(struct msgb *msg)
1191{
1192 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001193 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001194 int rc = 0;
1195
1196 switch (rslh->msg_type) {
1197 case RSL_MT_ERROR_REPORT:
1198 rc = rsl_rx_error_rep(msg);
1199 break;
1200 case RSL_MT_RF_RES_IND:
1201 /* interference on idle channels of TRX */
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001202 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001203 break;
1204 case RSL_MT_OVERLOAD:
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001205 /* indicate CCCH / ACCH / processor overload */
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001206 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001207 gsm_trx_name(sign_link->trx));
Harald Welte59b04682009-06-10 05:40:52 +08001208 break;
Dieter Spaar49c843e2011-07-28 00:01:50 +02001209 case 0x42: /* Nokia specific: SI End ACK */
1210 LOGP(DRSL, LOGL_INFO, "Nokia SI End ACK\n");
1211 break;
1212 case 0x43: /* Nokia specific: SI End NACK */
1213 LOGP(DRSL, LOGL_INFO, "Nokia SI End NACK\n");
1214 break;
Harald Welte59b04682009-06-10 05:40:52 +08001215 default:
Harald Welte (local)ab788cf2009-12-28 23:14:22 +01001216 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001217 "type 0x%02x\n", gsm_trx_name(sign_link->trx), rslh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001218 return -EINVAL;
1219 }
1220 return rc;
1221}
1222
Harald Welte427dbc42009-08-10 00:26:10 +02001223/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1224static void t3101_expired(void *data)
1225{
1226 struct gsm_lchan *lchan = data;
1227
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001228 rsl_rf_chan_release(lchan, 1);
Harald Welte427dbc42009-08-10 00:26:10 +02001229}
1230
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001231/* If T3111 expires, we will send the RF Channel Request */
1232static void t3111_expired(void *data)
1233{
1234 struct gsm_lchan *lchan = data;
1235
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001236 rsl_rf_chan_release(lchan, 0);
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001237}
1238
laforge50312e82010-06-21 12:08:52 +02001239#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1240
Harald Weltea00fdd72010-12-23 14:39:29 +01001241/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1242static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1243 unsigned int num_req_refs,
1244 struct gsm48_req_ref *rqd_refs,
1245 uint8_t wait_ind)
1246{
1247 uint8_t buf[GSM_MACBLOCK_LEN];
1248 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1249
1250 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1251 memset(iar, 0, sizeof(*iar));
1252 iar->proto_discr = GSM48_PDISC_RR;
1253 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1254 iar->page_mode = GSM48_PM_SAME;
1255
1256 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1257 iar->wait_ind1 = wait_ind;
1258
1259 if (num_req_refs >= 2)
1260 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1261 else
1262 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1263 iar->wait_ind2 = wait_ind;
1264
1265 if (num_req_refs >= 3)
1266 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1267 else
1268 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1269 iar->wait_ind3 = wait_ind;
1270
1271 if (num_req_refs >= 4)
1272 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1273 else
1274 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1275 iar->wait_ind4 = wait_ind;
1276
1277 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1278}
1279
Harald Welte59b04682009-06-10 05:40:52 +08001280/* MS has requested a channel on the RACH */
1281static int rsl_rx_chan_rqd(struct msgb *msg)
1282{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001283 struct e1inp_sign_link *sign_link = msg->dst;
1284 struct gsm_bts *bts = sign_link->trx->bts;
Harald Welte59b04682009-06-10 05:40:52 +08001285 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1286 struct gsm48_req_ref *rqd_ref;
Harald Welte59b04682009-06-10 05:40:52 +08001287 enum gsm_chan_t lctype;
1288 enum gsm_chreq_reason_t chreq_reason;
1289 struct gsm_lchan *lchan;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001290 uint8_t rqd_ta;
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001291 int is_lu;
Harald Welte59b04682009-06-10 05:40:52 +08001292
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001293 uint16_t arfcn;
Holger Hans Peter Freytherefd75b52012-02-03 20:10:13 +01001294 uint8_t subch;
Harald Welte59b04682009-06-10 05:40:52 +08001295
1296 /* parse request reference to be used in immediate assign */
1297 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1298 return -EINVAL;
1299
1300 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1301
1302 /* parse access delay and use as TA */
1303 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1304 return -EINVAL;
1305 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1306
1307 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1308 * request reference RA */
Holger Hans Peter Freytherf0f37f12010-09-06 09:36:02 +08001309 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1310 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001311
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001312 osmo_counter_inc(bts->network->stats.chreq.total);
Harald Welte3edc5a92009-12-22 00:41:05 +01001313
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001314 /*
1315 * We want LOCATION UPDATES to succeed and will assign a TCH
1316 * if we have no SDCCH available.
1317 */
1318 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1319
Harald Welte59b04682009-06-10 05:40:52 +08001320 /* check availability / allocate channel */
Holger Hans Peter Freytherdb392032010-09-06 08:58:42 +08001321 lchan = lchan_alloc(bts, lctype, is_lu);
Harald Welte59b04682009-06-10 05:40:52 +08001322 if (!lchan) {
Harald Welte (local)e0bb5fa2009-12-27 13:48:09 +01001323 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
Harald Welte (local)02204d02009-12-27 18:05:25 +01001324 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001325 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Harald Weltea00fdd72010-12-23 14:39:29 +01001326 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1327 if (bts->network->T3122)
1328 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
Harald Welte59b04682009-06-10 05:40:52 +08001329 return -ENOMEM;
1330 }
1331
Harald Weltec88a4432009-12-29 10:44:17 +01001332 if (lchan->state != LCHAN_S_NONE)
1333 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
Harald Welteab2534c2009-12-29 10:52:38 +01001334 "in state %s\n", gsm_lchan_name(lchan),
1335 gsm_lchans_name(lchan->state));
Harald Welte (local)c3be50c2009-12-27 18:12:29 +01001336
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001337 /* save the RACH data as we need it after the CHAN ACT ACK */
1338 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1339 if (!lchan->rqd_ref) {
1340 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1341 lchan_free(lchan);
1342 return -ENOMEM;
1343 }
1344
Holger Hans Peter Freyther161cec12011-12-29 23:33:04 +01001345 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001346 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1347 lchan->rqd_ta = rqd_ta;
1348
Harald Welte59b04682009-06-10 05:40:52 +08001349 arfcn = lchan->ts->trx->arfcn;
1350 subch = lchan->nr;
1351
Harald Welted2dd9de2009-08-30 15:37:11 +09001352 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001353 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001354 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001355 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001356 lchan->tch_mode = GSM48_CMODE_SIGN;
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001357
Harald Welte32951ea2011-08-10 23:26:33 +02001358 /* Start another timer or assume the BTS sends a ACK/NACK? */
1359 lchan->act_timer.cb = lchan_act_tmr_cb;
1360 lchan->act_timer.data = lchan;
1361 osmo_timer_schedule(&lchan->act_timer, 4, 0);
1362
Andreas Eversberg0f18e5e2011-12-16 17:45:37 +01001363 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1364 "r=%s ra=0x%02x ta=%d\n", gsm_lchan_name(lchan), arfcn, subch,
1365 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1366 rqd_ref->ra, rqd_ta);
1367
1368 /* BS11 requires TA shifted by 2 bits */
1369 if (bts->type == GSM_BTS_TYPE_BS11)
1370 rqd_ta <<= 2;
Harald Welteb90d7bd2009-12-17 00:31:10 +01001371 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001372
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001373 return 0;
1374}
1375
1376static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1377{
1378 struct gsm_bts *bts = lchan->ts->trx->bts;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001379 uint8_t buf[GSM_MACBLOCK_LEN];
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001380 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1381
Harald Welte59b04682009-06-10 05:40:52 +08001382 /* create IMMEDIATE ASSIGN 04.08 messge */
laforgee06d5982010-06-20 15:18:46 +02001383 memset(ia, 0, sizeof(*ia));
laforge50312e82010-06-21 12:08:52 +02001384 /* we set ia->l2_plen once we know the length of the MA below */
laforgee06d5982010-06-20 15:18:46 +02001385 ia->proto_discr = GSM48_PDISC_RR;
1386 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1387 ia->page_mode = GSM48_PM_SAME;
1388 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
Harald Weltea42a93f2010-06-14 22:26:10 +02001389
Harald Welte59b04682009-06-10 05:40:52 +08001390 /* use request reference extracted from CHAN_RQD */
Holger Hans Peter Freytherc08f6f02010-06-22 12:11:59 +08001391 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1392 ia->timing_advance = lchan->rqd_ta;
Harald Weltea42a93f2010-06-14 22:26:10 +02001393 if (!lchan->ts->hopping.enabled) {
laforgee06d5982010-06-20 15:18:46 +02001394 ia->mob_alloc_len = 0;
Harald Weltea42a93f2010-06-14 22:26:10 +02001395 } else {
laforgee06d5982010-06-20 15:18:46 +02001396 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1397 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
Harald Weltea42a93f2010-06-14 22:26:10 +02001398 }
Harald Welte07f32182010-06-28 18:41:27 +02001399 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1400 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
Harald Welte59b04682009-06-10 05:40:52 +08001401
Harald Welte427dbc42009-08-10 00:26:10 +02001402 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1403 lchan->T3101.cb = t3101_expired;
1404 lchan->T3101.data = lchan;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001405 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001406
1407 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001408 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Harald Welte59b04682009-06-10 05:40:52 +08001409}
1410
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001411/* current load on the CCCH */
Harald Welte59b04682009-06-10 05:40:52 +08001412static int rsl_rx_ccch_load(struct msgb *msg)
1413{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001414 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001415 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001416 struct ccch_signal_data sd;
1417
1418 sd.bts = sign_link->trx->bts;
1419 sd.rach_slot_count = -1;
1420 sd.rach_busy_count = -1;
1421 sd.rach_access_count = -1;
Harald Welte59b04682009-06-10 05:40:52 +08001422
1423 switch (rslh->data[0]) {
1424 case RSL_IE_PAGING_LOAD:
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001425 sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1426 if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == 0xffff) {
Harald Welte008a4922010-04-19 10:24:07 +02001427 /* paging load below configured threshold, use 50 as default */
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001428 sd.pg_buf_space = 50;
Harald Welte008a4922010-04-19 10:24:07 +02001429 }
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001430 paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
1431 osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001432 break;
1433 case RSL_IE_RACH_LOAD:
1434 if (msg->data_len >= 7) {
Holger Hans Peter Freyther285af692012-02-03 20:26:25 +01001435 sd.rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1436 sd.rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1437 sd.rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1438 osmo_signal_dispatch(SS_CCCH, S_CCCH_RACH_LOAD, &sd);
Harald Welte59b04682009-06-10 05:40:52 +08001439 }
1440 break;
1441 default:
1442 break;
1443 }
1444
1445 return 0;
1446}
1447
1448static int abis_rsl_rx_cchan(struct msgb *msg)
1449{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001450 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001451 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1452 int rc = 0;
1453
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001454 msg->lchan = lchan_lookup(sign_link->trx, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001455
1456 switch (rslh->c.msg_type) {
1457 case RSL_MT_CHAN_RQD:
1458 /* MS has requested a channel on the RACH */
1459 rc = rsl_rx_chan_rqd(msg);
1460 break;
1461 case RSL_MT_CCCH_LOAD_IND:
1462 /* current load on the CCCH */
1463 rc = rsl_rx_ccch_load(msg);
1464 break;
1465 case RSL_MT_DELETE_IND:
1466 /* CCCH overloaded, IMM_ASSIGN was dropped */
1467 case RSL_MT_CBCH_LOAD_IND:
1468 /* current load on the CBCH */
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001469 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1470 "type 0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001471 break;
1472 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001473 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1474 "0x%02x\n", rslh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001475 return -EINVAL;
1476 }
1477
1478 return rc;
1479}
1480
1481static int rsl_rx_rll_err_ind(struct msgb *msg)
1482{
1483 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001484 uint8_t *rlm_cause = rllh->data;
Harald Welte59b04682009-06-10 05:40:52 +08001485
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001486 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001487 gsm_lchan_name(msg->lchan),
Harald Welteb30935e2010-03-25 12:13:02 +08001488 rsl_rlm_cause_name(rlm_cause[1]));
Harald Welteed9a5ab2009-08-09 13:47:35 +02001489
1490 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte (local)bd76cce2009-12-26 23:55:00 +01001491
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001492 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
Pablo Neira Ayuso1c450742011-05-06 12:13:10 +02001493 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Holger Hans Peter Freyther10ea12f2010-05-31 21:38:24 +08001494 return rsl_rf_chan_release(msg->lchan, 1);
Holger Hans Peter Freyther27942e92010-04-17 06:48:29 +02001495 }
Harald Welte692f5852009-07-04 09:40:05 +02001496
Harald Welte59b04682009-06-10 05:40:52 +08001497 return 0;
1498}
1499
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001500static void rsl_handle_release(struct gsm_lchan *lchan)
1501{
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001502 int sapi;
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001503 struct gsm_bts *bts;
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001504
1505 /* maybe we have only brought down one RLL */
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001506 if (lchan->state != LCHAN_S_REL_REQ)
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001507 return;
1508
1509 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1510 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1511 continue;
Harald Welte497aa982010-12-24 12:51:07 +01001512 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001513 gsm_lchan_name(lchan), sapi);
1514 return;
1515 }
1516
Holger Hans Peter Freytherd26cbc82010-04-08 22:47:44 +02001517
1518
Holger Hans Peter Freyther4a00c062010-05-31 21:33:15 +08001519 /* wait a bit to send the RF Channel Release */
1520 lchan->T3111.cb = t3111_expired;
1521 lchan->T3111.data = lchan;
1522 bts = lchan->ts->trx->bts;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001523 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001524}
1525
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001526/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
Harald Welte59b04682009-06-10 05:40:52 +08001527 0x02, 0x06,
1528 0x01, 0x20,
1529 0x02, 0x00,
1530 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1531
1532static int abis_rsl_rx_rll(struct msgb *msg)
1533{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001534 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001535 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1536 int rc = 0;
1537 char *ts_name;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001538 uint8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001539
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001540 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001541 ts_name = gsm_lchan_name(msg->lchan);
Harald Weltede4477a2009-12-24 12:20:20 +01001542 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001543
1544 switch (rllh->c.msg_type) {
1545 case RSL_MT_DATA_IND:
1546 DEBUGPC(DRLL, "DATA INDICATION\n");
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001547 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001548 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1549 rllh->data[0] == RSL_IE_L3_INFO) {
1550 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001551 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001552 }
1553 break;
1554 case RSL_MT_EST_IND:
1555 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001556 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001557 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Pablo Neira Ayuso840ccf62011-05-06 12:11:06 +02001558 osmo_timer_del(&msg->lchan->T3101);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001559 if (msgb_l2len(msg) >
Harald Welte59b04682009-06-10 05:40:52 +08001560 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1561 rllh->data[0] == RSL_IE_L3_INFO) {
1562 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001563 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001564 }
1565 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001566 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001567 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001568 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001569 rll_indication(msg->lchan, rllh->link_id,
1570 BSC_RLLR_IND_EST_CONF);
1571 break;
Harald Welte59b04682009-06-10 05:40:52 +08001572 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001573 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001574 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001575 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001576 rll_indication(msg->lchan, rllh->link_id,
1577 BSC_RLLR_IND_REL_IND);
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001578 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001579 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001580 break;
1581 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001582 /* BTS informs us of having received UA from MS,
1583 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001584 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001585 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Holger Hans Peter Freyther65f08522010-04-08 22:39:34 +02001586 rsl_handle_release(msg->lchan);
Holger Hans Peter Freyther3fdf5b92010-07-29 17:09:36 +08001587 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001588 break;
1589 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001590 rc = rsl_rx_rll_err_ind(msg);
1591 break;
1592 case RSL_MT_UNIT_DATA_IND:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001593 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1594 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001595 break;
1596 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001597 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1598 "type 0x%02x\n", rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001599 }
Harald Welte59b04682009-06-10 05:40:52 +08001600 return rc;
1601}
1602
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001603static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Harald Welte98d79f92009-07-28 18:11:56 +02001604{
Harald Welteb284b472009-12-02 01:58:23 +05301605 switch (lchan->tch_mode) {
Harald Welte98d79f92009-07-28 18:11:56 +02001606 case GSM48_CMODE_SPEECH_V1:
Harald Welteb284b472009-12-02 01:58:23 +05301607 switch (lchan->type) {
1608 case GSM_LCHAN_TCH_F:
1609 return 0x00;
1610 case GSM_LCHAN_TCH_H:
1611 return 0x03;
1612 default:
1613 break;
1614 }
Harald Welte98d79f92009-07-28 18:11:56 +02001615 case GSM48_CMODE_SPEECH_EFR:
Harald Welteb284b472009-12-02 01:58:23 +05301616 switch (lchan->type) {
1617 case GSM_LCHAN_TCH_F:
1618 return 0x01;
1619 /* there's no half-rate EFR */
1620 default:
1621 break;
1622 }
Harald Welte98d79f92009-07-28 18:11:56 +02001623 case GSM48_CMODE_SPEECH_AMR:
Harald Welteb284b472009-12-02 01:58:23 +05301624 switch (lchan->type) {
1625 case GSM_LCHAN_TCH_F:
1626 return 0x02;
1627 case GSM_LCHAN_TCH_H:
1628 return 0x05;
1629 default:
1630 break;
1631 }
1632 default:
1633 break;
Harald Welte98d79f92009-07-28 18:11:56 +02001634 }
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001635 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
Harald Welteb284b472009-12-02 01:58:23 +05301636 "tch_mode == 0x%02x\n", lchan->tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001637 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001638}
1639
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001640static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Sylvain Munaut1338a552009-12-20 22:06:40 +01001641{
1642 switch (lchan->tch_mode) {
1643 case GSM48_CMODE_SPEECH_V1:
1644 switch (lchan->type) {
1645 case GSM_LCHAN_TCH_F:
1646 return RTP_PT_GSM_FULL;
1647 case GSM_LCHAN_TCH_H:
1648 return RTP_PT_GSM_HALF;
1649 default:
1650 break;
1651 }
1652 case GSM48_CMODE_SPEECH_EFR:
1653 switch (lchan->type) {
1654 case GSM_LCHAN_TCH_F:
1655 return RTP_PT_GSM_EFR;
1656 /* there's no half-rate EFR */
1657 default:
1658 break;
1659 }
1660 case GSM48_CMODE_SPEECH_AMR:
1661 switch (lchan->type) {
1662 case GSM_LCHAN_TCH_F:
Sylvain Munaut1338a552009-12-20 22:06:40 +01001663 case GSM_LCHAN_TCH_H:
Holger Hans Peter Freytherd78bee82011-07-21 10:24:46 +02001664 return RTP_PT_AMR;
Sylvain Munaut1338a552009-12-20 22:06:40 +01001665 default:
1666 break;
1667 }
1668 default:
1669 break;
1670 }
1671 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1672 "tch_mode == 0x%02x\n & lchan_type == %d",
1673 lchan->tch_mode, lchan->type);
1674 return 0;
1675}
1676
Harald Welte59b04682009-06-10 05:40:52 +08001677/* ip.access specific RSL extensions */
Harald Weltebffa4992009-12-19 16:42:06 +01001678static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1679{
1680 struct in_addr ip;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001681 uint16_t port, conn_id;
Harald Weltebffa4992009-12-19 16:42:06 +01001682
1683 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001684 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001685 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1686 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1687 }
1688
1689 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001690 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001691 port = ntohs(port);
1692 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1693 lchan->abis_ip.bound_port = port;
1694 }
1695
1696 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001697 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Harald Weltebffa4992009-12-19 16:42:06 +01001698 conn_id = ntohs(conn_id);
1699 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1700 lchan->abis_ip.conn_id = conn_id;
1701 }
1702
1703 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1704 lchan->abis_ip.rtp_payload2 =
1705 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1706 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1707 lchan->abis_ip.rtp_payload2);
1708 }
1709
1710 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1711 lchan->abis_ip.speech_mode =
1712 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1713 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1714 lchan->abis_ip.speech_mode);
1715 }
1716
1717 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001718 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Harald Weltebffa4992009-12-19 16:42:06 +01001719 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1720 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1721 }
1722
1723 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001724 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Harald Weltebffa4992009-12-19 16:42:06 +01001725 port = ntohs(port);
1726 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1727 lchan->abis_ip.connect_port = port;
1728 }
1729}
1730
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001731int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001732{
1733 struct msgb *msg = rsl_msgb_alloc();
1734 struct abis_rsl_dchan_hdr *dh;
1735
1736 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001737 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001738 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001739 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001740
Harald Welte98d79f92009-07-28 18:11:56 +02001741 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001742 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001743 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001744 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001745 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001746
Sylvain Munaut1338a552009-12-20 22:06:40 +01001747 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1748 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1749 lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001750
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001751 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001752
1753 return abis_rsl_sendmsg(msg);
1754}
1755
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001756int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1757 uint8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001758{
1759 struct msgb *msg = rsl_msgb_alloc();
1760 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001761 uint32_t *att_ip;
Harald Welte98d79f92009-07-28 18:11:56 +02001762 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001763
1764 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001765 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001766 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Harald Weltee6d51f92011-06-25 10:02:33 +02001767 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001768
Harald Weltebffa4992009-12-19 16:42:06 +01001769 /* we need to store these now as MDCX_ACK does not return them :( */
1770 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1771 lchan->abis_ip.connect_port = port;
1772 lchan->abis_ip.connect_ip = ip;
1773
Harald Weltefb4a9e92009-07-29 12:12:18 +02001774 /* 0x0- == both directions, 0x-1 == EFR codec */
Harald Weltebffa4992009-12-19 16:42:06 +01001775 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001776 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001777
Harald Welte98d79f92009-07-28 18:11:56 +02001778 ia.s_addr = htonl(ip);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001779 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1780 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1781 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1782 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001783
Harald Weltebffa4992009-12-19 16:42:06 +01001784 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1785 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001786 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Harald Weltebffa4992009-12-19 16:42:06 +01001787 *att_ip = ia.s_addr;
1788 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1789 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
Sylvain Munaut1338a552009-12-20 22:06:40 +01001790 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
Harald Welte98d79f92009-07-28 18:11:56 +02001791 if (rtp_payload2)
1792 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001793
1794 msg->dst = lchan->ts->trx->rsl_link;
Harald Welte59b04682009-06-10 05:40:52 +08001795
1796 return abis_rsl_sendmsg(msg);
1797}
1798
Harald Welte9947d9f2009-12-20 16:51:09 +01001799/* tell BTS to connect RTP stream to our local RTP socket */
1800int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1801{
1802 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1803 int rc;
1804
1805 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1806 ntohs(rs->rtp.sin_local.sin_port),
1807 /* FIXME: use RTP payload of bound socket, not BTS*/
1808 lchan->abis_ip.rtp_payload2);
1809
1810 return rc;
1811}
1812
Harald Welte6f40df02010-12-23 12:59:52 +01001813int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
Harald Welteaed946e2009-10-24 10:29:22 +02001814{
1815 struct msgb *msg = rsl_msgb_alloc();
1816 struct abis_rsl_dchan_hdr *dh;
Holger Hans Peter Freyther7eb8a9a2011-04-18 17:04:00 +02001817 uint8_t msg_type;
Harald Welte2b361522010-03-28 14:42:09 +08001818
1819 if (act)
1820 msg_type = RSL_MT_IPAC_PDCH_ACT;
1821 else
1822 msg_type = RSL_MT_IPAC_PDCH_DEACT;
Harald Welteaed946e2009-10-24 10:29:22 +02001823
1824 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Harald Welte2b361522010-03-28 14:42:09 +08001825 init_dchan_hdr(dh, msg_type);
Harald Welteaed946e2009-10-24 10:29:22 +02001826 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Weltee6d51f92011-06-25 10:02:33 +02001827 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Harald Welteaed946e2009-10-24 10:29:22 +02001828
Harald Welte6f40df02010-12-23 12:59:52 +01001829 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
Harald Welte2b361522010-03-28 14:42:09 +08001830 act ? "" : "DE");
Harald Welteaed946e2009-10-24 10:29:22 +02001831
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001832 msg->dst = ts->trx->rsl_link;
Harald Welteaed946e2009-10-24 10:29:22 +02001833
1834 return abis_rsl_sendmsg(msg);
1835}
1836
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001837static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001838{
1839 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1840 struct tlv_parsed tv;
Harald Welte87504212009-12-02 01:56:49 +05301841 struct gsm_lchan *lchan = msg->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001842
1843 /* the BTS has acknowledged a local bind, it now tells us the IP
1844 * address and port number to which it has bound the given logical
1845 * channel */
1846
1847 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1848 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1849 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001850 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001851 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
Harald Welte59b04682009-06-10 05:40:52 +08001852 return -EINVAL;
1853 }
Harald Welte50517742009-12-20 15:42:44 +01001854
Harald Weltebffa4992009-12-19 16:42:06 +01001855 ipac_parse_rtp(lchan, &tv);
Harald Welte50517742009-12-20 15:42:44 +01001856
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001857 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001858
1859 return 0;
1860}
1861
Harald Weltebffa4992009-12-19 16:42:06 +01001862static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1863{
1864 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1865 struct tlv_parsed tv;
1866 struct gsm_lchan *lchan = msg->lchan;
1867
1868 /* the BTS has acknowledged a remote connect request and
1869 * it now tells us the IP address and port number to which it has
1870 * connected the given logical channel */
1871
1872 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1873 ipac_parse_rtp(lchan, &tv);
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001874 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Harald Weltebffa4992009-12-19 16:42:06 +01001875
1876 return 0;
1877}
1878
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001879static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001880{
1881 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1882 struct tlv_parsed tv;
1883
1884 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001885
Harald Weltef1a168d2009-07-28 17:58:09 +02001886 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
Harald Weltede4477a2009-12-24 12:20:20 +01001887 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
Harald Weltef1a168d2009-07-28 17:58:09 +02001888 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001889
Pablo Neira Ayusoef717c62011-05-06 12:12:31 +02001890 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001891
Harald Welte59b04682009-06-10 05:40:52 +08001892 return 0;
1893}
1894
1895static int abis_rsl_rx_ipacc(struct msgb *msg)
1896{
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001897 struct e1inp_sign_link *sign_link = msg->dst;
Harald Welte59b04682009-06-10 05:40:52 +08001898 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltede4477a2009-12-24 12:20:20 +01001899 char *ts_name;
Harald Welte59b04682009-06-10 05:40:52 +08001900 int rc = 0;
1901
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02001902 msg->lchan = lchan_lookup(sign_link->trx, rllh->chan_nr);
Harald Welte (local)c4e9c9c2009-12-27 18:16:36 +01001903 ts_name = gsm_lchan_name(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001904
1905 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001906 case RSL_MT_IPAC_CRCX_ACK:
Harald Weltede4477a2009-12-24 12:20:20 +01001907 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001908 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001909 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001910 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001911 /* somehow the BTS was unable to bind the lchan to its local
1912 * port?!? */
Harald Weltede4477a2009-12-24 12:20:20 +01001913 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001914 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001915 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001916 /* the BTS tells us that a connect operation was successful */
Harald Weltede4477a2009-12-24 12:20:20 +01001917 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
Harald Weltebffa4992009-12-19 16:42:06 +01001918 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001919 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001920 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001921 /* somehow the BTS was unable to connect the lchan to a remote
1922 * port */
Harald Weltede4477a2009-12-24 12:20:20 +01001923 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
Harald Welte59b04682009-06-10 05:40:52 +08001924 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001925 case RSL_MT_IPAC_DLCX_IND:
Harald Weltede4477a2009-12-24 12:20:20 +01001926 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001927 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001928 break;
1929 default:
Harald Weltede4477a2009-12-24 12:20:20 +01001930 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001931 rllh->c.msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001932 break;
1933 }
1934 DEBUGPC(DRSL, "\n");
1935
1936 return rc;
1937}
1938
1939
1940/* Entry-point where L2 RSL from BTS enters */
1941int abis_rsl_rcvmsg(struct msgb *msg)
1942{
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001943 struct abis_rsl_common_hdr *rslh;
Harald Welte59b04682009-06-10 05:40:52 +08001944 int rc = 0;
1945
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001946 if (!msg) {
1947 DEBUGP(DRSL, "Empty RSL msg?..\n");
1948 return -1;
1949 }
1950
1951 if (msgb_l2len(msg) < sizeof(*rslh)) {
1952 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
Harald Weltece807262012-05-31 20:22:34 +02001953 msgb_free(msg);
Holger Hans Peter Freytherc7d94092009-11-20 15:14:01 +01001954 return -1;
1955 }
1956
1957 rslh = msgb_l2(msg);
1958
Harald Welte59b04682009-06-10 05:40:52 +08001959 switch (rslh->msg_discr & 0xfe) {
1960 case ABIS_RSL_MDISC_RLL:
1961 rc = abis_rsl_rx_rll(msg);
1962 break;
1963 case ABIS_RSL_MDISC_DED_CHAN:
1964 rc = abis_rsl_rx_dchan(msg);
1965 break;
1966 case ABIS_RSL_MDISC_COM_CHAN:
1967 rc = abis_rsl_rx_cchan(msg);
1968 break;
1969 case ABIS_RSL_MDISC_TRX:
1970 rc = abis_rsl_rx_trx(msg);
1971 break;
1972 case ABIS_RSL_MDISC_LOC:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001973 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001974 rslh->msg_discr);
1975 break;
1976 case ABIS_RSL_MDISC_IPACCESS:
1977 rc = abis_rsl_rx_ipacc(msg);
1978 break;
1979 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +01001980 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1981 "0x%02x\n", rslh->msg_discr);
Harald Weltece807262012-05-31 20:22:34 +02001982 rc = -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08001983 }
1984 msgb_free(msg);
1985 return rc;
1986}
1987
Holger Hans Peter Freytherb67f4082010-07-21 15:54:32 +08001988int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1989 uint8_t cb_command, const uint8_t *data, int len)
1990{
1991 struct abis_rsl_dchan_hdr *dh;
1992 struct msgb *cb_cmd;
1993
1994 cb_cmd = rsl_msgb_alloc();
1995 if (!cb_cmd)
1996 return -1;
1997
1998 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1999 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
2000 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
2001
2002 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
2003 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
2004
2005 cb_cmd->trx = bts->c0;
2006
2007 return abis_rsl_sendmsg(cb_cmd);
2008}
Dieter Spaar49c843e2011-07-28 00:01:50 +02002009
2010int rsl_nokia_si_begin(struct gsm_bts_trx *trx)
2011{
2012 struct abis_rsl_common_hdr *ch;
2013 struct msgb *msg = rsl_msgb_alloc();
2014
2015 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2016 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2017 ch->msg_type = 0x40; /* Nokia SI Begin */
2018
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002019 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002020
2021 return abis_rsl_sendmsg(msg);
2022}
2023
2024int rsl_nokia_si_end(struct gsm_bts_trx *trx)
2025{
2026 struct abis_rsl_common_hdr *ch;
2027 struct msgb *msg = rsl_msgb_alloc();
2028
2029 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2030 ch->msg_discr = ABIS_RSL_MDISC_TRX;
2031 ch->msg_type = 0x41; /* Nokia SI End */
2032
2033 msgb_tv_put(msg, 0xFD, 0x00); /* Nokia Pagemode Info, No paging reorganisation required */
2034
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002035 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002036
2037 return abis_rsl_sendmsg(msg);
2038}
2039
2040int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction)
2041{
2042 struct abis_rsl_common_hdr *ch;
2043 struct msgb *msg = rsl_msgb_alloc();
2044
2045 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
2046 ch->msg_discr = ABIS_RSL_MDISC_DED_CHAN;
2047 ch->msg_type = RSL_MT_BS_POWER_CONTROL;
2048
2049 msgb_tv_put(msg, RSL_IE_CHAN_NR, channel);
2050 msgb_tv_put(msg, RSL_IE_BS_POWER, reduction); /* reduction in 2dB steps */
2051
Pablo Neira Ayuso88c9bba2011-08-17 22:43:54 +02002052 msg->dst = trx->rsl_link;
Dieter Spaar49c843e2011-07-28 00:01:50 +02002053
2054 return abis_rsl_sendmsg(msg);
2055}