blob: 0dee79b17b84965434fcb9a38441e33d2eb971d6 [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
491 switch (lchan->type) {
492 case GSM_LCHAN_SDCCH:
493 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
494 break;
495 case GSM_LCHAN_TCH_F:
496 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
497 break;
498 case GSM_LCHAN_TCH_H:
499 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
500 break;
501 case GSM_LCHAN_NONE:
502 case GSM_LCHAN_UNKNOWN:
503 default:
504 return -EINVAL;
505 }
506
507 switch (lchan->tch_mode) {
508 case GSM48_CMODE_SIGN:
509 cm->chan_rate = 0;
510 break;
511 case GSM48_CMODE_SPEECH_V1:
512 cm->chan_rate = RSL_CMOD_SP_GSM1;
513 break;
514 case GSM48_CMODE_SPEECH_EFR:
515 cm->chan_rate = RSL_CMOD_SP_GSM2;
516 break;
517 case GSM48_CMODE_SPEECH_AMR:
518 cm->chan_rate = RSL_CMOD_SP_GSM3;
519 break;
520 case GSM48_CMODE_DATA_14k5:
521 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
522 break;
523 case GSM48_CMODE_DATA_12k0:
524 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
525 break;
526 case GSM48_CMODE_DATA_6k0:
527 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
528 break;
529 default:
530 return -EINVAL;
531 }
532
533 return 0;
534}
535
Harald Welte59b04682009-06-10 05:40:52 +0800536/* Chapter 8.4.1 */
537#if 0
538int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
539 u_int8_t act_type,
540 struct rsl_ie_chan_mode *chan_mode,
541 struct rsl_ie_chan_ident *chan_ident,
542 u_int8_t bs_power, u_int8_t ms_power,
543 u_int8_t ta)
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_CHAN_ACTIV);
550 dh->chan_nr = chan_nr;
551
552 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
553 /* For compatibility with Phase 1 */
554 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
555 (u_int8_t *) chan_mode);
556 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
557 (u_int8_t *) chan_ident);
558#if 0
559 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
560 (u_int8_t *) &encr_info);
561#endif
562 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
563 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
564 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
565
566 msg->trx = trx;
567
568 return abis_rsl_sendmsg(msg);
569}
570#endif
571
572int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte39274f42009-07-29 15:41:29 +0200573 u_int8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800574{
575 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200576 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200577 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800578
579 u_int8_t chan_nr = lchan2chan_nr(lchan);
580 u_int16_t arfcn = lchan->ts->trx->arfcn;
581 struct rsl_ie_chan_mode cm;
582 struct rsl_ie_chan_ident ci;
583
Harald Welte39274f42009-07-29 15:41:29 +0200584 rc = channel_mode_from_lchan(&cm, lchan);
585 if (rc < 0)
586 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800587
588 memset(&ci, 0, sizeof(ci));
589 ci.chan_desc.iei = 0x64;
590 ci.chan_desc.chan_nr = chan_nr;
591 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
592 ci.chan_desc.oct4 = arfcn & 0xff;
593
Harald Welteed831842009-06-27 03:09:08 +0200594 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800595 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
596 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
597 dh->chan_nr = chan_nr;
598
599 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
600 /* For compatibility with Phase 1 */
601 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
602 (u_int8_t *) &cm);
603 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
604 (u_int8_t *) &ci);
Harald Welted2dd9de2009-08-30 15:37:11 +0900605
606 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
607 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
608 rc = build_encr_info(encr_info, lchan);
609 if (rc > 0)
610 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
611 }
612
Harald Welte59b04682009-06-10 05:40:52 +0800613 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
614 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
615 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
616
617 msg->trx = lchan->ts->trx;
618
619 return abis_rsl_sendmsg(msg);
620}
621
Harald Welte8e770492009-07-29 11:38:15 +0200622/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800623int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
624{
625 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200626 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200627 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800628
629 u_int8_t chan_nr = lchan2chan_nr(lchan);
630 struct rsl_ie_chan_mode cm;
631
Harald Welte39274f42009-07-29 15:41:29 +0200632 rc = channel_mode_from_lchan(&cm, lchan);
633 if (rc < 0)
634 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800635
Harald Welteed831842009-06-27 03:09:08 +0200636 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800637 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
638 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
639 dh->chan_nr = chan_nr;
640
641 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
642 (u_int8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900643
644 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
645 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
646 rc = build_encr_info(encr_info, lchan);
647 if (rc > 0)
648 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
649 }
650
Holger Hans Peter Freyther3cce58f2009-11-18 22:57:02 +0100651 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
652 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
653 (u_int8_t *) &lchan->mr_conf);
654 }
655
Harald Welted2dd9de2009-08-30 15:37:11 +0900656 msg->trx = lchan->ts->trx;
657
658 return abis_rsl_sendmsg(msg);
659}
660
661/* Chapter 8.4.6: Send the encryption command with given L3 info */
662int rsl_encryption_cmd(struct msgb *msg)
663{
664 struct abis_rsl_dchan_hdr *dh;
665 struct gsm_lchan *lchan = msg->lchan;
666 u_int8_t chan_nr = lchan2chan_nr(lchan);
667 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut01f1caf2009-09-27 11:13:18 +0200668 u_int8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900669 int rc;
670
671 /* First push the L3 IE tag and length */
672 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
673
674 /* then the link identifier (SAPI0, main sign link) */
675 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
676
677 /* then encryption information */
678 rc = build_encr_info(encr_info, lchan);
679 if (rc <= 0)
680 return rc;
681 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
682
683 /* and finally the DCHAN header */
684 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
685 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
686 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800687
688 msg->trx = lchan->ts->trx;
689
690 return abis_rsl_sendmsg(msg);
691}
692
Harald Welte85a163c2009-08-10 11:43:22 +0200693/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200694int rsl_deact_sacch(struct gsm_lchan *lchan)
695{
696 struct abis_rsl_dchan_hdr *dh;
697 struct msgb *msg = rsl_msgb_alloc();
698
699 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
700 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
701 dh->chan_nr = lchan2chan_nr(lchan);
702
703 msg->lchan = lchan;
704 msg->trx = lchan->ts->trx;
705
706 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
707 gsm_ts_name(lchan->ts), dh->chan_nr);
708
709 return abis_rsl_sendmsg(msg);
710}
711
Harald Welte85a163c2009-08-10 11:43:22 +0200712/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
713int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800714{
715 struct abis_rsl_dchan_hdr *dh;
716 struct msgb *msg = rsl_msgb_alloc();
717
718 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
719 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
720 dh->chan_nr = lchan2chan_nr(lchan);
721
722 msg->lchan = lchan;
723 msg->trx = lchan->ts->trx;
724
Harald Welte85a163c2009-08-10 11:43:22 +0200725 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +0800726 gsm_ts_name(lchan->ts), dh->chan_nr);
727
Harald Welte85a163c2009-08-10 11:43:22 +0200728 /* BTS will respond by RF CHAN REL ACK */
Harald Welte59b04682009-06-10 05:40:52 +0800729 return abis_rsl_sendmsg(msg);
730}
731
732int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
733 u_int8_t *ms_ident, u_int8_t chan_needed)
734{
735 struct abis_rsl_dchan_hdr *dh;
736 struct msgb *msg = rsl_msgb_alloc();
737
738 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
739 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
740 dh->chan_nr = RSL_CHAN_PCH_AGCH;
741
742 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
743 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
744 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
745
746 msg->trx = bts->c0;
747
748 return abis_rsl_sendmsg(msg);
749}
750
751int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
752 struct gsm_subscriber *subscr)
753{
754#if 0
755 u_int8_t mi[128];
756 unsigned int mi_len;
757 u_int8_t paging_group;
758#endif
759
760 return -1;
761}
762
763int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
764{
765 int i, len = strlen(str_in);
766
767 for (i = 0; i < len; i++) {
768 int num = str_in[i] - 0x30;
769 if (num < 0 || num > 9)
770 return -1;
771 if (i % 2 == 0)
772 bcd_out[i/2] = num;
773 else
774 bcd_out[i/2] |= (num << 4);
775 }
776
777 return 0;
778}
779
780/* Chapter 8.5.6 */
781int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
782{
783 struct msgb *msg = rsl_msgb_alloc();
784 struct abis_rsl_dchan_hdr *dh;
785 u_int8_t buf[MACBLOCK_SIZE];
786
787 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
788 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
789 dh->chan_nr = RSL_CHAN_PCH_AGCH;
790
791 switch (bts->type) {
792 case GSM_BTS_TYPE_BS11:
793 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
794 break;
795 default:
796 /* If phase 2, construct a FULL_IMM_ASS_INFO */
797 pad_macblock(buf, val, len);
798 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
799 break;
800 }
801
802 msg->trx = bts->c0;
803
804 return abis_rsl_sendmsg(msg);
805}
806
Harald Welte4684e632009-08-10 09:51:40 +0200807/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200808int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200809{
810 struct msgb *msg = rsl_msgb_alloc();
811 struct abis_rsl_dchan_hdr *dh;
812
813 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
814 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200815 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte4684e632009-08-10 09:51:40 +0200816 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte12090752009-08-10 10:07:33 +0200817 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200818
Harald Welte874a5b42009-08-10 11:26:14 +0200819 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
820 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
821
822 msg->trx = lchan->ts->trx;
823
Harald Welte4684e632009-08-10 09:51:40 +0200824 return abis_rsl_sendmsg(msg);
825}
826
827
Harald Welte59b04682009-06-10 05:40:52 +0800828/* Send "DATA REQUEST" message with given L3 Info payload */
829/* Chapter 8.3.1 */
830int rsl_data_request(struct msgb *msg, u_int8_t link_id)
831{
832 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
833 struct abis_rsl_rll_hdr *rh;
834
835 if (msg->lchan == NULL) {
836 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
837 return -EINVAL;
838 }
839
840 /* First push the L3 IE tag and length */
841 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
842
843 /* Then push the RSL header */
844 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
845 init_llm_hdr(rh, RSL_MT_DATA_REQ);
846 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
847 rh->chan_nr = lchan2chan_nr(msg->lchan);
848 rh->link_id = link_id;
849
850 msg->trx = msg->lchan->ts->trx;
851
852 return abis_rsl_sendmsg(msg);
853}
854
Harald Welteed9a5ab2009-08-09 13:47:35 +0200855/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
856/* Chapter 8.3.1 */
857int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
858{
859 struct msgb *msg = rsl_msgb_alloc();
860 struct abis_rsl_rll_hdr *rh;
861
862 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200863 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200864 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
865 rh->chan_nr = lchan2chan_nr(lchan);
866 rh->link_id = link_id;
867
868 msg->trx = lchan->ts->trx;
869
870 return abis_rsl_sendmsg(msg);
871}
872
Harald Welte0f2e3c12009-08-08 13:15:07 +0200873/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
874 This is what higher layers should call. The BTS then responds with
875 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
876 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
877 lchan_free() */
878int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
879{
880 struct msgb *msg = rsl_msgb_alloc();
881 struct abis_rsl_rll_hdr *rh;
882
883 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
884 init_llm_hdr(rh, RSL_MT_REL_REQ);
885 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
886 rh->chan_nr = lchan2chan_nr(lchan);
887 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200888 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200889
890 msg->trx = lchan->ts->trx;
891
892 return abis_rsl_sendmsg(msg);
893}
894
Harald Welte59b04682009-06-10 05:40:52 +0800895/* Chapter 8.4.2: Channel Activate Acknowledge */
896static int rsl_rx_chan_act_ack(struct msgb *msg)
897{
898 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
899
900 /* BTS has confirmed channel activation, we now need
901 * to assign the activated channel to the MS */
902 if (rslh->ie_chan != RSL_IE_CHAN_NR)
903 return -EINVAL;
904
905 return 0;
906}
907
908/* Chapter 8.4.3: Channel Activate NACK */
909static int rsl_rx_chan_act_nack(struct msgb *msg)
910{
911 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
912 struct tlv_parsed tp;
913
914 /* BTS has rejected channel activation ?!? */
915 if (dh->ie_chan != RSL_IE_CHAN_NR)
916 return -EINVAL;
917
918 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
919 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200920 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
921 TLVP_LEN(&tp, RSL_IE_CAUSE));
922
Harald Weltecddb9802009-08-09 19:50:08 +0200923 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800924 return 0;
925}
926
927/* Chapter 8.4.4: Connection Failure Indication */
928static int rsl_rx_conn_fail(struct msgb *msg)
929{
930 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
931 struct tlv_parsed tp;
932
933 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800934
935 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
936
Harald Weltef1a168d2009-07-28 17:58:09 +0200937 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
938 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
939 TLVP_LEN(&tp, RSL_IE_CAUSE));
940
Harald Welte59b04682009-06-10 05:40:52 +0800941 DEBUGPC(DRSL, "RELEASING.\n");
942
943 /* FIXME: only free it after channel release ACK */
Harald Welte85a163c2009-08-10 11:43:22 +0200944 return rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800945}
946
947static int rsl_rx_meas_res(struct msgb *msg)
948{
949 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
950 struct tlv_parsed tp;
951
Harald Welte02993682009-06-27 02:53:10 +0200952 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800953 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
954
955 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200956 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800957 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
958 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
959 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
960 if (len >= 3) {
961 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200962 DEBUGPC(DMEAS, "DTXd ");
963 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800964 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200965 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800966 val[2]>>3 & 0x7, val[2] & 0x7);
967 }
968 }
969 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200970 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800971 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200972 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800973 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200974 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200975 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200976 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200977 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200978 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200979 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
980 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200981 }
Harald Welte59b04682009-06-10 05:40:52 +0800982 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200983 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freyther6d0c8b42009-10-22 15:43:55 +0200984 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)64994ce2009-08-14 11:41:12 +0200985 return gsm0408_rcvmsg(msg, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800986 } else
Harald Welte02993682009-06-27 02:53:10 +0200987 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800988
989 return 0;
990}
991
992static int abis_rsl_rx_dchan(struct msgb *msg)
993{
994 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
995 int rc = 0;
996 char *ts_name;
997
998 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
999 ts_name = gsm_ts_name(msg->lchan->ts);
1000
Harald Welte02993682009-06-27 02:53:10 +02001001 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
1002 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001003
1004 switch (rslh->c.msg_type) {
1005 case RSL_MT_CHAN_ACTIV_ACK:
1006 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
1007 rc = rsl_rx_chan_act_ack(msg);
1008 break;
1009 case RSL_MT_CHAN_ACTIV_NACK:
1010 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
1011 rc = rsl_rx_chan_act_nack(msg);
1012 break;
1013 case RSL_MT_CONN_FAIL:
1014 rc = rsl_rx_conn_fail(msg);
1015 break;
1016 case RSL_MT_MEAS_RES:
1017 rc = rsl_rx_meas_res(msg);
1018 break;
1019 case RSL_MT_RF_CHAN_REL_ACK:
1020 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
1021 lchan_free(msg->lchan);
1022 break;
1023 case RSL_MT_MODE_MODIFY_ACK:
1024 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
1025 break;
1026 case RSL_MT_MODE_MODIFY_NACK:
1027 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
1028 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001029 case RSL_MT_IPAC_PDCH_ACT_ACK:
1030 DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
1031 break;
1032 case RSL_MT_IPAC_PDCH_ACT_NACK:
1033 DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
1034 break;
1035 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1036 DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
1037 break;
1038 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1039 DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
1040 break;
Harald Welte59b04682009-06-10 05:40:52 +08001041 case RSL_MT_PHY_CONTEXT_CONF:
1042 case RSL_MT_PREPROC_MEAS_RES:
1043 case RSL_MT_TALKER_DET:
1044 case RSL_MT_LISTENER_DET:
1045 case RSL_MT_REMOTE_CODEC_CONF_REP:
1046 case RSL_MT_MR_CODEC_MOD_ACK:
1047 case RSL_MT_MR_CODEC_MOD_NACK:
1048 case RSL_MT_MR_CODEC_MOD_PER:
1049 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
1050 rslh->c.msg_type);
1051 break;
1052 default:
1053 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
1054 rslh->c.msg_type);
1055 return -EINVAL;
1056 }
1057
1058 return rc;
1059}
1060
1061static int rsl_rx_error_rep(struct msgb *msg)
1062{
1063 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001064 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001065
1066 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +02001067
1068 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1069
1070 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1071 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1072 TLVP_LEN(&tp, RSL_IE_CAUSE));
1073
Harald Welte59b04682009-06-10 05:40:52 +08001074 DEBUGPC(DRSL, "\n");
1075
1076 return 0;
1077}
1078
1079static int abis_rsl_rx_trx(struct msgb *msg)
1080{
1081 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1082 int rc = 0;
1083
1084 switch (rslh->msg_type) {
1085 case RSL_MT_ERROR_REPORT:
1086 rc = rsl_rx_error_rep(msg);
1087 break;
1088 case RSL_MT_RF_RES_IND:
1089 /* interference on idle channels of TRX */
1090 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1091 break;
1092 case RSL_MT_OVERLOAD:
1093 /* indicate CCCH / ACCH / processor overload */
1094 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1095 break;
1096 default:
1097 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1098 rslh->msg_type);
1099 return -EINVAL;
1100 }
1101 return rc;
1102}
1103
Harald Welte427dbc42009-08-10 00:26:10 +02001104/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1105static void t3101_expired(void *data)
1106{
1107 struct gsm_lchan *lchan = data;
1108
Harald Welte85a163c2009-08-10 11:43:22 +02001109 rsl_rf_chan_release(lchan);
Harald Welte427dbc42009-08-10 00:26:10 +02001110}
1111
Harald Welte59b04682009-06-10 05:40:52 +08001112/* MS has requested a channel on the RACH */
1113static int rsl_rx_chan_rqd(struct msgb *msg)
1114{
1115 struct gsm_bts *bts = msg->trx->bts;
1116 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1117 struct gsm48_req_ref *rqd_ref;
1118 struct gsm48_imm_ass ia;
1119 enum gsm_chan_t lctype;
1120 enum gsm_chreq_reason_t chreq_reason;
1121 struct gsm_lchan *lchan;
1122 u_int8_t rqd_ta;
1123 int ret;
1124
1125 u_int16_t arfcn;
1126 u_int8_t ts_number, subch;
1127
1128 /* parse request reference to be used in immediate assign */
1129 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1130 return -EINVAL;
1131
1132 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1133
1134 /* parse access delay and use as TA */
1135 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1136 return -EINVAL;
1137 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1138
1139 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1140 * request reference RA */
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +01001141 lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
1142 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001143
1144 /* check availability / allocate channel */
1145 lchan = lchan_alloc(bts, lctype);
1146 if (!lchan) {
Holger Hans Peter Freyther21ccb452009-11-16 15:37:05 +01001147 DEBUGP(DRSL, "CHAN RQD: no resources for %u 0x%x\n",
1148 lctype, rqd_ref->ra);
Harald Welte59b04682009-06-10 05:40:52 +08001149 /* FIXME: send some kind of reject ?!? */
1150 return -ENOMEM;
1151 }
1152
1153 ts_number = lchan->ts->nr;
1154 arfcn = lchan->ts->trx->arfcn;
1155 subch = lchan->nr;
1156
Harald Welted2dd9de2009-08-30 15:37:11 +09001157 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001158 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001159 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001160 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001161 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte39274f42009-07-29 15:41:29 +02001162 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001163
1164 /* create IMMEDIATE ASSIGN 04.08 messge */
1165 memset(&ia, 0, sizeof(ia));
1166 ia.l2_plen = 0x2d;
1167 ia.proto_discr = GSM48_PDISC_RR;
1168 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1169 ia.page_mode = GSM48_PM_SAME;
1170 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1171 ia.chan_desc.h0.h = 0;
1172 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1173 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001174 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001175 /* use request reference extracted from CHAN_RQD */
1176 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1177 ia.timing_advance = rqd_ta;
1178 ia.mob_alloc_len = 0;
1179
1180 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1181 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1182 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1183 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1184 rqd_ref->ra);
1185
Harald Welte427dbc42009-08-10 00:26:10 +02001186 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1187 lchan->T3101.cb = t3101_expired;
1188 lchan->T3101.data = lchan;
1189 bsc_schedule_timer(&lchan->T3101, 10, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001190
1191 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1192 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1193
1194 return ret;
1195}
1196
1197/* MS has requested a channel on the RACH */
1198static int rsl_rx_ccch_load(struct msgb *msg)
1199{
1200 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1201 u_int16_t pg_buf_space;
1202 u_int16_t rach_slot_count = -1;
1203 u_int16_t rach_busy_count = -1;
1204 u_int16_t rach_access_count = -1;
1205
1206 switch (rslh->data[0]) {
1207 case RSL_IE_PAGING_LOAD:
1208 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1209 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1210 break;
1211 case RSL_IE_RACH_LOAD:
1212 if (msg->data_len >= 7) {
1213 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1214 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1215 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1216 }
1217 break;
1218 default:
1219 break;
1220 }
1221
1222 return 0;
1223}
1224
1225static int abis_rsl_rx_cchan(struct msgb *msg)
1226{
1227 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1228 int rc = 0;
1229
1230 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1231
1232 switch (rslh->c.msg_type) {
1233 case RSL_MT_CHAN_RQD:
1234 /* MS has requested a channel on the RACH */
1235 rc = rsl_rx_chan_rqd(msg);
1236 break;
1237 case RSL_MT_CCCH_LOAD_IND:
1238 /* current load on the CCCH */
1239 rc = rsl_rx_ccch_load(msg);
1240 break;
1241 case RSL_MT_DELETE_IND:
1242 /* CCCH overloaded, IMM_ASSIGN was dropped */
1243 case RSL_MT_CBCH_LOAD_IND:
1244 /* current load on the CBCH */
1245 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1246 "0x%02x\n", rslh->c.msg_type);
1247 break;
1248 default:
1249 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1250 rslh->c.msg_type);
1251 return -EINVAL;
1252 }
1253
1254 return rc;
1255}
1256
1257static int rsl_rx_rll_err_ind(struct msgb *msg)
1258{
1259 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1260 u_int8_t *rlm_cause = rllh->data;
1261
Harald Welteb6601442009-08-04 02:50:21 +02001262 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001263
1264 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001265
Harald Welte692f5852009-07-04 09:40:05 +02001266 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte85a163c2009-08-10 11:43:22 +02001267 return rsl_rf_chan_release(msg->lchan);
Harald Welte692f5852009-07-04 09:40:05 +02001268
Harald Welte59b04682009-06-10 05:40:52 +08001269 return 0;
1270}
1271
1272/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1273 0x02, 0x06,
1274 0x01, 0x20,
1275 0x02, 0x00,
1276 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1277
1278static int abis_rsl_rx_rll(struct msgb *msg)
1279{
1280 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1281 int rc = 0;
1282 char *ts_name;
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001283 u_int8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001284
1285 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1286 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001287 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1288 rllh->chan_nr, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001289
1290 switch (rllh->c.msg_type) {
1291 case RSL_MT_DATA_IND:
1292 DEBUGPC(DRLL, "DATA INDICATION\n");
1293 if (msgb_l2len(msg) >
1294 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1295 rllh->data[0] == RSL_IE_L3_INFO) {
1296 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001297 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001298 }
1299 break;
1300 case RSL_MT_EST_IND:
1301 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001302 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001303 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welte427dbc42009-08-10 00:26:10 +02001304 bsc_del_timer(&msg->lchan->T3101);
Harald Welte59b04682009-06-10 05:40:52 +08001305 if (msgb_l2len(msg) >
1306 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1307 rllh->data[0] == RSL_IE_L3_INFO) {
1308 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001309 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001310 }
1311 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001312 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001313 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001314 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001315 rll_indication(msg->lchan, rllh->link_id,
1316 BSC_RLLR_IND_EST_CONF);
1317 break;
Harald Welte59b04682009-06-10 05:40:52 +08001318 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001319 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001320 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001321 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001322 rll_indication(msg->lchan, rllh->link_id,
1323 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001324 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001325 /* FIXME: officially we need to start T3111 and wait for
1326 * some grace period */
1327 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001328 break;
1329 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001330 /* BTS informs us of having received UA from MS,
1331 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001332 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001333 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welte0f2e3c12009-08-08 13:15:07 +02001334 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001335 /* FIXME: officially we need to start T3111 and wait for
1336 * some grace period */
1337 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001338 break;
1339 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001340 rc = rsl_rx_rll_err_ind(msg);
1341 break;
1342 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001343 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001344 rllh->c.msg_type);
1345 break;
1346 default:
Harald Welteb6601442009-08-04 02:50:21 +02001347 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001348 rllh->c.msg_type);
1349 }
Harald Welte59b04682009-06-10 05:40:52 +08001350 return rc;
1351}
1352
Harald Welte98d79f92009-07-28 18:11:56 +02001353static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1354{
Harald Welte98d79f92009-07-28 18:11:56 +02001355 switch (tch_mode) {
1356 case GSM48_CMODE_SPEECH_V1:
1357 return 0x00;
1358 case GSM48_CMODE_SPEECH_EFR:
1359 return 0x01;
1360 case GSM48_CMODE_SPEECH_AMR:
1361 return 0x02;
1362 /* FIXME: Type1 half-rate and type3 half-rate */
1363 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001364 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1365 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001366 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001367}
1368
Harald Welte59b04682009-06-10 05:40:52 +08001369/* ip.access specific RSL extensions */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001370int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001371{
1372 struct msgb *msg = rsl_msgb_alloc();
1373 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001374 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001375
1376 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001377 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001378 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1379 dh->chan_nr = lchan2chan_nr(lchan);
1380
Harald Welte98d79f92009-07-28 18:11:56 +02001381 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001382 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1383 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001384
Harald Weltefb4a9e92009-07-29 12:12:18 +02001385 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1386 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1387 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001388
Harald Welte59b04682009-06-10 05:40:52 +08001389 msg->trx = lchan->ts->trx;
1390
1391 return abis_rsl_sendmsg(msg);
1392}
1393
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001394int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Welte8cdeaad2009-07-12 09:50:35 +02001395 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001396{
1397 struct msgb *msg = rsl_msgb_alloc();
1398 struct abis_rsl_dchan_hdr *dh;
1399 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001400 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001401 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001402
1403 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001404 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001405 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1406 dh->chan_nr = lchan2chan_nr(lchan);
1407
Harald Weltefb4a9e92009-07-29 12:12:18 +02001408 /* 0x0- == both directions, 0x-1 == EFR codec */
1409 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1410
Harald Welte98d79f92009-07-28 18:11:56 +02001411 ia.s_addr = htonl(ip);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001412 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_MDCX "
Harald Weltefb4a9e92009-07-29 12:12:18 +02001413 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001414 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001415 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001416
Harald Welte8cdeaad2009-07-12 09:50:35 +02001417 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001418 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001419 att_f8[1] = conn_id >> 8;
1420 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001421
1422 att_ip = msgb_put(msg, sizeof(ip)+1);
1423 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1424 att_ip[1] = ip >> 24;
1425 att_ip[2] = ip >> 16;
1426 att_ip[3] = ip >> 8;
1427 att_ip[4] = ip & 0xff;
1428 //att_ip[4] = 11;
1429
1430 att_port = msgb_put(msg, sizeof(port)+1);
1431 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1432 att_port[1] = port >> 8;
1433 att_port[2] = port & 0xff;
1434
Harald Weltefb4a9e92009-07-29 12:12:18 +02001435 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001436 if (rtp_payload2)
1437 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1438
Harald Welte59b04682009-06-10 05:40:52 +08001439 msg->trx = lchan->ts->trx;
1440
1441 return abis_rsl_sendmsg(msg);
1442}
1443
Harald Welteaed946e2009-10-24 10:29:22 +02001444int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
1445{
1446 struct msgb *msg = rsl_msgb_alloc();
1447 struct abis_rsl_dchan_hdr *dh;
1448
1449 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1450 init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
1451 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1452 dh->chan_nr = lchan2chan_nr(lchan);
1453
1454 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
1455 gsm_ts_name(lchan->ts), dh->chan_nr);
1456
1457 msg->trx = lchan->ts->trx;
1458
1459 return abis_rsl_sendmsg(msg);
1460}
1461
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001462static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001463{
1464 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1465 struct tlv_parsed tv;
1466 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1467 struct in_addr ip;
1468 u_int16_t port, attr_f8;
1469
1470 /* the BTS has acknowledged a local bind, it now tells us the IP
1471 * address and port number to which it has bound the given logical
1472 * channel */
1473
1474 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1475 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1476 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001477 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001478 DEBUGPC(DRSL, "mandatory IE missing");
1479 return -EINVAL;
1480 }
1481 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1482 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1483 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1484
Harald Welte98d79f92009-07-28 18:11:56 +02001485 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1486 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1487
1488 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1489 ts->abis_ip.rtp_payload2 =
1490 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1491 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1492 ts->abis_ip.rtp_payload2);
1493 }
Harald Welte59b04682009-06-10 05:40:52 +08001494
1495 /* update our local information about this TS */
1496 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1497 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001498 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001499
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001500 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001501
1502 return 0;
1503}
1504
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001505static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001506{
1507 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1508 struct tlv_parsed tv;
1509
1510 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001511
Harald Weltef1a168d2009-07-28 17:58:09 +02001512 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1513 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1514 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001515
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001516 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001517
Harald Welte59b04682009-06-10 05:40:52 +08001518 return 0;
1519}
1520
1521static int abis_rsl_rx_ipacc(struct msgb *msg)
1522{
1523 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1524 int rc = 0;
1525
1526 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1527 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1528 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1529
1530 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001531 case RSL_MT_IPAC_CRCX_ACK:
1532 DEBUGPC(DRSL, "IPAC_CRCX_ACK ");
1533 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001534 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001535 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001536 /* somehow the BTS was unable to bind the lchan to its local
1537 * port?!? */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001538 DEBUGPC(DRSL, "IPAC_CRCX_NACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001539 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001540 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001541 /* the BTS tells us that a connect operation was successful */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001542 DEBUGPC(DRSL, "IPAC_MDCX_ACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001543 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001544 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001545 /* somehow the BTS was unable to connect the lchan to a remote
1546 * port */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001547 DEBUGPC(DRSL, "IPAC_MDCX_NACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001548 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001549 case RSL_MT_IPAC_DLCX_IND:
1550 DEBUGPC(DRSL, "IPAC_DLCX_IND ");
1551 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001552 break;
1553 default:
1554 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1555 break;
1556 }
1557 DEBUGPC(DRSL, "\n");
1558
1559 return rc;
1560}
1561
1562
1563/* Entry-point where L2 RSL from BTS enters */
1564int abis_rsl_rcvmsg(struct msgb *msg)
1565{
1566 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1567 int rc = 0;
1568
1569 switch (rslh->msg_discr & 0xfe) {
1570 case ABIS_RSL_MDISC_RLL:
1571 rc = abis_rsl_rx_rll(msg);
1572 break;
1573 case ABIS_RSL_MDISC_DED_CHAN:
1574 rc = abis_rsl_rx_dchan(msg);
1575 break;
1576 case ABIS_RSL_MDISC_COM_CHAN:
1577 rc = abis_rsl_rx_cchan(msg);
1578 break;
1579 case ABIS_RSL_MDISC_TRX:
1580 rc = abis_rsl_rx_trx(msg);
1581 break;
1582 case ABIS_RSL_MDISC_LOC:
1583 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1584 rslh->msg_discr);
1585 break;
1586 case ABIS_RSL_MDISC_IPACCESS:
1587 rc = abis_rsl_rx_ipacc(msg);
1588 break;
1589 default:
1590 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1591 rslh->msg_discr);
1592 return -EINVAL;
1593 }
1594 msgb_free(msg);
1595 return rc;
1596}
1597
1598
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001599/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001600int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1601{
1602 switch (ccch_conf) {
1603 case RSL_BCCH_CCCH_CONF_1_NC:
1604 return 1;
1605 case RSL_BCCH_CCCH_CONF_1_C:
1606 return 1;
1607 case RSL_BCCH_CCCH_CONF_2_NC:
1608 return 2;
1609 case RSL_BCCH_CCCH_CONF_3_NC:
1610 return 3;
1611 case RSL_BCCH_CCCH_CONF_4_NC:
1612 return 4;
1613 default:
1614 return -1;
1615 }
1616}
1617
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001618/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001619int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1620{
1621 switch (ccch_conf) {
1622 case RSL_BCCH_CCCH_CONF_1_NC:
1623 return 0;
1624 case RSL_BCCH_CCCH_CONF_1_C:
1625 return 1;
1626 case RSL_BCCH_CCCH_CONF_2_NC:
1627 return 0;
1628 case RSL_BCCH_CCCH_CONF_3_NC:
1629 return 0;
1630 case RSL_BCCH_CCCH_CONF_4_NC:
1631 return 0;
1632 default:
1633 return -1;
1634 }
1635}
1636
1637/* From Table 10.5.33 of GSM 04.08 */
1638int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1639{
1640 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1641 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1642 * (bts->chan_desc.bs_pa_mfrms + 2);
1643 } else {
1644 return (9 - bts->chan_desc.bs_ag_blks_res)
1645 * (bts->chan_desc.bs_pa_mfrms + 2);
1646 }
1647}