blob: 6b328bb28964b674d4c81ba83067ad937218153d [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* 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
Harald Welte8f5e2392009-02-03 12:57:37 +00004/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
Harald Welte8470bf22008-12-25 23:28:35 +00005 *
Harald Welte52b1f982008-12-23 20:25:15 +00006 * 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>
Harald Welte8470bf22008-12-25 23:28:35 +000025#include <stdlib.h>
Harald Welte52b1f982008-12-23 20:25:15 +000026#include <errno.h>
27#include <sys/types.h>
Harald Welte75099262009-02-16 21:12:08 +000028#include <netinet/in.h>
Harald Welte167df882009-02-17 14:35:45 +000029#include <arpa/inet.h>
Harald Welte52b1f982008-12-23 20:25:15 +000030
Harald Welte8470bf22008-12-25 23:28:35 +000031#include <openbsc/gsm_data.h>
32#include <openbsc/gsm_04_08.h>
Harald Welte66b6a8d2009-08-09 14:45:18 +020033#include <openbsc/gsm_utils.h>
Harald Welte8470bf22008-12-25 23:28:35 +000034#include <openbsc/abis_rsl.h>
35#include <openbsc/chan_alloc.h>
Harald Welteedcc5272009-08-09 13:47:35 +020036#include <openbsc/bsc_rll.h>
Harald Welte8470bf22008-12-25 23:28:35 +000037#include <openbsc/debug.h>
38#include <openbsc/tlv.h>
Holger Freyther392209c2009-02-10 00:06:19 +000039#include <openbsc/paging.h>
Harald Welte167df882009-02-17 14:35:45 +000040#include <openbsc/signal.h>
Harald Welte52b1f982008-12-23 20:25:15 +000041
Harald Welte8470bf22008-12-25 23:28:35 +000042#define RSL_ALLOC_SIZE 1024
43#define RSL_ALLOC_HEADROOM 128
Harald Welte52b1f982008-12-23 20:25:15 +000044
Holger Freyther3b72a892009-02-04 00:31:39 +000045#define MAX(a, b) (a) >= (b) ? (a) : (b)
46
Harald Welte75099262009-02-16 21:12:08 +000047static 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 Welte67fa91b2009-08-10 09:51:40 +0200108 [RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
Harald Welteab46d742009-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 Welte75099262009-02-16 21:12:08 +0000111 [RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
112 [RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welteab46d742009-07-12 09:56:39 +0200113 [RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
Harald Welte75099262009-02-16 21:12:08 +0000114 [RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welte86c162d2009-07-12 09:45:05 +0200115 [RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
Harald Welteab46d742009-07-12 09:56:39 +0200116 [RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
Harald Welte86c162d2009-07-12 09:45:05 +0200117 [RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
Harald Welteab46d742009-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 Welte86c162d2009-07-12 09:45:05 +0200121 [RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
Harald Welteab46d742009-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 Welte75099262009-02-16 21:12:08 +0000124 },
125};
Harald Weltea4d49e92009-05-23 06:39:58 +0000126#define rsl_tlv_parse(dec, buf, len) \
127 tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
Harald Welte75099262009-02-16 21:12:08 +0000128
Harald Welte52b1f982008-12-23 20:25:15 +0000129static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
130{
131 /* mask off the transparent bit ? */
132 msg_type &= 0xfe;
133
Harald Welte8470bf22008-12-25 23:28:35 +0000134 if ((msg_type & 0xf0) == 0x00)
Harald Welte52b1f982008-12-23 20:25:15 +0000135 return ABIS_RSL_MDISC_RLL;
Harald Welte8470bf22008-12-25 23:28:35 +0000136 if ((msg_type & 0xf0) == 0x10) {
Harald Welte52b1f982008-12-23 20:25:15 +0000137 if (msg_type >= 0x19 && msg_type <= 0x22)
138 return ABIS_RSL_MDISC_TRX;
139 else
140 return ABIS_RSL_MDISC_COM_CHAN;
141 }
Harald Welte2d5b6382008-12-27 19:46:06 +0000142 if ((msg_type & 0xe0) == 0x20)
Harald Welte52b1f982008-12-23 20:25:15 +0000143 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
Harald Welte8470bf22008-12-25 23:28:35 +0000194/* determine logical channel based on TRX and channel number IE */
195struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
196{
197 struct gsm_lchan *lchan;
198 u_int8_t ts_nr = chan_nr & 0x07;
199 u_int8_t cbits = chan_nr >> 3;
200 u_int8_t lch_idx;
201 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
202
203 if (cbits == 0x01) {
204 lch_idx = 0; /* TCH/F */
Harald Weltea1499d02009-10-24 10:25:50 +0200205 if (ts->pchan != GSM_PCHAN_TCH_F &&
206 ts->pchan != GSM_PCHAN_PDCH &&
207 ts->pchan != GSM_PCHAN_TCH_F_PDCH)
Harald Welte8470bf22008-12-25 23:28:35 +0000208 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
209 chan_nr, ts->pchan);
210 } else if ((cbits & 0x1e) == 0x02) {
211 lch_idx = cbits & 0x1; /* TCH/H */
212 if (ts->pchan != GSM_PCHAN_TCH_H)
213 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
214 chan_nr, ts->pchan);
215 } else if ((cbits & 0x1c) == 0x04) {
216 lch_idx = cbits & 0x3; /* SDCCH/4 */
217 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
218 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
219 chan_nr, ts->pchan);
220 } else if ((cbits & 0x18) == 0x08) {
221 lch_idx = cbits & 0x7; /* SDCCH/8 */
222 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
223 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
224 chan_nr, ts->pchan);
225 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
226 lch_idx = 0;
227 if (ts->pchan != GSM_PCHAN_CCCH &&
228 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
229 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
230 chan_nr, ts->pchan);
231 /* FIXME: we should not return first sdcch4 !!! */
232 } else {
233 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
234 return NULL;
235 }
236
237 lchan = &ts->lchan[lch_idx];
238
239 return lchan;
240}
241
242u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
243{
244 struct gsm_bts_trx_ts *ts = lchan->ts;
245 u_int8_t cbits, chan_nr;
246
247 switch (ts->pchan) {
248 case GSM_PCHAN_TCH_F:
Harald Weltea1499d02009-10-24 10:25:50 +0200249 case GSM_PCHAN_PDCH:
250 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte8470bf22008-12-25 23:28:35 +0000251 cbits = 0x01;
252 break;
253 case GSM_PCHAN_TCH_H:
254 cbits = 0x02;
255 cbits += lchan->nr;
256 break;
257 case GSM_PCHAN_CCCH_SDCCH4:
258 cbits = 0x04;
259 cbits += lchan->nr;
260 break;
261 case GSM_PCHAN_SDCCH8_SACCH8C:
262 cbits = 0x08;
263 cbits += lchan->nr;
264 break;
265 default:
266 case GSM_PCHAN_CCCH:
267 cbits = 0x10;
268 break;
269 }
270
271 chan_nr = (cbits << 3) | (ts->nr & 0x7);
272
273 return chan_nr;
274}
275
Harald Welte52b1f982008-12-23 20:25:15 +0000276/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
277u_int64_t str_to_imsi(const char *imsi_str)
278{
279 u_int64_t ret;
280
281 ret = strtoull(imsi_str, NULL, 10);
282
283 return ret;
284}
285
286/* Table 5 Clause 7 TS 05.02 */
287unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
288{
289 if (!bs_ccch_sdcch_comb)
290 return 9 - bs_ag_blks_res;
291 else
292 return 3 - bs_ag_blks_res;
293}
294
295/* Chapter 6.5.2 of TS 05.02 */
296unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
297 unsigned int n_pag_blocks)
298{
299 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
300}
301
302/* Chapter 6.5.2 of TS 05.02 */
303unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
304 int n_pag_blocks)
305{
306 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
307}
308
Harald Welte8470bf22008-12-25 23:28:35 +0000309static struct msgb *rsl_msgb_alloc(void)
310{
Harald Welte966636f2009-06-26 19:39:35 +0200311 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
312 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000313}
314
Harald Welte362322e2009-02-15 14:36:38 +0000315#define MACBLOCK_SIZE 23
316static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
317{
318 memcpy(out, in, len);
319
320 if (len < MACBLOCK_SIZE)
321 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
322}
323
Harald Welte08d91a52009-08-30 15:37:11 +0900324/* Chapter 9.3.7: Encryption Information */
325static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
326{
327 *out++ = lchan->encr.alg_id & 0xff;
328 if (lchan->encr.key_len)
329 memcpy(out, lchan->encr.key, lchan->encr.key_len);
330 return lchan->encr.key_len + 1;
331}
332
333
Harald Welte8830e072009-07-28 17:58:09 +0200334static const char *rsl_err_vals[0xff] = {
335 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
336 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
337 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
338 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
339 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
340 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welte2da86292009-08-04 02:31:05 +0200341 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Welte8830e072009-07-28 17:58:09 +0200342 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
343 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
344 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
345 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
346 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
347 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
348 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
349 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
350 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
351 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
352 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
353 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
354 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
355 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
356 [RSL_ERR_MSG_TYPE] = "Message Type Error",
357 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
358 [RSL_ERR_IE_ERROR] = "General IE error",
359 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
360 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
361 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
362 [RSL_ERR_IE_LENGTH] = "IE length error",
363 [RSL_ERR_IE_CONTENT] = "IE content error",
364 [RSL_ERR_PROTO] = "Protocol error, unspecified",
365 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
366};
367
368static const char *rsl_err_name(u_int8_t err)
Harald Welte7f93cea2009-02-23 00:02:59 +0000369{
Harald Welte8830e072009-07-28 17:58:09 +0200370 if (rsl_err_vals[err])
371 return rsl_err_vals[err];
372 else
373 return "unknown";
374}
375
376static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
377{
Harald Welte7f93cea2009-02-23 00:02:59 +0000378 int i;
379
Harald Welte8830e072009-07-28 17:58:09 +0200380 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
381 cause_v[0], rsl_err_name(cause_v[0]));
382 for (i = 1; i < cause_len-1; i++)
383 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000384}
385
Harald Welte52b1f982008-12-23 20:25:15 +0000386/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Harald Weltee79769b2009-02-07 00:48:17 +0000387int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000388 const u_int8_t *data, int len)
389{
390 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000391 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000392
393 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
394 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
395 dh->chan_nr = RSL_CHAN_BCCH;
396
397 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
398 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
399
Harald Weltee79769b2009-02-07 00:48:17 +0000400 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000401
402 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000403}
404
Harald Weltee79769b2009-02-07 00:48:17 +0000405int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000406 const u_int8_t *data, int len)
407{
408 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000409 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000410
411 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
412 ch->msg_discr = ABIS_RSL_MDISC_TRX;
413 ch->msg_type = RSL_MT_SACCH_FILL;
414
415 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000416 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000417
Harald Weltee79769b2009-02-07 00:48:17 +0000418 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000419
420 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000421}
422
Harald Weltefcd24452009-06-20 18:15:19 +0200423int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
424{
425 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200426 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200427 u_int8_t chan_nr = lchan2chan_nr(lchan);
428
429 db = abs(db);
430 if (db > 30)
431 return -EINVAL;
432
Harald Welteeab33352009-06-27 03:09:08 +0200433 msg = rsl_msgb_alloc();
434
Harald Weltefcd24452009-06-20 18:15:19 +0200435 lchan->bs_power = db/2;
436 if (fpc)
437 lchan->bs_power |= 0x10;
438
439 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
440 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
441 dh->chan_nr = chan_nr;
442
443 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
444
445 msg->trx = lchan->ts->trx;
446
447 return abis_rsl_sendmsg(msg);
448}
449
Harald Weltefcd24452009-06-20 18:15:19 +0200450int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
451{
452 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200453 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200454 u_int8_t chan_nr = lchan2chan_nr(lchan);
455 int ctl_lvl;
456
Harald Welte66b6a8d2009-08-09 14:45:18 +0200457 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200458 if (ctl_lvl < 0)
459 return ctl_lvl;
460
Harald Welteeab33352009-06-27 03:09:08 +0200461 msg = rsl_msgb_alloc();
462
Harald Weltefcd24452009-06-20 18:15:19 +0200463 lchan->ms_power = ctl_lvl;
464
465 if (fpc)
466 lchan->ms_power |= 0x20;
467
468 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
469 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
470 dh->chan_nr = chan_nr;
471
472 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
473
474 msg->trx = lchan->ts->trx;
475
476 return abis_rsl_sendmsg(msg);
477}
478
Harald Welte9943c5b2009-07-29 15:41:29 +0200479static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
480 struct gsm_lchan *lchan)
481{
482 memset(cm, 0, sizeof(cm));
483
484 /* FIXME: what to do with data calls ? */
485 cm->dtx_dtu = 0x00;
486
487 /* set TCH Speech/Data */
488 cm->spd_ind = lchan->rsl_cmode;
489
490 switch (lchan->type) {
491 case GSM_LCHAN_SDCCH:
492 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
493 break;
494 case GSM_LCHAN_TCH_F:
495 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
496 break;
497 case GSM_LCHAN_TCH_H:
498 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
499 break;
500 case GSM_LCHAN_NONE:
501 case GSM_LCHAN_UNKNOWN:
502 default:
503 return -EINVAL;
504 }
505
506 switch (lchan->tch_mode) {
507 case GSM48_CMODE_SIGN:
508 cm->chan_rate = 0;
509 break;
510 case GSM48_CMODE_SPEECH_V1:
511 cm->chan_rate = RSL_CMOD_SP_GSM1;
512 break;
513 case GSM48_CMODE_SPEECH_EFR:
514 cm->chan_rate = RSL_CMOD_SP_GSM2;
515 break;
516 case GSM48_CMODE_SPEECH_AMR:
517 cm->chan_rate = RSL_CMOD_SP_GSM3;
518 break;
519 case GSM48_CMODE_DATA_14k5:
520 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
521 break;
522 case GSM48_CMODE_DATA_12k0:
523 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
524 break;
525 case GSM48_CMODE_DATA_6k0:
526 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
527 break;
528 default:
529 return -EINVAL;
530 }
531
532 return 0;
533}
534
Harald Welte52b1f982008-12-23 20:25:15 +0000535/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000536#if 0
Harald Weltee79769b2009-02-07 00:48:17 +0000537int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
Harald Welte52b1f982008-12-23 20:25:15 +0000538 u_int8_t act_type,
539 struct rsl_ie_chan_mode *chan_mode,
540 struct rsl_ie_chan_ident *chan_ident,
541 u_int8_t bs_power, u_int8_t ms_power,
542 u_int8_t ta)
543{
544 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000545 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000546
547 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
548 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
549 dh->chan_nr = chan_nr;
550
551 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
552 /* For compatibility with Phase 1 */
553 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
554 (u_int8_t *) chan_mode);
555 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Harald Welte702d8702008-12-26 20:25:35 +0000556 (u_int8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000557#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000558 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
559 (u_int8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000560#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000561 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000562 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
563 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
564
Harald Weltee79769b2009-02-07 00:48:17 +0000565 msg->trx = trx;
566
Harald Welte8470bf22008-12-25 23:28:35 +0000567 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000568}
Harald Welteddab3c72009-02-28 13:19:15 +0000569#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000570
Harald Welte8f5e2392009-02-03 12:57:37 +0000571int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte9943c5b2009-07-29 15:41:29 +0200572 u_int8_t ta)
Harald Welte4b634542008-12-27 01:55:51 +0000573{
574 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200575 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200576 int rc;
Harald Welte4b634542008-12-27 01:55:51 +0000577
578 u_int8_t chan_nr = lchan2chan_nr(lchan);
579 u_int16_t arfcn = lchan->ts->trx->arfcn;
580 struct rsl_ie_chan_mode cm;
581 struct rsl_ie_chan_ident ci;
582
Harald Welte9943c5b2009-07-29 15:41:29 +0200583 rc = channel_mode_from_lchan(&cm, lchan);
584 if (rc < 0)
585 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000586
Harald Welte02b0e092009-02-28 13:11:07 +0000587 memset(&ci, 0, sizeof(ci));
Harald Welte4b634542008-12-27 01:55:51 +0000588 ci.chan_desc.iei = 0x64;
589 ci.chan_desc.chan_nr = chan_nr;
Harald Welte02b0e092009-02-28 13:11:07 +0000590 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
Harald Welte4b634542008-12-27 01:55:51 +0000591 ci.chan_desc.oct4 = arfcn & 0xff;
592
Harald Welteeab33352009-06-27 03:09:08 +0200593 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000594 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
595 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
596 dh->chan_nr = chan_nr;
597
598 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
599 /* For compatibility with Phase 1 */
600 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
601 (u_int8_t *) &cm);
602 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
603 (u_int8_t *) &ci);
Harald Welte08d91a52009-08-30 15:37:11 +0900604
605 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
606 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
607 rc = build_encr_info(encr_info, lchan);
608 if (rc > 0)
609 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
610 }
611
Harald Welted4c9bf32009-02-15 16:56:18 +0000612 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
613 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000614 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
615
Harald Weltee79769b2009-02-07 00:48:17 +0000616 msg->trx = lchan->ts->trx;
617
Harald Welte4b634542008-12-27 01:55:51 +0000618 return abis_rsl_sendmsg(msg);
619}
620
Harald Welte470abb72009-07-29 11:38:15 +0200621/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000622int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
623{
624 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200625 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200626 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000627
628 u_int8_t chan_nr = lchan2chan_nr(lchan);
629 struct rsl_ie_chan_mode cm;
630
Harald Welte9943c5b2009-07-29 15:41:29 +0200631 rc = channel_mode_from_lchan(&cm, lchan);
632 if (rc < 0)
633 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000634
Harald Welteeab33352009-06-27 03:09:08 +0200635 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000636 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
637 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
638 dh->chan_nr = chan_nr;
639
640 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
641 (u_int8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900642
643 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
644 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
645 rc = build_encr_info(encr_info, lchan);
646 if (rc > 0)
647 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
648 }
649
650 msg->trx = lchan->ts->trx;
651
652 return abis_rsl_sendmsg(msg);
653}
654
655/* Chapter 8.4.6: Send the encryption command with given L3 info */
656int rsl_encryption_cmd(struct msgb *msg)
657{
658 struct abis_rsl_dchan_hdr *dh;
659 struct gsm_lchan *lchan = msg->lchan;
660 u_int8_t chan_nr = lchan2chan_nr(lchan);
661 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut82aa6842009-09-27 11:13:18 +0200662 u_int8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900663 int rc;
664
665 /* First push the L3 IE tag and length */
666 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
667
668 /* then the link identifier (SAPI0, main sign link) */
669 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
670
671 /* then encryption information */
672 rc = build_encr_info(encr_info, lchan);
673 if (rc <= 0)
674 return rc;
675 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
676
677 /* and finally the DCHAN header */
678 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
679 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
680 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000681
682 msg->trx = lchan->ts->trx;
683
684 return abis_rsl_sendmsg(msg);
685}
686
Harald Welte115d1032009-08-10 11:43:22 +0200687/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200688int rsl_deact_sacch(struct gsm_lchan *lchan)
689{
690 struct abis_rsl_dchan_hdr *dh;
691 struct msgb *msg = rsl_msgb_alloc();
692
693 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
694 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
695 dh->chan_nr = lchan2chan_nr(lchan);
696
697 msg->lchan = lchan;
698 msg->trx = lchan->ts->trx;
699
700 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
701 gsm_ts_name(lchan->ts), dh->chan_nr);
702
703 return abis_rsl_sendmsg(msg);
704}
705
Harald Welte115d1032009-08-10 11:43:22 +0200706/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
707int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte52b1f982008-12-23 20:25:15 +0000708{
709 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000710 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000711
712 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
713 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000714 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000715
Harald Welte8470bf22008-12-25 23:28:35 +0000716 msg->lchan = lchan;
717 msg->trx = lchan->ts->trx;
718
Harald Welte115d1032009-08-10 11:43:22 +0200719 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Weltef325eb42009-02-19 17:07:39 +0000720 gsm_ts_name(lchan->ts), dh->chan_nr);
Harald Welte2d5b6382008-12-27 19:46:06 +0000721
Harald Welte115d1032009-08-10 11:43:22 +0200722 /* BTS will respond by RF CHAN REL ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000723 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000724}
725
726int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
727 u_int8_t *ms_ident, u_int8_t chan_needed)
728{
729 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000730 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000731
732 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
733 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
734 dh->chan_nr = RSL_CHAN_PCH_AGCH;
735
736 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000737 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000738 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
739
Harald Welte8470bf22008-12-25 23:28:35 +0000740 msg->trx = bts->c0;
741
742 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000743}
744
Holger Freyther7448a532009-01-04 20:18:23 +0000745int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
746 struct gsm_subscriber *subscr)
747{
Holger Freytherca362a62009-01-04 21:05:01 +0000748#if 0
Holger Freyther7448a532009-01-04 20:18:23 +0000749 u_int8_t mi[128];
750 unsigned int mi_len;
751 u_int8_t paging_group;
Holger Freytherca362a62009-01-04 21:05:01 +0000752#endif
Holger Freyther7448a532009-01-04 20:18:23 +0000753
754 return -1;
755}
756
Harald Welte52b1f982008-12-23 20:25:15 +0000757int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
758{
759 int i, len = strlen(str_in);
760
761 for (i = 0; i < len; i++) {
762 int num = str_in[i] - 0x30;
763 if (num < 0 || num > 9)
764 return -1;
765 if (i % 2 == 0)
766 bcd_out[i/2] = num;
767 else
768 bcd_out[i/2] |= (num << 4);
769 }
770
771 return 0;
772}
773
Harald Welte702d8702008-12-26 20:25:35 +0000774/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000775int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
776{
Harald Welte8470bf22008-12-25 23:28:35 +0000777 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000778 struct abis_rsl_dchan_hdr *dh;
Harald Welte362322e2009-02-15 14:36:38 +0000779 u_int8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000780
781 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
782 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
783 dh->chan_nr = RSL_CHAN_PCH_AGCH;
784
Harald Welte362322e2009-02-15 14:36:38 +0000785 switch (bts->type) {
786 case GSM_BTS_TYPE_BS11:
787 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
788 break;
789 default:
790 /* If phase 2, construct a FULL_IMM_ASS_INFO */
791 pad_macblock(buf, val, len);
792 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
793 break;
794 }
Harald Welte52b1f982008-12-23 20:25:15 +0000795
Harald Welte8470bf22008-12-25 23:28:35 +0000796 msg->trx = bts->c0;
797
798 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000799}
800
Harald Welte67fa91b2009-08-10 09:51:40 +0200801/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200802int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200803{
804 struct msgb *msg = rsl_msgb_alloc();
805 struct abis_rsl_dchan_hdr *dh;
806
807 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
808 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200809 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte67fa91b2009-08-10 09:51:40 +0200810 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte31c48932009-08-10 10:07:33 +0200811 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200812
Harald Welte3c456d02009-08-10 11:26:14 +0200813 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
814 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
815
816 msg->trx = lchan->ts->trx;
817
Harald Welte67fa91b2009-08-10 09:51:40 +0200818 return abis_rsl_sendmsg(msg);
819}
820
821
Harald Welte8470bf22008-12-25 23:28:35 +0000822/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000823/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000824int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000825{
Harald Welte8470bf22008-12-25 23:28:35 +0000826 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000827 struct abis_rsl_rll_hdr *rh;
828
Harald Welte8470bf22008-12-25 23:28:35 +0000829 if (msg->lchan == NULL) {
830 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
831 return -EINVAL;
832 }
Harald Welte52b1f982008-12-23 20:25:15 +0000833
Harald Welte8470bf22008-12-25 23:28:35 +0000834 /* First push the L3 IE tag and length */
Harald Welte4b634542008-12-27 01:55:51 +0000835 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
Harald Welte8470bf22008-12-25 23:28:35 +0000836
837 /* Then push the RSL header */
Harald Welte52b1f982008-12-23 20:25:15 +0000838 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
839 init_llm_hdr(rh, RSL_MT_DATA_REQ);
Harald Welte4a543e82009-02-28 13:17:55 +0000840 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
Harald Welte8470bf22008-12-25 23:28:35 +0000841 rh->chan_nr = lchan2chan_nr(msg->lchan);
842 rh->link_id = link_id;
Harald Welte52b1f982008-12-23 20:25:15 +0000843
Harald Welte8470bf22008-12-25 23:28:35 +0000844 msg->trx = msg->lchan->ts->trx;
845
846 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000847}
848
Harald Welteedcc5272009-08-09 13:47:35 +0200849/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
850/* Chapter 8.3.1 */
851int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
852{
853 struct msgb *msg = rsl_msgb_alloc();
854 struct abis_rsl_rll_hdr *rh;
855
856 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte1c409272009-08-09 14:13:58 +0200857 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteedcc5272009-08-09 13:47:35 +0200858 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
859 rh->chan_nr = lchan2chan_nr(lchan);
860 rh->link_id = link_id;
861
862 msg->trx = lchan->ts->trx;
863
864 return abis_rsl_sendmsg(msg);
865}
866
Harald Welted2dc1de2009-08-08 13:15:07 +0200867/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
868 This is what higher layers should call. The BTS then responds with
869 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
870 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
871 lchan_free() */
872int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
873{
874 struct msgb *msg = rsl_msgb_alloc();
875 struct abis_rsl_rll_hdr *rh;
876
877 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
878 init_llm_hdr(rh, RSL_MT_REL_REQ);
879 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
880 rh->chan_nr = lchan2chan_nr(lchan);
881 rh->link_id = link_id;
Harald Welte6c3d2ed2009-08-10 00:19:36 +0200882 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welted2dc1de2009-08-08 13:15:07 +0200883
884 msg->trx = lchan->ts->trx;
885
886 return abis_rsl_sendmsg(msg);
887}
888
Harald Welte702d8702008-12-26 20:25:35 +0000889/* Chapter 8.4.2: Channel Activate Acknowledge */
890static int rsl_rx_chan_act_ack(struct msgb *msg)
891{
892 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
893
894 /* BTS has confirmed channel activation, we now need
895 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000896 if (rslh->ie_chan != RSL_IE_CHAN_NR)
897 return -EINVAL;
898
Harald Welte4b634542008-12-27 01:55:51 +0000899 return 0;
900}
Harald Welte702d8702008-12-26 20:25:35 +0000901
Harald Welte4b634542008-12-27 01:55:51 +0000902/* Chapter 8.4.3: Channel Activate NACK */
903static int rsl_rx_chan_act_nack(struct msgb *msg)
904{
Harald Welte6dab0552009-05-01 17:21:37 +0000905 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
906 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000907
Harald Welte6dab0552009-05-01 17:21:37 +0000908 /* BTS has rejected channel activation ?!? */
909 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000910 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000911
912 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
913 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte8830e072009-07-28 17:58:09 +0200914 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
915 TLVP_LEN(&tp, RSL_IE_CAUSE));
916
Harald Welte3073a9f2009-08-09 19:50:08 +0200917 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000918 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000919}
920
Harald Welte7f93cea2009-02-23 00:02:59 +0000921/* Chapter 8.4.4: Connection Failure Indication */
922static int rsl_rx_conn_fail(struct msgb *msg)
923{
924 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
925 struct tlv_parsed tp;
926
927 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte7f93cea2009-02-23 00:02:59 +0000928
929 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
930
Harald Welte8830e072009-07-28 17:58:09 +0200931 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
932 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
933 TLVP_LEN(&tp, RSL_IE_CAUSE));
934
Holger Freytherf7b2a0e2009-06-02 02:55:17 +0000935 DEBUGPC(DRSL, "RELEASING.\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000936
937 /* FIXME: only free it after channel release ACK */
Harald Welte115d1032009-08-10 11:43:22 +0200938 return rsl_rf_chan_release(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +0000939}
940
Harald Welte440fed02009-05-01 18:43:47 +0000941static int rsl_rx_meas_res(struct msgb *msg)
942{
943 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
944 struct tlv_parsed tp;
945
Harald Welte10d0e672009-06-27 02:53:10 +0200946 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte440fed02009-05-01 18:43:47 +0000947 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
948
949 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte10d0e672009-06-27 02:53:10 +0200950 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte440fed02009-05-01 18:43:47 +0000951 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
952 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte75d34a82009-05-23 06:11:13 +0000953 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte440fed02009-05-01 18:43:47 +0000954 if (len >= 3) {
955 if (val[0] & 0x40)
Harald Welte10d0e672009-06-27 02:53:10 +0200956 DEBUGPC(DMEAS, "DTXd ");
957 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000958 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte10d0e672009-06-27 02:53:10 +0200959 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000960 val[2]>>3 & 0x7, val[2] & 0x7);
961 }
962 }
963 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte10d0e672009-06-27 02:53:10 +0200964 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte440fed02009-05-01 18:43:47 +0000965 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte10d0e672009-06-27 02:53:10 +0200966 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000967 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltefe9af262009-06-20 18:44:35 +0200968 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte86c162d2009-07-12 09:45:05 +0200969 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltefe9af262009-06-20 18:44:35 +0200970 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte10d0e672009-06-27 02:53:10 +0200971 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltefe9af262009-06-20 18:44:35 +0200972 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte10d0e672009-06-27 02:53:10 +0200973 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
974 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltefe9af262009-06-20 18:44:35 +0200975 }
Harald Weltef7c43522009-06-09 20:24:21 +0000976 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte10d0e672009-06-27 02:53:10 +0200977 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freytherddd918f2009-10-22 15:43:55 +0200978 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)daef6062009-08-14 11:41:12 +0200979 return gsm0408_rcvmsg(msg, 0);
Harald Weltef7c43522009-06-09 20:24:21 +0000980 } else
Harald Welte10d0e672009-06-27 02:53:10 +0200981 DEBUGPC(DMEAS, "\n");
Harald Welte60d68f12009-06-05 20:07:43 +0000982
Harald Welte75d34a82009-05-23 06:11:13 +0000983 return 0;
Harald Welte440fed02009-05-01 18:43:47 +0000984}
985
Harald Welte52b1f982008-12-23 20:25:15 +0000986static int abis_rsl_rx_dchan(struct msgb *msg)
987{
Harald Welte8470bf22008-12-25 23:28:35 +0000988 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
989 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +0000990 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +0000991
Harald Welte8470bf22008-12-25 23:28:35 +0000992 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +0000993 ts_name = gsm_ts_name(msg->lchan->ts);
994
Harald Welte10d0e672009-06-27 02:53:10 +0200995 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
996 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000997
998 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +0000999 case RSL_MT_CHAN_ACTIV_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001000 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001001 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001002 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001003 case RSL_MT_CHAN_ACTIV_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001004 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001005 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001006 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001007 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001008 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001009 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001010 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001011 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001012 break;
1013 case RSL_MT_RF_CHAN_REL_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001014 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
Harald Welte2d5b6382008-12-27 19:46:06 +00001015 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001016 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001017 case RSL_MT_MODE_MODIFY_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001018 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001019 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001020 case RSL_MT_MODE_MODIFY_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001021 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001022 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001023 case RSL_MT_IPAC_PDCH_ACT_ACK:
1024 DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
1025 break;
1026 case RSL_MT_IPAC_PDCH_ACT_NACK:
1027 DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
1028 break;
1029 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1030 DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
1031 break;
1032 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1033 DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
1034 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001035 case RSL_MT_PHY_CONTEXT_CONF:
1036 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001037 case RSL_MT_TALKER_DET:
1038 case RSL_MT_LISTENER_DET:
1039 case RSL_MT_REMOTE_CODEC_CONF_REP:
1040 case RSL_MT_MR_CODEC_MOD_ACK:
1041 case RSL_MT_MR_CODEC_MOD_NACK:
1042 case RSL_MT_MR_CODEC_MOD_PER:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001043 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001044 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001045 break;
1046 default:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001047 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001048 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001049 return -EINVAL;
1050 }
Harald Weltef325eb42009-02-19 17:07:39 +00001051
Harald Welte8470bf22008-12-25 23:28:35 +00001052 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001053}
1054
Harald Welte702d8702008-12-26 20:25:35 +00001055static int rsl_rx_error_rep(struct msgb *msg)
1056{
1057 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001058 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001059
Harald Welte7f93cea2009-02-23 00:02:59 +00001060 DEBUGP(DRSL, "ERROR REPORT ");
Harald Welte8830e072009-07-28 17:58:09 +02001061
1062 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1063
1064 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1065 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1066 TLVP_LEN(&tp, RSL_IE_CAUSE));
1067
Holger Freyther79f4ae62009-06-02 03:25:04 +00001068 DEBUGPC(DRSL, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001069
1070 return 0;
1071}
1072
Harald Welte52b1f982008-12-23 20:25:15 +00001073static int abis_rsl_rx_trx(struct msgb *msg)
1074{
Harald Welte702d8702008-12-26 20:25:35 +00001075 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001076 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001077
1078 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001079 case RSL_MT_ERROR_REPORT:
1080 rc = rsl_rx_error_rep(msg);
1081 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001082 case RSL_MT_RF_RES_IND:
1083 /* interference on idle channels of TRX */
Harald Welte3cf7c3f2009-05-01 18:28:00 +00001084 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
Harald Welte8f5e2392009-02-03 12:57:37 +00001085 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001086 case RSL_MT_OVERLOAD:
1087 /* indicate CCCH / ACCH / processor overload */
Harald Weltef325eb42009-02-19 17:07:39 +00001088 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
Harald Welte52b1f982008-12-23 20:25:15 +00001089 break;
1090 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001091 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001092 rslh->msg_type);
1093 return -EINVAL;
1094 }
Harald Welte8470bf22008-12-25 23:28:35 +00001095 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001096}
1097
Harald Welteb7e81162009-08-10 00:26:10 +02001098/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1099static void t3101_expired(void *data)
1100{
1101 struct gsm_lchan *lchan = data;
1102
Harald Welte115d1032009-08-10 11:43:22 +02001103 rsl_rf_chan_release(lchan);
Harald Welteb7e81162009-08-10 00:26:10 +02001104}
1105
Harald Welte8470bf22008-12-25 23:28:35 +00001106/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001107static int rsl_rx_chan_rqd(struct msgb *msg)
1108{
Harald Welte702d8702008-12-26 20:25:35 +00001109 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001110 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1111 struct gsm48_req_ref *rqd_ref;
Harald Welte52b1f982008-12-23 20:25:15 +00001112 struct gsm48_imm_ass ia;
Harald Welte8470bf22008-12-25 23:28:35 +00001113 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001114 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001115 struct gsm_lchan *lchan;
1116 u_int8_t rqd_ta;
Holger Freyther3186bf22008-12-29 06:23:49 +00001117 int ret;
Harald Welte8470bf22008-12-25 23:28:35 +00001118
Harald Welte52b1f982008-12-23 20:25:15 +00001119 u_int16_t arfcn;
1120 u_int8_t ts_number, subch;
1121
Harald Welte8470bf22008-12-25 23:28:35 +00001122 /* parse request reference to be used in immediate assign */
1123 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1124 return -EINVAL;
1125
1126 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1127
1128 /* parse access delay and use as TA */
1129 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1130 return -EINVAL;
1131 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1132
1133 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1134 * request reference RA */
1135 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
Harald Welte2cbe0922008-12-29 04:09:31 +00001136 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1137
Harald Welte8470bf22008-12-25 23:28:35 +00001138 /* check availability / allocate channel */
1139 lchan = lchan_alloc(bts, lctype);
1140 if (!lchan) {
1141 fprintf(stderr, "CHAN RQD: no resources\n");
1142 /* FIXME: send some kind of reject ?!? */
1143 return -ENOMEM;
1144 }
1145
1146 ts_number = lchan->ts->nr;
1147 arfcn = lchan->ts->trx->arfcn;
1148 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001149
Harald Welte08d91a52009-08-30 15:37:11 +09001150 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001151 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001152 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001153 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001154 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte9943c5b2009-07-29 15:41:29 +02001155 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte52b1f982008-12-23 20:25:15 +00001156
1157 /* create IMMEDIATE ASSIGN 04.08 messge */
1158 memset(&ia, 0, sizeof(ia));
1159 ia.l2_plen = 0x2d;
1160 ia.proto_discr = GSM48_PDISC_RR;
1161 ia.msg_type = GSM48_MT_RR_IMM_ASS;
Harald Welte2d5b6382008-12-27 19:46:06 +00001162 ia.page_mode = GSM48_PM_SAME;
Harald Welte4b634542008-12-27 01:55:51 +00001163 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +00001164 ia.chan_desc.h0.h = 0;
1165 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1166 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte814c4b72009-07-21 20:55:56 +02001167 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte8470bf22008-12-25 23:28:35 +00001168 /* use request reference extracted from CHAN_RQD */
1169 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1170 ia.timing_advance = rqd_ta;
Harald Welte52b1f982008-12-23 20:25:15 +00001171 ia.mob_alloc_len = 0;
1172
Harald Welte8f5e2392009-02-03 12:57:37 +00001173 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
Holger Freyther79f4ae62009-06-02 03:25:04 +00001174 "chan_nr=0x%02x r=%s ra=0x%02x\n",
Harald Welteca64da92009-01-04 16:54:12 +00001175 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
Harald Welte4a543e82009-02-28 13:17:55 +00001176 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1177 rqd_ref->ra);
Harald Welte75a983f2008-12-27 21:34:06 +00001178
Harald Welteb7e81162009-08-10 00:26:10 +02001179 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1180 lchan->T3101.cb = t3101_expired;
1181 lchan->T3101.data = lchan;
1182 bsc_schedule_timer(&lchan->T3101, 10, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001183
Harald Welte52b1f982008-12-23 20:25:15 +00001184 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Freyther3186bf22008-12-29 06:23:49 +00001185 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1186
Harald Welte817f3c82008-12-30 14:57:59 +00001187 return ret;
Harald Welte52b1f982008-12-23 20:25:15 +00001188}
1189
Harald Welteea280442009-02-02 22:29:56 +00001190/* MS has requested a channel on the RACH */
1191static int rsl_rx_ccch_load(struct msgb *msg)
1192{
1193 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1194 u_int16_t pg_buf_space;
Holger Freyther8c563cf2009-02-03 20:08:51 +00001195 u_int16_t rach_slot_count = -1;
1196 u_int16_t rach_busy_count = -1;
1197 u_int16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001198
1199 switch (rslh->data[0]) {
1200 case RSL_IE_PAGING_LOAD:
1201 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Holger Freyther392209c2009-02-10 00:06:19 +00001202 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001203 break;
1204 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001205 if (msg->data_len >= 7) {
1206 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1207 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1208 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1209 }
Harald Welteea280442009-02-02 22:29:56 +00001210 break;
1211 default:
1212 break;
1213 }
1214
1215 return 0;
1216}
1217
Harald Welte52b1f982008-12-23 20:25:15 +00001218static int abis_rsl_rx_cchan(struct msgb *msg)
1219{
Harald Welteea280442009-02-02 22:29:56 +00001220 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001221 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001222
Harald Welte8470bf22008-12-25 23:28:35 +00001223 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1224
1225 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001226 case RSL_MT_CHAN_RQD:
1227 /* MS has requested a channel on the RACH */
1228 rc = rsl_rx_chan_rqd(msg);
1229 break;
Harald Welteea280442009-02-02 22:29:56 +00001230 case RSL_MT_CCCH_LOAD_IND:
1231 /* current load on the CCCH */
1232 rc = rsl_rx_ccch_load(msg);
1233 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001234 case RSL_MT_DELETE_IND:
1235 /* CCCH overloaded, IMM_ASSIGN was dropped */
1236 case RSL_MT_CBCH_LOAD_IND:
1237 /* current load on the CBCH */
Harald Welte8f5e2392009-02-03 12:57:37 +00001238 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1239 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001240 break;
1241 default:
1242 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001243 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001244 return -EINVAL;
1245 }
Harald Welte8470bf22008-12-25 23:28:35 +00001246
1247 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001248}
1249
Harald Welte4b634542008-12-27 01:55:51 +00001250static int rsl_rx_rll_err_ind(struct msgb *msg)
1251{
1252 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1253 u_int8_t *rlm_cause = rllh->data;
1254
Harald Welte602f2b82009-08-04 02:50:21 +02001255 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteedcc5272009-08-09 13:47:35 +02001256
1257 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte4b634542008-12-27 01:55:51 +00001258
Harald Welte81543bc2009-07-04 09:40:05 +02001259 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte115d1032009-08-10 11:43:22 +02001260 return rsl_rf_chan_release(msg->lchan);
Harald Welte81543bc2009-07-04 09:40:05 +02001261
Harald Welte4b634542008-12-27 01:55:51 +00001262 return 0;
1263}
Harald Weltef325eb42009-02-19 17:07:39 +00001264
Harald Welte52b1f982008-12-23 20:25:15 +00001265/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1266 0x02, 0x06,
1267 0x01, 0x20,
1268 0x02, 0x00,
1269 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1270
1271static int abis_rsl_rx_rll(struct msgb *msg)
1272{
1273 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001274 int rc = 0;
1275 char *ts_name;
Harald Welte (local)daef6062009-08-14 11:41:12 +02001276 u_int8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001277
1278 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001279 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)daef6062009-08-14 11:41:12 +02001280 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1281 rllh->chan_nr, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001282
1283 switch (rllh->c.msg_type) {
1284 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001285 DEBUGPC(DRLL, "DATA INDICATION\n");
Harald Welte4a543e82009-02-28 13:17:55 +00001286 if (msgb_l2len(msg) >
1287 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1288 rllh->data[0] == RSL_IE_L3_INFO) {
1289 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001290 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001291 }
Harald Welte52b1f982008-12-23 20:25:15 +00001292 break;
1293 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001294 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001295 /* lchan is established, stop T3101 */
1296 bsc_del_timer(&msg->lchan->T3101);
Harald Welte4a543e82009-02-28 13:17:55 +00001297 if (msgb_l2len(msg) >
1298 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1299 rllh->data[0] == RSL_IE_L3_INFO) {
1300 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001301 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001302 }
Harald Welte52b1f982008-12-23 20:25:15 +00001303 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001304 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001305 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Harald Welteedcc5272009-08-09 13:47:35 +02001306 rll_indication(msg->lchan, rllh->link_id,
1307 BSC_RLLR_IND_EST_CONF);
1308 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001309 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001310 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001311 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteedcc5272009-08-09 13:47:35 +02001312 rll_indication(msg->lchan, rllh->link_id,
1313 BSC_RLLR_IND_REL_IND);
Harald Welted2dc1de2009-08-08 13:15:07 +02001314 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001315 /* FIXME: officially we need to start T3111 and wait for
1316 * some grace period */
1317 rsl_rf_chan_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001318 break;
1319 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001320 /* BTS informs us of having received UA from MS,
1321 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001322 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welted2dc1de2009-08-08 13:15:07 +02001323 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001324 /* FIXME: officially we need to start T3111 and wait for
1325 * some grace period */
1326 rsl_rf_chan_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001327 break;
1328 case RSL_MT_ERROR_IND:
1329 rc = rsl_rx_rll_err_ind(msg);
1330 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001331 case RSL_MT_UNIT_DATA_IND:
Harald Welte602f2b82009-08-04 02:50:21 +02001332 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001333 rllh->c.msg_type);
1334 break;
1335 default:
Harald Welte602f2b82009-08-04 02:50:21 +02001336 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001337 rllh->c.msg_type);
1338 }
Harald Welte8470bf22008-12-25 23:28:35 +00001339 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001340}
1341
Harald Weltef4e79f22009-07-28 18:11:56 +02001342static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1343{
Harald Weltef4e79f22009-07-28 18:11:56 +02001344 switch (tch_mode) {
1345 case GSM48_CMODE_SPEECH_V1:
1346 return 0x00;
1347 case GSM48_CMODE_SPEECH_EFR:
1348 return 0x01;
1349 case GSM48_CMODE_SPEECH_AMR:
1350 return 0x02;
1351 /* FIXME: Type1 half-rate and type3 half-rate */
1352 }
Harald Welte58ca5b72009-07-29 12:12:18 +02001353 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1354 "tch_mode == 0x%02x\n", tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001355 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001356}
1357
Harald Welte75099262009-02-16 21:12:08 +00001358/* ip.access specific RSL extensions */
1359int rsl_ipacc_bind(struct gsm_lchan *lchan)
1360{
1361 struct msgb *msg = rsl_msgb_alloc();
1362 struct abis_rsl_dchan_hdr *dh;
Harald Welte58ca5b72009-07-29 12:12:18 +02001363 u_int8_t speech_mode;
Harald Welte75099262009-02-16 21:12:08 +00001364
1365 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1366 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1367 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1368 dh->chan_nr = lchan2chan_nr(lchan);
1369
Harald Weltef4e79f22009-07-28 18:11:56 +02001370 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte58ca5b72009-07-29 12:12:18 +02001371 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1372 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001373
Harald Welte58ca5b72009-07-29 12:12:18 +02001374 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1375 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1376 dh->chan_nr, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001377
Harald Welte75099262009-02-16 21:12:08 +00001378 msg->trx = lchan->ts->trx;
1379
1380 return abis_rsl_sendmsg(msg);
1381}
1382
Harald Welte20855542009-07-12 09:50:35 +02001383int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1384 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001385{
1386 struct msgb *msg = rsl_msgb_alloc();
1387 struct abis_rsl_dchan_hdr *dh;
1388 u_int8_t *att_f8, *att_ip, *att_port;
Harald Welte58ca5b72009-07-29 12:12:18 +02001389 u_int8_t speech_mode;
Harald Weltef4e79f22009-07-28 18:11:56 +02001390 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001391
1392 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1393 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1394 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1395 dh->chan_nr = lchan2chan_nr(lchan);
1396
Harald Welte58ca5b72009-07-29 12:12:18 +02001397 /* 0x0- == both directions, 0x-1 == EFR codec */
1398 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1399
Harald Weltef4e79f22009-07-28 18:11:56 +02001400 ia.s_addr = htonl(ip);
Harald Welte58ca5b72009-07-29 12:12:18 +02001401 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1402 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Weltef4e79f22009-07-28 18:11:56 +02001403 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Welte58ca5b72009-07-29 12:12:18 +02001404 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001405
Harald Welte20855542009-07-12 09:50:35 +02001406 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welte86c162d2009-07-12 09:45:05 +02001407 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte20855542009-07-12 09:50:35 +02001408 att_f8[1] = conn_id >> 8;
1409 att_f8[2] = conn_id & 0xff;
Harald Welte75099262009-02-16 21:12:08 +00001410
1411 att_ip = msgb_put(msg, sizeof(ip)+1);
1412 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1413 att_ip[1] = ip >> 24;
1414 att_ip[2] = ip >> 16;
1415 att_ip[3] = ip >> 8;
1416 att_ip[4] = ip & 0xff;
Harald Welteda783762009-02-18 03:29:53 +00001417 //att_ip[4] = 11;
Harald Welte75099262009-02-16 21:12:08 +00001418
1419 att_port = msgb_put(msg, sizeof(port)+1);
1420 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1421 att_port[1] = port >> 8;
1422 att_port[2] = port & 0xff;
1423
Harald Welte58ca5b72009-07-29 12:12:18 +02001424 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001425 if (rtp_payload2)
1426 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1427
Harald Welte75099262009-02-16 21:12:08 +00001428 msg->trx = lchan->ts->trx;
1429
1430 return abis_rsl_sendmsg(msg);
1431}
1432
Harald Welte9c880c92009-10-24 10:29:22 +02001433int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
1434{
1435 struct msgb *msg = rsl_msgb_alloc();
1436 struct abis_rsl_dchan_hdr *dh;
1437
1438 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1439 init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
1440 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1441 dh->chan_nr = lchan2chan_nr(lchan);
1442
1443 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
1444 gsm_ts_name(lchan->ts), dh->chan_nr);
1445
1446 msg->trx = lchan->ts->trx;
1447
1448 return abis_rsl_sendmsg(msg);
1449}
1450
Harald Welte75099262009-02-16 21:12:08 +00001451static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1452{
1453 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1454 struct tlv_parsed tv;
1455 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
Harald Welte167df882009-02-17 14:35:45 +00001456 struct in_addr ip;
Harald Welte75099262009-02-16 21:12:08 +00001457 u_int16_t port, attr_f8;
1458
1459 /* the BTS has acknowledged a local bind, it now tells us the IP
1460 * address and port number to which it has bound the given logical
1461 * channel */
1462
1463 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1464 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1465 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001466 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltef325eb42009-02-19 17:07:39 +00001467 DEBUGPC(DRSL, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001468 return -EINVAL;
1469 }
Harald Welte167df882009-02-17 14:35:45 +00001470 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte75099262009-02-16 21:12:08 +00001471 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1472 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1473
Harald Weltef4e79f22009-07-28 18:11:56 +02001474 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1475 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1476
1477 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1478 ts->abis_ip.rtp_payload2 =
1479 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1480 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1481 ts->abis_ip.rtp_payload2);
1482 }
Harald Welte167df882009-02-17 14:35:45 +00001483
Harald Welte75099262009-02-16 21:12:08 +00001484 /* update our local information about this TS */
Harald Welte167df882009-02-17 14:35:45 +00001485 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1486 ts->abis_ip.bound_port = ntohs(port);
Harald Welte20855542009-07-12 09:50:35 +02001487 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte75099262009-02-16 21:12:08 +00001488
Harald Welte167df882009-02-17 14:35:45 +00001489 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1490
Harald Welte75099262009-02-16 21:12:08 +00001491 return 0;
1492}
1493
1494static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1495{
1496 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1497 struct tlv_parsed tv;
1498
1499 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001500
Harald Welte8830e072009-07-28 17:58:09 +02001501 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1502 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1503 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001504
Harald Welte888b1142009-07-28 18:02:05 +02001505 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1506
Harald Welte75099262009-02-16 21:12:08 +00001507 return 0;
1508}
1509
1510static int abis_rsl_rx_ipacc(struct msgb *msg)
1511{
1512 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1513 int rc = 0;
1514
1515 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001516 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1517 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
Harald Welte75099262009-02-16 21:12:08 +00001518
1519 switch (rllh->c.msg_type) {
1520 case RSL_MT_IPAC_BIND_ACK:
Harald Welte4a543e82009-02-28 13:17:55 +00001521 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001522 rc = abis_rsl_rx_ipacc_bindack(msg);
1523 break;
1524 case RSL_MT_IPAC_BIND_NACK:
1525 /* somehow the BTS was unable to bind the lchan to its local
1526 * port?!? */
Harald Weltef325eb42009-02-19 17:07:39 +00001527 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001528 break;
1529 case RSL_MT_IPAC_CONNECT_ACK:
1530 /* the BTS tells us that a connect operation was successful */
Harald Weltef325eb42009-02-19 17:07:39 +00001531 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001532 break;
1533 case RSL_MT_IPAC_CONNECT_NACK:
1534 /* somehow the BTS was unable to connect the lchan to a remote
1535 * port */
Harald Weltef325eb42009-02-19 17:07:39 +00001536 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001537 break;
1538 case RSL_MT_IPAC_DISCONNECT_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001539 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
Harald Welte75099262009-02-16 21:12:08 +00001540 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1541 break;
1542 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001543 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001544 break;
1545 }
Harald Welte6dab0552009-05-01 17:21:37 +00001546 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001547
1548 return rc;
1549}
1550
1551
Harald Welte52b1f982008-12-23 20:25:15 +00001552/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001553int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001554{
1555 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
Harald Welte8f5e2392009-02-03 12:57:37 +00001556 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001557
1558 switch (rslh->msg_discr & 0xfe) {
1559 case ABIS_RSL_MDISC_RLL:
1560 rc = abis_rsl_rx_rll(msg);
1561 break;
1562 case ABIS_RSL_MDISC_DED_CHAN:
1563 rc = abis_rsl_rx_dchan(msg);
1564 break;
1565 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001566 rc = abis_rsl_rx_cchan(msg);
1567 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001568 case ABIS_RSL_MDISC_TRX:
1569 rc = abis_rsl_rx_trx(msg);
1570 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001571 case ABIS_RSL_MDISC_LOC:
Harald Welte8f5e2392009-02-03 12:57:37 +00001572 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1573 rslh->msg_discr);
1574 break;
Harald Welte75099262009-02-16 21:12:08 +00001575 case ABIS_RSL_MDISC_IPACCESS:
1576 rc = abis_rsl_rx_ipacc(msg);
1577 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001578 default:
1579 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1580 rslh->msg_discr);
1581 return -EINVAL;
1582 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001583 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001584 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001585}
Holger Freyther3b72a892009-02-04 00:31:39 +00001586
1587
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001588/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Holger Freyther3b72a892009-02-04 00:31:39 +00001589int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1590{
1591 switch (ccch_conf) {
1592 case RSL_BCCH_CCCH_CONF_1_NC:
1593 return 1;
1594 case RSL_BCCH_CCCH_CONF_1_C:
1595 return 1;
1596 case RSL_BCCH_CCCH_CONF_2_NC:
1597 return 2;
1598 case RSL_BCCH_CCCH_CONF_3_NC:
1599 return 3;
1600 case RSL_BCCH_CCCH_CONF_4_NC:
1601 return 4;
1602 default:
1603 return -1;
1604 }
1605}
1606
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001607/* Section 3.3.2.3 TS 05.02 */
Holger Freyther3b72a892009-02-04 00:31:39 +00001608int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1609{
1610 switch (ccch_conf) {
1611 case RSL_BCCH_CCCH_CONF_1_NC:
1612 return 0;
1613 case RSL_BCCH_CCCH_CONF_1_C:
1614 return 1;
1615 case RSL_BCCH_CCCH_CONF_2_NC:
1616 return 0;
1617 case RSL_BCCH_CCCH_CONF_3_NC:
1618 return 0;
1619 case RSL_BCCH_CCCH_CONF_4_NC:
1620 return 0;
1621 default:
1622 return -1;
1623 }
1624}
1625
1626/* From Table 10.5.33 of GSM 04.08 */
1627int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1628{
1629 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1630 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001631 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001632 } else {
1633 return (9 - bts->chan_desc.bs_ag_blks_res)
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001634 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001635 }
1636}