blob: 5c4fbdae3113be662e5f4befd3c4965ce54e3744 [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 Welte85a163c2009-08-10 11:43:22 +0200634/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteafe3c232009-07-19 18:36:49 +0200635int 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 Welte85a163c2009-08-10 11:43:22 +0200653/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
654int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800655{
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
Harald Welte85a163c2009-08-10 11:43:22 +0200666 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +0800667 gsm_ts_name(lchan->ts), dh->chan_nr);
668
Harald Welte85a163c2009-08-10 11:43:22 +0200669 /* BTS will respond by RF CHAN REL ACK */
Harald Welte59b04682009-06-10 05:40:52 +0800670 return abis_rsl_sendmsg(msg);
671}
672
673int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
674 u_int8_t *ms_ident, u_int8_t chan_needed)
675{
676 struct abis_rsl_dchan_hdr *dh;
677 struct msgb *msg = rsl_msgb_alloc();
678
679 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
680 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
681 dh->chan_nr = RSL_CHAN_PCH_AGCH;
682
683 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
684 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
685 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
686
687 msg->trx = bts->c0;
688
689 return abis_rsl_sendmsg(msg);
690}
691
692int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
693 struct gsm_subscriber *subscr)
694{
695#if 0
696 u_int8_t mi[128];
697 unsigned int mi_len;
698 u_int8_t paging_group;
699#endif
700
701 return -1;
702}
703
704int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
705{
706 int i, len = strlen(str_in);
707
708 for (i = 0; i < len; i++) {
709 int num = str_in[i] - 0x30;
710 if (num < 0 || num > 9)
711 return -1;
712 if (i % 2 == 0)
713 bcd_out[i/2] = num;
714 else
715 bcd_out[i/2] |= (num << 4);
716 }
717
718 return 0;
719}
720
721/* Chapter 8.5.6 */
722int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
723{
724 struct msgb *msg = rsl_msgb_alloc();
725 struct abis_rsl_dchan_hdr *dh;
726 u_int8_t buf[MACBLOCK_SIZE];
727
728 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
729 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
730 dh->chan_nr = RSL_CHAN_PCH_AGCH;
731
732 switch (bts->type) {
733 case GSM_BTS_TYPE_BS11:
734 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
735 break;
736 default:
737 /* If phase 2, construct a FULL_IMM_ASS_INFO */
738 pad_macblock(buf, val, len);
739 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
740 break;
741 }
742
743 msg->trx = bts->c0;
744
745 return abis_rsl_sendmsg(msg);
746}
747
Harald Welte4684e632009-08-10 09:51:40 +0200748/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte12090752009-08-10 10:07:33 +0200749int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte4684e632009-08-10 09:51:40 +0200750{
751 struct msgb *msg = rsl_msgb_alloc();
752 struct abis_rsl_dchan_hdr *dh;
753
754 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
755 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte874a5b42009-08-10 11:26:14 +0200756 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte4684e632009-08-10 09:51:40 +0200757 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte12090752009-08-10 10:07:33 +0200758 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte4684e632009-08-10 09:51:40 +0200759
Harald Welte874a5b42009-08-10 11:26:14 +0200760 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
761 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
762
763 msg->trx = lchan->ts->trx;
764
Harald Welte4684e632009-08-10 09:51:40 +0200765 return abis_rsl_sendmsg(msg);
766}
767
768
Harald Welte59b04682009-06-10 05:40:52 +0800769/* Send "DATA REQUEST" message with given L3 Info payload */
770/* Chapter 8.3.1 */
771int rsl_data_request(struct msgb *msg, u_int8_t link_id)
772{
773 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
774 struct abis_rsl_rll_hdr *rh;
775
776 if (msg->lchan == NULL) {
777 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
778 return -EINVAL;
779 }
780
781 /* First push the L3 IE tag and length */
782 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
783
784 /* Then push the RSL header */
785 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
786 init_llm_hdr(rh, RSL_MT_DATA_REQ);
787 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
788 rh->chan_nr = lchan2chan_nr(msg->lchan);
789 rh->link_id = link_id;
790
791 msg->trx = msg->lchan->ts->trx;
792
793 return abis_rsl_sendmsg(msg);
794}
795
Harald Welteed9a5ab2009-08-09 13:47:35 +0200796/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
797/* Chapter 8.3.1 */
798int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
799{
800 struct msgb *msg = rsl_msgb_alloc();
801 struct abis_rsl_rll_hdr *rh;
802
803 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200804 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200805 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
806 rh->chan_nr = lchan2chan_nr(lchan);
807 rh->link_id = link_id;
808
809 msg->trx = lchan->ts->trx;
810
811 return abis_rsl_sendmsg(msg);
812}
813
Harald Welte0f2e3c12009-08-08 13:15:07 +0200814/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
815 This is what higher layers should call. The BTS then responds with
816 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
817 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
818 lchan_free() */
819int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
820{
821 struct msgb *msg = rsl_msgb_alloc();
822 struct abis_rsl_rll_hdr *rh;
823
824 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
825 init_llm_hdr(rh, RSL_MT_REL_REQ);
826 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
827 rh->chan_nr = lchan2chan_nr(lchan);
828 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200829 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200830
831 msg->trx = lchan->ts->trx;
832
833 return abis_rsl_sendmsg(msg);
834}
835
Harald Welte59b04682009-06-10 05:40:52 +0800836/* Chapter 8.4.2: Channel Activate Acknowledge */
837static int rsl_rx_chan_act_ack(struct msgb *msg)
838{
839 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
840
841 /* BTS has confirmed channel activation, we now need
842 * to assign the activated channel to the MS */
843 if (rslh->ie_chan != RSL_IE_CHAN_NR)
844 return -EINVAL;
845
846 return 0;
847}
848
849/* Chapter 8.4.3: Channel Activate NACK */
850static int rsl_rx_chan_act_nack(struct msgb *msg)
851{
852 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
853 struct tlv_parsed tp;
854
855 /* BTS has rejected channel activation ?!? */
856 if (dh->ie_chan != RSL_IE_CHAN_NR)
857 return -EINVAL;
858
859 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
860 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200861 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
862 TLVP_LEN(&tp, RSL_IE_CAUSE));
863
Harald Weltecddb9802009-08-09 19:50:08 +0200864 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800865 return 0;
866}
867
868/* Chapter 8.4.4: Connection Failure Indication */
869static int rsl_rx_conn_fail(struct msgb *msg)
870{
871 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
872 struct tlv_parsed tp;
873
874 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800875
876 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
877
Harald Weltef1a168d2009-07-28 17:58:09 +0200878 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
879 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
880 TLVP_LEN(&tp, RSL_IE_CAUSE));
881
Harald Welte59b04682009-06-10 05:40:52 +0800882 if (msg->trx->bts->type == GSM_BTS_TYPE_BS11) {
883 /* FIXME: we have no idea what cause 0x18 is !!! */
884 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE) &&
885 TLVP_LEN(&tp, RSL_IE_CAUSE) >= 1 &&
886 *TLVP_VAL(&tp, RSL_IE_CAUSE) == 0x18) {
Harald Weltedf0c6502009-07-04 10:05:51 +0200887 DEBUGPC(DRSL, "Cause 0x18 IGNORING\n");
888 return 0;
Harald Welte59b04682009-06-10 05:40:52 +0800889 }
890 }
891
892 DEBUGPC(DRSL, "RELEASING.\n");
893
894 /* FIXME: only free it after channel release ACK */
Harald Welte85a163c2009-08-10 11:43:22 +0200895 return rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800896}
897
898static int rsl_rx_meas_res(struct msgb *msg)
899{
900 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
901 struct tlv_parsed tp;
902
Harald Welte02993682009-06-27 02:53:10 +0200903 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800904 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
905
906 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200907 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800908 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
909 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
910 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
911 if (len >= 3) {
912 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200913 DEBUGPC(DMEAS, "DTXd ");
914 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800915 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200916 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800917 val[2]>>3 & 0x7, val[2] & 0x7);
918 }
919 }
920 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200921 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800922 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200923 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800924 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200925 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200926 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200927 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200928 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200929 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200930 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
931 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200932 }
Harald Welte59b04682009-06-10 05:40:52 +0800933 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200934 DEBUGPC(DMEAS, "L3\n");
Harald Welte59b04682009-06-10 05:40:52 +0800935 msg->l3h = TLVP_VAL(&tp, RSL_IE_L3_INFO);
936 return gsm0408_rcvmsg(msg);
937 } else
Harald Welte02993682009-06-27 02:53:10 +0200938 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800939
940 return 0;
941}
942
943static int abis_rsl_rx_dchan(struct msgb *msg)
944{
945 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
946 int rc = 0;
947 char *ts_name;
948
949 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
950 ts_name = gsm_ts_name(msg->lchan->ts);
951
Harald Welte02993682009-06-27 02:53:10 +0200952 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
953 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800954
955 switch (rslh->c.msg_type) {
956 case RSL_MT_CHAN_ACTIV_ACK:
957 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
958 rc = rsl_rx_chan_act_ack(msg);
959 break;
960 case RSL_MT_CHAN_ACTIV_NACK:
961 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
962 rc = rsl_rx_chan_act_nack(msg);
963 break;
964 case RSL_MT_CONN_FAIL:
965 rc = rsl_rx_conn_fail(msg);
966 break;
967 case RSL_MT_MEAS_RES:
968 rc = rsl_rx_meas_res(msg);
969 break;
970 case RSL_MT_RF_CHAN_REL_ACK:
971 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
972 lchan_free(msg->lchan);
973 break;
974 case RSL_MT_MODE_MODIFY_ACK:
975 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
976 break;
977 case RSL_MT_MODE_MODIFY_NACK:
978 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
979 break;
980 case RSL_MT_PHY_CONTEXT_CONF:
981 case RSL_MT_PREPROC_MEAS_RES:
982 case RSL_MT_TALKER_DET:
983 case RSL_MT_LISTENER_DET:
984 case RSL_MT_REMOTE_CODEC_CONF_REP:
985 case RSL_MT_MR_CODEC_MOD_ACK:
986 case RSL_MT_MR_CODEC_MOD_NACK:
987 case RSL_MT_MR_CODEC_MOD_PER:
988 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
989 rslh->c.msg_type);
990 break;
991 default:
992 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
993 rslh->c.msg_type);
994 return -EINVAL;
995 }
996
997 return rc;
998}
999
1000static int rsl_rx_error_rep(struct msgb *msg)
1001{
1002 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001003 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001004
1005 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +02001006
1007 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1008
1009 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1010 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1011 TLVP_LEN(&tp, RSL_IE_CAUSE));
1012
Harald Welte59b04682009-06-10 05:40:52 +08001013 DEBUGPC(DRSL, "\n");
1014
1015 return 0;
1016}
1017
1018static int abis_rsl_rx_trx(struct msgb *msg)
1019{
1020 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1021 int rc = 0;
1022
1023 switch (rslh->msg_type) {
1024 case RSL_MT_ERROR_REPORT:
1025 rc = rsl_rx_error_rep(msg);
1026 break;
1027 case RSL_MT_RF_RES_IND:
1028 /* interference on idle channels of TRX */
1029 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1030 break;
1031 case RSL_MT_OVERLOAD:
1032 /* indicate CCCH / ACCH / processor overload */
1033 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1034 break;
1035 default:
1036 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1037 rslh->msg_type);
1038 return -EINVAL;
1039 }
1040 return rc;
1041}
1042
Harald Welte427dbc42009-08-10 00:26:10 +02001043/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1044static void t3101_expired(void *data)
1045{
1046 struct gsm_lchan *lchan = data;
1047
Harald Welte85a163c2009-08-10 11:43:22 +02001048 rsl_rf_chan_release(lchan);
Harald Welte427dbc42009-08-10 00:26:10 +02001049}
1050
Harald Welte59b04682009-06-10 05:40:52 +08001051/* MS has requested a channel on the RACH */
1052static int rsl_rx_chan_rqd(struct msgb *msg)
1053{
1054 struct gsm_bts *bts = msg->trx->bts;
1055 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1056 struct gsm48_req_ref *rqd_ref;
1057 struct gsm48_imm_ass ia;
1058 enum gsm_chan_t lctype;
1059 enum gsm_chreq_reason_t chreq_reason;
1060 struct gsm_lchan *lchan;
1061 u_int8_t rqd_ta;
1062 int ret;
1063
1064 u_int16_t arfcn;
1065 u_int8_t ts_number, subch;
1066
1067 /* parse request reference to be used in immediate assign */
1068 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1069 return -EINVAL;
1070
1071 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1072
1073 /* parse access delay and use as TA */
1074 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1075 return -EINVAL;
1076 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1077
1078 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1079 * request reference RA */
1080 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
1081 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1082
1083 /* check availability / allocate channel */
1084 lchan = lchan_alloc(bts, lctype);
1085 if (!lchan) {
1086 fprintf(stderr, "CHAN RQD: no resources\n");
1087 /* FIXME: send some kind of reject ?!? */
1088 return -ENOMEM;
1089 }
1090
1091 ts_number = lchan->ts->nr;
1092 arfcn = lchan->ts->trx->arfcn;
1093 subch = lchan->nr;
1094
Harald Weltec4dcda02009-08-09 14:45:18 +02001095 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte9a229e12009-08-10 00:45:40 +02001096 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte39274f42009-07-29 15:41:29 +02001097 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
1098 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001099
1100 /* create IMMEDIATE ASSIGN 04.08 messge */
1101 memset(&ia, 0, sizeof(ia));
1102 ia.l2_plen = 0x2d;
1103 ia.proto_discr = GSM48_PDISC_RR;
1104 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1105 ia.page_mode = GSM48_PM_SAME;
1106 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1107 ia.chan_desc.h0.h = 0;
1108 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1109 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001110 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001111 /* use request reference extracted from CHAN_RQD */
1112 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1113 ia.timing_advance = rqd_ta;
1114 ia.mob_alloc_len = 0;
1115
1116 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1117 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1118 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1119 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1120 rqd_ref->ra);
1121
Harald Welte427dbc42009-08-10 00:26:10 +02001122 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1123 lchan->T3101.cb = t3101_expired;
1124 lchan->T3101.data = lchan;
1125 bsc_schedule_timer(&lchan->T3101, 10, 0);
Harald Welte59b04682009-06-10 05:40:52 +08001126
1127 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1128 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1129
1130 return ret;
1131}
1132
1133/* MS has requested a channel on the RACH */
1134static int rsl_rx_ccch_load(struct msgb *msg)
1135{
1136 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1137 u_int16_t pg_buf_space;
1138 u_int16_t rach_slot_count = -1;
1139 u_int16_t rach_busy_count = -1;
1140 u_int16_t rach_access_count = -1;
1141
1142 switch (rslh->data[0]) {
1143 case RSL_IE_PAGING_LOAD:
1144 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1145 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1146 break;
1147 case RSL_IE_RACH_LOAD:
1148 if (msg->data_len >= 7) {
1149 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1150 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1151 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1152 }
1153 break;
1154 default:
1155 break;
1156 }
1157
1158 return 0;
1159}
1160
1161static int abis_rsl_rx_cchan(struct msgb *msg)
1162{
1163 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1164 int rc = 0;
1165
1166 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1167
1168 switch (rslh->c.msg_type) {
1169 case RSL_MT_CHAN_RQD:
1170 /* MS has requested a channel on the RACH */
1171 rc = rsl_rx_chan_rqd(msg);
1172 break;
1173 case RSL_MT_CCCH_LOAD_IND:
1174 /* current load on the CCCH */
1175 rc = rsl_rx_ccch_load(msg);
1176 break;
1177 case RSL_MT_DELETE_IND:
1178 /* CCCH overloaded, IMM_ASSIGN was dropped */
1179 case RSL_MT_CBCH_LOAD_IND:
1180 /* current load on the CBCH */
1181 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1182 "0x%02x\n", rslh->c.msg_type);
1183 break;
1184 default:
1185 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1186 rslh->c.msg_type);
1187 return -EINVAL;
1188 }
1189
1190 return rc;
1191}
1192
1193static int rsl_rx_rll_err_ind(struct msgb *msg)
1194{
1195 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1196 u_int8_t *rlm_cause = rllh->data;
1197
Harald Welteb6601442009-08-04 02:50:21 +02001198 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001199
1200 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001201
Harald Welte692f5852009-07-04 09:40:05 +02001202 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte85a163c2009-08-10 11:43:22 +02001203 return rsl_rf_chan_release(msg->lchan);
Harald Welte692f5852009-07-04 09:40:05 +02001204
Harald Welte59b04682009-06-10 05:40:52 +08001205 return 0;
1206}
1207
1208/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1209 0x02, 0x06,
1210 0x01, 0x20,
1211 0x02, 0x00,
1212 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1213
1214static int abis_rsl_rx_rll(struct msgb *msg)
1215{
1216 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1217 int rc = 0;
1218 char *ts_name;
1219
1220 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1221 ts_name = gsm_ts_name(msg->lchan->ts);
1222 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x ", ts_name, rllh->chan_nr);
1223
1224 switch (rllh->c.msg_type) {
1225 case RSL_MT_DATA_IND:
1226 DEBUGPC(DRLL, "DATA INDICATION\n");
1227 if (msgb_l2len(msg) >
1228 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1229 rllh->data[0] == RSL_IE_L3_INFO) {
1230 msg->l3h = &rllh->data[3];
1231 return gsm0408_rcvmsg(msg);
1232 }
1233 break;
1234 case RSL_MT_EST_IND:
1235 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welte427dbc42009-08-10 00:26:10 +02001236 /* lchan is established, stop T3101 */
1237 bsc_del_timer(&msg->lchan->T3101);
Harald Welte59b04682009-06-10 05:40:52 +08001238 if (msgb_l2len(msg) >
1239 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1240 rllh->data[0] == RSL_IE_L3_INFO) {
1241 msg->l3h = &rllh->data[3];
1242 return gsm0408_rcvmsg(msg);
1243 }
1244 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001245 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001246 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001247 rll_indication(msg->lchan, rllh->link_id,
1248 BSC_RLLR_IND_EST_CONF);
1249 break;
Harald Welte59b04682009-06-10 05:40:52 +08001250 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001251 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001252 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001253 rll_indication(msg->lchan, rllh->link_id,
1254 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001255 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001256 /* FIXME: officially we need to start T3111 and wait for
1257 * some grace period */
1258 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001259 break;
1260 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001261 /* BTS informs us of having received UA from MS,
1262 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001263 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welte0f2e3c12009-08-08 13:15:07 +02001264 /* we can now releae the channel on the BTS/Abis side */
Harald Welte85a163c2009-08-10 11:43:22 +02001265 /* FIXME: officially we need to start T3111 and wait for
1266 * some grace period */
1267 rsl_rf_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001268 break;
1269 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001270 rc = rsl_rx_rll_err_ind(msg);
1271 break;
1272 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001273 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001274 rllh->c.msg_type);
1275 break;
1276 default:
Harald Welteb6601442009-08-04 02:50:21 +02001277 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001278 rllh->c.msg_type);
1279 }
Harald Welte59b04682009-06-10 05:40:52 +08001280 return rc;
1281}
1282
Harald Welte98d79f92009-07-28 18:11:56 +02001283static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1284{
Harald Welte98d79f92009-07-28 18:11:56 +02001285 switch (tch_mode) {
1286 case GSM48_CMODE_SPEECH_V1:
1287 return 0x00;
1288 case GSM48_CMODE_SPEECH_EFR:
1289 return 0x01;
1290 case GSM48_CMODE_SPEECH_AMR:
1291 return 0x02;
1292 /* FIXME: Type1 half-rate and type3 half-rate */
1293 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001294 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1295 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001296 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001297}
1298
Harald Welte59b04682009-06-10 05:40:52 +08001299/* ip.access specific RSL extensions */
1300int rsl_ipacc_bind(struct gsm_lchan *lchan)
1301{
1302 struct msgb *msg = rsl_msgb_alloc();
1303 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001304 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001305
1306 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1307 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1308 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1309 dh->chan_nr = lchan2chan_nr(lchan);
1310
Harald Welte98d79f92009-07-28 18:11:56 +02001311 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001312 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1313 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001314
Harald Weltefb4a9e92009-07-29 12:12:18 +02001315 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1316 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1317 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001318
Harald Welte59b04682009-06-10 05:40:52 +08001319 msg->trx = lchan->ts->trx;
1320
1321 return abis_rsl_sendmsg(msg);
1322}
1323
Harald Welte8cdeaad2009-07-12 09:50:35 +02001324int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1325 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001326{
1327 struct msgb *msg = rsl_msgb_alloc();
1328 struct abis_rsl_dchan_hdr *dh;
1329 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001330 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001331 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001332
1333 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1334 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1335 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1336 dh->chan_nr = lchan2chan_nr(lchan);
1337
Harald Weltefb4a9e92009-07-29 12:12:18 +02001338 /* 0x0- == both directions, 0x-1 == EFR codec */
1339 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1340
Harald Welte98d79f92009-07-28 18:11:56 +02001341 ia.s_addr = htonl(ip);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001342 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1343 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001344 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001345 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001346
Harald Welte8cdeaad2009-07-12 09:50:35 +02001347 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001348 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001349 att_f8[1] = conn_id >> 8;
1350 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001351
1352 att_ip = msgb_put(msg, sizeof(ip)+1);
1353 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1354 att_ip[1] = ip >> 24;
1355 att_ip[2] = ip >> 16;
1356 att_ip[3] = ip >> 8;
1357 att_ip[4] = ip & 0xff;
1358 //att_ip[4] = 11;
1359
1360 att_port = msgb_put(msg, sizeof(port)+1);
1361 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1362 att_port[1] = port >> 8;
1363 att_port[2] = port & 0xff;
1364
Harald Weltefb4a9e92009-07-29 12:12:18 +02001365 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001366 if (rtp_payload2)
1367 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1368
Harald Welte59b04682009-06-10 05:40:52 +08001369 msg->trx = lchan->ts->trx;
1370
1371 return abis_rsl_sendmsg(msg);
1372}
1373
1374static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1375{
1376 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1377 struct tlv_parsed tv;
1378 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1379 struct in_addr ip;
1380 u_int16_t port, attr_f8;
1381
1382 /* the BTS has acknowledged a local bind, it now tells us the IP
1383 * address and port number to which it has bound the given logical
1384 * channel */
1385
1386 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1387 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1388 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001389 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001390 DEBUGPC(DRSL, "mandatory IE missing");
1391 return -EINVAL;
1392 }
1393 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1394 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1395 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1396
Harald Welte98d79f92009-07-28 18:11:56 +02001397 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1398 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1399
1400 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1401 ts->abis_ip.rtp_payload2 =
1402 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1403 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1404 ts->abis_ip.rtp_payload2);
1405 }
Harald Welte59b04682009-06-10 05:40:52 +08001406
1407 /* update our local information about this TS */
1408 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1409 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001410 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001411
1412 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1413
1414 return 0;
1415}
1416
1417static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1418{
1419 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1420 struct tlv_parsed tv;
1421
1422 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001423
Harald Weltef1a168d2009-07-28 17:58:09 +02001424 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1425 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1426 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001427
Harald Welteba4e58d2009-07-28 18:02:05 +02001428 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1429
Harald Welte59b04682009-06-10 05:40:52 +08001430 return 0;
1431}
1432
1433static int abis_rsl_rx_ipacc(struct msgb *msg)
1434{
1435 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1436 int rc = 0;
1437
1438 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1439 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1440 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1441
1442 switch (rllh->c.msg_type) {
1443 case RSL_MT_IPAC_BIND_ACK:
1444 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
1445 rc = abis_rsl_rx_ipacc_bindack(msg);
1446 break;
1447 case RSL_MT_IPAC_BIND_NACK:
1448 /* somehow the BTS was unable to bind the lchan to its local
1449 * port?!? */
1450 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
1451 break;
1452 case RSL_MT_IPAC_CONNECT_ACK:
1453 /* the BTS tells us that a connect operation was successful */
1454 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
1455 break;
1456 case RSL_MT_IPAC_CONNECT_NACK:
1457 /* somehow the BTS was unable to connect the lchan to a remote
1458 * port */
1459 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
1460 break;
1461 case RSL_MT_IPAC_DISCONNECT_IND:
1462 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
1463 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1464 break;
1465 default:
1466 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1467 break;
1468 }
1469 DEBUGPC(DRSL, "\n");
1470
1471 return rc;
1472}
1473
1474
1475/* Entry-point where L2 RSL from BTS enters */
1476int abis_rsl_rcvmsg(struct msgb *msg)
1477{
1478 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1479 int rc = 0;
1480
1481 switch (rslh->msg_discr & 0xfe) {
1482 case ABIS_RSL_MDISC_RLL:
1483 rc = abis_rsl_rx_rll(msg);
1484 break;
1485 case ABIS_RSL_MDISC_DED_CHAN:
1486 rc = abis_rsl_rx_dchan(msg);
1487 break;
1488 case ABIS_RSL_MDISC_COM_CHAN:
1489 rc = abis_rsl_rx_cchan(msg);
1490 break;
1491 case ABIS_RSL_MDISC_TRX:
1492 rc = abis_rsl_rx_trx(msg);
1493 break;
1494 case ABIS_RSL_MDISC_LOC:
1495 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1496 rslh->msg_discr);
1497 break;
1498 case ABIS_RSL_MDISC_IPACCESS:
1499 rc = abis_rsl_rx_ipacc(msg);
1500 break;
1501 default:
1502 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1503 rslh->msg_discr);
1504 return -EINVAL;
1505 }
1506 msgb_free(msg);
1507 return rc;
1508}
1509
1510
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001511/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001512int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1513{
1514 switch (ccch_conf) {
1515 case RSL_BCCH_CCCH_CONF_1_NC:
1516 return 1;
1517 case RSL_BCCH_CCCH_CONF_1_C:
1518 return 1;
1519 case RSL_BCCH_CCCH_CONF_2_NC:
1520 return 2;
1521 case RSL_BCCH_CCCH_CONF_3_NC:
1522 return 3;
1523 case RSL_BCCH_CCCH_CONF_4_NC:
1524 return 4;
1525 default:
1526 return -1;
1527 }
1528}
1529
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001530/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001531int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1532{
1533 switch (ccch_conf) {
1534 case RSL_BCCH_CCCH_CONF_1_NC:
1535 return 0;
1536 case RSL_BCCH_CCCH_CONF_1_C:
1537 return 1;
1538 case RSL_BCCH_CCCH_CONF_2_NC:
1539 return 0;
1540 case RSL_BCCH_CCCH_CONF_3_NC:
1541 return 0;
1542 case RSL_BCCH_CCCH_CONF_4_NC:
1543 return 0;
1544 default:
1545 return -1;
1546 }
1547}
1548
1549/* From Table 10.5.33 of GSM 04.08 */
1550int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1551{
1552 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1553 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1554 * (bts->chan_desc.bs_pa_mfrms + 2);
1555 } else {
1556 return (9 - bts->chan_desc.bs_ag_blks_res)
1557 * (bts->chan_desc.bs_pa_mfrms + 2);
1558 }
1559}