blob: 1ef0b84c87f1b8550e1cdcbd0e2d4295ab8dcf12 [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 */
205 if (ts->pchan != GSM_PCHAN_TCH_F)
206 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
207 chan_nr, ts->pchan);
208 } else if ((cbits & 0x1e) == 0x02) {
209 lch_idx = cbits & 0x1; /* TCH/H */
210 if (ts->pchan != GSM_PCHAN_TCH_H)
211 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
212 chan_nr, ts->pchan);
213 } else if ((cbits & 0x1c) == 0x04) {
214 lch_idx = cbits & 0x3; /* SDCCH/4 */
215 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
216 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
217 chan_nr, ts->pchan);
218 } else if ((cbits & 0x18) == 0x08) {
219 lch_idx = cbits & 0x7; /* SDCCH/8 */
220 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
221 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
222 chan_nr, ts->pchan);
223 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
224 lch_idx = 0;
225 if (ts->pchan != GSM_PCHAN_CCCH &&
226 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
227 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
228 chan_nr, ts->pchan);
229 /* FIXME: we should not return first sdcch4 !!! */
230 } else {
231 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
232 return NULL;
233 }
234
235 lchan = &ts->lchan[lch_idx];
236
237 return lchan;
238}
239
240u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
241{
242 struct gsm_bts_trx_ts *ts = lchan->ts;
243 u_int8_t cbits, chan_nr;
244
245 switch (ts->pchan) {
246 case GSM_PCHAN_TCH_F:
247 cbits = 0x01;
248 break;
249 case GSM_PCHAN_TCH_H:
250 cbits = 0x02;
251 cbits += lchan->nr;
252 break;
253 case GSM_PCHAN_CCCH_SDCCH4:
254 cbits = 0x04;
255 cbits += lchan->nr;
256 break;
257 case GSM_PCHAN_SDCCH8_SACCH8C:
258 cbits = 0x08;
259 cbits += lchan->nr;
260 break;
261 default:
262 case GSM_PCHAN_CCCH:
263 cbits = 0x10;
264 break;
265 }
266
267 chan_nr = (cbits << 3) | (ts->nr & 0x7);
268
269 return chan_nr;
270}
271
272/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
273u_int64_t str_to_imsi(const char *imsi_str)
274{
275 u_int64_t ret;
276
277 ret = strtoull(imsi_str, NULL, 10);
278
279 return ret;
280}
281
282/* Table 5 Clause 7 TS 05.02 */
283unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
284{
285 if (!bs_ccch_sdcch_comb)
286 return 9 - bs_ag_blks_res;
287 else
288 return 3 - bs_ag_blks_res;
289}
290
291/* Chapter 6.5.2 of TS 05.02 */
292unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
293 unsigned int n_pag_blocks)
294{
295 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
296}
297
298/* Chapter 6.5.2 of TS 05.02 */
299unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
300 int n_pag_blocks)
301{
302 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
303}
304
305static struct msgb *rsl_msgb_alloc(void)
306{
Harald Welte9cfc9352009-06-26 19:39:35 +0200307 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
308 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800309}
310
311#define MACBLOCK_SIZE 23
312static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
313{
314 memcpy(out, in, len);
315
316 if (len < MACBLOCK_SIZE)
317 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
318}
319
Harald Weltef1a168d2009-07-28 17:58:09 +0200320static const char *rsl_err_vals[0xff] = {
321 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
322 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
323 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
324 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
325 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
326 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welteb1717e92009-08-04 02:31:05 +0200327 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Weltef1a168d2009-07-28 17:58:09 +0200328 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
329 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
330 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
331 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
332 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
333 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
334 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
335 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
336 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
337 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
338 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
339 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
340 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
341 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
342 [RSL_ERR_MSG_TYPE] = "Message Type Error",
343 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
344 [RSL_ERR_IE_ERROR] = "General IE error",
345 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
346 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
347 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
348 [RSL_ERR_IE_LENGTH] = "IE length error",
349 [RSL_ERR_IE_CONTENT] = "IE content error",
350 [RSL_ERR_PROTO] = "Protocol error, unspecified",
351 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
352};
353
354static const char *rsl_err_name(u_int8_t err)
Harald Welte59b04682009-06-10 05:40:52 +0800355{
Harald Weltef1a168d2009-07-28 17:58:09 +0200356 if (rsl_err_vals[err])
357 return rsl_err_vals[err];
358 else
359 return "unknown";
360}
361
362static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
363{
Harald Welte59b04682009-06-10 05:40:52 +0800364 int i;
365
Harald Weltef1a168d2009-07-28 17:58:09 +0200366 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
367 cause_v[0], rsl_err_name(cause_v[0]));
368 for (i = 1; i < cause_len-1; i++)
369 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800370}
371
372/* Send a BCCH_INFO message as per Chapter 8.5.1 */
373int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
374 const u_int8_t *data, int len)
375{
376 struct abis_rsl_dchan_hdr *dh;
377 struct msgb *msg = rsl_msgb_alloc();
378
379 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
380 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
381 dh->chan_nr = RSL_CHAN_BCCH;
382
383 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
384 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
385
386 msg->trx = trx;
387
388 return abis_rsl_sendmsg(msg);
389}
390
391int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
392 const u_int8_t *data, int len)
393{
394 struct abis_rsl_common_hdr *ch;
395 struct msgb *msg = rsl_msgb_alloc();
396
397 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
398 ch->msg_discr = ABIS_RSL_MDISC_TRX;
399 ch->msg_type = RSL_MT_SACCH_FILL;
400
401 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
402 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
403
404 msg->trx = trx;
405
406 return abis_rsl_sendmsg(msg);
407}
408
Harald Welte91afe4c2009-06-20 18:15:19 +0200409int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
410{
411 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200412 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200413 u_int8_t chan_nr = lchan2chan_nr(lchan);
414
415 db = abs(db);
416 if (db > 30)
417 return -EINVAL;
418
Harald Welteed831842009-06-27 03:09:08 +0200419 msg = rsl_msgb_alloc();
420
Harald Welte91afe4c2009-06-20 18:15:19 +0200421 lchan->bs_power = db/2;
422 if (fpc)
423 lchan->bs_power |= 0x10;
424
425 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
426 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
427 dh->chan_nr = chan_nr;
428
429 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
430
431 msg->trx = lchan->ts->trx;
432
433 return abis_rsl_sendmsg(msg);
434}
435
Harald Welte91afe4c2009-06-20 18:15:19 +0200436int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
437{
438 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200439 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200440 u_int8_t chan_nr = lchan2chan_nr(lchan);
441 int ctl_lvl;
442
Harald Weltec4dcda02009-08-09 14:45:18 +0200443 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200444 if (ctl_lvl < 0)
445 return ctl_lvl;
446
Harald Welteed831842009-06-27 03:09:08 +0200447 msg = rsl_msgb_alloc();
448
Harald Welte91afe4c2009-06-20 18:15:19 +0200449 lchan->ms_power = ctl_lvl;
450
451 if (fpc)
452 lchan->ms_power |= 0x20;
453
454 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
455 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
456 dh->chan_nr = chan_nr;
457
458 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
459
460 msg->trx = lchan->ts->trx;
461
462 return abis_rsl_sendmsg(msg);
463}
464
Harald Welte39274f42009-07-29 15:41:29 +0200465static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
466 struct gsm_lchan *lchan)
467{
468 memset(cm, 0, sizeof(cm));
469
470 /* FIXME: what to do with data calls ? */
471 cm->dtx_dtu = 0x00;
472
473 /* set TCH Speech/Data */
474 cm->spd_ind = lchan->rsl_cmode;
475
476 switch (lchan->type) {
477 case GSM_LCHAN_SDCCH:
478 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
479 break;
480 case GSM_LCHAN_TCH_F:
481 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
482 break;
483 case GSM_LCHAN_TCH_H:
484 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
485 break;
486 case GSM_LCHAN_NONE:
487 case GSM_LCHAN_UNKNOWN:
488 default:
489 return -EINVAL;
490 }
491
492 switch (lchan->tch_mode) {
493 case GSM48_CMODE_SIGN:
494 cm->chan_rate = 0;
495 break;
496 case GSM48_CMODE_SPEECH_V1:
497 cm->chan_rate = RSL_CMOD_SP_GSM1;
498 break;
499 case GSM48_CMODE_SPEECH_EFR:
500 cm->chan_rate = RSL_CMOD_SP_GSM2;
501 break;
502 case GSM48_CMODE_SPEECH_AMR:
503 cm->chan_rate = RSL_CMOD_SP_GSM3;
504 break;
505 case GSM48_CMODE_DATA_14k5:
506 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
507 break;
508 case GSM48_CMODE_DATA_12k0:
509 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
510 break;
511 case GSM48_CMODE_DATA_6k0:
512 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
513 break;
514 default:
515 return -EINVAL;
516 }
517
518 return 0;
519}
520
Harald Welte59b04682009-06-10 05:40:52 +0800521/* Chapter 8.4.1 */
522#if 0
523int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
524 u_int8_t act_type,
525 struct rsl_ie_chan_mode *chan_mode,
526 struct rsl_ie_chan_ident *chan_ident,
527 u_int8_t bs_power, u_int8_t ms_power,
528 u_int8_t ta)
529{
530 struct abis_rsl_dchan_hdr *dh;
531 struct msgb *msg = rsl_msgb_alloc();
532
533 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
534 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
535 dh->chan_nr = chan_nr;
536
537 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
538 /* For compatibility with Phase 1 */
539 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
540 (u_int8_t *) chan_mode);
541 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
542 (u_int8_t *) chan_ident);
543#if 0
544 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
545 (u_int8_t *) &encr_info);
546#endif
547 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
548 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
549 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
550
551 msg->trx = trx;
552
553 return abis_rsl_sendmsg(msg);
554}
555#endif
556
557int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte39274f42009-07-29 15:41:29 +0200558 u_int8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800559{
560 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200561 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200562 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800563
564 u_int8_t chan_nr = lchan2chan_nr(lchan);
565 u_int16_t arfcn = lchan->ts->trx->arfcn;
566 struct rsl_ie_chan_mode cm;
567 struct rsl_ie_chan_ident ci;
568
Harald Welte39274f42009-07-29 15:41:29 +0200569 rc = channel_mode_from_lchan(&cm, lchan);
570 if (rc < 0)
571 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800572
573 memset(&ci, 0, sizeof(ci));
574 ci.chan_desc.iei = 0x64;
575 ci.chan_desc.chan_nr = chan_nr;
576 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
577 ci.chan_desc.oct4 = arfcn & 0xff;
578
Harald Welteed831842009-06-27 03:09:08 +0200579 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800580 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
581 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
582 dh->chan_nr = chan_nr;
583
584 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
585 /* For compatibility with Phase 1 */
586 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
587 (u_int8_t *) &cm);
588 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
589 (u_int8_t *) &ci);
590#if 0
591 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
592 (u_int8_t *) &encr_info);
593#endif
594 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
595 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
596 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
597
598 msg->trx = lchan->ts->trx;
599
600 return abis_rsl_sendmsg(msg);
601}
602
Harald Welte8e770492009-07-29 11:38:15 +0200603/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800604int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
605{
606 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200607 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200608 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800609
610 u_int8_t chan_nr = lchan2chan_nr(lchan);
611 struct rsl_ie_chan_mode cm;
612
Harald Welte39274f42009-07-29 15:41:29 +0200613 rc = channel_mode_from_lchan(&cm, lchan);
614 if (rc < 0)
615 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800616
Harald Welteed831842009-06-27 03:09:08 +0200617 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800618 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
619 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
620 dh->chan_nr = chan_nr;
621
622 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
623 (u_int8_t *) &cm);
624#if 0
625 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
626 (u_int8_t *) &encr_info);
627#endif
628
629 msg->trx = lchan->ts->trx;
630
631 return abis_rsl_sendmsg(msg);
632}
633
Harald Welteafe3c232009-07-19 18:36:49 +0200634/* Chapter 8.4.5 */
635int rsl_deact_sacch(struct gsm_lchan *lchan)
636{
637 struct abis_rsl_dchan_hdr *dh;
638 struct msgb *msg = rsl_msgb_alloc();
639
640 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
641 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
642 dh->chan_nr = lchan2chan_nr(lchan);
643
644 msg->lchan = lchan;
645 msg->trx = lchan->ts->trx;
646
647 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
648 gsm_ts_name(lchan->ts), dh->chan_nr);
649
650 return abis_rsl_sendmsg(msg);
651}
652
Harald Welte59b04682009-06-10 05:40:52 +0800653/* Chapter 9.1.7 of 04.08 */
654int rsl_chan_release(struct gsm_lchan *lchan)
655{
656 struct abis_rsl_dchan_hdr *dh;
657 struct msgb *msg = rsl_msgb_alloc();
658
659 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
660 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
661 dh->chan_nr = lchan2chan_nr(lchan);
662
663 msg->lchan = lchan;
664 msg->trx = lchan->ts->trx;
665
666 DEBUGP(DRSL, "Channel Release CMD channel=%s chan_nr=0x%02x\n",
667 gsm_ts_name(lchan->ts), dh->chan_nr);
668
669 return abis_rsl_sendmsg(msg);
670}
671
672int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
673 u_int8_t *ms_ident, u_int8_t chan_needed)
674{
675 struct abis_rsl_dchan_hdr *dh;
676 struct msgb *msg = rsl_msgb_alloc();
677
678 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
679 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
680 dh->chan_nr = RSL_CHAN_PCH_AGCH;
681
682 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
683 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
684 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
685
686 msg->trx = bts->c0;
687
688 return abis_rsl_sendmsg(msg);
689}
690
691int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
692 struct gsm_subscriber *subscr)
693{
694#if 0
695 u_int8_t mi[128];
696 unsigned int mi_len;
697 u_int8_t paging_group;
698#endif
699
700 return -1;
701}
702
703int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
704{
705 int i, len = strlen(str_in);
706
707 for (i = 0; i < len; i++) {
708 int num = str_in[i] - 0x30;
709 if (num < 0 || num > 9)
710 return -1;
711 if (i % 2 == 0)
712 bcd_out[i/2] = num;
713 else
714 bcd_out[i/2] |= (num << 4);
715 }
716
717 return 0;
718}
719
720/* Chapter 8.5.6 */
721int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
722{
723 struct msgb *msg = rsl_msgb_alloc();
724 struct abis_rsl_dchan_hdr *dh;
725 u_int8_t buf[MACBLOCK_SIZE];
726
727 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
728 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
729 dh->chan_nr = RSL_CHAN_PCH_AGCH;
730
731 switch (bts->type) {
732 case GSM_BTS_TYPE_BS11:
733 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
734 break;
735 default:
736 /* If phase 2, construct a FULL_IMM_ASS_INFO */
737 pad_macblock(buf, val, len);
738 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
739 break;
740 }
741
742 msg->trx = bts->c0;
743
744 return abis_rsl_sendmsg(msg);
745}
746
Harald Welte4684e632009-08-10 09:51:40 +0200747/* Send Siemens specific MS RF Power Capability Indication */
748int rsl_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t mrpci)
749{
750 struct msgb *msg = rsl_msgb_alloc();
751 struct abis_rsl_dchan_hdr *dh;
752
753 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
754 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
755 dh->chan_nr = lchan2chan_nr(lchan);
756 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, mrpci);
757
758 return abis_rsl_sendmsg(msg);
759}
760
761
Harald Welte59b04682009-06-10 05:40:52 +0800762/* Send "DATA REQUEST" message with given L3 Info payload */
763/* Chapter 8.3.1 */
764int rsl_data_request(struct msgb *msg, u_int8_t link_id)
765{
766 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
767 struct abis_rsl_rll_hdr *rh;
768
769 if (msg->lchan == NULL) {
770 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
771 return -EINVAL;
772 }
773
774 /* First push the L3 IE tag and length */
775 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
776
777 /* Then push the RSL header */
778 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
779 init_llm_hdr(rh, RSL_MT_DATA_REQ);
780 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
781 rh->chan_nr = lchan2chan_nr(msg->lchan);
782 rh->link_id = link_id;
783
784 msg->trx = msg->lchan->ts->trx;
785
786 return abis_rsl_sendmsg(msg);
787}
788
Harald Welteed9a5ab2009-08-09 13:47:35 +0200789/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
790/* Chapter 8.3.1 */
791int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
792{
793 struct msgb *msg = rsl_msgb_alloc();
794 struct abis_rsl_rll_hdr *rh;
795
796 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200797 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200798 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
799 rh->chan_nr = lchan2chan_nr(lchan);
800 rh->link_id = link_id;
801
802 msg->trx = lchan->ts->trx;
803
804 return abis_rsl_sendmsg(msg);
805}
806
Harald Welte0f2e3c12009-08-08 13:15:07 +0200807/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
808 This is what higher layers should call. The BTS then responds with
809 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
810 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
811 lchan_free() */
812int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
813{
814 struct msgb *msg = rsl_msgb_alloc();
815 struct abis_rsl_rll_hdr *rh;
816
817 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
818 init_llm_hdr(rh, RSL_MT_REL_REQ);
819 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
820 rh->chan_nr = lchan2chan_nr(lchan);
821 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200822 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200823
824 msg->trx = lchan->ts->trx;
825
826 return abis_rsl_sendmsg(msg);
827}
828
Harald Welte59b04682009-06-10 05:40:52 +0800829/* Chapter 8.4.2: Channel Activate Acknowledge */
830static int rsl_rx_chan_act_ack(struct msgb *msg)
831{
832 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
833
834 /* BTS has confirmed channel activation, we now need
835 * to assign the activated channel to the MS */
836 if (rslh->ie_chan != RSL_IE_CHAN_NR)
837 return -EINVAL;
838
839 return 0;
840}
841
842/* Chapter 8.4.3: Channel Activate NACK */
843static int rsl_rx_chan_act_nack(struct msgb *msg)
844{
845 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
846 struct tlv_parsed tp;
847
848 /* BTS has rejected channel activation ?!? */
849 if (dh->ie_chan != RSL_IE_CHAN_NR)
850 return -EINVAL;
851
852 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
853 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200854 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
855 TLVP_LEN(&tp, RSL_IE_CAUSE));
856
Harald Weltecddb9802009-08-09 19:50:08 +0200857 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800858 return 0;
859}
860
861/* Chapter 8.4.4: Connection Failure Indication */
862static int rsl_rx_conn_fail(struct msgb *msg)
863{
864 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
865 struct tlv_parsed tp;
866
867 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800868
869 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
870
Harald Weltef1a168d2009-07-28 17:58:09 +0200871 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
872 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
873 TLVP_LEN(&tp, RSL_IE_CAUSE));
874
Harald Welte59b04682009-06-10 05:40:52 +0800875 if (msg->trx->bts->type == GSM_BTS_TYPE_BS11) {
876 /* FIXME: we have no idea what cause 0x18 is !!! */
877 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE) &&
878 TLVP_LEN(&tp, RSL_IE_CAUSE) >= 1 &&
879 *TLVP_VAL(&tp, RSL_IE_CAUSE) == 0x18) {
Harald Weltedf0c6502009-07-04 10:05:51 +0200880 DEBUGPC(DRSL, "Cause 0x18 IGNORING\n");
881 return 0;
Harald Welte59b04682009-06-10 05:40:52 +0800882 }
883 }
884
885 DEBUGPC(DRSL, "RELEASING.\n");
886
887 /* FIXME: only free it after channel release ACK */
888 return rsl_chan_release(msg->lchan);
889}
890
891static int rsl_rx_meas_res(struct msgb *msg)
892{
893 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
894 struct tlv_parsed tp;
895
Harald Welte02993682009-06-27 02:53:10 +0200896 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800897 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
898
899 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200900 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800901 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
902 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
903 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
904 if (len >= 3) {
905 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200906 DEBUGPC(DMEAS, "DTXd ");
907 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800908 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200909 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800910 val[2]>>3 & 0x7, val[2] & 0x7);
911 }
912 }
913 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200914 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800915 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200916 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800917 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200918 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200919 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200920 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200921 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200922 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200923 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
924 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200925 }
Harald Welte59b04682009-06-10 05:40:52 +0800926 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200927 DEBUGPC(DMEAS, "L3\n");
Harald Welte59b04682009-06-10 05:40:52 +0800928 msg->l3h = TLVP_VAL(&tp, RSL_IE_L3_INFO);
929 return gsm0408_rcvmsg(msg);
930 } else
Harald Welte02993682009-06-27 02:53:10 +0200931 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800932
933 return 0;
934}
935
936static int abis_rsl_rx_dchan(struct msgb *msg)
937{
938 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
939 int rc = 0;
940 char *ts_name;
941
942 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
943 ts_name = gsm_ts_name(msg->lchan->ts);
944
Harald Welte02993682009-06-27 02:53:10 +0200945 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
946 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800947
948 switch (rslh->c.msg_type) {
949 case RSL_MT_CHAN_ACTIV_ACK:
950 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
951 rc = rsl_rx_chan_act_ack(msg);
952 break;
953 case RSL_MT_CHAN_ACTIV_NACK:
954 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
955 rc = rsl_rx_chan_act_nack(msg);
956 break;
957 case RSL_MT_CONN_FAIL:
958 rc = rsl_rx_conn_fail(msg);
959 break;
960 case RSL_MT_MEAS_RES:
961 rc = rsl_rx_meas_res(msg);
962 break;
963 case RSL_MT_RF_CHAN_REL_ACK:
964 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
965 lchan_free(msg->lchan);
966 break;
967 case RSL_MT_MODE_MODIFY_ACK:
968 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
969 break;
970 case RSL_MT_MODE_MODIFY_NACK:
971 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
972 break;
973 case RSL_MT_PHY_CONTEXT_CONF:
974 case RSL_MT_PREPROC_MEAS_RES:
975 case RSL_MT_TALKER_DET:
976 case RSL_MT_LISTENER_DET:
977 case RSL_MT_REMOTE_CODEC_CONF_REP:
978 case RSL_MT_MR_CODEC_MOD_ACK:
979 case RSL_MT_MR_CODEC_MOD_NACK:
980 case RSL_MT_MR_CODEC_MOD_PER:
981 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
982 rslh->c.msg_type);
983 break;
984 default:
985 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
986 rslh->c.msg_type);
987 return -EINVAL;
988 }
989
990 return rc;
991}
992
993static int rsl_rx_error_rep(struct msgb *msg)
994{
995 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +0200996 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +0800997
998 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +0200999
1000 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1001
1002 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1003 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1004 TLVP_LEN(&tp, RSL_IE_CAUSE));
1005
Harald Welte59b04682009-06-10 05:40:52 +08001006 DEBUGPC(DRSL, "\n");
1007
1008 return 0;
1009}
1010
1011static int abis_rsl_rx_trx(struct msgb *msg)
1012{
1013 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1014 int rc = 0;
1015
1016 switch (rslh->msg_type) {
1017 case RSL_MT_ERROR_REPORT:
1018 rc = rsl_rx_error_rep(msg);
1019 break;
1020 case RSL_MT_RF_RES_IND:
1021 /* interference on idle channels of TRX */
1022 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1023 break;
1024 case RSL_MT_OVERLOAD:
1025 /* indicate CCCH / ACCH / processor overload */
1026 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1027 break;
1028 default:
1029 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1030 rslh->msg_type);
1031 return -EINVAL;
1032 }
1033 return rc;
1034}
1035
Harald Welte427dbc42009-08-10 00:26:10 +02001036/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1037static void t3101_expired(void *data)
1038{
1039 struct gsm_lchan *lchan = data;
1040
1041 rsl_chan_release(lchan);
1042}
1043
Harald Welte59b04682009-06-10 05:40:52 +08001044/* MS has requested a channel on the RACH */
1045static int rsl_rx_chan_rqd(struct msgb *msg)
1046{
1047 struct gsm_bts *bts = msg->trx->bts;
1048 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1049 struct gsm48_req_ref *rqd_ref;
1050 struct gsm48_imm_ass ia;
1051 enum gsm_chan_t lctype;
1052 enum gsm_chreq_reason_t chreq_reason;
1053 struct gsm_lchan *lchan;
1054 u_int8_t rqd_ta;
1055 int ret;
1056
1057 u_int16_t arfcn;
1058 u_int8_t ts_number, subch;
1059
1060 /* parse request reference to be used in immediate assign */
1061 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1062 return -EINVAL;
1063
1064 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1065
1066 /* parse access delay and use as TA */
1067 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1068 return -EINVAL;
1069 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1070
1071 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1072 * request reference RA */
1073 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
1074 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1075
1076 /* check availability / allocate channel */
1077 lchan = lchan_alloc(bts, lctype);
1078 if (!lchan) {
1079 fprintf(stderr, "CHAN RQD: no resources\n");
1080 /* FIXME: send some kind of reject ?!? */
1081 return -ENOMEM;
1082 }
1083
1084 ts_number = lchan->ts->nr;
1085 arfcn = lchan->ts->trx->arfcn;
1086 subch = lchan->nr;
1087
Harald Weltec4dcda02009-08-09 14:45:18 +02001088 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte9a229e12009-08-10 00:45:40 +02001089 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001090 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
1091 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001092
1093 /* create IMMEDIATE ASSIGN 04.08 messge */
1094 memset(&ia, 0, sizeof(ia));
1095 ia.l2_plen = 0x2d;
1096 ia.proto_discr = GSM48_PDISC_RR;
1097 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1098 ia.page_mode = GSM48_PM_SAME;
1099 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1100 ia.chan_desc.h0.h = 0;
1101 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1102 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001103 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001104 /* use request reference extracted from CHAN_RQD */
1105 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1106 ia.timing_advance = rqd_ta;
1107 ia.mob_alloc_len = 0;
1108
1109 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1110 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1111 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1112 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1113 rqd_ref->ra);
1114
Harald Welte427dbc42009-08-10 00:26:10 +02001115 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1116 lchan->T3101.cb = t3101_expired;
1117 lchan->T3101.data = lchan;
1118 bsc_schedule_timer(&lchan->T3101, 10, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001119
1120 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1121 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1122
1123 return ret;
1124}
1125
1126/* MS has requested a channel on the RACH */
1127static int rsl_rx_ccch_load(struct msgb *msg)
1128{
1129 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1130 u_int16_t pg_buf_space;
1131 u_int16_t rach_slot_count = -1;
1132 u_int16_t rach_busy_count = -1;
1133 u_int16_t rach_access_count = -1;
1134
1135 switch (rslh->data[0]) {
1136 case RSL_IE_PAGING_LOAD:
1137 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1138 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1139 break;
1140 case RSL_IE_RACH_LOAD:
1141 if (msg->data_len >= 7) {
1142 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1143 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1144 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1145 }
1146 break;
1147 default:
1148 break;
1149 }
1150
1151 return 0;
1152}
1153
1154static int abis_rsl_rx_cchan(struct msgb *msg)
1155{
1156 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1157 int rc = 0;
1158
1159 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1160
1161 switch (rslh->c.msg_type) {
1162 case RSL_MT_CHAN_RQD:
1163 /* MS has requested a channel on the RACH */
1164 rc = rsl_rx_chan_rqd(msg);
1165 break;
1166 case RSL_MT_CCCH_LOAD_IND:
1167 /* current load on the CCCH */
1168 rc = rsl_rx_ccch_load(msg);
1169 break;
1170 case RSL_MT_DELETE_IND:
1171 /* CCCH overloaded, IMM_ASSIGN was dropped */
1172 case RSL_MT_CBCH_LOAD_IND:
1173 /* current load on the CBCH */
1174 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1175 "0x%02x\n", rslh->c.msg_type);
1176 break;
1177 default:
1178 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1179 rslh->c.msg_type);
1180 return -EINVAL;
1181 }
1182
1183 return rc;
1184}
1185
1186static int rsl_rx_rll_err_ind(struct msgb *msg)
1187{
1188 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1189 u_int8_t *rlm_cause = rllh->data;
1190
Harald Welteb6601442009-08-04 02:50:21 +02001191 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001192
1193 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001194
Harald Welte692f5852009-07-04 09:40:05 +02001195 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
1196 return rsl_chan_release(msg->lchan);
1197
Harald Welte59b04682009-06-10 05:40:52 +08001198 return 0;
1199}
1200
1201/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1202 0x02, 0x06,
1203 0x01, 0x20,
1204 0x02, 0x00,
1205 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1206
1207static int abis_rsl_rx_rll(struct msgb *msg)
1208{
1209 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1210 int rc = 0;
1211 char *ts_name;
1212
1213 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1214 ts_name = gsm_ts_name(msg->lchan->ts);
1215 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x ", ts_name, rllh->chan_nr);
1216
1217 switch (rllh->c.msg_type) {
1218 case RSL_MT_DATA_IND:
1219 DEBUGPC(DRLL, "DATA INDICATION\n");
1220 if (msgb_l2len(msg) >
1221 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1222 rllh->data[0] == RSL_IE_L3_INFO) {
1223 msg->l3h = &rllh->data[3];
1224 return gsm0408_rcvmsg(msg);
1225 }
1226 break;
1227 case RSL_MT_EST_IND:
1228 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001229 /* lchan is established, stop T3101 */
1230 bsc_del_timer(&msg->lchan->T3101);
Harald Welte59b04682009-06-10 05:40:52 +08001231 if (msgb_l2len(msg) >
1232 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1233 rllh->data[0] == RSL_IE_L3_INFO) {
1234 msg->l3h = &rllh->data[3];
1235 return gsm0408_rcvmsg(msg);
1236 }
1237 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001238 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001239 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001240 rll_indication(msg->lchan, rllh->link_id,
1241 BSC_RLLR_IND_EST_CONF);
1242 break;
Harald Welte59b04682009-06-10 05:40:52 +08001243 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001244 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001245 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001246 rll_indication(msg->lchan, rllh->link_id,
1247 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001248 /* we can now releae the channel on the BTS/Abis side */
1249 rsl_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001250 break;
1251 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001252 /* BTS informs us of having received UA from MS,
1253 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001254 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welte0f2e3c12009-08-08 13:15:07 +02001255 /* we can now releae the channel on the BTS/Abis side */
1256 rsl_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001257 break;
1258 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001259 rc = rsl_rx_rll_err_ind(msg);
1260 break;
1261 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001262 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001263 rllh->c.msg_type);
1264 break;
1265 default:
Harald Welteb6601442009-08-04 02:50:21 +02001266 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001267 rllh->c.msg_type);
1268 }
Harald Welte59b04682009-06-10 05:40:52 +08001269 return rc;
1270}
1271
Harald Welte98d79f92009-07-28 18:11:56 +02001272static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1273{
Harald Welte98d79f92009-07-28 18:11:56 +02001274 switch (tch_mode) {
1275 case GSM48_CMODE_SPEECH_V1:
1276 return 0x00;
1277 case GSM48_CMODE_SPEECH_EFR:
1278 return 0x01;
1279 case GSM48_CMODE_SPEECH_AMR:
1280 return 0x02;
1281 /* FIXME: Type1 half-rate and type3 half-rate */
1282 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001283 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1284 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001285 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001286}
1287
Harald Welte59b04682009-06-10 05:40:52 +08001288/* ip.access specific RSL extensions */
1289int rsl_ipacc_bind(struct gsm_lchan *lchan)
1290{
1291 struct msgb *msg = rsl_msgb_alloc();
1292 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001293 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001294
1295 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1296 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1297 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1298 dh->chan_nr = lchan2chan_nr(lchan);
1299
Harald Welte98d79f92009-07-28 18:11:56 +02001300 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001301 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1302 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001303
Harald Weltefb4a9e92009-07-29 12:12:18 +02001304 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1305 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1306 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001307
Harald Welte59b04682009-06-10 05:40:52 +08001308 msg->trx = lchan->ts->trx;
1309
1310 return abis_rsl_sendmsg(msg);
1311}
1312
Harald Welte8cdeaad2009-07-12 09:50:35 +02001313int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1314 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001315{
1316 struct msgb *msg = rsl_msgb_alloc();
1317 struct abis_rsl_dchan_hdr *dh;
1318 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001319 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001320 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001321
1322 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1323 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1324 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1325 dh->chan_nr = lchan2chan_nr(lchan);
1326
Harald Weltefb4a9e92009-07-29 12:12:18 +02001327 /* 0x0- == both directions, 0x-1 == EFR codec */
1328 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1329
Harald Welte98d79f92009-07-28 18:11:56 +02001330 ia.s_addr = htonl(ip);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001331 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1332 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001333 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001334 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001335
Harald Welte8cdeaad2009-07-12 09:50:35 +02001336 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001337 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001338 att_f8[1] = conn_id >> 8;
1339 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001340
1341 att_ip = msgb_put(msg, sizeof(ip)+1);
1342 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1343 att_ip[1] = ip >> 24;
1344 att_ip[2] = ip >> 16;
1345 att_ip[3] = ip >> 8;
1346 att_ip[4] = ip & 0xff;
1347 //att_ip[4] = 11;
1348
1349 att_port = msgb_put(msg, sizeof(port)+1);
1350 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1351 att_port[1] = port >> 8;
1352 att_port[2] = port & 0xff;
1353
Harald Weltefb4a9e92009-07-29 12:12:18 +02001354 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001355 if (rtp_payload2)
1356 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1357
Harald Welte59b04682009-06-10 05:40:52 +08001358 msg->trx = lchan->ts->trx;
1359
1360 return abis_rsl_sendmsg(msg);
1361}
1362
1363static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1364{
1365 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1366 struct tlv_parsed tv;
1367 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1368 struct in_addr ip;
1369 u_int16_t port, attr_f8;
1370
1371 /* the BTS has acknowledged a local bind, it now tells us the IP
1372 * address and port number to which it has bound the given logical
1373 * channel */
1374
1375 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1376 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1377 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001378 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001379 DEBUGPC(DRSL, "mandatory IE missing");
1380 return -EINVAL;
1381 }
1382 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1383 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1384 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1385
Harald Welte98d79f92009-07-28 18:11:56 +02001386 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1387 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1388
1389 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1390 ts->abis_ip.rtp_payload2 =
1391 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1392 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1393 ts->abis_ip.rtp_payload2);
1394 }
Harald Welte59b04682009-06-10 05:40:52 +08001395
1396 /* update our local information about this TS */
1397 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1398 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001399 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001400
1401 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1402
1403 return 0;
1404}
1405
1406static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1407{
1408 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1409 struct tlv_parsed tv;
1410
1411 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001412
Harald Weltef1a168d2009-07-28 17:58:09 +02001413 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1414 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1415 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001416
Harald Welteba4e58d2009-07-28 18:02:05 +02001417 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1418
Harald Welte59b04682009-06-10 05:40:52 +08001419 return 0;
1420}
1421
1422static int abis_rsl_rx_ipacc(struct msgb *msg)
1423{
1424 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1425 int rc = 0;
1426
1427 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1428 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1429 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1430
1431 switch (rllh->c.msg_type) {
1432 case RSL_MT_IPAC_BIND_ACK:
1433 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
1434 rc = abis_rsl_rx_ipacc_bindack(msg);
1435 break;
1436 case RSL_MT_IPAC_BIND_NACK:
1437 /* somehow the BTS was unable to bind the lchan to its local
1438 * port?!? */
1439 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
1440 break;
1441 case RSL_MT_IPAC_CONNECT_ACK:
1442 /* the BTS tells us that a connect operation was successful */
1443 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
1444 break;
1445 case RSL_MT_IPAC_CONNECT_NACK:
1446 /* somehow the BTS was unable to connect the lchan to a remote
1447 * port */
1448 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
1449 break;
1450 case RSL_MT_IPAC_DISCONNECT_IND:
1451 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
1452 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1453 break;
1454 default:
1455 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1456 break;
1457 }
1458 DEBUGPC(DRSL, "\n");
1459
1460 return rc;
1461}
1462
1463
1464/* Entry-point where L2 RSL from BTS enters */
1465int abis_rsl_rcvmsg(struct msgb *msg)
1466{
1467 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1468 int rc = 0;
1469
1470 switch (rslh->msg_discr & 0xfe) {
1471 case ABIS_RSL_MDISC_RLL:
1472 rc = abis_rsl_rx_rll(msg);
1473 break;
1474 case ABIS_RSL_MDISC_DED_CHAN:
1475 rc = abis_rsl_rx_dchan(msg);
1476 break;
1477 case ABIS_RSL_MDISC_COM_CHAN:
1478 rc = abis_rsl_rx_cchan(msg);
1479 break;
1480 case ABIS_RSL_MDISC_TRX:
1481 rc = abis_rsl_rx_trx(msg);
1482 break;
1483 case ABIS_RSL_MDISC_LOC:
1484 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1485 rslh->msg_discr);
1486 break;
1487 case ABIS_RSL_MDISC_IPACCESS:
1488 rc = abis_rsl_rx_ipacc(msg);
1489 break;
1490 default:
1491 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1492 rslh->msg_discr);
1493 return -EINVAL;
1494 }
1495 msgb_free(msg);
1496 return rc;
1497}
1498
1499
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001500/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001501int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1502{
1503 switch (ccch_conf) {
1504 case RSL_BCCH_CCCH_CONF_1_NC:
1505 return 1;
1506 case RSL_BCCH_CCCH_CONF_1_C:
1507 return 1;
1508 case RSL_BCCH_CCCH_CONF_2_NC:
1509 return 2;
1510 case RSL_BCCH_CCCH_CONF_3_NC:
1511 return 3;
1512 case RSL_BCCH_CCCH_CONF_4_NC:
1513 return 4;
1514 default:
1515 return -1;
1516 }
1517}
1518
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001519/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001520int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1521{
1522 switch (ccch_conf) {
1523 case RSL_BCCH_CCCH_CONF_1_NC:
1524 return 0;
1525 case RSL_BCCH_CCCH_CONF_1_C:
1526 return 1;
1527 case RSL_BCCH_CCCH_CONF_2_NC:
1528 return 0;
1529 case RSL_BCCH_CCCH_CONF_3_NC:
1530 return 0;
1531 case RSL_BCCH_CCCH_CONF_4_NC:
1532 return 0;
1533 default:
1534 return -1;
1535 }
1536}
1537
1538/* From Table 10.5.33 of GSM 04.08 */
1539int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1540{
1541 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1542 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1543 * (bts->chan_desc.bs_pa_mfrms + 2);
1544 } else {
1545 return (9 - bts->chan_desc.bs_ag_blks_res)
1546 * (bts->chan_desc.bs_pa_mfrms + 2);
1547 }
1548}