blob: 8356bd9a580e2c714414fbbba8339382ad4e0452 [file] [log] [blame]
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001/* GSM Radio Signalling Link messages on the A-bis interface
2 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
4/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * 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
11 * (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
16 * GNU Affero General Public License for more details.
17 *
18 * 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/>.
20 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <errno.h>
Jonathan Santos03fd8d02011-05-25 13:54:02 -040026#include <netinet/in.h>
27#include <arpa/inet.h>
28
29#include <openbsc/gsm_data.h>
30#include <openbsc/gsm_04_08.h>
Jonathan Santos5a45b152011-08-17 15:33:57 -040031#include <osmocom/gsm/gsm_utils.h>
Jonathan Santos03fd8d02011-05-25 13:54:02 -040032#include <openbsc/abis_rsl.h>
33#include <openbsc/chan_alloc.h>
34#include <openbsc/bsc_rll.h>
35#include <openbsc/debug.h>
Jonathan Santos5a45b152011-08-17 15:33:57 -040036#include <osmocom/gsm/tlv.h>
Jonathan Santos03fd8d02011-05-25 13:54:02 -040037#include <openbsc/paging.h>
38#include <openbsc/signal.h>
39#include <openbsc/meas_rep.h>
40#include <openbsc/rtp_proxy.h>
Jonathan Santos5a45b152011-08-17 15:33:57 -040041#include <osmocom/gsm/rsl.h>
Jonathan Santos03fd8d02011-05-25 13:54:02 -040042
Jonathan Santos5a45b152011-08-17 15:33:57 -040043#include <osmocom/core/talloc.h>
Jonathan Santos03fd8d02011-05-25 13:54:02 -040044
45#define RSL_ALLOC_SIZE 1024
46#define RSL_ALLOC_HEADROOM 128
47
Jonathan Santos03fd8d02011-05-25 13:54:02 -040048static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
49
50static 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;
Jonathan Santos5a45b152011-08-17 15:33:57 -040056 osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
Jonathan Santos03fd8d02011-05-25 13:54:02 -040057}
58
Jonathan Santos5a45b152011-08-17 15:33:57 -040059static uint8_t mdisc_by_msgtype(uint8_t msg_type)
Jonathan Santos03fd8d02011-05-25 13:54:02 -040060{
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,
Jonathan Santos5a45b152011-08-17 15:33:57 -040079 uint8_t msg_type)
Jonathan Santos03fd8d02011-05-25 13:54:02 -040080{
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
86/* determine logical channel based on TRX and channel number IE */
Jonathan Santos5a45b152011-08-17 15:33:57 -040087struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr)
Jonathan Santos03fd8d02011-05-25 13:54:02 -040088{
89 struct gsm_lchan *lchan;
Jonathan Santos5a45b152011-08-17 15:33:57 -040090 uint8_t ts_nr = chan_nr & 0x07;
91 uint8_t cbits = chan_nr >> 3;
92 uint8_t lch_idx;
Jonathan Santos03fd8d02011-05-25 13:54:02 -040093 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
94
95 if (cbits == 0x01) {
96 lch_idx = 0; /* TCH/F */
97 if (ts->pchan != GSM_PCHAN_TCH_F &&
98 ts->pchan != GSM_PCHAN_PDCH &&
99 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
100 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
101 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)
105 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
106 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)
110 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
111 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)
115 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
116 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)
121 LOGP(DRSL, LOGL_ERROR, "chan_nr=0x%02x but pchan=%u\n",
122 chan_nr, ts->pchan);
123 /* FIXME: we should not return first sdcch4 !!! */
124 } else {
125 LOGP(DRSL, LOGL_ERROR, "unknown chan_nr=0x%02x\n", chan_nr);
126 return NULL;
127 }
128
129 lchan = &ts->lchan[lch_idx];
130 log_set_context(BSC_CTX_LCHAN, lchan);
131 if (lchan->conn)
132 log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
133
134 return lchan;
135}
136
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400137/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400138uint64_t str_to_imsi(const char *imsi_str)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400139{
Jonathan Santos5a45b152011-08-17 15:33:57 -0400140 uint64_t ret;
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400141
142 ret = strtoull(imsi_str, NULL, 10);
143
144 return ret;
145}
146
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400147static struct msgb *rsl_msgb_alloc(void)
148{
149 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
150 "RSL");
151}
152
153#define MACBLOCK_SIZE 23
Jonathan Santos5a45b152011-08-17 15:33:57 -0400154static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400155{
156 memcpy(out, in, len);
157
158 if (len < MACBLOCK_SIZE)
159 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
160}
161
162/* Chapter 9.3.7: Encryption Information */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400163static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400164{
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
Jonathan Santos5a45b152011-08-17 15:33:57 -0400171static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400172{
173 int i;
174
175 LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
176 cause_v[0], rsl_err_name(cause_v[0]));
177 for (i = 1; i < cause_len-1; i++)
178 LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
179}
180
181/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400182int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
183 const uint8_t *data, int len)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400184{
185 struct abis_rsl_dchan_hdr *dh;
186 struct msgb *msg = rsl_msgb_alloc();
187
188 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
189 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
190 dh->chan_nr = RSL_CHAN_BCCH;
191
192 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
193 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
194
195 msg->trx = trx;
196
197 return abis_rsl_sendmsg(msg);
198}
199
Jonathan Santos5a45b152011-08-17 15:33:57 -0400200int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
201 const uint8_t *data, int len)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400202{
203 struct abis_rsl_common_hdr *ch;
204 struct msgb *msg = rsl_msgb_alloc();
205
206 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
207 ch->msg_discr = ABIS_RSL_MDISC_TRX;
208 ch->msg_type = RSL_MT_SACCH_FILL;
209
210 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
211 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
212
213 msg->trx = trx;
214
215 return abis_rsl_sendmsg(msg);
216}
217
Jonathan Santos5a45b152011-08-17 15:33:57 -0400218int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
219 const uint8_t *data, int len)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400220{
221 struct abis_rsl_dchan_hdr *dh;
222 struct msgb *msg = rsl_msgb_alloc();
Jonathan Santos5a45b152011-08-17 15:33:57 -0400223 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400224
225 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
226 init_dchan_hdr(dh, RSL_MT_SACCH_INFO_MODIFY);
227 dh->chan_nr = chan_nr;
228
229 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
230 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
231
232 msg->trx = lchan->ts->trx;
233
234 return abis_rsl_sendmsg(msg);
235}
236
237int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
238{
239 struct abis_rsl_dchan_hdr *dh;
240 struct msgb *msg;
Jonathan Santos5a45b152011-08-17 15:33:57 -0400241 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400242
243 db = abs(db);
244 if (db > 30)
245 return -EINVAL;
246
247 msg = rsl_msgb_alloc();
248
249 lchan->bs_power = db/2;
250 if (fpc)
251 lchan->bs_power |= 0x10;
252
253 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
254 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
255 dh->chan_nr = chan_nr;
256
257 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
258
259 msg->trx = lchan->ts->trx;
260
261 return abis_rsl_sendmsg(msg);
262}
263
264int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
265{
266 struct abis_rsl_dchan_hdr *dh;
267 struct msgb *msg;
Jonathan Santos5a45b152011-08-17 15:33:57 -0400268 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400269 int ctl_lvl;
270
271 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
272 if (ctl_lvl < 0)
273 return ctl_lvl;
274
275 msg = rsl_msgb_alloc();
276
277 lchan->ms_power = ctl_lvl;
278
279 if (fpc)
280 lchan->ms_power |= 0x20;
281
282 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
283 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
284 dh->chan_nr = chan_nr;
285
286 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
287
288 msg->trx = lchan->ts->trx;
289
290 return abis_rsl_sendmsg(msg);
291}
292
293static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
294 struct gsm_lchan *lchan)
295{
296 memset(cm, 0, sizeof(cm));
297
298 /* FIXME: what to do with data calls ? */
299 if (lchan->ts->trx->bts->network->dtx_enabled)
300 cm->dtx_dtu = 0x03;
301 else
302 cm->dtx_dtu = 0x00;
303
304 /* set TCH Speech/Data */
305 cm->spd_ind = lchan->rsl_cmode;
306
307 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
308 lchan->tch_mode != GSM48_CMODE_SIGN)
309 LOGP(DRSL, LOGL_ERROR, "unsupported: rsl_mode == signalling, "
310 "but tch_mode != signalling\n");
311
312 switch (lchan->type) {
313 case GSM_LCHAN_SDCCH:
314 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
315 break;
316 case GSM_LCHAN_TCH_F:
317 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
318 break;
319 case GSM_LCHAN_TCH_H:
320 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
321 break;
322 case GSM_LCHAN_NONE:
323 case GSM_LCHAN_UNKNOWN:
324 default:
325 return -EINVAL;
326 }
327
328 switch (lchan->tch_mode) {
329 case GSM48_CMODE_SIGN:
330 cm->chan_rate = 0;
331 break;
332 case GSM48_CMODE_SPEECH_V1:
333 cm->chan_rate = RSL_CMOD_SP_GSM1;
334 break;
335 case GSM48_CMODE_SPEECH_EFR:
336 cm->chan_rate = RSL_CMOD_SP_GSM2;
337 break;
338 case GSM48_CMODE_SPEECH_AMR:
339 cm->chan_rate = RSL_CMOD_SP_GSM3;
340 break;
341 case GSM48_CMODE_DATA_14k5:
342 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
343 break;
344 case GSM48_CMODE_DATA_12k0:
345 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
346 break;
347 case GSM48_CMODE_DATA_6k0:
348 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
349 break;
350 default:
351 return -EINVAL;
352 }
353
354 return 0;
355}
356
357/* Chapter 8.4.1 */
358#if 0
Jonathan Santos5a45b152011-08-17 15:33:57 -0400359int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
360 uint8_t act_type,
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400361 struct rsl_ie_chan_mode *chan_mode,
362 struct rsl_ie_chan_ident *chan_ident,
Jonathan Santos5a45b152011-08-17 15:33:57 -0400363 uint8_t bs_power, uint8_t ms_power,
364 uint8_t ta)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400365{
366 struct abis_rsl_dchan_hdr *dh;
367 struct msgb *msg = rsl_msgb_alloc();
368
369 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
370 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
371 dh->chan_nr = chan_nr;
372
373 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
374 /* For compatibility with Phase 1 */
375 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
Jonathan Santos5a45b152011-08-17 15:33:57 -0400376 (uint8_t *) chan_mode);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400377 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Jonathan Santos5a45b152011-08-17 15:33:57 -0400378 (uint8_t *) chan_ident);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400379#if 0
380 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
Jonathan Santos5a45b152011-08-17 15:33:57 -0400381 (uint8_t *) &encr_info);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400382#endif
383 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
384 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
385 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
386
387 msg->trx = trx;
388
389 return abis_rsl_sendmsg(msg);
390}
391#endif
392
Jonathan Santos5a45b152011-08-17 15:33:57 -0400393int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
394 uint8_t ta, uint8_t ho_ref)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400395{
396 struct abis_rsl_dchan_hdr *dh;
397 struct msgb *msg;
398 int rc;
399 uint8_t *len;
400
Jonathan Santos5a45b152011-08-17 15:33:57 -0400401 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400402 struct rsl_ie_chan_mode cm;
403 struct gsm48_chan_desc cd;
404
405 rc = channel_mode_from_lchan(&cm, lchan);
406 if (rc < 0)
407 return rc;
408
409 memset(&cd, 0, sizeof(cd));
410 gsm48_lchan2chan_desc(&cd, lchan);
411
412 msg = rsl_msgb_alloc();
413 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
414 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
415 dh->chan_nr = chan_nr;
416
417 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
418 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Jonathan Santos5a45b152011-08-17 15:33:57 -0400419 (uint8_t *) &cm);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400420
421 /*
422 * The Channel Identification is needed for Phase1 phones
423 * and it contains the GSM48 Channel Description and the
424 * Mobile Allocation. The GSM 08.58 asks for the Mobile
425 * Allocation to have a length of zero. We are using the
426 * msgb_l3len to calculate the length of both messages.
427 */
428 msgb_v_put(msg, RSL_IE_CHAN_IDENT);
429 len = msgb_put(msg, 1);
430 msgb_tlv_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
431
432 if (lchan->ts->hopping.enabled)
433 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,
434 lchan->ts->hopping.ma_data);
435 else
436 msgb_tlv_put(msg, GSM48_IE_MA_AFTER, 0, NULL);
437
438 /* update the calculated size */
439 msg->l3h = len + 1;
440 *len = msgb_l3len(msg);
441
442 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -0400443 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400444 rc = build_encr_info(encr_info, lchan);
445 if (rc > 0)
446 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
447 }
448
449 switch (act_type) {
450 case RSL_ACT_INTER_ASYNC:
451 case RSL_ACT_INTER_SYNC:
452 msgb_tv_put(msg, RSL_IE_HANDO_REF, ho_ref);
453 break;
454 default:
455 break;
456 }
457
458 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
459 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
460 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
461
462 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
463 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Jonathan Santos5a45b152011-08-17 15:33:57 -0400464 (uint8_t *) &lchan->mr_conf);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400465
466 msg->trx = lchan->ts->trx;
467
468 return abis_rsl_sendmsg(msg);
469}
470
471/* Chapter 8.4.9: Modify channel mode on BTS side */
472int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
473{
474 struct abis_rsl_dchan_hdr *dh;
475 struct msgb *msg;
476 int rc;
477
Jonathan Santos5a45b152011-08-17 15:33:57 -0400478 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400479 struct rsl_ie_chan_mode cm;
480
481 rc = channel_mode_from_lchan(&cm, lchan);
482 if (rc < 0)
483 return rc;
484
485 msg = rsl_msgb_alloc();
486 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
487 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
488 dh->chan_nr = chan_nr;
489
490 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
Jonathan Santos5a45b152011-08-17 15:33:57 -0400491 (uint8_t *) &cm);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400492
493 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -0400494 uint8_t encr_info[MAX_A5_KEY_LEN+2];
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400495 rc = build_encr_info(encr_info, lchan);
496 if (rc > 0)
497 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
498 }
499
500 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
501 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
Jonathan Santos5a45b152011-08-17 15:33:57 -0400502 (uint8_t *) &lchan->mr_conf);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400503 }
504
505 msg->trx = lchan->ts->trx;
506
507 return abis_rsl_sendmsg(msg);
508}
509
510/* Chapter 8.4.6: Send the encryption command with given L3 info */
511int rsl_encryption_cmd(struct msgb *msg)
512{
513 struct abis_rsl_dchan_hdr *dh;
514 struct gsm_lchan *lchan = msg->lchan;
Jonathan Santos5a45b152011-08-17 15:33:57 -0400515 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
516 uint8_t encr_info[MAX_A5_KEY_LEN+2];
517 uint8_t l3_len = msg->len;
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400518 int rc;
519
520 /* First push the L3 IE tag and length */
521 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
522
523 /* then the link identifier (SAPI0, main sign link) */
524 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
525
526 /* then encryption information */
527 rc = build_encr_info(encr_info, lchan);
528 if (rc <= 0)
529 return rc;
530 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
531
532 /* and finally the DCHAN header */
533 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
534 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
535 dh->chan_nr = chan_nr;
536
537 msg->trx = lchan->ts->trx;
538
539 return abis_rsl_sendmsg(msg);
540}
541
542/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
543int rsl_deact_sacch(struct gsm_lchan *lchan)
544{
545 struct abis_rsl_dchan_hdr *dh;
546 struct msgb *msg = rsl_msgb_alloc();
547
548 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
549 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
Jonathan Santos5a45b152011-08-17 15:33:57 -0400550 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400551
552 msg->lchan = lchan;
553 msg->trx = lchan->ts->trx;
554
555 DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
556
557 return abis_rsl_sendmsg(msg);
558}
559
560static void error_timeout_cb(void *data)
561{
562 struct gsm_lchan *lchan = data;
563 if (lchan->state != LCHAN_S_REL_ERR) {
564 LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
565 gsm_lchan_name(lchan), lchan->state);
566 return;
567 }
568
569 /* go back to the none state */
570 LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
571 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
572}
573
574static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
575
576/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
577static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
578{
579 struct abis_rsl_dchan_hdr *dh;
580 struct msgb *msg;
581 int rc;
582
583 if (lchan->state == LCHAN_S_REL_ERR) {
584 LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
585 gsm_lchan_name(lchan));
586 return -1;
587 }
588
589 msg = rsl_msgb_alloc();
590 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
591 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Jonathan Santos5a45b152011-08-17 15:33:57 -0400592 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400593
594 msg->lchan = lchan;
595 msg->trx = lchan->ts->trx;
596
597 DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
598
599 if (error) {
600 /*
601 * the nanoBTS sends RLL release indications after the channel release. This can
602 * be a problem when we have reassigned the channel to someone else and then can
603 * not figure out who used this channel.
604 */
605 rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
606 lchan->error_timer.data = lchan;
607 lchan->error_timer.cb = error_timeout_cb;
Jonathan Santos5a45b152011-08-17 15:33:57 -0400608 osmo_timer_schedule(&lchan->error_timer,
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400609 msg->trx->bts->network->T3111 + 2, 0);
610 }
611
612 rc = abis_rsl_sendmsg(msg);
613
614 /* BTS will respond by RF CHAN REL ACK */
615#ifdef HSL_SR_1_0
616 /* The HSL Femto seems to 'forget' sending a REL ACK for TS1...TS7 */
617 if (lchan->ts->trx->bts->type == GSM_BTS_TYPE_HSL_FEMTO && lchan->ts->nr != 0)
618 rc = rsl_rx_rf_chan_rel_ack(lchan);
619#endif
620
621 return rc;
622}
623
624static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
625{
626
627 DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
628
629 if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
630 LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
631 gsm_lchan_name(lchan),
632 gsm_lchans_name(lchan->state));
Jonathan Santos5a45b152011-08-17 15:33:57 -0400633 osmo_timer_del(&lchan->T3111);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400634 /* we have an error timer pending to release that */
635 if (lchan->state != LCHAN_S_REL_ERR)
636 rsl_lchan_set_state(lchan, LCHAN_S_NONE);
637 lchan_free(lchan);
638
639 return 0;
640}
641
Jonathan Santos5a45b152011-08-17 15:33:57 -0400642int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
643 uint8_t *ms_ident, uint8_t chan_needed)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400644{
645 struct abis_rsl_dchan_hdr *dh;
646 struct msgb *msg = rsl_msgb_alloc();
647
648 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
649 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
650 dh->chan_nr = RSL_CHAN_PCH_AGCH;
651
652 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
653 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
654 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
655
656 msg->trx = bts->c0;
657
658 return abis_rsl_sendmsg(msg);
659}
660
Jonathan Santos5a45b152011-08-17 15:33:57 -0400661int imsi_str2bcd(uint8_t *bcd_out, const char *str_in)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400662{
663 int i, len = strlen(str_in);
664
665 for (i = 0; i < len; i++) {
666 int num = str_in[i] - 0x30;
667 if (num < 0 || num > 9)
668 return -1;
669 if (i % 2 == 0)
670 bcd_out[i/2] = num;
671 else
672 bcd_out[i/2] |= (num << 4);
673 }
674
675 return 0;
676}
677
678/* Chapter 8.5.6 */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400679int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400680{
681 struct msgb *msg = rsl_msgb_alloc();
682 struct abis_rsl_dchan_hdr *dh;
Jonathan Santos5a45b152011-08-17 15:33:57 -0400683 uint8_t buf[MACBLOCK_SIZE];
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400684
685 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
686 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
687 dh->chan_nr = RSL_CHAN_PCH_AGCH;
688
689 switch (bts->type) {
690 case GSM_BTS_TYPE_BS11:
691 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
692 break;
693 default:
694 /* If phase 2, construct a FULL_IMM_ASS_INFO */
695 pad_macblock(buf, val, len);
696 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
697 break;
698 }
699
700 msg->trx = bts->c0;
701
702 return abis_rsl_sendmsg(msg);
703}
704
705/* Send Siemens specific MS RF Power Capability Indication */
706int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
707{
708 struct msgb *msg = rsl_msgb_alloc();
709 struct abis_rsl_dchan_hdr *dh;
710
711 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
712 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
713 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Jonathan Santos5a45b152011-08-17 15:33:57 -0400714 dh->chan_nr = gsm_lchan2chan_nr(lchan);
715 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(uint8_t *)mrpci);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400716
717 DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
Jonathan Santos5a45b152011-08-17 15:33:57 -0400718 gsm_lchan_name(lchan), *(uint8_t *)mrpci);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400719
720 msg->trx = lchan->ts->trx;
721
722 return abis_rsl_sendmsg(msg);
723}
724
725
726/* Send "DATA REQUEST" message with given L3 Info payload */
727/* Chapter 8.3.1 */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400728int rsl_data_request(struct msgb *msg, uint8_t link_id)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400729{
730 if (msg->lchan == NULL) {
731 LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
732 return -EINVAL;
733 }
734
Jonathan Santos5a45b152011-08-17 15:33:57 -0400735 rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, gsm_lchan2chan_nr(msg->lchan),
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400736 link_id, 1);
737
738 msg->trx = msg->lchan->ts->trx;
739
740 return abis_rsl_sendmsg(msg);
741}
742
743/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
744/* Chapter 8.3.1 */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400745int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400746{
747 struct msgb *msg;
748
Jonathan Santos5a45b152011-08-17 15:33:57 -0400749 msg = rsl_rll_simple(RSL_MT_EST_REQ, gsm_lchan2chan_nr(lchan),
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400750 link_id, 0);
751 msg->trx = lchan->ts->trx;
752
753 return abis_rsl_sendmsg(msg);
754}
755
756/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
757 This is what higher layers should call. The BTS then responds with
758 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
759 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
760 lchan_free() */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400761int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason)
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400762{
763
764 struct msgb *msg;
765
Jonathan Santos5a45b152011-08-17 15:33:57 -0400766 msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400767 link_id, 0);
768 /* 0 is normal release, 1 is local end */
769 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
770
771 /* FIXME: start some timer in case we don't receive a REL ACK ? */
772
773 msg->trx = lchan->ts->trx;
774
775 return abis_rsl_sendmsg(msg);
776}
777
778int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
779{
780 lchan->state = state;
781 return 0;
782}
783
784/* Chapter 8.4.2: Channel Activate Acknowledge */
785static int rsl_rx_chan_act_ack(struct msgb *msg)
786{
787 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
788
789 /* BTS has confirmed channel activation, we now need
790 * to assign the activated channel to the MS */
791 if (rslh->ie_chan != RSL_IE_CHAN_NR)
792 return -EINVAL;
793
794 if (msg->lchan->state != LCHAN_S_ACT_REQ)
795 LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
796 gsm_lchan_name(msg->lchan),
797 gsm_lchans_name(msg->lchan->state));
798 rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
799
800 if (msg->lchan->rqd_ref) {
801 rsl_send_imm_assignment(msg->lchan);
802 talloc_free(msg->lchan->rqd_ref);
803 msg->lchan->rqd_ref = NULL;
804 msg->lchan->rqd_ta = 0;
805 }
806
807 send_lchan_signal(S_LCHAN_ACTIVATE_ACK, msg->lchan, NULL);
808
809 return 0;
810}
811
812/* Chapter 8.4.3: Channel Activate NACK */
813static int rsl_rx_chan_act_nack(struct msgb *msg)
814{
815 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
816 struct tlv_parsed tp;
817
818 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
819 gsm_lchan_name(msg->lchan));
820
821 /* BTS has rejected channel activation ?!? */
822 if (dh->ie_chan != RSL_IE_CHAN_NR)
823 return -EINVAL;
824
825 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
826 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -0400827 const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400828 print_rsl_cause(LOGL_ERROR, cause,
829 TLVP_LEN(&tp, RSL_IE_CAUSE));
830 if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
831 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
832 } else
833 rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
834
835 LOGPC(DRSL, LOGL_ERROR, "\n");
836
837 send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
838
839 lchan_free(msg->lchan);
840 return 0;
841}
842
843/* Chapter 8.4.4: Connection Failure Indication */
844static int rsl_rx_conn_fail(struct msgb *msg)
845{
846 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
847 struct tlv_parsed tp;
848
849 /* FIXME: print which channel */
850 LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
851 gsm_lchan_name(msg->lchan));
852
853 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
854
855 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
856 print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
857 TLVP_LEN(&tp, RSL_IE_CAUSE));
858
859 LOGPC(DRSL, LOGL_NOTICE, "\n");
860 /* FIXME: only free it after channel release ACK */
Jonathan Santos5a45b152011-08-17 15:33:57 -0400861 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400862 return rsl_rf_chan_release(msg->lchan, 1);
863}
864
865static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
866 const char *prefix)
867{
868 DEBUGPC(DMEAS, "RXL-FULL-%s=%3ddBm RXL-SUB-%s=%3ddBm ",
869 prefix, rxlev2dbm(mru->full.rx_lev),
870 prefix, rxlev2dbm(mru->sub.rx_lev));
871 DEBUGPC(DMEAS, "RXQ-FULL-%s=%d RXQ-SUB-%s=%d ",
872 prefix, mru->full.rx_qual, prefix, mru->sub.rx_qual);
873}
874
875static void print_meas_rep(struct gsm_meas_rep *mr)
876{
877 int i;
878
879 DEBUGP(DMEAS, "MEASUREMENT RESULT NR=%d ", mr->nr);
880
881 if (mr->flags & MEAS_REP_F_DL_DTX)
882 DEBUGPC(DMEAS, "DTXd ");
883
884 print_meas_rep_uni(&mr->ul, "ul");
885 DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power);
886 if (mr->flags & MEAS_REP_F_MS_TO)
887 DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset);
888
889 if (mr->flags & MEAS_REP_F_MS_L1) {
890 DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr);
891 DEBUGPC(DMEAS, "L1_FPC=%u ",
892 mr->flags & MEAS_REP_F_FPC ? 1 : 0);
893 DEBUGPC(DMEAS, "L1_TA=%u ", mr->ms_l1.ta);
894 }
895
896 if (mr->flags & MEAS_REP_F_UL_DTX)
897 DEBUGPC(DMEAS, "DTXu ");
898 if (mr->flags & MEAS_REP_F_BA1)
899 DEBUGPC(DMEAS, "BA1 ");
900 if (!(mr->flags & MEAS_REP_F_DL_VALID))
901 DEBUGPC(DMEAS, "NOT VALID ");
902 else
903 print_meas_rep_uni(&mr->dl, "dl");
904
905 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", mr->num_cell);
906 if (mr->num_cell == 7)
907 return;
908 for (i = 0; i < mr->num_cell; i++) {
909 struct gsm_meas_rep_cell *mrc = &mr->cell[i];
910 DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
911 mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
912 }
913}
914
915static int rsl_rx_meas_res(struct msgb *msg)
916{
917 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
918 struct tlv_parsed tp;
919 struct gsm_meas_rep *mr = lchan_next_meas_rep(msg->lchan);
Jonathan Santos5a45b152011-08-17 15:33:57 -0400920 uint8_t len;
921 const uint8_t *val;
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400922 int rc;
923
924 /* check if this channel is actually active */
925 /* FIXME: maybe this check should be way more generic/centralized */
926 if (msg->lchan->state != LCHAN_S_ACTIVE) {
927 LOGP(DRSL, LOGL_DEBUG, "%s: MEAS RES for inactive channel\n",
928 gsm_lchan_name(msg->lchan));
929 return 0;
930 }
931
932 memset(mr, 0, sizeof(*mr));
933 mr->lchan = msg->lchan;
934
935 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
936
937 if (!TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR) ||
938 !TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS) ||
939 !TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
940 return -EIO;
941
942 /* Mandatory Parts */
943 mr->nr = *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR);
944
945 len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
946 val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
947 if (len >= 3) {
948 if (val[0] & 0x40)
949 mr->flags |= MEAS_REP_F_DL_DTX;
950 mr->ul.full.rx_lev = val[0] & 0x3f;
951 mr->ul.sub.rx_lev = val[1] & 0x3f;
952 mr->ul.full.rx_qual = val[2]>>3 & 0x7;
953 mr->ul.sub.rx_qual = val[2] & 0x7;
954 }
955
956 mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER);
957
958 /* Optional Parts */
959 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
960 mr->ms_timing_offset =
961 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET);
962
963 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
964 val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
965 mr->flags |= MEAS_REP_F_MS_L1;
966 mr->ms_l1.pwr = ms_pwr_dbm(msg->trx->bts->band, val[0] >> 3);
967 if (val[0] & 0x04)
968 mr->flags |= MEAS_REP_F_FPC;
969 mr->ms_l1.ta = val[1];
970 }
971 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -0400972 msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Jonathan Santos03fd8d02011-05-25 13:54:02 -0400973 rc = gsm48_parse_meas_rep(mr, msg);
974 if (rc < 0)
975 return rc;
976 }
977
978 print_meas_rep(mr);
979
980 send_lchan_signal(S_LCHAN_MEAS_REP, msg->lchan, mr);
981
982 return 0;
983}
984
985/* Chapter 8.4.7 */
986static int rsl_rx_hando_det(struct msgb *msg)
987{
988 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
989 struct tlv_parsed tp;
990
991 DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
992
993 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
994
995 if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
996 DEBUGPC(DRSL, "access delay = %u\n",
997 *TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
998 else
999 DEBUGPC(DRSL, "\n");
1000
1001 send_lchan_signal(S_LCHAN_HANDOVER_DETECT, msg->lchan, NULL);
1002
1003 return 0;
1004}
1005
1006static int abis_rsl_rx_dchan(struct msgb *msg)
1007{
1008 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1009 int rc = 0;
1010 char *ts_name;
1011
1012 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1013 ts_name = gsm_lchan_name(msg->lchan);
1014
1015 switch (rslh->c.msg_type) {
1016 case RSL_MT_CHAN_ACTIV_ACK:
1017 DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
1018 rc = rsl_rx_chan_act_ack(msg);
1019 break;
1020 case RSL_MT_CHAN_ACTIV_NACK:
1021 rc = rsl_rx_chan_act_nack(msg);
1022 break;
1023 case RSL_MT_CONN_FAIL:
1024 rc = rsl_rx_conn_fail(msg);
1025 break;
1026 case RSL_MT_MEAS_RES:
1027 rc = rsl_rx_meas_res(msg);
1028 break;
1029 case RSL_MT_HANDO_DET:
1030 rc = rsl_rx_hando_det(msg);
1031 break;
1032 case RSL_MT_RF_CHAN_REL_ACK:
1033 rc = rsl_rx_rf_chan_rel_ack(msg->lchan);
1034 break;
1035 case RSL_MT_MODE_MODIFY_ACK:
1036 DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
1037 break;
1038 case RSL_MT_MODE_MODIFY_NACK:
1039 LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
1040 break;
1041 case RSL_MT_IPAC_PDCH_ACT_ACK:
1042 DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
1043 msg->lchan->ts->flags |= TS_F_PDCH_MODE;
1044 break;
1045 case RSL_MT_IPAC_PDCH_ACT_NACK:
1046 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
1047 break;
1048 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1049 DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
1050 msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
1051 break;
1052 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1053 LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
1054 break;
1055 case RSL_MT_PHY_CONTEXT_CONF:
1056 case RSL_MT_PREPROC_MEAS_RES:
1057 case RSL_MT_TALKER_DET:
1058 case RSL_MT_LISTENER_DET:
1059 case RSL_MT_REMOTE_CODEC_CONF_REP:
1060 case RSL_MT_MR_CODEC_MOD_ACK:
1061 case RSL_MT_MR_CODEC_MOD_NACK:
1062 case RSL_MT_MR_CODEC_MOD_PER:
1063 LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
1064 "msg 0x%02x\n", ts_name, rslh->c.msg_type);
1065 break;
1066 default:
1067 LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
1068 ts_name, rslh->c.msg_type);
1069 return -EINVAL;
1070 }
1071
1072 return rc;
1073}
1074
1075static int rsl_rx_error_rep(struct msgb *msg)
1076{
1077 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1078 struct tlv_parsed tp;
1079
1080 LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
1081
1082 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1083
1084 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1085 print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
1086 TLVP_LEN(&tp, RSL_IE_CAUSE));
1087
1088 LOGPC(DRSL, LOGL_ERROR, "\n");
1089
1090 return 0;
1091}
1092
1093static int abis_rsl_rx_trx(struct msgb *msg)
1094{
1095 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1096 int rc = 0;
1097
1098 switch (rslh->msg_type) {
1099 case RSL_MT_ERROR_REPORT:
1100 rc = rsl_rx_error_rep(msg);
1101 break;
1102 case RSL_MT_RF_RES_IND:
1103 /* interference on idle channels of TRX */
1104 //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
1105 break;
1106 case RSL_MT_OVERLOAD:
1107 /* indicate CCCH / ACCH / processor overload */
1108 LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
1109 gsm_trx_name(msg->trx));
1110 break;
1111 default:
1112 LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
1113 "type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
1114 return -EINVAL;
1115 }
1116 return rc;
1117}
1118
1119/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1120static void t3101_expired(void *data)
1121{
1122 struct gsm_lchan *lchan = data;
1123
1124 rsl_rf_chan_release(lchan, 1);
1125}
1126
1127/* If T3111 expires, we will send the RF Channel Request */
1128static void t3111_expired(void *data)
1129{
1130 struct gsm_lchan *lchan = data;
1131
1132 rsl_rf_chan_release(lchan, 0);
1133}
1134
1135#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
1136
1137/* Format an IMM ASS REJ according to 04.08 Chapter 9.1.20 */
1138static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
1139 unsigned int num_req_refs,
1140 struct gsm48_req_ref *rqd_refs,
1141 uint8_t wait_ind)
1142{
1143 uint8_t buf[GSM_MACBLOCK_LEN];
1144 struct gsm48_imm_ass_rej *iar = (struct gsm48_imm_ass_rej *)buf;
1145
1146 /* create IMMEDIATE ASSIGN REJECT 04.08 message */
1147 memset(iar, 0, sizeof(*iar));
1148 iar->proto_discr = GSM48_PDISC_RR;
1149 iar->msg_type = GSM48_MT_RR_IMM_ASS;
1150 iar->page_mode = GSM48_PM_SAME;
1151
1152 memcpy(&iar->req_ref1, &rqd_refs[0], sizeof(iar->req_ref1));
1153 iar->wait_ind1 = wait_ind;
1154
1155 if (num_req_refs >= 2)
1156 memcpy(&iar->req_ref2, &rqd_refs[1], sizeof(iar->req_ref2));
1157 else
1158 memcpy(&iar->req_ref2, &rqd_refs[0], sizeof(iar->req_ref2));
1159 iar->wait_ind2 = wait_ind;
1160
1161 if (num_req_refs >= 3)
1162 memcpy(&iar->req_ref3, &rqd_refs[2], sizeof(iar->req_ref3));
1163 else
1164 memcpy(&iar->req_ref3, &rqd_refs[0], sizeof(iar->req_ref3));
1165 iar->wait_ind3 = wait_ind;
1166
1167 if (num_req_refs >= 4)
1168 memcpy(&iar->req_ref4, &rqd_refs[3], sizeof(iar->req_ref4));
1169 else
1170 memcpy(&iar->req_ref4, &rqd_refs[0], sizeof(iar->req_ref4));
1171 iar->wait_ind4 = wait_ind;
1172
1173 return rsl_imm_assign_cmd(bts, sizeof(iar), (uint8_t *) iar);
1174}
1175
1176/* MS has requested a channel on the RACH */
1177static int rsl_rx_chan_rqd(struct msgb *msg)
1178{
1179 struct gsm_bts *bts = msg->trx->bts;
1180 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1181 struct gsm48_req_ref *rqd_ref;
1182 enum gsm_chan_t lctype;
1183 enum gsm_chreq_reason_t chreq_reason;
1184 struct gsm_lchan *lchan;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001185 uint8_t rqd_ta;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001186 int is_lu;
1187
Jonathan Santos5a45b152011-08-17 15:33:57 -04001188 uint16_t arfcn;
1189 uint8_t ts_number, subch;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001190
1191 /* parse request reference to be used in immediate assign */
1192 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1193 return -EINVAL;
1194
1195 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1196
1197 /* parse access delay and use as TA */
1198 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1199 return -EINVAL;
1200 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1201
1202 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1203 * request reference RA */
1204 lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
1205 chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
1206
Jonathan Santos5a45b152011-08-17 15:33:57 -04001207 osmo_counter_inc(bts->network->stats.chreq.total);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001208
1209 /*
1210 * We want LOCATION UPDATES to succeed and will assign a TCH
1211 * if we have no SDCCH available.
1212 */
1213 is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
1214
1215 /* check availability / allocate channel */
1216 lchan = lchan_alloc(bts, lctype, is_lu);
1217 if (!lchan) {
1218 LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
1219 msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
Jonathan Santos5a45b152011-08-17 15:33:57 -04001220 osmo_counter_inc(bts->network->stats.chreq.no_channel);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001221 /* FIXME gather multiple CHAN RQD and reject up to 4 at the same time */
1222 if (bts->network->T3122)
1223 rsl_send_imm_ass_rej(bts, 1, rqd_ref, bts->network->T3122 & 0xff);
1224 return -ENOMEM;
1225 }
1226
1227 if (lchan->state != LCHAN_S_NONE)
1228 LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
1229 "in state %s\n", gsm_lchan_name(lchan),
1230 gsm_lchans_name(lchan->state));
1231 rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
1232
1233 /* save the RACH data as we need it after the CHAN ACT ACK */
1234 lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);
1235 if (!lchan->rqd_ref) {
1236 LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n");
1237 lchan_free(lchan);
1238 return -ENOMEM;
1239 }
1240
1241 memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref));
1242 lchan->rqd_ta = rqd_ta;
1243
1244 ts_number = lchan->ts->nr;
1245 arfcn = lchan->ts->trx->arfcn;
1246 subch = lchan->nr;
1247
1248 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
1249 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
1250 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
1251 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
1252 lchan->tch_mode = GSM48_CMODE_SIGN;
1253
1254 /* FIXME: Start another timer or assume the BTS sends a ACK/NACK? */
1255 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0);
1256
1257 DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
1258 "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
1259 gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
1260 rqd_ref->ra);
1261 return 0;
1262}
1263
1264static int rsl_send_imm_assignment(struct gsm_lchan *lchan)
1265{
1266 struct gsm_bts *bts = lchan->ts->trx->bts;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001267 uint8_t buf[GSM_MACBLOCK_LEN];
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001268 struct gsm48_imm_ass *ia = (struct gsm48_imm_ass *) buf;
1269
1270 /* create IMMEDIATE ASSIGN 04.08 messge */
1271 memset(ia, 0, sizeof(*ia));
1272 /* we set ia->l2_plen once we know the length of the MA below */
1273 ia->proto_discr = GSM48_PDISC_RR;
1274 ia->msg_type = GSM48_MT_RR_IMM_ASS;
1275 ia->page_mode = GSM48_PM_SAME;
1276 gsm48_lchan2chan_desc(&ia->chan_desc, lchan);
1277
1278 /* use request reference extracted from CHAN_RQD */
1279 memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
1280 ia->timing_advance = lchan->rqd_ta;
1281 if (!lchan->ts->hopping.enabled) {
1282 ia->mob_alloc_len = 0;
1283 } else {
1284 ia->mob_alloc_len = lchan->ts->hopping.ma_len;
1285 memcpy(ia->mob_alloc, lchan->ts->hopping.ma_data, ia->mob_alloc_len);
1286 }
1287 /* we need to subtract 1 byte from sizeof(*ia) since ia includes the l2_plen field */
1288 ia->l2_plen = GSM48_LEN2PLEN((sizeof(*ia)-1) + ia->mob_alloc_len);
1289
1290 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1291 lchan->T3101.cb = t3101_expired;
1292 lchan->T3101.data = lchan;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001293 osmo_timer_schedule(&lchan->T3101, bts->network->T3101, 0);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001294
1295 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Jonathan Santos5a45b152011-08-17 15:33:57 -04001296 return rsl_imm_assign_cmd(bts, sizeof(*ia)+ia->mob_alloc_len, (uint8_t *) ia);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001297}
1298
1299/* MS has requested a channel on the RACH */
1300static int rsl_rx_ccch_load(struct msgb *msg)
1301{
1302 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Jonathan Santos5a45b152011-08-17 15:33:57 -04001303 uint16_t pg_buf_space;
1304 uint16_t rach_slot_count = -1;
1305 uint16_t rach_busy_count = -1;
1306 uint16_t rach_access_count = -1;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001307
1308 switch (rslh->data[0]) {
1309 case RSL_IE_PAGING_LOAD:
1310 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1311 if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
1312 /* paging load below configured threshold, use 50 as default */
1313 pg_buf_space = 50;
1314 }
1315 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1316 break;
1317 case RSL_IE_RACH_LOAD:
1318 if (msg->data_len >= 7) {
1319 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1320 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1321 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1322 }
1323 break;
1324 default:
1325 break;
1326 }
1327
1328 return 0;
1329}
1330
1331static int abis_rsl_rx_cchan(struct msgb *msg)
1332{
1333 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1334 int rc = 0;
1335
1336 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1337
1338 switch (rslh->c.msg_type) {
1339 case RSL_MT_CHAN_RQD:
1340 /* MS has requested a channel on the RACH */
1341 rc = rsl_rx_chan_rqd(msg);
1342 break;
1343 case RSL_MT_CCCH_LOAD_IND:
1344 /* current load on the CCCH */
1345 rc = rsl_rx_ccch_load(msg);
1346 break;
1347 case RSL_MT_DELETE_IND:
1348 /* CCCH overloaded, IMM_ASSIGN was dropped */
1349 case RSL_MT_CBCH_LOAD_IND:
1350 /* current load on the CBCH */
1351 LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "
1352 "type 0x%02x\n", rslh->c.msg_type);
1353 break;
1354 default:
1355 LOGP(DRSL, LOGL_NOTICE, "Unknown Abis RSL TRX message type "
1356 "0x%02x\n", rslh->c.msg_type);
1357 return -EINVAL;
1358 }
1359
1360 return rc;
1361}
1362
1363static int rsl_rx_rll_err_ind(struct msgb *msg)
1364{
1365 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Jonathan Santos5a45b152011-08-17 15:33:57 -04001366 uint8_t *rlm_cause = rllh->data;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001367
1368 LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
1369 gsm_lchan_name(msg->lchan),
1370 rsl_rlm_cause_name(rlm_cause[1]));
1371
1372 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
1373
1374 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
Jonathan Santos5a45b152011-08-17 15:33:57 -04001375 osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001376 return rsl_rf_chan_release(msg->lchan, 1);
1377 }
1378
1379 return 0;
1380}
1381
1382static void rsl_handle_release(struct gsm_lchan *lchan)
1383{
1384 int sapi;
1385 struct gsm_bts *bts;
1386
1387 /* maybe we have only brought down one RLL */
1388 if (lchan->state != LCHAN_S_REL_REQ)
1389 return;
1390
1391 for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
1392 if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
1393 continue;
1394 LOGP(DRSL, LOGL_DEBUG, "%s waiting for SAPI=%d to be released.\n",
1395 gsm_lchan_name(lchan), sapi);
1396 return;
1397 }
1398
1399
1400
1401 /* wait a bit to send the RF Channel Release */
1402 lchan->T3111.cb = t3111_expired;
1403 lchan->T3111.data = lchan;
1404 bts = lchan->ts->trx->bts;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001405 osmo_timer_schedule(&lchan->T3111, bts->network->T3111, 0);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001406}
1407
1408/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1409 0x02, 0x06,
1410 0x01, 0x20,
1411 0x02, 0x00,
1412 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1413
1414static int abis_rsl_rx_rll(struct msgb *msg)
1415{
1416 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1417 int rc = 0;
1418 char *ts_name;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001419 uint8_t sapi = rllh->link_id & 7;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001420
1421 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1422 ts_name = gsm_lchan_name(msg->lchan);
1423 DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
1424
1425 switch (rllh->c.msg_type) {
1426 case RSL_MT_DATA_IND:
1427 DEBUGPC(DRLL, "DATA INDICATION\n");
1428 if (msgb_l2len(msg) >
1429 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1430 rllh->data[0] == RSL_IE_L3_INFO) {
1431 msg->l3h = &rllh->data[3];
1432 return gsm0408_rcvmsg(msg, rllh->link_id);
1433 }
1434 break;
1435 case RSL_MT_EST_IND:
1436 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
1437 /* lchan is established, stop T3101 */
1438 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001439 osmo_timer_del(&msg->lchan->T3101);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001440 if (msgb_l2len(msg) >
1441 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1442 rllh->data[0] == RSL_IE_L3_INFO) {
1443 msg->l3h = &rllh->data[3];
1444 return gsm0408_rcvmsg(msg, rllh->link_id);
1445 }
1446 break;
1447 case RSL_MT_EST_CONF:
1448 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
1449 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
1450 rll_indication(msg->lchan, rllh->link_id,
1451 BSC_RLLR_IND_EST_CONF);
1452 break;
1453 case RSL_MT_REL_IND:
1454 /* BTS informs us of having received DISC from MS */
1455 DEBUGPC(DRLL, "RELEASE INDICATION\n");
1456 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
1457 rll_indication(msg->lchan, rllh->link_id,
1458 BSC_RLLR_IND_REL_IND);
1459 rsl_handle_release(msg->lchan);
1460 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
1461 break;
1462 case RSL_MT_REL_CONF:
1463 /* BTS informs us of having received UA from MS,
1464 * in response to DISC that we've sent earlier */
1465 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
1466 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
1467 rsl_handle_release(msg->lchan);
1468 rsl_lchan_rll_release(msg->lchan, rllh->link_id);
1469 break;
1470 case RSL_MT_ERROR_IND:
1471 rc = rsl_rx_rll_err_ind(msg);
1472 break;
1473 case RSL_MT_UNIT_DATA_IND:
1474 LOGP(DRLL, LOGL_NOTICE, "unimplemented Abis RLL message "
1475 "type 0x%02x\n", rllh->c.msg_type);
1476 break;
1477 default:
1478 LOGP(DRLL, LOGL_NOTICE, "unknown Abis RLL message "
1479 "type 0x%02x\n", rllh->c.msg_type);
1480 }
1481 return rc;
1482}
1483
Jonathan Santos5a45b152011-08-17 15:33:57 -04001484static uint8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001485{
1486 switch (lchan->tch_mode) {
1487 case GSM48_CMODE_SPEECH_V1:
1488 switch (lchan->type) {
1489 case GSM_LCHAN_TCH_F:
1490 return 0x00;
1491 case GSM_LCHAN_TCH_H:
1492 return 0x03;
1493 default:
1494 break;
1495 }
1496 case GSM48_CMODE_SPEECH_EFR:
1497 switch (lchan->type) {
1498 case GSM_LCHAN_TCH_F:
1499 return 0x01;
1500 /* there's no half-rate EFR */
1501 default:
1502 break;
1503 }
1504 case GSM48_CMODE_SPEECH_AMR:
1505 switch (lchan->type) {
1506 case GSM_LCHAN_TCH_F:
1507 return 0x02;
1508 case GSM_LCHAN_TCH_H:
1509 return 0x05;
1510 default:
1511 break;
1512 }
1513 default:
1514 break;
1515 }
1516 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access speech mode for "
1517 "tch_mode == 0x%02x\n", lchan->tch_mode);
1518 return 0;
1519}
1520
Jonathan Santos5a45b152011-08-17 15:33:57 -04001521static uint8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001522{
1523 struct gsm_network *net = lchan->ts->trx->bts->network;
1524
1525 /* allow to hardcode the rtp payload */
1526 if (net->hardcoded_rtp_payload != 0)
1527 return net->hardcoded_rtp_payload;
1528
1529 switch (lchan->tch_mode) {
1530 case GSM48_CMODE_SPEECH_V1:
1531 switch (lchan->type) {
1532 case GSM_LCHAN_TCH_F:
1533 return RTP_PT_GSM_FULL;
1534 case GSM_LCHAN_TCH_H:
1535 return RTP_PT_GSM_HALF;
1536 default:
1537 break;
1538 }
1539 case GSM48_CMODE_SPEECH_EFR:
1540 switch (lchan->type) {
1541 case GSM_LCHAN_TCH_F:
1542 return RTP_PT_GSM_EFR;
1543 /* there's no half-rate EFR */
1544 default:
1545 break;
1546 }
1547 case GSM48_CMODE_SPEECH_AMR:
1548 switch (lchan->type) {
1549 case GSM_LCHAN_TCH_F:
1550 return RTP_PT_AMR_FULL;
1551 case GSM_LCHAN_TCH_H:
1552 return RTP_PT_AMR_HALF;
1553 default:
1554 break;
1555 }
1556 default:
1557 break;
1558 }
1559 LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
1560 "tch_mode == 0x%02x\n & lchan_type == %d",
1561 lchan->tch_mode, lchan->type);
1562 return 0;
1563}
1564
1565/* ip.access specific RSL extensions */
1566static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
1567{
1568 struct in_addr ip;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001569 uint16_t port, conn_id;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001570
1571 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_IP)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -04001572 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_IP));
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001573 DEBUGPC(DRSL, "LOCAL_IP=%s ", inet_ntoa(ip));
1574 lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
1575 }
1576
1577 if (TLVP_PRESENT(tv, RSL_IE_IPAC_LOCAL_PORT)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -04001578 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_LOCAL_PORT));
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001579 port = ntohs(port);
1580 DEBUGPC(DRSL, "LOCAL_PORT=%u ", port);
1581 lchan->abis_ip.bound_port = port;
1582 }
1583
1584 if (TLVP_PRESENT(tv, RSL_IE_IPAC_CONN_ID)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -04001585 conn_id = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_CONN_ID));
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001586 conn_id = ntohs(conn_id);
1587 DEBUGPC(DRSL, "CON_ID=%u ", conn_id);
1588 lchan->abis_ip.conn_id = conn_id;
1589 }
1590
1591 if (TLVP_PRESENT(tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1592 lchan->abis_ip.rtp_payload2 =
1593 *TLVP_VAL(tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1594 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1595 lchan->abis_ip.rtp_payload2);
1596 }
1597
1598 if (TLVP_PRESENT(tv, RSL_IE_IPAC_SPEECH_MODE)) {
1599 lchan->abis_ip.speech_mode =
1600 *TLVP_VAL(tv, RSL_IE_IPAC_SPEECH_MODE);
1601 DEBUGPC(DRSL, "speech_mode=0x%02x ",
1602 lchan->abis_ip.speech_mode);
1603 }
1604
1605 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_IP)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -04001606 ip.s_addr = *((uint32_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_IP));
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001607 DEBUGPC(DRSL, "REMOTE_IP=%s ", inet_ntoa(ip));
1608 lchan->abis_ip.connect_ip = ntohl(ip.s_addr);
1609 }
1610
1611 if (TLVP_PRESENT(tv, RSL_IE_IPAC_REMOTE_PORT)) {
Jonathan Santos5a45b152011-08-17 15:33:57 -04001612 port = *((uint16_t *) TLVP_VAL(tv, RSL_IE_IPAC_REMOTE_PORT));
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001613 port = ntohs(port);
1614 DEBUGPC(DRSL, "REMOTE_PORT=%u ", port);
1615 lchan->abis_ip.connect_port = port;
1616 }
1617}
1618
1619int rsl_ipacc_crcx(struct gsm_lchan *lchan)
1620{
1621 struct msgb *msg = rsl_msgb_alloc();
1622 struct abis_rsl_dchan_hdr *dh;
1623
1624 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1625 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
1626 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001627 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001628
1629 /* 0x1- == receive-only, 0x-1 == EFR codec */
1630 lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
1631 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
1632 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
1633 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
1634
1635 DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
1636 gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
1637 lchan->abis_ip.rtp_payload);
1638
1639 msg->trx = lchan->ts->trx;
1640
1641 return abis_rsl_sendmsg(msg);
1642}
1643
Jonathan Santos5a45b152011-08-17 15:33:57 -04001644int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port,
1645 uint8_t rtp_payload2)
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001646{
1647 struct msgb *msg = rsl_msgb_alloc();
1648 struct abis_rsl_dchan_hdr *dh;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001649 uint32_t *att_ip;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001650 struct in_addr ia;
1651
1652 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1653 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
1654 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001655 dh->chan_nr = gsm_lchan2chan_nr(lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001656
1657 /* we need to store these now as MDCX_ACK does not return them :( */
1658 lchan->abis_ip.rtp_payload2 = rtp_payload2;
1659 lchan->abis_ip.connect_port = port;
1660 lchan->abis_ip.connect_ip = ip;
1661
1662 /* 0x0- == both directions, 0x-1 == EFR codec */
1663 lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
1664 lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
1665
1666 ia.s_addr = htonl(ip);
1667 DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
1668 "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
1669 inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
1670 lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
1671
1672 msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
1673 msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
Jonathan Santos5a45b152011-08-17 15:33:57 -04001674 att_ip = (uint32_t *) msgb_put(msg, sizeof(ip));
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001675 *att_ip = ia.s_addr;
1676 msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
1677 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
1678 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
1679 if (rtp_payload2)
1680 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1681
1682 msg->trx = lchan->ts->trx;
1683
1684 return abis_rsl_sendmsg(msg);
1685}
1686
1687/* tell BTS to connect RTP stream to our local RTP socket */
1688int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
1689{
1690 struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
1691 int rc;
1692
1693 rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
1694 ntohs(rs->rtp.sin_local.sin_port),
1695 /* FIXME: use RTP payload of bound socket, not BTS*/
1696 lchan->abis_ip.rtp_payload2);
1697
1698 return rc;
1699}
1700
1701int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act)
1702{
1703 struct msgb *msg = rsl_msgb_alloc();
1704 struct abis_rsl_dchan_hdr *dh;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001705 uint8_t msg_type;
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001706
1707 if (act)
1708 msg_type = RSL_MT_IPAC_PDCH_ACT;
1709 else
1710 msg_type = RSL_MT_IPAC_PDCH_DEACT;
1711
1712 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1713 init_dchan_hdr(dh, msg_type);
1714 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Jonathan Santos5a45b152011-08-17 15:33:57 -04001715 dh->chan_nr = gsm_ts2chan_nr(ts, 0);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001716
1717 DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_ts_name(ts),
1718 act ? "" : "DE");
1719
1720 msg->trx = ts->trx;
1721
1722 return abis_rsl_sendmsg(msg);
1723}
1724
1725static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
1726{
1727 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1728 struct tlv_parsed tv;
1729 struct gsm_lchan *lchan = msg->lchan;
1730
1731 /* the BTS has acknowledged a local bind, it now tells us the IP
1732 * address and port number to which it has bound the given logical
1733 * channel */
1734
1735 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1736 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1737 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
1738 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
1739 LOGP(DRSL, LOGL_NOTICE, "mandatory IE missing");
1740 return -EINVAL;
1741 }
1742
1743 ipac_parse_rtp(lchan, &tv);
1744
Jonathan Santos5a45b152011-08-17 15:33:57 -04001745 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001746
1747 return 0;
1748}
1749
1750static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
1751{
1752 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1753 struct tlv_parsed tv;
1754 struct gsm_lchan *lchan = msg->lchan;
1755
1756 /* the BTS has acknowledged a remote connect request and
1757 * it now tells us the IP address and port number to which it has
1758 * connected the given logical channel */
1759
1760 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1761 ipac_parse_rtp(lchan, &tv);
Jonathan Santos5a45b152011-08-17 15:33:57 -04001762 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_MDCX_ACK, msg->lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001763
1764 return 0;
1765}
1766
1767static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
1768{
1769 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1770 struct tlv_parsed tv;
1771
1772 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1773
1774 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1775 print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
1776 TLVP_LEN(&tv, RSL_IE_CAUSE));
1777
Jonathan Santos5a45b152011-08-17 15:33:57 -04001778 osmo_signal_dispatch(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001779
1780 return 0;
1781}
1782
1783static int abis_rsl_rx_ipacc(struct msgb *msg)
1784{
1785 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1786 char *ts_name;
1787 int rc = 0;
1788
1789 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1790 ts_name = gsm_lchan_name(msg->lchan);
1791
1792 switch (rllh->c.msg_type) {
1793 case RSL_MT_IPAC_CRCX_ACK:
1794 DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
1795 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
1796 break;
1797 case RSL_MT_IPAC_CRCX_NACK:
1798 /* somehow the BTS was unable to bind the lchan to its local
1799 * port?!? */
1800 LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
1801 break;
1802 case RSL_MT_IPAC_MDCX_ACK:
1803 /* the BTS tells us that a connect operation was successful */
1804 DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
1805 rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
1806 break;
1807 case RSL_MT_IPAC_MDCX_NACK:
1808 /* somehow the BTS was unable to connect the lchan to a remote
1809 * port */
1810 LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
1811 break;
1812 case RSL_MT_IPAC_DLCX_IND:
1813 DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
1814 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
1815 break;
1816 default:
1817 LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
1818 rllh->c.msg_type);
1819 break;
1820 }
1821 DEBUGPC(DRSL, "\n");
1822
1823 return rc;
1824}
1825
1826
1827/* Entry-point where L2 RSL from BTS enters */
1828int abis_rsl_rcvmsg(struct msgb *msg)
1829{
1830 struct abis_rsl_common_hdr *rslh;
1831 int rc = 0;
1832
1833 if (!msg) {
1834 DEBUGP(DRSL, "Empty RSL msg?..\n");
1835 return -1;
1836 }
1837
1838 if (msgb_l2len(msg) < sizeof(*rslh)) {
1839 DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
1840 return -1;
1841 }
1842
1843 rslh = msgb_l2(msg);
1844
1845 switch (rslh->msg_discr & 0xfe) {
1846 case ABIS_RSL_MDISC_RLL:
1847 rc = abis_rsl_rx_rll(msg);
1848 break;
1849 case ABIS_RSL_MDISC_DED_CHAN:
1850 rc = abis_rsl_rx_dchan(msg);
1851 break;
1852 case ABIS_RSL_MDISC_COM_CHAN:
1853 rc = abis_rsl_rx_cchan(msg);
1854 break;
1855 case ABIS_RSL_MDISC_TRX:
1856 rc = abis_rsl_rx_trx(msg);
1857 break;
1858 case ABIS_RSL_MDISC_LOC:
1859 LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
1860 rslh->msg_discr);
1861 break;
1862 case ABIS_RSL_MDISC_IPACCESS:
1863 rc = abis_rsl_rx_ipacc(msg);
1864 break;
1865 default:
1866 LOGP(DRSL, LOGL_NOTICE, "unknown RSL message discriminator "
1867 "0x%02x\n", rslh->msg_discr);
1868 return -EINVAL;
1869 }
1870 msgb_free(msg);
1871 return rc;
1872}
1873
Jonathan Santos03fd8d02011-05-25 13:54:02 -04001874int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
1875 uint8_t cb_command, const uint8_t *data, int len)
1876{
1877 struct abis_rsl_dchan_hdr *dh;
1878 struct msgb *cb_cmd;
1879
1880 cb_cmd = rsl_msgb_alloc();
1881 if (!cb_cmd)
1882 return -1;
1883
1884 dh = (struct abis_rsl_dchan_hdr *) msgb_put(cb_cmd, sizeof*dh);
1885 init_dchan_hdr(dh, RSL_MT_SMS_BC_CMD);
1886 dh->chan_nr = RSL_CHAN_SDCCH4_ACCH; /* TODO: check the chan config */
1887
1888 msgb_tv_put(cb_cmd, RSL_IE_CB_CMD_TYPE, cb_command);
1889 msgb_tlv_put(cb_cmd, RSL_IE_SMSCB_MSG, len, data);
1890
1891 cb_cmd->trx = bts->c0;
1892
1893 return abis_rsl_sendmsg(cb_cmd);
1894}