blob: 219b01aa02623d9c3e1aede485e184809128a6c8 [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* 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-2009 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 General Public License as published by
10 * the Free Software Foundation; either version 2 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 General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <sys/types.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30
31#include <openbsc/gsm_data.h>
32#include <openbsc/gsm_04_08.h>
Harald Weltec4dcda02009-08-09 14:45:18 +020033#include <openbsc/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080034#include <openbsc/abis_rsl.h>
35#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020036#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080037#include <openbsc/debug.h>
38#include <openbsc/tlv.h>
39#include <openbsc/paging.h>
40#include <openbsc/signal.h>
41
42#define RSL_ALLOC_SIZE 1024
43#define RSL_ALLOC_HEADROOM 128
44
45#define MAX(a, b) (a) >= (b) ? (a) : (b)
46
47static const struct tlv_definition rsl_att_tlvdef = {
48 .def = {
49 [RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
50 [RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
51 [RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
52 [RSL_IE_BS_POWER] = { TLV_TYPE_TV },
53 [RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
54 [RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
55 [RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
56 [RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
57 [RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
58 [RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
59 [RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
60 [RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
61 [RSL_IE_MS_POWER] = { TLV_TYPE_TV },
62 [RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
63 [RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
64 [RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
65 [RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
66 [RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
67 [RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
68 [RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
69 [RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
70 [RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
71 [RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
72 [RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
73 [RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
74 [RSL_IE_CAUSE] = { TLV_TYPE_TLV },
75 [RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
76 [RSL_IE_MSG_ID] = { TLV_TYPE_TV },
77 [RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
78 [RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
79 [RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
80 [RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
81 [RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
82 [RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
83 [RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
84 [RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
85 [RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
86 [RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
87 [RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
88 [RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
89 [RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
90 [RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
91 [RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
92 [RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
93 [RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
94 [RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
95 [RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
96 [RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
97 [RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
98 [RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
99 [RSL_IE_UIC] = { TLV_TYPE_TLV },
100 [RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
101 [RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
102 [RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
103 [RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
104 [RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
105 [RSL_IE_RTD] = { TLV_TYPE_TV },
106 [RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
107 [RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
Harald Welte4684e632009-08-10 09:51:40 +0200108 [RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200109 [RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
110 [RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800111 [RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
112 [RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welte1610d302009-07-12 09:56:39 +0200113 [RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800114 [RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welteb9498952009-07-12 09:45:05 +0200115 [RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200116 [RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
Harald Welteb9498952009-07-12 09:45:05 +0200117 [RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
Harald Welte1610d302009-07-12 09:56:39 +0200118 [RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
119 [RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
120 [RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
Harald Welteb9498952009-07-12 09:45:05 +0200121 [RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200122 [RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
123 [RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800124 },
125};
126#define rsl_tlv_parse(dec, buf, len) \
127 tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
128
129static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
130{
131 /* mask off the transparent bit ? */
132 msg_type &= 0xfe;
133
134 if ((msg_type & 0xf0) == 0x00)
135 return ABIS_RSL_MDISC_RLL;
136 if ((msg_type & 0xf0) == 0x10) {
137 if (msg_type >= 0x19 && msg_type <= 0x22)
138 return ABIS_RSL_MDISC_TRX;
139 else
140 return ABIS_RSL_MDISC_COM_CHAN;
141 }
142 if ((msg_type & 0xe0) == 0x20)
143 return ABIS_RSL_MDISC_DED_CHAN;
144
145 return ABIS_RSL_MDISC_LOC;
146}
147
148static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
149 u_int8_t msg_type)
150{
151 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
152 dh->c.msg_type = msg_type;
153 dh->ie_chan = RSL_IE_CHAN_NR;
154}
155
156static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
157 u_int8_t msg_type)
158{
159 /* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
160 dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
161 dh->c.msg_type = msg_type;
162 dh->ie_chan = RSL_IE_CHAN_NR;
163 dh->ie_link_id = RSL_IE_LINK_IDENT;
164}
165
166
167/* encode channel number as per Section 9.3.1 */
168u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
169{
170 u_int8_t ret;
171
172 ret = (timeslot & 0x07) | type;
173
174 switch (type) {
175 case RSL_CHAN_Lm_ACCHs:
176 subch &= 0x01;
177 break;
178 case RSL_CHAN_SDCCH4_ACCH:
179 subch &= 0x07;
180 break;
181 case RSL_CHAN_SDCCH8_ACCH:
182 subch &= 0x07;
183 break;
184 default:
185 /* no subchannels allowed */
186 subch = 0x00;
187 break;
188 }
189 ret |= (subch << 3);
190
191 return ret;
192}
193
194/* determine logical channel based on TRX and channel number IE */
195struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
196{
197 struct gsm_lchan *lchan;
198 u_int8_t ts_nr = chan_nr & 0x07;
199 u_int8_t cbits = chan_nr >> 3;
200 u_int8_t lch_idx;
201 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
202
203 if (cbits == 0x01) {
204 lch_idx = 0; /* TCH/F */
Harald Welte37884ed2009-10-24 10:25:50 +0200205 if (ts->pchan != GSM_PCHAN_TCH_F &&
206 ts->pchan != GSM_PCHAN_PDCH &&
207 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welte59b04682009-06-10 05:40:52 +0800208 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
209 chan_nr, ts->pchan);
210 } else if ((cbits & 0x1e) == 0x02) {
211 lch_idx = cbits & 0x1; /* TCH/H */
212 if (ts->pchan != GSM_PCHAN_TCH_H)
213 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
214 chan_nr, ts->pchan);
215 } else if ((cbits & 0x1c) == 0x04) {
216 lch_idx = cbits & 0x3; /* SDCCH/4 */
217 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
218 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
219 chan_nr, ts->pchan);
220 } else if ((cbits & 0x18) == 0x08) {
221 lch_idx = cbits & 0x7; /* SDCCH/8 */
222 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
223 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
224 chan_nr, ts->pchan);
225 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
226 lch_idx = 0;
227 if (ts->pchan != GSM_PCHAN_CCCH &&
228 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
229 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
230 chan_nr, ts->pchan);
231 /* FIXME: we should not return first sdcch4 !!! */
232 } else {
233 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
234 return NULL;
235 }
236
237 lchan = &ts->lchan[lch_idx];
238
239 return lchan;
240}
241
Holger Hans Peter Freyther942ff172009-10-22 11:47:45 +0200242/* See Table 10.5.25 of GSM04.08 */
Harald Welte59b04682009-06-10 05:40:52 +0800243u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
244{
245 struct gsm_bts_trx_ts *ts = lchan->ts;
246 u_int8_t cbits, chan_nr;
247
248 switch (ts->pchan) {
249 case GSM_PCHAN_TCH_F:
Harald Welte37884ed2009-10-24 10:25:50 +0200250 case GSM_PCHAN_PDCH:
251 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte59b04682009-06-10 05:40:52 +0800252 cbits = 0x01;
253 break;
254 case GSM_PCHAN_TCH_H:
255 cbits = 0x02;
256 cbits += lchan->nr;
257 break;
258 case GSM_PCHAN_CCCH_SDCCH4:
259 cbits = 0x04;
260 cbits += lchan->nr;
261 break;
262 case GSM_PCHAN_SDCCH8_SACCH8C:
263 cbits = 0x08;
264 cbits += lchan->nr;
265 break;
266 default:
267 case GSM_PCHAN_CCCH:
268 cbits = 0x10;
269 break;
270 }
271
272 chan_nr = (cbits << 3) | (ts->nr & 0x7);
273
274 return chan_nr;
275}
276
277/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
278u_int64_t str_to_imsi(const char *imsi_str)
279{
280 u_int64_t ret;
281
282 ret = strtoull(imsi_str, NULL, 10);
283
284 return ret;
285}
286
287/* Table 5 Clause 7 TS 05.02 */
288unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
289{
290 if (!bs_ccch_sdcch_comb)
291 return 9 - bs_ag_blks_res;
292 else
293 return 3 - bs_ag_blks_res;
294}
295
296/* Chapter 6.5.2 of TS 05.02 */
297unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
298 unsigned int n_pag_blocks)
299{
300 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
301}
302
303/* Chapter 6.5.2 of TS 05.02 */
304unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
305 int n_pag_blocks)
306{
307 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
308}
309
310static struct msgb *rsl_msgb_alloc(void)
311{
Harald Welte9cfc9352009-06-26 19:39:35 +0200312 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
313 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800314}
315
316#define MACBLOCK_SIZE 23
317static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
318{
319 memcpy(out, in, len);
320
321 if (len < MACBLOCK_SIZE)
322 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
323}
324
Harald Welted2dd9de2009-08-30 15:37:11 +0900325/* Chapter 9.3.7: Encryption Information */
326static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
327{
328 *out++ = lchan->encr.alg_id & 0xff;
329 if (lchan->encr.key_len)
330 memcpy(out, lchan->encr.key, lchan->encr.key_len);
331 return lchan->encr.key_len + 1;
332}
333
334
Harald Weltef1a168d2009-07-28 17:58:09 +0200335static const char *rsl_err_vals[0xff] = {
336 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
337 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
338 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
339 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
340 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
341 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welteb1717e92009-08-04 02:31:05 +0200342 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Weltef1a168d2009-07-28 17:58:09 +0200343 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
344 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
345 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
346 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
347 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
348 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
349 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
350 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
351 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
352 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
353 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
354 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
355 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
356 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
357 [RSL_ERR_MSG_TYPE] = "Message Type Error",
358 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
359 [RSL_ERR_IE_ERROR] = "General IE error",
360 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
361 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
362 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
363 [RSL_ERR_IE_LENGTH] = "IE length error",
364 [RSL_ERR_IE_CONTENT] = "IE content error",
365 [RSL_ERR_PROTO] = "Protocol error, unspecified",
366 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
367};
368
369static const char *rsl_err_name(u_int8_t err)
Harald Welte59b04682009-06-10 05:40:52 +0800370{
Harald Weltef1a168d2009-07-28 17:58:09 +0200371 if (rsl_err_vals[err])
372 return rsl_err_vals[err];
373 else
374 return "unknown";
375}
376
377static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
378{
Harald Welte59b04682009-06-10 05:40:52 +0800379 int i;
380
Harald Weltef1a168d2009-07-28 17:58:09 +0200381 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
382 cause_v[0], rsl_err_name(cause_v[0]));
383 for (i = 1; i < cause_len-1; i++)
384 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800385}
386
387/* Send a BCCH_INFO message as per Chapter 8.5.1 */
388int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
389 const u_int8_t *data, int len)
390{
391 struct abis_rsl_dchan_hdr *dh;
392 struct msgb *msg = rsl_msgb_alloc();
393
394 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
395 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
396 dh->chan_nr = RSL_CHAN_BCCH;
397
398 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
399 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
400
401 msg->trx = trx;
402
403 return abis_rsl_sendmsg(msg);
404}
405
406int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
407 const u_int8_t *data, int len)
408{
409 struct abis_rsl_common_hdr *ch;
410 struct msgb *msg = rsl_msgb_alloc();
411
412 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
413 ch->msg_discr = ABIS_RSL_MDISC_TRX;
414 ch->msg_type = RSL_MT_SACCH_FILL;
415
416 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
417 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
418
419 msg->trx = trx;
420
421 return abis_rsl_sendmsg(msg);
422}
423
Harald Welte91afe4c2009-06-20 18:15:19 +0200424int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
425{
426 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200427 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200428 u_int8_t chan_nr = lchan2chan_nr(lchan);
429
430 db = abs(db);
431 if (db > 30)
432 return -EINVAL;
433
Harald Welteed831842009-06-27 03:09:08 +0200434 msg = rsl_msgb_alloc();
435
Harald Welte91afe4c2009-06-20 18:15:19 +0200436 lchan->bs_power = db/2;
437 if (fpc)
438 lchan->bs_power |= 0x10;
439
440 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
441 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
442 dh->chan_nr = chan_nr;
443
444 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
445
446 msg->trx = lchan->ts->trx;
447
448 return abis_rsl_sendmsg(msg);
449}
450
Harald Welte91afe4c2009-06-20 18:15:19 +0200451int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
452{
453 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200454 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200455 u_int8_t chan_nr = lchan2chan_nr(lchan);
456 int ctl_lvl;
457
Harald Weltec4dcda02009-08-09 14:45:18 +0200458 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200459 if (ctl_lvl < 0)
460 return ctl_lvl;
461
Harald Welteed831842009-06-27 03:09:08 +0200462 msg = rsl_msgb_alloc();
463
Harald Welte91afe4c2009-06-20 18:15:19 +0200464 lchan->ms_power = ctl_lvl;
465
466 if (fpc)
467 lchan->ms_power |= 0x20;
468
469 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
470 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
471 dh->chan_nr = chan_nr;
472
473 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
474
475 msg->trx = lchan->ts->trx;
476
477 return abis_rsl_sendmsg(msg);
478}
479
Harald Welte39274f42009-07-29 15:41:29 +0200480static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
481 struct gsm_lchan *lchan)
482{
483 memset(cm, 0, sizeof(cm));
484
485 /* FIXME: what to do with data calls ? */
486 cm->dtx_dtu = 0x00;
487
488 /* set TCH Speech/Data */
489 cm->spd_ind = lchan->rsl_cmode;
490
Harald Welte951e3512009-11-27 08:55:16 +0100491 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
492 lchan->tch_mode != GSM48_CMODE_SIGN)
493 DEBUGP(DRSL, "unsupported: rsl_mode == signalling, "
494 "but tch_mode != signalling\n");
495
Harald Welte39274f42009-07-29 15:41:29 +0200496 switch (lchan->type) {
497 case GSM_LCHAN_SDCCH:
498 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
499 break;
500 case GSM_LCHAN_TCH_F:
501 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
502 break;
503 case GSM_LCHAN_TCH_H:
504 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
505 break;
506 case GSM_LCHAN_NONE:
507 case GSM_LCHAN_UNKNOWN:
508 default:
509 return -EINVAL;
510 }
511
512 switch (lchan->tch_mode) {
513 case GSM48_CMODE_SIGN:
514 cm->chan_rate = 0;
515 break;
516 case GSM48_CMODE_SPEECH_V1:
517 cm->chan_rate = RSL_CMOD_SP_GSM1;
518 break;
519 case GSM48_CMODE_SPEECH_EFR:
520 cm->chan_rate = RSL_CMOD_SP_GSM2;
521 break;
522 case GSM48_CMODE_SPEECH_AMR:
523 cm->chan_rate = RSL_CMOD_SP_GSM3;
524 break;
525 case GSM48_CMODE_DATA_14k5:
526 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
527 break;
528 case GSM48_CMODE_DATA_12k0:
529 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
530 break;
531 case GSM48_CMODE_DATA_6k0:
532 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
533 break;
534 default:
535 return -EINVAL;
536 }
537
538 return 0;
539}
540
Harald Welte59b04682009-06-10 05:40:52 +0800541/* Chapter 8.4.1 */
542#if 0
543int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
544 u_int8_t act_type,
545 struct rsl_ie_chan_mode *chan_mode,
546 struct rsl_ie_chan_ident *chan_ident,
547 u_int8_t bs_power, u_int8_t ms_power,
548 u_int8_t ta)
549{
550 struct abis_rsl_dchan_hdr *dh;
551 struct msgb *msg = rsl_msgb_alloc();
552
553 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
554 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
555 dh->chan_nr = chan_nr;
556
557 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
558 /* For compatibility with Phase 1 */
559 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
560 (u_int8_t *) chan_mode);
561 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
562 (u_int8_t *) chan_ident);
563#if 0
564 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
565 (u_int8_t *) &encr_info);
566#endif
567 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
568 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
569 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
570
571 msg->trx = trx;
572
573 return abis_rsl_sendmsg(msg);
574}
575#endif
576
577int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte39274f42009-07-29 15:41:29 +0200578 u_int8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800579{
580 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200581 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200582 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800583
584 u_int8_t chan_nr = lchan2chan_nr(lchan);
585 u_int16_t arfcn = lchan->ts->trx->arfcn;
586 struct rsl_ie_chan_mode cm;
587 struct rsl_ie_chan_ident ci;
588
Harald Welte39274f42009-07-29 15:41:29 +0200589 rc = channel_mode_from_lchan(&cm, lchan);
590 if (rc < 0)
591 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800592
593 memset(&ci, 0, sizeof(ci));
594 ci.chan_desc.iei = 0x64;
595 ci.chan_desc.chan_nr = chan_nr;
596 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
597 ci.chan_desc.oct4 = arfcn & 0xff;
598
Harald Welteed831842009-06-27 03:09:08 +0200599 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800600 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
601 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
602 dh->chan_nr = chan_nr;
603
604 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
605 /* For compatibility with Phase 1 */
606 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
607 (u_int8_t *) &cm);
608 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
609 (u_int8_t *) &ci);
Harald Welted2dd9de2009-08-30 15:37:11 +0900610
611 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
612 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
613 rc = build_encr_info(encr_info, lchan);
614 if (rc > 0)
615 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
616 }
617
Harald Welte59b04682009-06-10 05:40:52 +0800618 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
619 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
620 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
621
622 msg->trx = lchan->ts->trx;
623
624 return abis_rsl_sendmsg(msg);
625}
626
Harald Welte8e770492009-07-29 11:38:15 +0200627/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800628int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
629{
630 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200631 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200632 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800633
634 u_int8_t chan_nr = lchan2chan_nr(lchan);
635 struct rsl_ie_chan_mode cm;
636
Harald Welte39274f42009-07-29 15:41:29 +0200637 rc = channel_mode_from_lchan(&cm, lchan);
638 if (rc < 0)
639 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800640
Harald Welteed831842009-06-27 03:09:08 +0200641 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800642 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
643 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
644 dh->chan_nr = chan_nr;
645
646 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
647 (u_int8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900648
649 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
650 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
651 rc = build_encr_info(encr_info, lchan);
652 if (rc > 0)
653 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
654 }
655
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100656 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
657 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
658 (u_int8_t *) &lchan->mr_conf);
659 }
660
Harald Welted2dd9de2009-08-30 15:37:11 +0900661 msg->trx = lchan->ts->trx;
662
663 return abis_rsl_sendmsg(msg);
664}
665
666/* Chapter 8.4.6: Send the encryption command with given L3 info */
667int rsl_encryption_cmd(struct msgb *msg)
668{
669 struct abis_rsl_dchan_hdr *dh;
670 struct gsm_lchan *lchan = msg->lchan;
671 u_int8_t chan_nr = lchan2chan_nr(lchan);
672 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut01f1caf2009-09-27 11:13:18 +0200673 u_int8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900674 int rc;
675
676 /* First push the L3 IE tag and length */
677 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
678
679 /* then the link identifier (SAPI0, main sign link) */
680 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
681
682 /* then encryption information */
683 rc = build_encr_info(encr_info, lchan);
684 if (rc <= 0)
685 return rc;
686 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
687
688 /* and finally the DCHAN header */
689 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
690 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
691 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800692
693 msg->trx = lchan->ts->trx;
694
695 return abis_rsl_sendmsg(msg);
696}
697
Harald Welte85a163c2009-08-10 11:43:22 +0200698/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200699int rsl_deact_sacch(struct gsm_lchan *lchan)
700{
701 struct abis_rsl_dchan_hdr *dh;
702 struct msgb *msg = rsl_msgb_alloc();
703
704 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
705 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
706 dh->chan_nr = lchan2chan_nr(lchan);
707
708 msg->lchan = lchan;
709 msg->trx = lchan->ts->trx;
710
711 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
712 gsm_ts_name(lchan->ts), dh->chan_nr);
713
714 return abis_rsl_sendmsg(msg);
715}
716
Harald Welte85a163c2009-08-10 11:43:22 +0200717/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
718int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800719{
720 struct abis_rsl_dchan_hdr *dh;
721 struct msgb *msg = rsl_msgb_alloc();
722
723 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
724 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
725 dh->chan_nr = lchan2chan_nr(lchan);
726
727 msg->lchan = lchan;
728 msg->trx = lchan->ts->trx;
729
Harald Welte85a163c2009-08-10 11:43:22 +0200730 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +0800731 gsm_ts_name(lchan->ts), dh->chan_nr);
732
Harald Welte85a163c2009-08-10 11:43:22 +0200733 /* BTS will respond by RF CHAN REL ACK */
Harald Welte59b04682009-06-10 05:40:52 +0800734 return abis_rsl_sendmsg(msg);
735}
736
737int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
738 u_int8_t *ms_ident, u_int8_t chan_needed)
739{
740 struct abis_rsl_dchan_hdr *dh;
741 struct msgb *msg = rsl_msgb_alloc();
742
743 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
744 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
745 dh->chan_nr = RSL_CHAN_PCH_AGCH;
746
747 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
748 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
749 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
750
751 msg->trx = bts->c0;
752
753 return abis_rsl_sendmsg(msg);
754}
755
756int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
757 struct gsm_subscriber *subscr)
758{
759#if 0
760 u_int8_t mi[128];
761 unsigned int mi_len;
762 u_int8_t paging_group;
763#endif
764
765 return -1;
766}
767
768int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
769{
770 int i, len = strlen(str_in);
771
772 for (i = 0; i < len; i++) {
773 int num = str_in[i] - 0x30;
774 if (num < 0 || num > 9)
775 return -1;
776 if (i % 2 == 0)
777 bcd_out[i/2] = num;
778 else
779 bcd_out[i/2] |= (num << 4);
780 }
781
782 return 0;
783}
784
785/* Chapter 8.5.6 */
786int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
787{
788 struct msgb *msg = rsl_msgb_alloc();
789 struct abis_rsl_dchan_hdr *dh;
790 u_int8_t buf[MACBLOCK_SIZE];
791
792 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
793 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
794 dh->chan_nr = RSL_CHAN_PCH_AGCH;
795
796 switch (bts->type) {
797 case GSM_BTS_TYPE_BS11:
798 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
799 break;
800 default:
801 /* If phase 2, construct a FULL_IMM_ASS_INFO */
802 pad_macblock(buf, val, len);
803 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
804 break;
805 }
806
807 msg->trx = bts->c0;
808
809 return abis_rsl_sendmsg(msg);
810}
811
Harald Welte4684e632009-08-10 09:51:40 +0200812/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200813int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200814{
815 struct msgb *msg = rsl_msgb_alloc();
816 struct abis_rsl_dchan_hdr *dh;
817
818 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
819 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200820 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte4684e632009-08-10 09:51:40 +0200821 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte12090752009-08-10 10:07:33 +0200822 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200823
Harald Welte874a5b42009-08-10 11:26:14 +0200824 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
825 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
826
827 msg->trx = lchan->ts->trx;
828
Harald Welte4684e632009-08-10 09:51:40 +0200829 return abis_rsl_sendmsg(msg);
830}
831
832
Harald Welte59b04682009-06-10 05:40:52 +0800833/* Send "DATA REQUEST" message with given L3 Info payload */
834/* Chapter 8.3.1 */
835int rsl_data_request(struct msgb *msg, u_int8_t link_id)
836{
837 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
838 struct abis_rsl_rll_hdr *rh;
839
840 if (msg->lchan == NULL) {
841 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
842 return -EINVAL;
843 }
844
845 /* First push the L3 IE tag and length */
846 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
847
848 /* Then push the RSL header */
849 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
850 init_llm_hdr(rh, RSL_MT_DATA_REQ);
851 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
852 rh->chan_nr = lchan2chan_nr(msg->lchan);
853 rh->link_id = link_id;
854
855 msg->trx = msg->lchan->ts->trx;
856
857 return abis_rsl_sendmsg(msg);
858}
859
Harald Welteed9a5ab2009-08-09 13:47:35 +0200860/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
861/* Chapter 8.3.1 */
862int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
863{
864 struct msgb *msg = rsl_msgb_alloc();
865 struct abis_rsl_rll_hdr *rh;
866
867 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200868 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200869 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
870 rh->chan_nr = lchan2chan_nr(lchan);
871 rh->link_id = link_id;
872
873 msg->trx = lchan->ts->trx;
874
875 return abis_rsl_sendmsg(msg);
876}
877
Harald Welte0f2e3c12009-08-08 13:15:07 +0200878/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
879 This is what higher layers should call. The BTS then responds with
880 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
881 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
882 lchan_free() */
883int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
884{
885 struct msgb *msg = rsl_msgb_alloc();
886 struct abis_rsl_rll_hdr *rh;
887
888 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
889 init_llm_hdr(rh, RSL_MT_REL_REQ);
890 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
891 rh->chan_nr = lchan2chan_nr(lchan);
892 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200893 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200894
895 msg->trx = lchan->ts->trx;
896
897 return abis_rsl_sendmsg(msg);
898}
899
Harald Welte59b04682009-06-10 05:40:52 +0800900/* Chapter 8.4.2: Channel Activate Acknowledge */
901static int rsl_rx_chan_act_ack(struct msgb *msg)
902{
903 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
904
905 /* BTS has confirmed channel activation, we now need
906 * to assign the activated channel to the MS */
907 if (rslh->ie_chan != RSL_IE_CHAN_NR)
908 return -EINVAL;
909
910 return 0;
911}
912
913/* Chapter 8.4.3: Channel Activate NACK */
914static int rsl_rx_chan_act_nack(struct msgb *msg)
915{
916 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
917 struct tlv_parsed tp;
918
919 /* BTS has rejected channel activation ?!? */
920 if (dh->ie_chan != RSL_IE_CHAN_NR)
921 return -EINVAL;
922
923 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
924 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200925 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
926 TLVP_LEN(&tp, RSL_IE_CAUSE));
927
Harald Weltecddb9802009-08-09 19:50:08 +0200928 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800929 return 0;
930}
931
932/* Chapter 8.4.4: Connection Failure Indication */
933static int rsl_rx_conn_fail(struct msgb *msg)
934{
935 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
936 struct tlv_parsed tp;
937
938 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800939
940 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
941
Harald Weltef1a168d2009-07-28 17:58:09 +0200942 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
943 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
944 TLVP_LEN(&tp, RSL_IE_CAUSE));
945
Harald Welte59b04682009-06-10 05:40:52 +0800946 DEBUGPC(DRSL, "RELEASING.\n");
947
948 /* FIXME: only free it after channel release ACK */
Harald Welte85a163c2009-08-10 11:43:22 +0200949 return rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800950}
951
952static int rsl_rx_meas_res(struct msgb *msg)
953{
954 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
955 struct tlv_parsed tp;
956
Harald Welte02993682009-06-27 02:53:10 +0200957 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800958 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
959
960 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200961 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800962 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
963 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
964 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
965 if (len >= 3) {
966 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200967 DEBUGPC(DMEAS, "DTXd ");
968 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800969 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200970 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800971 val[2]>>3 & 0x7, val[2] & 0x7);
972 }
973 }
974 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200975 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800976 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200977 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800978 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200979 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200980 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200981 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200982 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200983 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200984 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
985 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200986 }
Harald Welte59b04682009-06-10 05:40:52 +0800987 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200988 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freyther6d0c8b42009-10-22 15:43:55 +0200989 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)64994ce2009-08-14 11:41:12 +0200990 return gsm0408_rcvmsg(msg, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800991 } else
Harald Welte02993682009-06-27 02:53:10 +0200992 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800993
994 return 0;
995}
996
997static int abis_rsl_rx_dchan(struct msgb *msg)
998{
999 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1000 int rc = 0;
1001 char *ts_name;
1002
1003 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1004 ts_name = gsm_ts_name(msg->lchan->ts);
1005
Harald Welte02993682009-06-27 02:53:10 +02001006 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
1007 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001008
1009 switch (rslh->c.msg_type) {
1010 case RSL_MT_CHAN_ACTIV_ACK:
1011 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
1012 rc = rsl_rx_chan_act_ack(msg);
1013 break;
1014 case RSL_MT_CHAN_ACTIV_NACK:
1015 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
1016 rc = rsl_rx_chan_act_nack(msg);
1017 break;
1018 case RSL_MT_CONN_FAIL:
1019 rc = rsl_rx_conn_fail(msg);
1020 break;
1021 case RSL_MT_MEAS_RES:
1022 rc = rsl_rx_meas_res(msg);
1023 break;
1024 case RSL_MT_RF_CHAN_REL_ACK:
1025 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
1026 lchan_free(msg->lchan);
1027 break;
1028 case RSL_MT_MODE_MODIFY_ACK:
1029 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
1030 break;
1031 case RSL_MT_MODE_MODIFY_NACK:
1032 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
1033 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001034 case RSL_MT_IPAC_PDCH_ACT_ACK:
1035 DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
1036 break;
1037 case RSL_MT_IPAC_PDCH_ACT_NACK:
1038 DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
1039 break;
1040 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1041 DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
1042 break;
1043 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1044 DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
1045 break;
Harald Welte59b04682009-06-10 05:40:52 +08001046 case RSL_MT_PHY_CONTEXT_CONF:
1047 case RSL_MT_PREPROC_MEAS_RES:
1048 case RSL_MT_TALKER_DET:
1049 case RSL_MT_LISTENER_DET:
1050 case RSL_MT_REMOTE_CODEC_CONF_REP:
1051 case RSL_MT_MR_CODEC_MOD_ACK:
1052 case RSL_MT_MR_CODEC_MOD_NACK:
1053 case RSL_MT_MR_CODEC_MOD_PER:
1054 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
1055 rslh->c.msg_type);
1056 break;
1057 default:
1058 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
1059 rslh->c.msg_type);
1060 return -EINVAL;
1061 }
1062
1063 return rc;
1064}
1065
1066static int rsl_rx_error_rep(struct msgb *msg)
1067{
1068 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001069 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001070
1071 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +02001072
1073 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1074
1075 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1076 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1077 TLVP_LEN(&tp, RSL_IE_CAUSE));
1078
Harald Welte59b04682009-06-10 05:40:52 +08001079 DEBUGPC(DRSL, "\n");
1080
1081 return 0;
1082}
1083
1084static int abis_rsl_rx_trx(struct msgb *msg)
1085{
1086 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1087 int rc = 0;
1088
1089 switch (rslh->msg_type) {
1090 case RSL_MT_ERROR_REPORT:
1091 rc = rsl_rx_error_rep(msg);
1092 break;
1093 case RSL_MT_RF_RES_IND:
1094 /* interference on idle channels of TRX */
1095 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1096 break;
1097 case RSL_MT_OVERLOAD:
1098 /* indicate CCCH / ACCH / processor overload */
1099 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1100 break;
1101 default:
1102 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1103 rslh->msg_type);
1104 return -EINVAL;
1105 }
1106 return rc;
1107}
1108
Harald Welte427dbc42009-08-10 00:26:10 +02001109/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1110static void t3101_expired(void *data)
1111{
1112 struct gsm_lchan *lchan = data;
1113
Harald Welte85a163c2009-08-10 11:43:22 +02001114 rsl_rf_chan_release(lchan);
Harald Welte427dbc42009-08-10 00:26:10 +02001115}
1116
Harald Welte59b04682009-06-10 05:40:52 +08001117/* MS has requested a channel on the RACH */
1118static int rsl_rx_chan_rqd(struct msgb *msg)
1119{
1120 struct gsm_bts *bts = msg->trx->bts;
1121 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1122 struct gsm48_req_ref *rqd_ref;
1123 struct gsm48_imm_ass ia;
1124 enum gsm_chan_t lctype;
1125 enum gsm_chreq_reason_t chreq_reason;
1126 struct gsm_lchan *lchan;
1127 u_int8_t rqd_ta;
1128 int ret;
1129
1130 u_int16_t arfcn;
1131 u_int8_t ts_number, subch;
1132
1133 /* parse request reference to be used in immediate assign */
1134 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1135 return -EINVAL;
1136
1137 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1138
1139 /* parse access delay and use as TA */
1140 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1141 return -EINVAL;
1142 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1143
1144 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1145 * request reference RA */
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +01001146 lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
1147 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001148
1149 /* check availability / allocate channel */
1150 lchan = lchan_alloc(bts, lctype);
1151 if (!lchan) {
Holger Hans Peter Freyther21ccb452009-11-16 15:37:05 +01001152 DEBUGP(DRSL, "CHAN RQD: no resources for %u 0x%x\n",
1153 lctype, rqd_ref->ra);
Harald Welte59b04682009-06-10 05:40:52 +08001154 /* FIXME: send some kind of reject ?!? */
1155 return -ENOMEM;
1156 }
1157
1158 ts_number = lchan->ts->nr;
1159 arfcn = lchan->ts->trx->arfcn;
1160 subch = lchan->nr;
1161
Harald Welted2dd9de2009-08-30 15:37:11 +09001162 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001163 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001164 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001165 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001166 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte39274f42009-07-29 15:41:29 +02001167 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001168
1169 /* create IMMEDIATE ASSIGN 04.08 messge */
1170 memset(&ia, 0, sizeof(ia));
1171 ia.l2_plen = 0x2d;
1172 ia.proto_discr = GSM48_PDISC_RR;
1173 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1174 ia.page_mode = GSM48_PM_SAME;
1175 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1176 ia.chan_desc.h0.h = 0;
1177 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1178 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001179 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001180 /* use request reference extracted from CHAN_RQD */
1181 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1182 ia.timing_advance = rqd_ta;
1183 ia.mob_alloc_len = 0;
1184
1185 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1186 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1187 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1188 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1189 rqd_ref->ra);
1190
Harald Welte427dbc42009-08-10 00:26:10 +02001191 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1192 lchan->T3101.cb = t3101_expired;
1193 lchan->T3101.data = lchan;
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +01001194 bsc_schedule_timer(&lchan->T3101, bts->network->T3101, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001195
1196 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1197 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1198
1199 return ret;
1200}
1201
1202/* MS has requested a channel on the RACH */
1203static int rsl_rx_ccch_load(struct msgb *msg)
1204{
1205 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1206 u_int16_t pg_buf_space;
1207 u_int16_t rach_slot_count = -1;
1208 u_int16_t rach_busy_count = -1;
1209 u_int16_t rach_access_count = -1;
1210
1211 switch (rslh->data[0]) {
1212 case RSL_IE_PAGING_LOAD:
1213 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1214 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1215 break;
1216 case RSL_IE_RACH_LOAD:
1217 if (msg->data_len >= 7) {
1218 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1219 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1220 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1221 }
1222 break;
1223 default:
1224 break;
1225 }
1226
1227 return 0;
1228}
1229
1230static int abis_rsl_rx_cchan(struct msgb *msg)
1231{
1232 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1233 int rc = 0;
1234
1235 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1236
1237 switch (rslh->c.msg_type) {
1238 case RSL_MT_CHAN_RQD:
1239 /* MS has requested a channel on the RACH */
1240 rc = rsl_rx_chan_rqd(msg);
1241 break;
1242 case RSL_MT_CCCH_LOAD_IND:
1243 /* current load on the CCCH */
1244 rc = rsl_rx_ccch_load(msg);
1245 break;
1246 case RSL_MT_DELETE_IND:
1247 /* CCCH overloaded, IMM_ASSIGN was dropped */
1248 case RSL_MT_CBCH_LOAD_IND:
1249 /* current load on the CBCH */
1250 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1251 "0x%02x\n", rslh->c.msg_type);
1252 break;
1253 default:
1254 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1255 rslh->c.msg_type);
1256 return -EINVAL;
1257 }
1258
1259 return rc;
1260}
1261
1262static int rsl_rx_rll_err_ind(struct msgb *msg)
1263{
1264 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1265 u_int8_t *rlm_cause = rllh->data;
1266
Harald Welteb6601442009-08-04 02:50:21 +02001267 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001268
1269 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001270
Harald Welte692f5852009-07-04 09:40:05 +02001271 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte85a163c2009-08-10 11:43:22 +02001272 return rsl_rf_chan_release(msg->lchan);
Harald Welte692f5852009-07-04 09:40:05 +02001273
Harald Welte59b04682009-06-10 05:40:52 +08001274 return 0;
1275}
1276
1277/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1278 0x02, 0x06,
1279 0x01, 0x20,
1280 0x02, 0x00,
1281 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1282
1283static int abis_rsl_rx_rll(struct msgb *msg)
1284{
1285 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1286 int rc = 0;
1287 char *ts_name;
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001288 u_int8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001289
1290 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1291 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001292 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1293 rllh->chan_nr, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001294
1295 switch (rllh->c.msg_type) {
1296 case RSL_MT_DATA_IND:
1297 DEBUGPC(DRLL, "DATA INDICATION\n");
1298 if (msgb_l2len(msg) >
1299 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1300 rllh->data[0] == RSL_IE_L3_INFO) {
1301 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001302 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001303 }
1304 break;
1305 case RSL_MT_EST_IND:
1306 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001307 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001308 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welte427dbc42009-08-10 00:26:10 +02001309 bsc_del_timer(&msg->lchan->T3101);
Harald Welte59b04682009-06-10 05:40:52 +08001310 if (msgb_l2len(msg) >
1311 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1312 rllh->data[0] == RSL_IE_L3_INFO) {
1313 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001314 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001315 }
1316 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001317 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001318 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001319 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001320 rll_indication(msg->lchan, rllh->link_id,
1321 BSC_RLLR_IND_EST_CONF);
1322 break;
Harald Welte59b04682009-06-10 05:40:52 +08001323 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001324 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001325 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001326 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001327 rll_indication(msg->lchan, rllh->link_id,
1328 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001329 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001330 /* FIXME: officially we need to start T3111 and wait for
1331 * some grace period */
1332 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001333 break;
1334 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001335 /* BTS informs us of having received UA from MS,
1336 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001337 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001338 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welte0f2e3c12009-08-08 13:15:07 +02001339 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001340 /* FIXME: officially we need to start T3111 and wait for
1341 * some grace period */
1342 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001343 break;
1344 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001345 rc = rsl_rx_rll_err_ind(msg);
1346 break;
1347 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001348 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001349 rllh->c.msg_type);
1350 break;
1351 default:
Harald Welteb6601442009-08-04 02:50:21 +02001352 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001353 rllh->c.msg_type);
1354 }
Harald Welte59b04682009-06-10 05:40:52 +08001355 return rc;
1356}
1357
Harald Welte98d79f92009-07-28 18:11:56 +02001358static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1359{
Harald Welte98d79f92009-07-28 18:11:56 +02001360 switch (tch_mode) {
1361 case GSM48_CMODE_SPEECH_V1:
1362 return 0x00;
1363 case GSM48_CMODE_SPEECH_EFR:
1364 return 0x01;
1365 case GSM48_CMODE_SPEECH_AMR:
1366 return 0x02;
1367 /* FIXME: Type1 half-rate and type3 half-rate */
1368 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001369 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1370 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001371 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001372}
1373
Harald Welte59b04682009-06-10 05:40:52 +08001374/* ip.access specific RSL extensions */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001375int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001376{
1377 struct msgb *msg = rsl_msgb_alloc();
1378 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001379 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001380
1381 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001382 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001383 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1384 dh->chan_nr = lchan2chan_nr(lchan);
1385
Harald Welte98d79f92009-07-28 18:11:56 +02001386 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001387 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1388 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001389
Harald Weltefb4a9e92009-07-29 12:12:18 +02001390 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1391 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1392 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001393
Harald Welte59b04682009-06-10 05:40:52 +08001394 msg->trx = lchan->ts->trx;
1395
1396 return abis_rsl_sendmsg(msg);
1397}
1398
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001399int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Welte8cdeaad2009-07-12 09:50:35 +02001400 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001401{
1402 struct msgb *msg = rsl_msgb_alloc();
1403 struct abis_rsl_dchan_hdr *dh;
1404 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001405 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001406 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001407
1408 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001409 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001410 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1411 dh->chan_nr = lchan2chan_nr(lchan);
1412
Harald Weltefb4a9e92009-07-29 12:12:18 +02001413 /* 0x0- == both directions, 0x-1 == EFR codec */
1414 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1415
Harald Welte98d79f92009-07-28 18:11:56 +02001416 ia.s_addr = htonl(ip);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001417 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_MDCX "
Harald Weltefb4a9e92009-07-29 12:12:18 +02001418 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001419 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001420 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001421
Harald Welte8cdeaad2009-07-12 09:50:35 +02001422 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001423 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001424 att_f8[1] = conn_id >> 8;
1425 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001426
1427 att_ip = msgb_put(msg, sizeof(ip)+1);
1428 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1429 att_ip[1] = ip >> 24;
1430 att_ip[2] = ip >> 16;
1431 att_ip[3] = ip >> 8;
1432 att_ip[4] = ip & 0xff;
1433 //att_ip[4] = 11;
1434
1435 att_port = msgb_put(msg, sizeof(port)+1);
1436 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1437 att_port[1] = port >> 8;
1438 att_port[2] = port & 0xff;
1439
Harald Weltefb4a9e92009-07-29 12:12:18 +02001440 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001441 if (rtp_payload2)
1442 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1443
Harald Welte59b04682009-06-10 05:40:52 +08001444 msg->trx = lchan->ts->trx;
1445
1446 return abis_rsl_sendmsg(msg);
1447}
1448
Harald Welteaed946e2009-10-24 10:29:22 +02001449int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
1450{
1451 struct msgb *msg = rsl_msgb_alloc();
1452 struct abis_rsl_dchan_hdr *dh;
1453
1454 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1455 init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
1456 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1457 dh->chan_nr = lchan2chan_nr(lchan);
1458
1459 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
1460 gsm_ts_name(lchan->ts), dh->chan_nr);
1461
1462 msg->trx = lchan->ts->trx;
1463
1464 return abis_rsl_sendmsg(msg);
1465}
1466
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001467static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001468{
1469 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1470 struct tlv_parsed tv;
1471 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1472 struct in_addr ip;
1473 u_int16_t port, attr_f8;
1474
1475 /* the BTS has acknowledged a local bind, it now tells us the IP
1476 * address and port number to which it has bound the given logical
1477 * channel */
1478
1479 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1480 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1481 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001482 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001483 DEBUGPC(DRSL, "mandatory IE missing");
1484 return -EINVAL;
1485 }
1486 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1487 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1488 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1489
Harald Welte98d79f92009-07-28 18:11:56 +02001490 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1491 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1492
1493 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1494 ts->abis_ip.rtp_payload2 =
1495 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1496 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1497 ts->abis_ip.rtp_payload2);
1498 }
Harald Welte59b04682009-06-10 05:40:52 +08001499
1500 /* update our local information about this TS */
1501 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1502 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001503 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001504
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001505 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001506
1507 return 0;
1508}
1509
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001510static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001511{
1512 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1513 struct tlv_parsed tv;
1514
1515 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001516
Harald Weltef1a168d2009-07-28 17:58:09 +02001517 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1518 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1519 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001520
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001521 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001522
Harald Welte59b04682009-06-10 05:40:52 +08001523 return 0;
1524}
1525
1526static int abis_rsl_rx_ipacc(struct msgb *msg)
1527{
1528 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1529 int rc = 0;
1530
1531 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1532 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1533 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1534
1535 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001536 case RSL_MT_IPAC_CRCX_ACK:
1537 DEBUGPC(DRSL, "IPAC_CRCX_ACK ");
1538 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001539 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001540 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001541 /* somehow the BTS was unable to bind the lchan to its local
1542 * port?!? */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001543 DEBUGPC(DRSL, "IPAC_CRCX_NACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001544 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001545 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001546 /* the BTS tells us that a connect operation was successful */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001547 DEBUGPC(DRSL, "IPAC_MDCX_ACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001548 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001549 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001550 /* somehow the BTS was unable to connect the lchan to a remote
1551 * port */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001552 DEBUGPC(DRSL, "IPAC_MDCX_NACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001553 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001554 case RSL_MT_IPAC_DLCX_IND:
1555 DEBUGPC(DRSL, "IPAC_DLCX_IND ");
1556 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001557 break;
1558 default:
1559 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1560 break;
1561 }
1562 DEBUGPC(DRSL, "\n");
1563
1564 return rc;
1565}
1566
1567
1568/* Entry-point where L2 RSL from BTS enters */
1569int abis_rsl_rcvmsg(struct msgb *msg)
1570{
1571 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1572 int rc = 0;
1573
1574 switch (rslh->msg_discr & 0xfe) {
1575 case ABIS_RSL_MDISC_RLL:
1576 rc = abis_rsl_rx_rll(msg);
1577 break;
1578 case ABIS_RSL_MDISC_DED_CHAN:
1579 rc = abis_rsl_rx_dchan(msg);
1580 break;
1581 case ABIS_RSL_MDISC_COM_CHAN:
1582 rc = abis_rsl_rx_cchan(msg);
1583 break;
1584 case ABIS_RSL_MDISC_TRX:
1585 rc = abis_rsl_rx_trx(msg);
1586 break;
1587 case ABIS_RSL_MDISC_LOC:
1588 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1589 rslh->msg_discr);
1590 break;
1591 case ABIS_RSL_MDISC_IPACCESS:
1592 rc = abis_rsl_rx_ipacc(msg);
1593 break;
1594 default:
1595 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1596 rslh->msg_discr);
1597 return -EINVAL;
1598 }
1599 msgb_free(msg);
1600 return rc;
1601}
1602
1603
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001604/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001605int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1606{
1607 switch (ccch_conf) {
1608 case RSL_BCCH_CCCH_CONF_1_NC:
1609 return 1;
1610 case RSL_BCCH_CCCH_CONF_1_C:
1611 return 1;
1612 case RSL_BCCH_CCCH_CONF_2_NC:
1613 return 2;
1614 case RSL_BCCH_CCCH_CONF_3_NC:
1615 return 3;
1616 case RSL_BCCH_CCCH_CONF_4_NC:
1617 return 4;
1618 default:
1619 return -1;
1620 }
1621}
1622
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001623/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001624int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1625{
1626 switch (ccch_conf) {
1627 case RSL_BCCH_CCCH_CONF_1_NC:
1628 return 0;
1629 case RSL_BCCH_CCCH_CONF_1_C:
1630 return 1;
1631 case RSL_BCCH_CCCH_CONF_2_NC:
1632 return 0;
1633 case RSL_BCCH_CCCH_CONF_3_NC:
1634 return 0;
1635 case RSL_BCCH_CCCH_CONF_4_NC:
1636 return 0;
1637 default:
1638 return -1;
1639 }
1640}
1641
1642/* From Table 10.5.33 of GSM 04.08 */
1643int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1644{
1645 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1646 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1647 * (bts->chan_desc.bs_pa_mfrms + 2);
1648 } else {
1649 return (9 - bts->chan_desc.bs_ag_blks_res)
1650 * (bts->chan_desc.bs_pa_mfrms + 2);
1651 }
1652}