blob: 1a42b75b06b096bc6183cd04359f6eaf356a5301 [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
242u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
243{
244 struct gsm_bts_trx_ts *ts = lchan->ts;
245 u_int8_t cbits, chan_nr;
246
247 switch (ts->pchan) {
248 case GSM_PCHAN_TCH_F:
Harald Welte37884ed2009-10-24 10:25:50 +0200249 case GSM_PCHAN_PDCH:
250 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte59b04682009-06-10 05:40:52 +0800251 cbits = 0x01;
252 break;
253 case GSM_PCHAN_TCH_H:
254 cbits = 0x02;
255 cbits += lchan->nr;
256 break;
257 case GSM_PCHAN_CCCH_SDCCH4:
258 cbits = 0x04;
259 cbits += lchan->nr;
260 break;
261 case GSM_PCHAN_SDCCH8_SACCH8C:
262 cbits = 0x08;
263 cbits += lchan->nr;
264 break;
265 default:
266 case GSM_PCHAN_CCCH:
267 cbits = 0x10;
268 break;
269 }
270
271 chan_nr = (cbits << 3) | (ts->nr & 0x7);
272
273 return chan_nr;
274}
275
276/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
277u_int64_t str_to_imsi(const char *imsi_str)
278{
279 u_int64_t ret;
280
281 ret = strtoull(imsi_str, NULL, 10);
282
283 return ret;
284}
285
286/* Table 5 Clause 7 TS 05.02 */
287unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
288{
289 if (!bs_ccch_sdcch_comb)
290 return 9 - bs_ag_blks_res;
291 else
292 return 3 - bs_ag_blks_res;
293}
294
295/* Chapter 6.5.2 of TS 05.02 */
296unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
297 unsigned int n_pag_blocks)
298{
299 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
300}
301
302/* Chapter 6.5.2 of TS 05.02 */
303unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
304 int n_pag_blocks)
305{
306 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
307}
308
309static struct msgb *rsl_msgb_alloc(void)
310{
Harald Welte9cfc9352009-06-26 19:39:35 +0200311 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
312 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800313}
314
315#define MACBLOCK_SIZE 23
316static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
317{
318 memcpy(out, in, len);
319
320 if (len < MACBLOCK_SIZE)
321 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
322}
323
Harald Welted2dd9de2009-08-30 15:37:11 +0900324/* Chapter 9.3.7: Encryption Information */
325static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
326{
327 *out++ = lchan->encr.alg_id & 0xff;
328 if (lchan->encr.key_len)
329 memcpy(out, lchan->encr.key, lchan->encr.key_len);
330 return lchan->encr.key_len + 1;
331}
332
333
Harald Weltef1a168d2009-07-28 17:58:09 +0200334static const char *rsl_err_vals[0xff] = {
335 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
336 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
337 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
338 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
339 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
340 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welteb1717e92009-08-04 02:31:05 +0200341 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Weltef1a168d2009-07-28 17:58:09 +0200342 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
343 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
344 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
345 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
346 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
347 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
348 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
349 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
350 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
351 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
352 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
353 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
354 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
355 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
356 [RSL_ERR_MSG_TYPE] = "Message Type Error",
357 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
358 [RSL_ERR_IE_ERROR] = "General IE error",
359 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
360 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
361 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
362 [RSL_ERR_IE_LENGTH] = "IE length error",
363 [RSL_ERR_IE_CONTENT] = "IE content error",
364 [RSL_ERR_PROTO] = "Protocol error, unspecified",
365 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
366};
367
368static const char *rsl_err_name(u_int8_t err)
Harald Welte59b04682009-06-10 05:40:52 +0800369{
Harald Weltef1a168d2009-07-28 17:58:09 +0200370 if (rsl_err_vals[err])
371 return rsl_err_vals[err];
372 else
373 return "unknown";
374}
375
376static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
377{
Harald Welte59b04682009-06-10 05:40:52 +0800378 int i;
379
Harald Weltef1a168d2009-07-28 17:58:09 +0200380 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
381 cause_v[0], rsl_err_name(cause_v[0]));
382 for (i = 1; i < cause_len-1; i++)
383 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800384}
385
386/* Send a BCCH_INFO message as per Chapter 8.5.1 */
387int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
388 const u_int8_t *data, int len)
389{
390 struct abis_rsl_dchan_hdr *dh;
391 struct msgb *msg = rsl_msgb_alloc();
392
393 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
394 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
395 dh->chan_nr = RSL_CHAN_BCCH;
396
397 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
398 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
399
400 msg->trx = trx;
401
402 return abis_rsl_sendmsg(msg);
403}
404
405int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
406 const u_int8_t *data, int len)
407{
408 struct abis_rsl_common_hdr *ch;
409 struct msgb *msg = rsl_msgb_alloc();
410
411 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
412 ch->msg_discr = ABIS_RSL_MDISC_TRX;
413 ch->msg_type = RSL_MT_SACCH_FILL;
414
415 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
416 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
417
418 msg->trx = trx;
419
420 return abis_rsl_sendmsg(msg);
421}
422
Harald Welte91afe4c2009-06-20 18:15:19 +0200423int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
424{
425 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200426 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200427 u_int8_t chan_nr = lchan2chan_nr(lchan);
428
429 db = abs(db);
430 if (db > 30)
431 return -EINVAL;
432
Harald Welteed831842009-06-27 03:09:08 +0200433 msg = rsl_msgb_alloc();
434
Harald Welte91afe4c2009-06-20 18:15:19 +0200435 lchan->bs_power = db/2;
436 if (fpc)
437 lchan->bs_power |= 0x10;
438
439 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
440 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
441 dh->chan_nr = chan_nr;
442
443 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
444
445 msg->trx = lchan->ts->trx;
446
447 return abis_rsl_sendmsg(msg);
448}
449
Harald Welte91afe4c2009-06-20 18:15:19 +0200450int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
451{
452 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200453 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200454 u_int8_t chan_nr = lchan2chan_nr(lchan);
455 int ctl_lvl;
456
Harald Weltec4dcda02009-08-09 14:45:18 +0200457 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200458 if (ctl_lvl < 0)
459 return ctl_lvl;
460
Harald Welteed831842009-06-27 03:09:08 +0200461 msg = rsl_msgb_alloc();
462
Harald Welte91afe4c2009-06-20 18:15:19 +0200463 lchan->ms_power = ctl_lvl;
464
465 if (fpc)
466 lchan->ms_power |= 0x20;
467
468 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
469 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
470 dh->chan_nr = chan_nr;
471
472 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
473
474 msg->trx = lchan->ts->trx;
475
476 return abis_rsl_sendmsg(msg);
477}
478
Harald Welte39274f42009-07-29 15:41:29 +0200479static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
480 struct gsm_lchan *lchan)
481{
482 memset(cm, 0, sizeof(cm));
483
484 /* FIXME: what to do with data calls ? */
485 cm->dtx_dtu = 0x00;
486
487 /* set TCH Speech/Data */
488 cm->spd_ind = lchan->rsl_cmode;
489
490 switch (lchan->type) {
491 case GSM_LCHAN_SDCCH:
492 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
493 break;
494 case GSM_LCHAN_TCH_F:
495 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
496 break;
497 case GSM_LCHAN_TCH_H:
498 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
499 break;
500 case GSM_LCHAN_NONE:
501 case GSM_LCHAN_UNKNOWN:
502 default:
503 return -EINVAL;
504 }
505
506 switch (lchan->tch_mode) {
507 case GSM48_CMODE_SIGN:
508 cm->chan_rate = 0;
509 break;
510 case GSM48_CMODE_SPEECH_V1:
511 cm->chan_rate = RSL_CMOD_SP_GSM1;
512 break;
513 case GSM48_CMODE_SPEECH_EFR:
514 cm->chan_rate = RSL_CMOD_SP_GSM2;
515 break;
516 case GSM48_CMODE_SPEECH_AMR:
517 cm->chan_rate = RSL_CMOD_SP_GSM3;
518 break;
519 case GSM48_CMODE_DATA_14k5:
520 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
521 break;
522 case GSM48_CMODE_DATA_12k0:
523 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
524 break;
525 case GSM48_CMODE_DATA_6k0:
526 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
527 break;
528 default:
529 return -EINVAL;
530 }
531
532 return 0;
533}
534
Harald Welte59b04682009-06-10 05:40:52 +0800535/* Chapter 8.4.1 */
536#if 0
537int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
538 u_int8_t act_type,
539 struct rsl_ie_chan_mode *chan_mode,
540 struct rsl_ie_chan_ident *chan_ident,
541 u_int8_t bs_power, u_int8_t ms_power,
542 u_int8_t ta)
543{
544 struct abis_rsl_dchan_hdr *dh;
545 struct msgb *msg = rsl_msgb_alloc();
546
547 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
548 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
549 dh->chan_nr = chan_nr;
550
551 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
552 /* For compatibility with Phase 1 */
553 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
554 (u_int8_t *) chan_mode);
555 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
556 (u_int8_t *) chan_ident);
557#if 0
558 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
559 (u_int8_t *) &encr_info);
560#endif
561 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
562 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
563 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
564
565 msg->trx = trx;
566
567 return abis_rsl_sendmsg(msg);
568}
569#endif
570
571int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte39274f42009-07-29 15:41:29 +0200572 u_int8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800573{
574 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200575 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200576 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800577
578 u_int8_t chan_nr = lchan2chan_nr(lchan);
579 u_int16_t arfcn = lchan->ts->trx->arfcn;
580 struct rsl_ie_chan_mode cm;
581 struct rsl_ie_chan_ident ci;
582
Harald Welte39274f42009-07-29 15:41:29 +0200583 rc = channel_mode_from_lchan(&cm, lchan);
584 if (rc < 0)
585 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800586
587 memset(&ci, 0, sizeof(ci));
588 ci.chan_desc.iei = 0x64;
589 ci.chan_desc.chan_nr = chan_nr;
590 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
591 ci.chan_desc.oct4 = arfcn & 0xff;
592
Harald Welteed831842009-06-27 03:09:08 +0200593 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800594 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
595 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
596 dh->chan_nr = chan_nr;
597
598 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
599 /* For compatibility with Phase 1 */
600 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
601 (u_int8_t *) &cm);
602 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
603 (u_int8_t *) &ci);
Harald Welted2dd9de2009-08-30 15:37:11 +0900604
605 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
606 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
607 rc = build_encr_info(encr_info, lchan);
608 if (rc > 0)
609 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
610 }
611
Harald Welte59b04682009-06-10 05:40:52 +0800612 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
613 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
614 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
615
616 msg->trx = lchan->ts->trx;
617
618 return abis_rsl_sendmsg(msg);
619}
620
Harald Welte8e770492009-07-29 11:38:15 +0200621/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800622int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
623{
624 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200625 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200626 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800627
628 u_int8_t chan_nr = lchan2chan_nr(lchan);
629 struct rsl_ie_chan_mode cm;
630
Harald Welte39274f42009-07-29 15:41:29 +0200631 rc = channel_mode_from_lchan(&cm, lchan);
632 if (rc < 0)
633 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800634
Harald Welteed831842009-06-27 03:09:08 +0200635 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800636 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
637 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
638 dh->chan_nr = chan_nr;
639
640 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
641 (u_int8_t *) &cm);
Harald Welted2dd9de2009-08-30 15:37:11 +0900642
643 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
644 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
645 rc = build_encr_info(encr_info, lchan);
646 if (rc > 0)
647 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
648 }
649
650 msg->trx = lchan->ts->trx;
651
652 return abis_rsl_sendmsg(msg);
653}
654
655/* Chapter 8.4.6: Send the encryption command with given L3 info */
656int rsl_encryption_cmd(struct msgb *msg)
657{
658 struct abis_rsl_dchan_hdr *dh;
659 struct gsm_lchan *lchan = msg->lchan;
660 u_int8_t chan_nr = lchan2chan_nr(lchan);
661 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut01f1caf2009-09-27 11:13:18 +0200662 u_int8_t l3_len = msg->len;
Harald Welted2dd9de2009-08-30 15:37:11 +0900663 int rc;
664
665 /* First push the L3 IE tag and length */
666 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
667
668 /* then the link identifier (SAPI0, main sign link) */
669 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
670
671 /* then encryption information */
672 rc = build_encr_info(encr_info, lchan);
673 if (rc <= 0)
674 return rc;
675 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
676
677 /* and finally the DCHAN header */
678 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
679 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
680 dh->chan_nr = chan_nr;
Harald Welte59b04682009-06-10 05:40:52 +0800681
682 msg->trx = lchan->ts->trx;
683
684 return abis_rsl_sendmsg(msg);
685}
686
Harald Welte85a163c2009-08-10 11:43:22 +0200687/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200688int rsl_deact_sacch(struct gsm_lchan *lchan)
689{
690 struct abis_rsl_dchan_hdr *dh;
691 struct msgb *msg = rsl_msgb_alloc();
692
693 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
694 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
695 dh->chan_nr = lchan2chan_nr(lchan);
696
697 msg->lchan = lchan;
698 msg->trx = lchan->ts->trx;
699
700 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
701 gsm_ts_name(lchan->ts), dh->chan_nr);
702
703 return abis_rsl_sendmsg(msg);
704}
705
Harald Welte85a163c2009-08-10 11:43:22 +0200706/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
707int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800708{
709 struct abis_rsl_dchan_hdr *dh;
710 struct msgb *msg = rsl_msgb_alloc();
711
712 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
713 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
714 dh->chan_nr = lchan2chan_nr(lchan);
715
716 msg->lchan = lchan;
717 msg->trx = lchan->ts->trx;
718
Harald Welte85a163c2009-08-10 11:43:22 +0200719 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +0800720 gsm_ts_name(lchan->ts), dh->chan_nr);
721
Harald Welte85a163c2009-08-10 11:43:22 +0200722 /* BTS will respond by RF CHAN REL ACK */
Harald Welte59b04682009-06-10 05:40:52 +0800723 return abis_rsl_sendmsg(msg);
724}
725
726int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
727 u_int8_t *ms_ident, u_int8_t chan_needed)
728{
729 struct abis_rsl_dchan_hdr *dh;
730 struct msgb *msg = rsl_msgb_alloc();
731
732 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
733 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
734 dh->chan_nr = RSL_CHAN_PCH_AGCH;
735
736 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
737 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
738 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
739
740 msg->trx = bts->c0;
741
742 return abis_rsl_sendmsg(msg);
743}
744
745int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
746 struct gsm_subscriber *subscr)
747{
748#if 0
749 u_int8_t mi[128];
750 unsigned int mi_len;
751 u_int8_t paging_group;
752#endif
753
754 return -1;
755}
756
757int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
758{
759 int i, len = strlen(str_in);
760
761 for (i = 0; i < len; i++) {
762 int num = str_in[i] - 0x30;
763 if (num < 0 || num > 9)
764 return -1;
765 if (i % 2 == 0)
766 bcd_out[i/2] = num;
767 else
768 bcd_out[i/2] |= (num << 4);
769 }
770
771 return 0;
772}
773
774/* Chapter 8.5.6 */
775int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
776{
777 struct msgb *msg = rsl_msgb_alloc();
778 struct abis_rsl_dchan_hdr *dh;
779 u_int8_t buf[MACBLOCK_SIZE];
780
781 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
782 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
783 dh->chan_nr = RSL_CHAN_PCH_AGCH;
784
785 switch (bts->type) {
786 case GSM_BTS_TYPE_BS11:
787 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
788 break;
789 default:
790 /* If phase 2, construct a FULL_IMM_ASS_INFO */
791 pad_macblock(buf, val, len);
792 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
793 break;
794 }
795
796 msg->trx = bts->c0;
797
798 return abis_rsl_sendmsg(msg);
799}
800
Harald Welte4684e632009-08-10 09:51:40 +0200801/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200802int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200803{
804 struct msgb *msg = rsl_msgb_alloc();
805 struct abis_rsl_dchan_hdr *dh;
806
807 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
808 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200809 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte4684e632009-08-10 09:51:40 +0200810 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte12090752009-08-10 10:07:33 +0200811 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200812
Harald Welte874a5b42009-08-10 11:26:14 +0200813 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
814 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
815
816 msg->trx = lchan->ts->trx;
817
Harald Welte4684e632009-08-10 09:51:40 +0200818 return abis_rsl_sendmsg(msg);
819}
820
821
Harald Welte59b04682009-06-10 05:40:52 +0800822/* Send "DATA REQUEST" message with given L3 Info payload */
823/* Chapter 8.3.1 */
824int rsl_data_request(struct msgb *msg, u_int8_t link_id)
825{
826 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
827 struct abis_rsl_rll_hdr *rh;
828
829 if (msg->lchan == NULL) {
830 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
831 return -EINVAL;
832 }
833
834 /* First push the L3 IE tag and length */
835 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
836
837 /* Then push the RSL header */
838 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
839 init_llm_hdr(rh, RSL_MT_DATA_REQ);
840 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
841 rh->chan_nr = lchan2chan_nr(msg->lchan);
842 rh->link_id = link_id;
843
844 msg->trx = msg->lchan->ts->trx;
845
846 return abis_rsl_sendmsg(msg);
847}
848
Harald Welteed9a5ab2009-08-09 13:47:35 +0200849/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
850/* Chapter 8.3.1 */
851int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
852{
853 struct msgb *msg = rsl_msgb_alloc();
854 struct abis_rsl_rll_hdr *rh;
855
856 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200857 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200858 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
859 rh->chan_nr = lchan2chan_nr(lchan);
860 rh->link_id = link_id;
861
862 msg->trx = lchan->ts->trx;
863
864 return abis_rsl_sendmsg(msg);
865}
866
Harald Welte0f2e3c12009-08-08 13:15:07 +0200867/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
868 This is what higher layers should call. The BTS then responds with
869 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
870 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
871 lchan_free() */
872int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
873{
874 struct msgb *msg = rsl_msgb_alloc();
875 struct abis_rsl_rll_hdr *rh;
876
877 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
878 init_llm_hdr(rh, RSL_MT_REL_REQ);
879 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
880 rh->chan_nr = lchan2chan_nr(lchan);
881 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200882 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200883
884 msg->trx = lchan->ts->trx;
885
886 return abis_rsl_sendmsg(msg);
887}
888
Harald Welte59b04682009-06-10 05:40:52 +0800889/* Chapter 8.4.2: Channel Activate Acknowledge */
890static int rsl_rx_chan_act_ack(struct msgb *msg)
891{
892 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
893
894 /* BTS has confirmed channel activation, we now need
895 * to assign the activated channel to the MS */
896 if (rslh->ie_chan != RSL_IE_CHAN_NR)
897 return -EINVAL;
898
899 return 0;
900}
901
902/* Chapter 8.4.3: Channel Activate NACK */
903static int rsl_rx_chan_act_nack(struct msgb *msg)
904{
905 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
906 struct tlv_parsed tp;
907
908 /* BTS has rejected channel activation ?!? */
909 if (dh->ie_chan != RSL_IE_CHAN_NR)
910 return -EINVAL;
911
912 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
913 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200914 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
915 TLVP_LEN(&tp, RSL_IE_CAUSE));
916
Harald Weltecddb9802009-08-09 19:50:08 +0200917 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800918 return 0;
919}
920
921/* Chapter 8.4.4: Connection Failure Indication */
922static int rsl_rx_conn_fail(struct msgb *msg)
923{
924 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
925 struct tlv_parsed tp;
926
927 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800928
929 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
930
Harald Weltef1a168d2009-07-28 17:58:09 +0200931 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
932 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
933 TLVP_LEN(&tp, RSL_IE_CAUSE));
934
Harald Welte59b04682009-06-10 05:40:52 +0800935 DEBUGPC(DRSL, "RELEASING.\n");
936
937 /* FIXME: only free it after channel release ACK */
Harald Welte85a163c2009-08-10 11:43:22 +0200938 return rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800939}
940
941static int rsl_rx_meas_res(struct msgb *msg)
942{
943 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
944 struct tlv_parsed tp;
945
Harald Welte02993682009-06-27 02:53:10 +0200946 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800947 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
948
949 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200950 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800951 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
952 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
953 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
954 if (len >= 3) {
955 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200956 DEBUGPC(DMEAS, "DTXd ");
957 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800958 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200959 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800960 val[2]>>3 & 0x7, val[2] & 0x7);
961 }
962 }
963 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200964 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800965 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200966 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800967 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200968 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200969 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200970 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200971 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200972 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200973 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
974 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200975 }
Harald Welte59b04682009-06-10 05:40:52 +0800976 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200977 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freyther6d0c8b42009-10-22 15:43:55 +0200978 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)64994ce2009-08-14 11:41:12 +0200979 return gsm0408_rcvmsg(msg, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800980 } else
Harald Welte02993682009-06-27 02:53:10 +0200981 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800982
983 return 0;
984}
985
986static int abis_rsl_rx_dchan(struct msgb *msg)
987{
988 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
989 int rc = 0;
990 char *ts_name;
991
992 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
993 ts_name = gsm_ts_name(msg->lchan->ts);
994
Harald Welte02993682009-06-27 02:53:10 +0200995 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
996 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800997
998 switch (rslh->c.msg_type) {
999 case RSL_MT_CHAN_ACTIV_ACK:
1000 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
1001 rc = rsl_rx_chan_act_ack(msg);
1002 break;
1003 case RSL_MT_CHAN_ACTIV_NACK:
1004 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
1005 rc = rsl_rx_chan_act_nack(msg);
1006 break;
1007 case RSL_MT_CONN_FAIL:
1008 rc = rsl_rx_conn_fail(msg);
1009 break;
1010 case RSL_MT_MEAS_RES:
1011 rc = rsl_rx_meas_res(msg);
1012 break;
1013 case RSL_MT_RF_CHAN_REL_ACK:
1014 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
1015 lchan_free(msg->lchan);
1016 break;
1017 case RSL_MT_MODE_MODIFY_ACK:
1018 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
1019 break;
1020 case RSL_MT_MODE_MODIFY_NACK:
1021 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
1022 break;
1023 case RSL_MT_PHY_CONTEXT_CONF:
1024 case RSL_MT_PREPROC_MEAS_RES:
1025 case RSL_MT_TALKER_DET:
1026 case RSL_MT_LISTENER_DET:
1027 case RSL_MT_REMOTE_CODEC_CONF_REP:
1028 case RSL_MT_MR_CODEC_MOD_ACK:
1029 case RSL_MT_MR_CODEC_MOD_NACK:
1030 case RSL_MT_MR_CODEC_MOD_PER:
1031 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
1032 rslh->c.msg_type);
1033 break;
1034 default:
1035 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
1036 rslh->c.msg_type);
1037 return -EINVAL;
1038 }
1039
1040 return rc;
1041}
1042
1043static int rsl_rx_error_rep(struct msgb *msg)
1044{
1045 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001046 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001047
1048 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +02001049
1050 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1051
1052 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1053 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1054 TLVP_LEN(&tp, RSL_IE_CAUSE));
1055
Harald Welte59b04682009-06-10 05:40:52 +08001056 DEBUGPC(DRSL, "\n");
1057
1058 return 0;
1059}
1060
1061static int abis_rsl_rx_trx(struct msgb *msg)
1062{
1063 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1064 int rc = 0;
1065
1066 switch (rslh->msg_type) {
1067 case RSL_MT_ERROR_REPORT:
1068 rc = rsl_rx_error_rep(msg);
1069 break;
1070 case RSL_MT_RF_RES_IND:
1071 /* interference on idle channels of TRX */
1072 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1073 break;
1074 case RSL_MT_OVERLOAD:
1075 /* indicate CCCH / ACCH / processor overload */
1076 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1077 break;
1078 default:
1079 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1080 rslh->msg_type);
1081 return -EINVAL;
1082 }
1083 return rc;
1084}
1085
Harald Welte427dbc42009-08-10 00:26:10 +02001086/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1087static void t3101_expired(void *data)
1088{
1089 struct gsm_lchan *lchan = data;
1090
Harald Welte85a163c2009-08-10 11:43:22 +02001091 rsl_rf_chan_release(lchan);
Harald Welte427dbc42009-08-10 00:26:10 +02001092}
1093
Harald Welte59b04682009-06-10 05:40:52 +08001094/* MS has requested a channel on the RACH */
1095static int rsl_rx_chan_rqd(struct msgb *msg)
1096{
1097 struct gsm_bts *bts = msg->trx->bts;
1098 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1099 struct gsm48_req_ref *rqd_ref;
1100 struct gsm48_imm_ass ia;
1101 enum gsm_chan_t lctype;
1102 enum gsm_chreq_reason_t chreq_reason;
1103 struct gsm_lchan *lchan;
1104 u_int8_t rqd_ta;
1105 int ret;
1106
1107 u_int16_t arfcn;
1108 u_int8_t ts_number, subch;
1109
1110 /* parse request reference to be used in immediate assign */
1111 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1112 return -EINVAL;
1113
1114 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1115
1116 /* parse access delay and use as TA */
1117 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1118 return -EINVAL;
1119 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1120
1121 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1122 * request reference RA */
1123 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
1124 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1125
1126 /* check availability / allocate channel */
1127 lchan = lchan_alloc(bts, lctype);
1128 if (!lchan) {
1129 fprintf(stderr, "CHAN RQD: no resources\n");
1130 /* FIXME: send some kind of reject ?!? */
1131 return -ENOMEM;
1132 }
1133
1134 ts_number = lchan->ts->nr;
1135 arfcn = lchan->ts->trx->arfcn;
1136 subch = lchan->nr;
1137
Harald Welted2dd9de2009-08-30 15:37:11 +09001138 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001139 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte9a229e12009-08-10 00:45:40 +02001140 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001141 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte77234e12009-08-28 23:28:28 +09001142 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte39274f42009-07-29 15:41:29 +02001143 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001144
1145 /* create IMMEDIATE ASSIGN 04.08 messge */
1146 memset(&ia, 0, sizeof(ia));
1147 ia.l2_plen = 0x2d;
1148 ia.proto_discr = GSM48_PDISC_RR;
1149 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1150 ia.page_mode = GSM48_PM_SAME;
1151 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1152 ia.chan_desc.h0.h = 0;
1153 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1154 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001155 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001156 /* use request reference extracted from CHAN_RQD */
1157 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1158 ia.timing_advance = rqd_ta;
1159 ia.mob_alloc_len = 0;
1160
1161 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1162 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1163 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1164 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1165 rqd_ref->ra);
1166
Harald Welte427dbc42009-08-10 00:26:10 +02001167 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1168 lchan->T3101.cb = t3101_expired;
1169 lchan->T3101.data = lchan;
1170 bsc_schedule_timer(&lchan->T3101, 10, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001171
1172 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1173 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1174
1175 return ret;
1176}
1177
1178/* MS has requested a channel on the RACH */
1179static int rsl_rx_ccch_load(struct msgb *msg)
1180{
1181 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1182 u_int16_t pg_buf_space;
1183 u_int16_t rach_slot_count = -1;
1184 u_int16_t rach_busy_count = -1;
1185 u_int16_t rach_access_count = -1;
1186
1187 switch (rslh->data[0]) {
1188 case RSL_IE_PAGING_LOAD:
1189 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1190 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1191 break;
1192 case RSL_IE_RACH_LOAD:
1193 if (msg->data_len >= 7) {
1194 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1195 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1196 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1197 }
1198 break;
1199 default:
1200 break;
1201 }
1202
1203 return 0;
1204}
1205
1206static int abis_rsl_rx_cchan(struct msgb *msg)
1207{
1208 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1209 int rc = 0;
1210
1211 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1212
1213 switch (rslh->c.msg_type) {
1214 case RSL_MT_CHAN_RQD:
1215 /* MS has requested a channel on the RACH */
1216 rc = rsl_rx_chan_rqd(msg);
1217 break;
1218 case RSL_MT_CCCH_LOAD_IND:
1219 /* current load on the CCCH */
1220 rc = rsl_rx_ccch_load(msg);
1221 break;
1222 case RSL_MT_DELETE_IND:
1223 /* CCCH overloaded, IMM_ASSIGN was dropped */
1224 case RSL_MT_CBCH_LOAD_IND:
1225 /* current load on the CBCH */
1226 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1227 "0x%02x\n", rslh->c.msg_type);
1228 break;
1229 default:
1230 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1231 rslh->c.msg_type);
1232 return -EINVAL;
1233 }
1234
1235 return rc;
1236}
1237
1238static int rsl_rx_rll_err_ind(struct msgb *msg)
1239{
1240 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1241 u_int8_t *rlm_cause = rllh->data;
1242
Harald Welteb6601442009-08-04 02:50:21 +02001243 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001244
1245 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001246
Harald Welte692f5852009-07-04 09:40:05 +02001247 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte85a163c2009-08-10 11:43:22 +02001248 return rsl_rf_chan_release(msg->lchan);
Harald Welte692f5852009-07-04 09:40:05 +02001249
Harald Welte59b04682009-06-10 05:40:52 +08001250 return 0;
1251}
1252
1253/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1254 0x02, 0x06,
1255 0x01, 0x20,
1256 0x02, 0x00,
1257 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1258
1259static int abis_rsl_rx_rll(struct msgb *msg)
1260{
1261 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1262 int rc = 0;
1263 char *ts_name;
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001264 u_int8_t sapi = rllh->link_id & 7;
Harald Welte59b04682009-06-10 05:40:52 +08001265
1266 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1267 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001268 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1269 rllh->chan_nr, sapi);
Harald Welte59b04682009-06-10 05:40:52 +08001270
1271 switch (rllh->c.msg_type) {
1272 case RSL_MT_DATA_IND:
1273 DEBUGPC(DRLL, "DATA INDICATION\n");
1274 if (msgb_l2len(msg) >
1275 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1276 rllh->data[0] == RSL_IE_L3_INFO) {
1277 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001278 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001279 }
1280 break;
1281 case RSL_MT_EST_IND:
1282 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001283 /* lchan is established, stop T3101 */
1284 bsc_del_timer(&msg->lchan->T3101);
Harald Welte59b04682009-06-10 05:40:52 +08001285 if (msgb_l2len(msg) >
1286 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1287 rllh->data[0] == RSL_IE_L3_INFO) {
1288 msg->l3h = &rllh->data[3];
Harald Welte (local)64994ce2009-08-14 11:41:12 +02001289 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte59b04682009-06-10 05:40:52 +08001290 }
1291 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001292 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001293 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001294 rll_indication(msg->lchan, rllh->link_id,
1295 BSC_RLLR_IND_EST_CONF);
1296 break;
Harald Welte59b04682009-06-10 05:40:52 +08001297 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001298 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001299 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001300 rll_indication(msg->lchan, rllh->link_id,
1301 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001302 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001303 /* FIXME: officially we need to start T3111 and wait for
1304 * some grace period */
1305 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001306 break;
1307 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001308 /* BTS informs us of having received UA from MS,
1309 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001310 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welte0f2e3c12009-08-08 13:15:07 +02001311 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001312 /* FIXME: officially we need to start T3111 and wait for
1313 * some grace period */
1314 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001315 break;
1316 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001317 rc = rsl_rx_rll_err_ind(msg);
1318 break;
1319 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001320 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001321 rllh->c.msg_type);
1322 break;
1323 default:
Harald Welteb6601442009-08-04 02:50:21 +02001324 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001325 rllh->c.msg_type);
1326 }
Harald Welte59b04682009-06-10 05:40:52 +08001327 return rc;
1328}
1329
Harald Welte98d79f92009-07-28 18:11:56 +02001330static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1331{
Harald Welte98d79f92009-07-28 18:11:56 +02001332 switch (tch_mode) {
1333 case GSM48_CMODE_SPEECH_V1:
1334 return 0x00;
1335 case GSM48_CMODE_SPEECH_EFR:
1336 return 0x01;
1337 case GSM48_CMODE_SPEECH_AMR:
1338 return 0x02;
1339 /* FIXME: Type1 half-rate and type3 half-rate */
1340 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001341 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1342 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001343 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001344}
1345
Harald Welte59b04682009-06-10 05:40:52 +08001346/* ip.access specific RSL extensions */
1347int rsl_ipacc_bind(struct gsm_lchan *lchan)
1348{
1349 struct msgb *msg = rsl_msgb_alloc();
1350 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001351 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001352
1353 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1354 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1355 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1356 dh->chan_nr = lchan2chan_nr(lchan);
1357
Harald Welte98d79f92009-07-28 18:11:56 +02001358 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001359 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1360 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001361
Harald Weltefb4a9e92009-07-29 12:12:18 +02001362 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1363 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1364 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001365
Harald Welte59b04682009-06-10 05:40:52 +08001366 msg->trx = lchan->ts->trx;
1367
1368 return abis_rsl_sendmsg(msg);
1369}
1370
Harald Welte8cdeaad2009-07-12 09:50:35 +02001371int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1372 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001373{
1374 struct msgb *msg = rsl_msgb_alloc();
1375 struct abis_rsl_dchan_hdr *dh;
1376 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001377 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001378 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001379
1380 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1381 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1382 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1383 dh->chan_nr = lchan2chan_nr(lchan);
1384
Harald Weltefb4a9e92009-07-29 12:12:18 +02001385 /* 0x0- == both directions, 0x-1 == EFR codec */
1386 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1387
Harald Welte98d79f92009-07-28 18:11:56 +02001388 ia.s_addr = htonl(ip);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001389 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1390 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001391 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001392 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001393
Harald Welte8cdeaad2009-07-12 09:50:35 +02001394 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001395 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001396 att_f8[1] = conn_id >> 8;
1397 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001398
1399 att_ip = msgb_put(msg, sizeof(ip)+1);
1400 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1401 att_ip[1] = ip >> 24;
1402 att_ip[2] = ip >> 16;
1403 att_ip[3] = ip >> 8;
1404 att_ip[4] = ip & 0xff;
1405 //att_ip[4] = 11;
1406
1407 att_port = msgb_put(msg, sizeof(port)+1);
1408 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1409 att_port[1] = port >> 8;
1410 att_port[2] = port & 0xff;
1411
Harald Weltefb4a9e92009-07-29 12:12:18 +02001412 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001413 if (rtp_payload2)
1414 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1415
Harald Welte59b04682009-06-10 05:40:52 +08001416 msg->trx = lchan->ts->trx;
1417
1418 return abis_rsl_sendmsg(msg);
1419}
1420
1421static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1422{
1423 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1424 struct tlv_parsed tv;
1425 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1426 struct in_addr ip;
1427 u_int16_t port, attr_f8;
1428
1429 /* the BTS has acknowledged a local bind, it now tells us the IP
1430 * address and port number to which it has bound the given logical
1431 * channel */
1432
1433 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1434 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1435 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001436 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001437 DEBUGPC(DRSL, "mandatory IE missing");
1438 return -EINVAL;
1439 }
1440 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1441 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1442 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1443
Harald Welte98d79f92009-07-28 18:11:56 +02001444 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1445 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1446
1447 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1448 ts->abis_ip.rtp_payload2 =
1449 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1450 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1451 ts->abis_ip.rtp_payload2);
1452 }
Harald Welte59b04682009-06-10 05:40:52 +08001453
1454 /* update our local information about this TS */
1455 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1456 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001457 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001458
1459 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1460
1461 return 0;
1462}
1463
1464static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1465{
1466 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1467 struct tlv_parsed tv;
1468
1469 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001470
Harald Weltef1a168d2009-07-28 17:58:09 +02001471 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1472 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1473 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001474
Harald Welteba4e58d2009-07-28 18:02:05 +02001475 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1476
Harald Welte59b04682009-06-10 05:40:52 +08001477 return 0;
1478}
1479
1480static int abis_rsl_rx_ipacc(struct msgb *msg)
1481{
1482 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1483 int rc = 0;
1484
1485 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1486 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1487 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1488
1489 switch (rllh->c.msg_type) {
1490 case RSL_MT_IPAC_BIND_ACK:
1491 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
1492 rc = abis_rsl_rx_ipacc_bindack(msg);
1493 break;
1494 case RSL_MT_IPAC_BIND_NACK:
1495 /* somehow the BTS was unable to bind the lchan to its local
1496 * port?!? */
1497 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
1498 break;
1499 case RSL_MT_IPAC_CONNECT_ACK:
1500 /* the BTS tells us that a connect operation was successful */
1501 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
1502 break;
1503 case RSL_MT_IPAC_CONNECT_NACK:
1504 /* somehow the BTS was unable to connect the lchan to a remote
1505 * port */
1506 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
1507 break;
1508 case RSL_MT_IPAC_DISCONNECT_IND:
1509 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
1510 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1511 break;
1512 default:
1513 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1514 break;
1515 }
1516 DEBUGPC(DRSL, "\n");
1517
1518 return rc;
1519}
1520
1521
1522/* Entry-point where L2 RSL from BTS enters */
1523int abis_rsl_rcvmsg(struct msgb *msg)
1524{
1525 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1526 int rc = 0;
1527
1528 switch (rslh->msg_discr & 0xfe) {
1529 case ABIS_RSL_MDISC_RLL:
1530 rc = abis_rsl_rx_rll(msg);
1531 break;
1532 case ABIS_RSL_MDISC_DED_CHAN:
1533 rc = abis_rsl_rx_dchan(msg);
1534 break;
1535 case ABIS_RSL_MDISC_COM_CHAN:
1536 rc = abis_rsl_rx_cchan(msg);
1537 break;
1538 case ABIS_RSL_MDISC_TRX:
1539 rc = abis_rsl_rx_trx(msg);
1540 break;
1541 case ABIS_RSL_MDISC_LOC:
1542 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1543 rslh->msg_discr);
1544 break;
1545 case ABIS_RSL_MDISC_IPACCESS:
1546 rc = abis_rsl_rx_ipacc(msg);
1547 break;
1548 default:
1549 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1550 rslh->msg_discr);
1551 return -EINVAL;
1552 }
1553 msgb_free(msg);
1554 return rc;
1555}
1556
1557
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001558/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001559int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1560{
1561 switch (ccch_conf) {
1562 case RSL_BCCH_CCCH_CONF_1_NC:
1563 return 1;
1564 case RSL_BCCH_CCCH_CONF_1_C:
1565 return 1;
1566 case RSL_BCCH_CCCH_CONF_2_NC:
1567 return 2;
1568 case RSL_BCCH_CCCH_CONF_3_NC:
1569 return 3;
1570 case RSL_BCCH_CCCH_CONF_4_NC:
1571 return 4;
1572 default:
1573 return -1;
1574 }
1575}
1576
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001577/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001578int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1579{
1580 switch (ccch_conf) {
1581 case RSL_BCCH_CCCH_CONF_1_NC:
1582 return 0;
1583 case RSL_BCCH_CCCH_CONF_1_C:
1584 return 1;
1585 case RSL_BCCH_CCCH_CONF_2_NC:
1586 return 0;
1587 case RSL_BCCH_CCCH_CONF_3_NC:
1588 return 0;
1589 case RSL_BCCH_CCCH_CONF_4_NC:
1590 return 0;
1591 default:
1592 return -1;
1593 }
1594}
1595
1596/* From Table 10.5.33 of GSM 04.08 */
1597int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1598{
1599 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1600 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1601 * (bts->chan_desc.bs_pa_mfrms + 2);
1602 } else {
1603 return (9 - bts->chan_desc.bs_ag_blks_res)
1604 * (bts->chan_desc.bs_pa_mfrms + 2);
1605 }
1606}