blob: f6e0b87a714dacdbb15d2564d9a006564c795adc [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
651 msg->trx = lchan->ts->trx;
652
653 return abis_rsl_sendmsg(msg);
654}
655
656/* Chapter 8.4.6: Send the encryption command with given L3 info */
657int rsl_encryption_cmd(struct msgb *msg)
658{
659 struct abis_rsl_dchan_hdr *dh;
660 struct gsm_lchan *lchan = msg->lchan;
661 u_int8_t chan_nr = lchan2chan_nr(lchan);
662 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut01f1caf2009-09-27 11:13:18 +0200663 u_int8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900664 int rc;
665
666 /* First push the L3 IE tag and length */
667 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
668
669 /* then the link identifier (SAPI0, main sign link) */
670 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
671
672 /* then encryption information */
673 rc = build_encr_info(encr_info, lchan);
674 if (rc <= 0)
675 return rc;
676 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
677
678 /* and finally the DCHAN header */
679 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
680 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
681 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800682
683 msg->trx = lchan->ts->trx;
684
685 return abis_rsl_sendmsg(msg);
686}
687
Harald Welte85a163c2009-08-10 11:43:22 +0200688/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200689int rsl_deact_sacch(struct gsm_lchan *lchan)
690{
691 struct abis_rsl_dchan_hdr *dh;
692 struct msgb *msg = rsl_msgb_alloc();
693
694 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
695 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
696 dh->chan_nr = lchan2chan_nr(lchan);
697
698 msg->lchan = lchan;
699 msg->trx = lchan->ts->trx;
700
701 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
702 gsm_ts_name(lchan->ts), dh->chan_nr);
703
704 return abis_rsl_sendmsg(msg);
705}
706
Harald Welte85a163c2009-08-10 11:43:22 +0200707/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
708int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800709{
710 struct abis_rsl_dchan_hdr *dh;
711 struct msgb *msg = rsl_msgb_alloc();
712
713 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
714 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
715 dh->chan_nr = lchan2chan_nr(lchan);
716
717 msg->lchan = lchan;
718 msg->trx = lchan->ts->trx;
719
Harald Welte85a163c2009-08-10 11:43:22 +0200720 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +0800721 gsm_ts_name(lchan->ts), dh->chan_nr);
722
Harald Welte85a163c2009-08-10 11:43:22 +0200723 /* BTS will respond by RF CHAN REL ACK */
Harald Welte59b04682009-06-10 05:40:52 +0800724 return abis_rsl_sendmsg(msg);
725}
726
727int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
728 u_int8_t *ms_ident, u_int8_t chan_needed)
729{
730 struct abis_rsl_dchan_hdr *dh;
731 struct msgb *msg = rsl_msgb_alloc();
732
733 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
734 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
735 dh->chan_nr = RSL_CHAN_PCH_AGCH;
736
737 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
738 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
739 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
740
741 msg->trx = bts->c0;
742
743 return abis_rsl_sendmsg(msg);
744}
745
746int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
747 struct gsm_subscriber *subscr)
748{
749#if 0
750 u_int8_t mi[128];
751 unsigned int mi_len;
752 u_int8_t paging_group;
753#endif
754
755 return -1;
756}
757
758int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
759{
760 int i, len = strlen(str_in);
761
762 for (i = 0; i < len; i++) {
763 int num = str_in[i] - 0x30;
764 if (num < 0 || num > 9)
765 return -1;
766 if (i % 2 == 0)
767 bcd_out[i/2] = num;
768 else
769 bcd_out[i/2] |= (num << 4);
770 }
771
772 return 0;
773}
774
775/* Chapter 8.5.6 */
776int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
777{
778 struct msgb *msg = rsl_msgb_alloc();
779 struct abis_rsl_dchan_hdr *dh;
780 u_int8_t buf[MACBLOCK_SIZE];
781
782 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
783 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
784 dh->chan_nr = RSL_CHAN_PCH_AGCH;
785
786 switch (bts->type) {
787 case GSM_BTS_TYPE_BS11:
788 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
789 break;
790 default:
791 /* If phase 2, construct a FULL_IMM_ASS_INFO */
792 pad_macblock(buf, val, len);
793 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
794 break;
795 }
796
797 msg->trx = bts->c0;
798
799 return abis_rsl_sendmsg(msg);
800}
801
Harald Welte4684e632009-08-10 09:51:40 +0200802/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200803int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200804{
805 struct msgb *msg = rsl_msgb_alloc();
806 struct abis_rsl_dchan_hdr *dh;
807
808 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
809 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200810 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte4684e632009-08-10 09:51:40 +0200811 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte12090752009-08-10 10:07:33 +0200812 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200813
Harald Welte874a5b42009-08-10 11:26:14 +0200814 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
815 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
816
817 msg->trx = lchan->ts->trx;
818
Harald Welte4684e632009-08-10 09:51:40 +0200819 return abis_rsl_sendmsg(msg);
820}
821
822
Harald Welte59b04682009-06-10 05:40:52 +0800823/* Send "DATA REQUEST" message with given L3 Info payload */
824/* Chapter 8.3.1 */
825int rsl_data_request(struct msgb *msg, u_int8_t link_id)
826{
827 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
828 struct abis_rsl_rll_hdr *rh;
829
830 if (msg->lchan == NULL) {
831 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
832 return -EINVAL;
833 }
834
835 /* First push the L3 IE tag and length */
836 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
837
838 /* Then push the RSL header */
839 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
840 init_llm_hdr(rh, RSL_MT_DATA_REQ);
841 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
842 rh->chan_nr = lchan2chan_nr(msg->lchan);
843 rh->link_id = link_id;
844
845 msg->trx = msg->lchan->ts->trx;
846
847 return abis_rsl_sendmsg(msg);
848}
849
Harald Welteed9a5ab2009-08-09 13:47:35 +0200850/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
851/* Chapter 8.3.1 */
852int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
853{
854 struct msgb *msg = rsl_msgb_alloc();
855 struct abis_rsl_rll_hdr *rh;
856
857 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200858 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200859 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
860 rh->chan_nr = lchan2chan_nr(lchan);
861 rh->link_id = link_id;
862
863 msg->trx = lchan->ts->trx;
864
865 return abis_rsl_sendmsg(msg);
866}
867
Harald Welte0f2e3c12009-08-08 13:15:07 +0200868/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
869 This is what higher layers should call. The BTS then responds with
870 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
871 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
872 lchan_free() */
873int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
874{
875 struct msgb *msg = rsl_msgb_alloc();
876 struct abis_rsl_rll_hdr *rh;
877
878 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
879 init_llm_hdr(rh, RSL_MT_REL_REQ);
880 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
881 rh->chan_nr = lchan2chan_nr(lchan);
882 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200883 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200884
885 msg->trx = lchan->ts->trx;
886
887 return abis_rsl_sendmsg(msg);
888}
889
Harald Welte59b04682009-06-10 05:40:52 +0800890/* Chapter 8.4.2: Channel Activate Acknowledge */
891static int rsl_rx_chan_act_ack(struct msgb *msg)
892{
893 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
894
895 /* BTS has confirmed channel activation, we now need
896 * to assign the activated channel to the MS */
897 if (rslh->ie_chan != RSL_IE_CHAN_NR)
898 return -EINVAL;
899
900 return 0;
901}
902
903/* Chapter 8.4.3: Channel Activate NACK */
904static int rsl_rx_chan_act_nack(struct msgb *msg)
905{
906 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
907 struct tlv_parsed tp;
908
909 /* BTS has rejected channel activation ?!? */
910 if (dh->ie_chan != RSL_IE_CHAN_NR)
911 return -EINVAL;
912
913 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
914 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200915 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
916 TLVP_LEN(&tp, RSL_IE_CAUSE));
917
Harald Weltecddb9802009-08-09 19:50:08 +0200918 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800919 return 0;
920}
921
922/* Chapter 8.4.4: Connection Failure Indication */
923static int rsl_rx_conn_fail(struct msgb *msg)
924{
925 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
926 struct tlv_parsed tp;
927
928 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800929
930 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
931
Harald Weltef1a168d2009-07-28 17:58:09 +0200932 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
933 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
934 TLVP_LEN(&tp, RSL_IE_CAUSE));
935
Harald Welte59b04682009-06-10 05:40:52 +0800936 DEBUGPC(DRSL, "RELEASING.\n");
937
938 /* FIXME: only free it after channel release ACK */
Harald Welte85a163c2009-08-10 11:43:22 +0200939 return rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800940}
941
942static int rsl_rx_meas_res(struct msgb *msg)
943{
944 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
945 struct tlv_parsed tp;
946
Harald Welte02993682009-06-27 02:53:10 +0200947 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800948 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
949
950 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200951 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800952 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
953 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
954 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
955 if (len >= 3) {
956 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200957 DEBUGPC(DMEAS, "DTXd ");
958 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800959 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200960 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800961 val[2]>>3 & 0x7, val[2] & 0x7);
962 }
963 }
964 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200965 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800966 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200967 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800968 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200969 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200970 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200971 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200972 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200973 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200974 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
975 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200976 }
Harald Welte59b04682009-06-10 05:40:52 +0800977 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200978 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freyther6d0c8b42009-10-22 15:43:55 +0200979 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)64994ce2009-08-14 11:41:12 +0200980 return gsm0408_rcvmsg(msg, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800981 } else
Harald Welte02993682009-06-27 02:53:10 +0200982 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800983
984 return 0;
985}
986
987static int abis_rsl_rx_dchan(struct msgb *msg)
988{
989 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
990 int rc = 0;
991 char *ts_name;
992
993 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
994 ts_name = gsm_ts_name(msg->lchan->ts);
995
Harald Welte02993682009-06-27 02:53:10 +0200996 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
997 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800998
999 switch (rslh->c.msg_type) {
1000 case RSL_MT_CHAN_ACTIV_ACK:
1001 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
1002 rc = rsl_rx_chan_act_ack(msg);
1003 break;
1004 case RSL_MT_CHAN_ACTIV_NACK:
1005 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
1006 rc = rsl_rx_chan_act_nack(msg);
1007 break;
1008 case RSL_MT_CONN_FAIL:
1009 rc = rsl_rx_conn_fail(msg);
1010 break;
1011 case RSL_MT_MEAS_RES:
1012 rc = rsl_rx_meas_res(msg);
1013 break;
1014 case RSL_MT_RF_CHAN_REL_ACK:
1015 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
1016 lchan_free(msg->lchan);
1017 break;
1018 case RSL_MT_MODE_MODIFY_ACK:
1019 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
1020 break;
1021 case RSL_MT_MODE_MODIFY_NACK:
1022 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
1023 break;
Harald Welteaed946e2009-10-24 10:29:22 +02001024 case RSL_MT_IPAC_PDCH_ACT_ACK:
1025 DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
1026 break;
1027 case RSL_MT_IPAC_PDCH_ACT_NACK:
1028 DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
1029 break;
1030 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1031 DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
1032 break;
1033 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1034 DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
1035 break;
Harald Welte59b04682009-06-10 05:40:52 +08001036 case RSL_MT_PHY_CONTEXT_CONF:
1037 case RSL_MT_PREPROC_MEAS_RES:
1038 case RSL_MT_TALKER_DET:
1039 case RSL_MT_LISTENER_DET:
1040 case RSL_MT_REMOTE_CODEC_CONF_REP:
1041 case RSL_MT_MR_CODEC_MOD_ACK:
1042 case RSL_MT_MR_CODEC_MOD_NACK:
1043 case RSL_MT_MR_CODEC_MOD_PER:
1044 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
1045 rslh->c.msg_type);
1046 break;
1047 default:
1048 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
1049 rslh->c.msg_type);
1050 return -EINVAL;
1051 }
1052
1053 return rc;
1054}
1055
1056static int rsl_rx_error_rep(struct msgb *msg)
1057{
1058 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001059 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001060
1061 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +02001062
1063 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1064
1065 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1066 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1067 TLVP_LEN(&tp, RSL_IE_CAUSE));
1068
Harald Welte59b04682009-06-10 05:40:52 +08001069 DEBUGPC(DRSL, "\n");
1070
1071 return 0;
1072}
1073
1074static int abis_rsl_rx_trx(struct msgb *msg)
1075{
1076 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1077 int rc = 0;
1078
1079 switch (rslh->msg_type) {
1080 case RSL_MT_ERROR_REPORT:
1081 rc = rsl_rx_error_rep(msg);
1082 break;
1083 case RSL_MT_RF_RES_IND:
1084 /* interference on idle channels of TRX */
1085 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1086 break;
1087 case RSL_MT_OVERLOAD:
1088 /* indicate CCCH / ACCH / processor overload */
1089 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1090 break;
1091 default:
1092 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1093 rslh->msg_type);
1094 return -EINVAL;
1095 }
1096 return rc;
1097}
1098
Harald Welte427dbc42009-08-10 00:26:10 +02001099/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1100static void t3101_expired(void *data)
1101{
1102 struct gsm_lchan *lchan = data;
1103
Harald Welte85a163c2009-08-10 11:43:22 +02001104 rsl_rf_chan_release(lchan);
Harald Welte427dbc42009-08-10 00:26:10 +02001105}
1106
Harald Welte59b04682009-06-10 05:40:52 +08001107/* MS has requested a channel on the RACH */
1108static int rsl_rx_chan_rqd(struct msgb *msg)
1109{
1110 struct gsm_bts *bts = msg->trx->bts;
1111 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1112 struct gsm48_req_ref *rqd_ref;
1113 struct gsm48_imm_ass ia;
1114 enum gsm_chan_t lctype;
1115 enum gsm_chreq_reason_t chreq_reason;
1116 struct gsm_lchan *lchan;
1117 u_int8_t rqd_ta;
1118 int ret;
1119
1120 u_int16_t arfcn;
1121 u_int8_t ts_number, subch;
1122
1123 /* parse request reference to be used in immediate assign */
1124 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1125 return -EINVAL;
1126
1127 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1128
1129 /* parse access delay and use as TA */
1130 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1131 return -EINVAL;
1132 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1133
1134 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1135 * request reference RA */
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +01001136 lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
1137 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
Harald Welte59b04682009-06-10 05:40:52 +08001138
1139 /* check availability / allocate channel */
1140 lchan = lchan_alloc(bts, lctype);
1141 if (!lchan) {
Holger Hans Peter Freyther21ccb452009-11-16 15:37:05 +01001142 DEBUGP(DRSL, "CHAN RQD: no resources for %u 0x%x\n",
1143 lctype, rqd_ref->ra);
Harald Welte59b04682009-06-10 05:40:52 +08001144 /* FIXME: send some kind of reject ?!? */
1145 return -ENOMEM;
1146 }
1147
1148 ts_number = lchan->ts->nr;
1149 arfcn = lchan->ts->trx->arfcn;
1150 subch = lchan->nr;
1151
Harald Welted2dd9de2009-08-30 15:37:11 +09001152 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001153 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001154 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001155 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001156 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte39274f42009-07-29 15:41:29 +02001157 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001158
1159 /* create IMMEDIATE ASSIGN 04.08 messge */
1160 memset(&ia, 0, sizeof(ia));
1161 ia.l2_plen = 0x2d;
1162 ia.proto_discr = GSM48_PDISC_RR;
1163 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1164 ia.page_mode = GSM48_PM_SAME;
1165 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1166 ia.chan_desc.h0.h = 0;
1167 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1168 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001169 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001170 /* use request reference extracted from CHAN_RQD */
1171 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1172 ia.timing_advance = rqd_ta;
1173 ia.mob_alloc_len = 0;
1174
1175 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1176 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1177 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1178 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1179 rqd_ref->ra);
1180
Harald Welte427dbc42009-08-10 00:26:10 +02001181 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1182 lchan->T3101.cb = t3101_expired;
1183 lchan->T3101.data = lchan;
1184 bsc_schedule_timer(&lchan->T3101, 10, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001185
1186 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1187 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1188
1189 return ret;
1190}
1191
1192/* MS has requested a channel on the RACH */
1193static int rsl_rx_ccch_load(struct msgb *msg)
1194{
1195 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1196 u_int16_t pg_buf_space;
1197 u_int16_t rach_slot_count = -1;
1198 u_int16_t rach_busy_count = -1;
1199 u_int16_t rach_access_count = -1;
1200
1201 switch (rslh->data[0]) {
1202 case RSL_IE_PAGING_LOAD:
1203 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1204 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1205 break;
1206 case RSL_IE_RACH_LOAD:
1207 if (msg->data_len >= 7) {
1208 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1209 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1210 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1211 }
1212 break;
1213 default:
1214 break;
1215 }
1216
1217 return 0;
1218}
1219
1220static int abis_rsl_rx_cchan(struct msgb *msg)
1221{
1222 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1223 int rc = 0;
1224
1225 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1226
1227 switch (rslh->c.msg_type) {
1228 case RSL_MT_CHAN_RQD:
1229 /* MS has requested a channel on the RACH */
1230 rc = rsl_rx_chan_rqd(msg);
1231 break;
1232 case RSL_MT_CCCH_LOAD_IND:
1233 /* current load on the CCCH */
1234 rc = rsl_rx_ccch_load(msg);
1235 break;
1236 case RSL_MT_DELETE_IND:
1237 /* CCCH overloaded, IMM_ASSIGN was dropped */
1238 case RSL_MT_CBCH_LOAD_IND:
1239 /* current load on the CBCH */
1240 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1241 "0x%02x\n", rslh->c.msg_type);
1242 break;
1243 default:
1244 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1245 rslh->c.msg_type);
1246 return -EINVAL;
1247 }
1248
1249 return rc;
1250}
1251
1252static int rsl_rx_rll_err_ind(struct msgb *msg)
1253{
1254 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1255 u_int8_t *rlm_cause = rllh->data;
1256
Harald Welteb6601442009-08-04 02:50:21 +02001257 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001258
1259 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001260
Harald Welte692f5852009-07-04 09:40:05 +02001261 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte85a163c2009-08-10 11:43:22 +02001262 return rsl_rf_chan_release(msg->lchan);
Harald Welte692f5852009-07-04 09:40:05 +02001263
Harald Welte59b04682009-06-10 05:40:52 +08001264 return 0;
1265}
1266
1267/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1268 0x02, 0x06,
1269 0x01, 0x20,
1270 0x02, 0x00,
1271 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1272
1273static int abis_rsl_rx_rll(struct msgb *msg)
1274{
1275 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1276 int rc = 0;
1277 char *ts_name;
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001278 u_int8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001279
1280 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1281 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001282 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1283 rllh->chan_nr, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001284
1285 switch (rllh->c.msg_type) {
1286 case RSL_MT_DATA_IND:
1287 DEBUGPC(DRLL, "DATA INDICATION\n");
1288 if (msgb_l2len(msg) >
1289 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1290 rllh->data[0] == RSL_IE_L3_INFO) {
1291 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001292 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001293 }
1294 break;
1295 case RSL_MT_EST_IND:
1296 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001297 /* lchan is established, stop T3101 */
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001298 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welte427dbc42009-08-10 00:26:10 +02001299 bsc_del_timer(&msg->lchan->T3101);
Harald Welte59b04682009-06-10 05:40:52 +08001300 if (msgb_l2len(msg) >
1301 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1302 rllh->data[0] == RSL_IE_L3_INFO) {
1303 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001304 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001305 }
1306 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001307 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001308 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001309 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001310 rll_indication(msg->lchan, rllh->link_id,
1311 BSC_RLLR_IND_EST_CONF);
1312 break;
Harald Welte59b04682009-06-10 05:40:52 +08001313 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001314 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001315 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001316 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001317 rll_indication(msg->lchan, rllh->link_id,
1318 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001319 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001320 /* FIXME: officially we need to start T3111 and wait for
1321 * some grace period */
1322 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001323 break;
1324 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001325 /* BTS informs us of having received UA from MS,
1326 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001327 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freytherd8318052009-10-28 14:23:39 +01001328 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
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_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001335 rc = rsl_rx_rll_err_ind(msg);
1336 break;
1337 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001338 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001339 rllh->c.msg_type);
1340 break;
1341 default:
Harald Welteb6601442009-08-04 02:50:21 +02001342 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001343 rllh->c.msg_type);
1344 }
Harald Welte59b04682009-06-10 05:40:52 +08001345 return rc;
1346}
1347
Harald Welte98d79f92009-07-28 18:11:56 +02001348static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1349{
Harald Welte98d79f92009-07-28 18:11:56 +02001350 switch (tch_mode) {
1351 case GSM48_CMODE_SPEECH_V1:
1352 return 0x00;
1353 case GSM48_CMODE_SPEECH_EFR:
1354 return 0x01;
1355 case GSM48_CMODE_SPEECH_AMR:
1356 return 0x02;
1357 /* FIXME: Type1 half-rate and type3 half-rate */
1358 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001359 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1360 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001361 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001362}
1363
Harald Welte59b04682009-06-10 05:40:52 +08001364/* ip.access specific RSL extensions */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001365int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +08001366{
1367 struct msgb *msg = rsl_msgb_alloc();
1368 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001369 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001370
1371 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001372 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte59b04682009-06-10 05:40:52 +08001373 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1374 dh->chan_nr = lchan2chan_nr(lchan);
1375
Harald Welte98d79f92009-07-28 18:11:56 +02001376 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001377 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1378 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001379
Harald Weltefb4a9e92009-07-29 12:12:18 +02001380 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1381 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1382 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001383
Harald Welte59b04682009-06-10 05:40:52 +08001384 msg->trx = lchan->ts->trx;
1385
1386 return abis_rsl_sendmsg(msg);
1387}
1388
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001389int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Welte8cdeaad2009-07-12 09:50:35 +02001390 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001391{
1392 struct msgb *msg = rsl_msgb_alloc();
1393 struct abis_rsl_dchan_hdr *dh;
1394 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001395 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001396 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001397
1398 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001399 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte59b04682009-06-10 05:40:52 +08001400 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1401 dh->chan_nr = lchan2chan_nr(lchan);
1402
Harald Weltefb4a9e92009-07-29 12:12:18 +02001403 /* 0x0- == both directions, 0x-1 == EFR codec */
1404 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1405
Harald Welte98d79f92009-07-28 18:11:56 +02001406 ia.s_addr = htonl(ip);
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001407 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_MDCX "
Harald Weltefb4a9e92009-07-29 12:12:18 +02001408 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001409 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001410 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001411
Harald Welte8cdeaad2009-07-12 09:50:35 +02001412 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001413 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001414 att_f8[1] = conn_id >> 8;
1415 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001416
1417 att_ip = msgb_put(msg, sizeof(ip)+1);
1418 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1419 att_ip[1] = ip >> 24;
1420 att_ip[2] = ip >> 16;
1421 att_ip[3] = ip >> 8;
1422 att_ip[4] = ip & 0xff;
1423 //att_ip[4] = 11;
1424
1425 att_port = msgb_put(msg, sizeof(port)+1);
1426 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1427 att_port[1] = port >> 8;
1428 att_port[2] = port & 0xff;
1429
Harald Weltefb4a9e92009-07-29 12:12:18 +02001430 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001431 if (rtp_payload2)
1432 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1433
Harald Welte59b04682009-06-10 05:40:52 +08001434 msg->trx = lchan->ts->trx;
1435
1436 return abis_rsl_sendmsg(msg);
1437}
1438
Harald Welteaed946e2009-10-24 10:29:22 +02001439int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
1440{
1441 struct msgb *msg = rsl_msgb_alloc();
1442 struct abis_rsl_dchan_hdr *dh;
1443
1444 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1445 init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
1446 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1447 dh->chan_nr = lchan2chan_nr(lchan);
1448
1449 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
1450 gsm_ts_name(lchan->ts), dh->chan_nr);
1451
1452 msg->trx = lchan->ts->trx;
1453
1454 return abis_rsl_sendmsg(msg);
1455}
1456
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001457static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001458{
1459 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1460 struct tlv_parsed tv;
1461 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1462 struct in_addr ip;
1463 u_int16_t port, attr_f8;
1464
1465 /* the BTS has acknowledged a local bind, it now tells us the IP
1466 * address and port number to which it has bound the given logical
1467 * channel */
1468
1469 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1470 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1471 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001472 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001473 DEBUGPC(DRSL, "mandatory IE missing");
1474 return -EINVAL;
1475 }
1476 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1477 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1478 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1479
Harald Welte98d79f92009-07-28 18:11:56 +02001480 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1481 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1482
1483 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1484 ts->abis_ip.rtp_payload2 =
1485 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1486 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1487 ts->abis_ip.rtp_payload2);
1488 }
Harald Welte59b04682009-06-10 05:40:52 +08001489
1490 /* update our local information about this TS */
1491 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1492 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001493 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001494
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001495 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001496
1497 return 0;
1498}
1499
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001500static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte59b04682009-06-10 05:40:52 +08001501{
1502 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1503 struct tlv_parsed tv;
1504
1505 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001506
Harald Weltef1a168d2009-07-28 17:58:09 +02001507 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1508 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1509 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001510
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001511 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welteba4e58d2009-07-28 18:02:05 +02001512
Harald Welte59b04682009-06-10 05:40:52 +08001513 return 0;
1514}
1515
1516static int abis_rsl_rx_ipacc(struct msgb *msg)
1517{
1518 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1519 int rc = 0;
1520
1521 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1522 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1523 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1524
1525 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001526 case RSL_MT_IPAC_CRCX_ACK:
1527 DEBUGPC(DRSL, "IPAC_CRCX_ACK ");
1528 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001529 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001530 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001531 /* somehow the BTS was unable to bind the lchan to its local
1532 * port?!? */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001533 DEBUGPC(DRSL, "IPAC_CRCX_NACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001534 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001535 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte59b04682009-06-10 05:40:52 +08001536 /* the BTS tells us that a connect operation was successful */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001537 DEBUGPC(DRSL, "IPAC_MDCX_ACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001538 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001539 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte59b04682009-06-10 05:40:52 +08001540 /* somehow the BTS was unable to connect the lchan to a remote
1541 * port */
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001542 DEBUGPC(DRSL, "IPAC_MDCX_NACK ");
Harald Welte59b04682009-06-10 05:40:52 +08001543 break;
Holger Hans Peter Freyther5ea7ea62009-11-18 21:06:12 +01001544 case RSL_MT_IPAC_DLCX_IND:
1545 DEBUGPC(DRSL, "IPAC_DLCX_IND ");
1546 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte59b04682009-06-10 05:40:52 +08001547 break;
1548 default:
1549 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1550 break;
1551 }
1552 DEBUGPC(DRSL, "\n");
1553
1554 return rc;
1555}
1556
1557
1558/* Entry-point where L2 RSL from BTS enters */
1559int abis_rsl_rcvmsg(struct msgb *msg)
1560{
1561 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1562 int rc = 0;
1563
1564 switch (rslh->msg_discr & 0xfe) {
1565 case ABIS_RSL_MDISC_RLL:
1566 rc = abis_rsl_rx_rll(msg);
1567 break;
1568 case ABIS_RSL_MDISC_DED_CHAN:
1569 rc = abis_rsl_rx_dchan(msg);
1570 break;
1571 case ABIS_RSL_MDISC_COM_CHAN:
1572 rc = abis_rsl_rx_cchan(msg);
1573 break;
1574 case ABIS_RSL_MDISC_TRX:
1575 rc = abis_rsl_rx_trx(msg);
1576 break;
1577 case ABIS_RSL_MDISC_LOC:
1578 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1579 rslh->msg_discr);
1580 break;
1581 case ABIS_RSL_MDISC_IPACCESS:
1582 rc = abis_rsl_rx_ipacc(msg);
1583 break;
1584 default:
1585 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1586 rslh->msg_discr);
1587 return -EINVAL;
1588 }
1589 msgb_free(msg);
1590 return rc;
1591}
1592
1593
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001594/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001595int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1596{
1597 switch (ccch_conf) {
1598 case RSL_BCCH_CCCH_CONF_1_NC:
1599 return 1;
1600 case RSL_BCCH_CCCH_CONF_1_C:
1601 return 1;
1602 case RSL_BCCH_CCCH_CONF_2_NC:
1603 return 2;
1604 case RSL_BCCH_CCCH_CONF_3_NC:
1605 return 3;
1606 case RSL_BCCH_CCCH_CONF_4_NC:
1607 return 4;
1608 default:
1609 return -1;
1610 }
1611}
1612
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001613/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001614int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1615{
1616 switch (ccch_conf) {
1617 case RSL_BCCH_CCCH_CONF_1_NC:
1618 return 0;
1619 case RSL_BCCH_CCCH_CONF_1_C:
1620 return 1;
1621 case RSL_BCCH_CCCH_CONF_2_NC:
1622 return 0;
1623 case RSL_BCCH_CCCH_CONF_3_NC:
1624 return 0;
1625 case RSL_BCCH_CCCH_CONF_4_NC:
1626 return 0;
1627 default:
1628 return -1;
1629 }
1630}
1631
1632/* From Table 10.5.33 of GSM 04.08 */
1633int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1634{
1635 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1636 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1637 * (bts->chan_desc.bs_pa_mfrms + 2);
1638 } else {
1639 return (9 - bts->chan_desc.bs_ag_blks_res)
1640 * (bts->chan_desc.bs_pa_mfrms + 2);
1641 }
1642}