blob: acd41dd6328c1abbb52ed8be66ac439e4447a24f [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
Holger Hans Peter Freythere81a6102009-10-22 11:47:45 +0200242/* See Table 10.5.25 of GSM04.08 */
Harald Welte8470bf22008-12-25 23:28:35 +0000243u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
244{
245 struct gsm_bts_trx_ts *ts = lchan->ts;
246 u_int8_t cbits, chan_nr;
247
248 switch (ts->pchan) {
249 case GSM_PCHAN_TCH_F:
Harald Weltea1499d02009-10-24 10:25:50 +0200250 case GSM_PCHAN_PDCH:
251 case GSM_PCHAN_TCH_F_PDCH:
Harald Welte8470bf22008-12-25 23:28:35 +0000252 cbits = 0x01;
253 break;
254 case GSM_PCHAN_TCH_H:
255 cbits = 0x02;
256 cbits += lchan->nr;
257 break;
258 case GSM_PCHAN_CCCH_SDCCH4:
259 cbits = 0x04;
260 cbits += lchan->nr;
261 break;
262 case GSM_PCHAN_SDCCH8_SACCH8C:
263 cbits = 0x08;
264 cbits += lchan->nr;
265 break;
266 default:
267 case GSM_PCHAN_CCCH:
268 cbits = 0x10;
269 break;
270 }
271
272 chan_nr = (cbits << 3) | (ts->nr & 0x7);
273
274 return chan_nr;
275}
276
Harald Welte52b1f982008-12-23 20:25:15 +0000277/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
278u_int64_t str_to_imsi(const char *imsi_str)
279{
280 u_int64_t ret;
281
282 ret = strtoull(imsi_str, NULL, 10);
283
284 return ret;
285}
286
287/* Table 5 Clause 7 TS 05.02 */
288unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
289{
290 if (!bs_ccch_sdcch_comb)
291 return 9 - bs_ag_blks_res;
292 else
293 return 3 - bs_ag_blks_res;
294}
295
296/* Chapter 6.5.2 of TS 05.02 */
297unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
298 unsigned int n_pag_blocks)
299{
300 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
301}
302
303/* Chapter 6.5.2 of TS 05.02 */
304unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
305 int n_pag_blocks)
306{
307 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
308}
309
Harald Welte8470bf22008-12-25 23:28:35 +0000310static struct msgb *rsl_msgb_alloc(void)
311{
Harald Welte966636f2009-06-26 19:39:35 +0200312 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
313 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000314}
315
Harald Welte362322e2009-02-15 14:36:38 +0000316#define MACBLOCK_SIZE 23
317static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
318{
319 memcpy(out, in, len);
320
321 if (len < MACBLOCK_SIZE)
322 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
323}
324
Harald Welte08d91a52009-08-30 15:37:11 +0900325/* Chapter 9.3.7: Encryption Information */
326static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
327{
328 *out++ = lchan->encr.alg_id & 0xff;
329 if (lchan->encr.key_len)
330 memcpy(out, lchan->encr.key, lchan->encr.key_len);
331 return lchan->encr.key_len + 1;
332}
333
334
Harald Welte8830e072009-07-28 17:58:09 +0200335static const char *rsl_err_vals[0xff] = {
336 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
337 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
338 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
339 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
340 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
341 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welte2da86292009-08-04 02:31:05 +0200342 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Welte8830e072009-07-28 17:58:09 +0200343 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
344 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
345 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
346 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
347 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
348 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
349 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
350 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
351 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
352 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
353 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
354 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
355 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
356 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
357 [RSL_ERR_MSG_TYPE] = "Message Type Error",
358 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
359 [RSL_ERR_IE_ERROR] = "General IE error",
360 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
361 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
362 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
363 [RSL_ERR_IE_LENGTH] = "IE length error",
364 [RSL_ERR_IE_CONTENT] = "IE content error",
365 [RSL_ERR_PROTO] = "Protocol error, unspecified",
366 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
367};
368
369static const char *rsl_err_name(u_int8_t err)
Harald Welte7f93cea2009-02-23 00:02:59 +0000370{
Harald Welte8830e072009-07-28 17:58:09 +0200371 if (rsl_err_vals[err])
372 return rsl_err_vals[err];
373 else
374 return "unknown";
375}
376
377static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
378{
Harald Welte7f93cea2009-02-23 00:02:59 +0000379 int i;
380
Harald Welte8830e072009-07-28 17:58:09 +0200381 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
382 cause_v[0], rsl_err_name(cause_v[0]));
383 for (i = 1; i < cause_len-1; i++)
384 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000385}
386
Harald Welte52b1f982008-12-23 20:25:15 +0000387/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Harald Weltee79769b2009-02-07 00:48:17 +0000388int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000389 const u_int8_t *data, int len)
390{
391 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000392 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000393
394 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
395 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
396 dh->chan_nr = RSL_CHAN_BCCH;
397
398 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
399 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
400
Harald Weltee79769b2009-02-07 00:48:17 +0000401 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000402
403 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000404}
405
Harald Weltee79769b2009-02-07 00:48:17 +0000406int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000407 const u_int8_t *data, int len)
408{
409 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000410 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000411
412 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
413 ch->msg_discr = ABIS_RSL_MDISC_TRX;
414 ch->msg_type = RSL_MT_SACCH_FILL;
415
416 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000417 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000418
Harald Weltee79769b2009-02-07 00:48:17 +0000419 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000420
421 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000422}
423
Harald Weltefcd24452009-06-20 18:15:19 +0200424int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
425{
426 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200427 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200428 u_int8_t chan_nr = lchan2chan_nr(lchan);
429
430 db = abs(db);
431 if (db > 30)
432 return -EINVAL;
433
Harald Welteeab33352009-06-27 03:09:08 +0200434 msg = rsl_msgb_alloc();
435
Harald Weltefcd24452009-06-20 18:15:19 +0200436 lchan->bs_power = db/2;
437 if (fpc)
438 lchan->bs_power |= 0x10;
439
440 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
441 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
442 dh->chan_nr = chan_nr;
443
444 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
445
446 msg->trx = lchan->ts->trx;
447
448 return abis_rsl_sendmsg(msg);
449}
450
Harald Weltefcd24452009-06-20 18:15:19 +0200451int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
452{
453 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200454 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200455 u_int8_t chan_nr = lchan2chan_nr(lchan);
456 int ctl_lvl;
457
Harald Welte66b6a8d2009-08-09 14:45:18 +0200458 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200459 if (ctl_lvl < 0)
460 return ctl_lvl;
461
Harald Welteeab33352009-06-27 03:09:08 +0200462 msg = rsl_msgb_alloc();
463
Harald Weltefcd24452009-06-20 18:15:19 +0200464 lchan->ms_power = ctl_lvl;
465
466 if (fpc)
467 lchan->ms_power |= 0x20;
468
469 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
470 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
471 dh->chan_nr = chan_nr;
472
473 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
474
475 msg->trx = lchan->ts->trx;
476
477 return abis_rsl_sendmsg(msg);
478}
479
Harald Welte9943c5b2009-07-29 15:41:29 +0200480static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
481 struct gsm_lchan *lchan)
482{
483 memset(cm, 0, sizeof(cm));
484
485 /* FIXME: what to do with data calls ? */
486 cm->dtx_dtu = 0x00;
487
488 /* set TCH Speech/Data */
489 cm->spd_ind = lchan->rsl_cmode;
490
491 switch (lchan->type) {
492 case GSM_LCHAN_SDCCH:
493 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
494 break;
495 case GSM_LCHAN_TCH_F:
496 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
497 break;
498 case GSM_LCHAN_TCH_H:
499 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
500 break;
501 case GSM_LCHAN_NONE:
502 case GSM_LCHAN_UNKNOWN:
503 default:
504 return -EINVAL;
505 }
506
507 switch (lchan->tch_mode) {
508 case GSM48_CMODE_SIGN:
509 cm->chan_rate = 0;
510 break;
511 case GSM48_CMODE_SPEECH_V1:
512 cm->chan_rate = RSL_CMOD_SP_GSM1;
513 break;
514 case GSM48_CMODE_SPEECH_EFR:
515 cm->chan_rate = RSL_CMOD_SP_GSM2;
516 break;
517 case GSM48_CMODE_SPEECH_AMR:
518 cm->chan_rate = RSL_CMOD_SP_GSM3;
519 break;
520 case GSM48_CMODE_DATA_14k5:
521 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
522 break;
523 case GSM48_CMODE_DATA_12k0:
524 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
525 break;
526 case GSM48_CMODE_DATA_6k0:
527 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
528 break;
529 default:
530 return -EINVAL;
531 }
532
533 return 0;
534}
535
Harald Welte52b1f982008-12-23 20:25:15 +0000536/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000537#if 0
Harald Weltee79769b2009-02-07 00:48:17 +0000538int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
Harald Welte52b1f982008-12-23 20:25:15 +0000539 u_int8_t act_type,
540 struct rsl_ie_chan_mode *chan_mode,
541 struct rsl_ie_chan_ident *chan_ident,
542 u_int8_t bs_power, u_int8_t ms_power,
543 u_int8_t ta)
544{
545 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000546 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000547
548 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
549 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
550 dh->chan_nr = chan_nr;
551
552 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
553 /* For compatibility with Phase 1 */
554 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
555 (u_int8_t *) chan_mode);
556 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Harald Welte702d8702008-12-26 20:25:35 +0000557 (u_int8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000558#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000559 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
560 (u_int8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000561#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000562 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000563 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
564 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
565
Harald Weltee79769b2009-02-07 00:48:17 +0000566 msg->trx = trx;
567
Harald Welte8470bf22008-12-25 23:28:35 +0000568 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000569}
Harald Welteddab3c72009-02-28 13:19:15 +0000570#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000571
Harald Welte8f5e2392009-02-03 12:57:37 +0000572int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte9943c5b2009-07-29 15:41:29 +0200573 u_int8_t ta)
Harald Welte4b634542008-12-27 01:55:51 +0000574{
575 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200576 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200577 int rc;
Harald Welte4b634542008-12-27 01:55:51 +0000578
579 u_int8_t chan_nr = lchan2chan_nr(lchan);
580 u_int16_t arfcn = lchan->ts->trx->arfcn;
581 struct rsl_ie_chan_mode cm;
582 struct rsl_ie_chan_ident ci;
583
Harald Welte9943c5b2009-07-29 15:41:29 +0200584 rc = channel_mode_from_lchan(&cm, lchan);
585 if (rc < 0)
586 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000587
Harald Welte02b0e092009-02-28 13:11:07 +0000588 memset(&ci, 0, sizeof(ci));
Harald Welte4b634542008-12-27 01:55:51 +0000589 ci.chan_desc.iei = 0x64;
590 ci.chan_desc.chan_nr = chan_nr;
Harald Welte02b0e092009-02-28 13:11:07 +0000591 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
Harald Welte4b634542008-12-27 01:55:51 +0000592 ci.chan_desc.oct4 = arfcn & 0xff;
593
Harald Welteeab33352009-06-27 03:09:08 +0200594 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000595 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
596 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
597 dh->chan_nr = chan_nr;
598
599 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
600 /* For compatibility with Phase 1 */
601 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
602 (u_int8_t *) &cm);
603 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
604 (u_int8_t *) &ci);
Harald Welte08d91a52009-08-30 15:37:11 +0900605
606 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
607 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
608 rc = build_encr_info(encr_info, lchan);
609 if (rc > 0)
610 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
611 }
612
Harald Welted4c9bf32009-02-15 16:56:18 +0000613 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
614 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000615 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
616
Harald Weltee79769b2009-02-07 00:48:17 +0000617 msg->trx = lchan->ts->trx;
618
Harald Welte4b634542008-12-27 01:55:51 +0000619 return abis_rsl_sendmsg(msg);
620}
621
Harald Welte470abb72009-07-29 11:38:15 +0200622/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000623int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
624{
625 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200626 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200627 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000628
629 u_int8_t chan_nr = lchan2chan_nr(lchan);
630 struct rsl_ie_chan_mode cm;
631
Harald Welte9943c5b2009-07-29 15:41:29 +0200632 rc = channel_mode_from_lchan(&cm, lchan);
633 if (rc < 0)
634 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000635
Harald Welteeab33352009-06-27 03:09:08 +0200636 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000637 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
638 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
639 dh->chan_nr = chan_nr;
640
641 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
642 (u_int8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900643
644 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
645 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
646 rc = build_encr_info(encr_info, lchan);
647 if (rc > 0)
648 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
649 }
650
651 msg->trx = lchan->ts->trx;
652
653 return abis_rsl_sendmsg(msg);
654}
655
656/* Chapter 8.4.6: Send the encryption command with given L3 info */
657int rsl_encryption_cmd(struct msgb *msg)
658{
659 struct abis_rsl_dchan_hdr *dh;
660 struct gsm_lchan *lchan = msg->lchan;
661 u_int8_t chan_nr = lchan2chan_nr(lchan);
662 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut82aa6842009-09-27 11:13:18 +0200663 u_int8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900664 int rc;
665
666 /* First push the L3 IE tag and length */
667 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
668
669 /* then the link identifier (SAPI0, main sign link) */
670 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
671
672 /* then encryption information */
673 rc = build_encr_info(encr_info, lchan);
674 if (rc <= 0)
675 return rc;
676 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
677
678 /* and finally the DCHAN header */
679 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
680 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
681 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000682
683 msg->trx = lchan->ts->trx;
684
685 return abis_rsl_sendmsg(msg);
686}
687
Harald Welte115d1032009-08-10 11:43:22 +0200688/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200689int rsl_deact_sacch(struct gsm_lchan *lchan)
690{
691 struct abis_rsl_dchan_hdr *dh;
692 struct msgb *msg = rsl_msgb_alloc();
693
694 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
695 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
696 dh->chan_nr = lchan2chan_nr(lchan);
697
698 msg->lchan = lchan;
699 msg->trx = lchan->ts->trx;
700
701 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
702 gsm_ts_name(lchan->ts), dh->chan_nr);
703
704 return abis_rsl_sendmsg(msg);
705}
706
Harald Welte115d1032009-08-10 11:43:22 +0200707/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
708int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte52b1f982008-12-23 20:25:15 +0000709{
710 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000711 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000712
713 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
714 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000715 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000716
Harald Welte8470bf22008-12-25 23:28:35 +0000717 msg->lchan = lchan;
718 msg->trx = lchan->ts->trx;
719
Harald Welte115d1032009-08-10 11:43:22 +0200720 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Weltef325eb42009-02-19 17:07:39 +0000721 gsm_ts_name(lchan->ts), dh->chan_nr);
Harald Welte2d5b6382008-12-27 19:46:06 +0000722
Harald Welte115d1032009-08-10 11:43:22 +0200723 /* BTS will respond by RF CHAN REL ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000724 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000725}
726
727int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
728 u_int8_t *ms_ident, u_int8_t chan_needed)
729{
730 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000731 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000732
733 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
734 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
735 dh->chan_nr = RSL_CHAN_PCH_AGCH;
736
737 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000738 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000739 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
740
Harald Welte8470bf22008-12-25 23:28:35 +0000741 msg->trx = bts->c0;
742
743 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000744}
745
Holger Freyther7448a532009-01-04 20:18:23 +0000746int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
747 struct gsm_subscriber *subscr)
748{
Holger Freytherca362a62009-01-04 21:05:01 +0000749#if 0
Holger Freyther7448a532009-01-04 20:18:23 +0000750 u_int8_t mi[128];
751 unsigned int mi_len;
752 u_int8_t paging_group;
Holger Freytherca362a62009-01-04 21:05:01 +0000753#endif
Holger Freyther7448a532009-01-04 20:18:23 +0000754
755 return -1;
756}
757
Harald Welte52b1f982008-12-23 20:25:15 +0000758int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
759{
760 int i, len = strlen(str_in);
761
762 for (i = 0; i < len; i++) {
763 int num = str_in[i] - 0x30;
764 if (num < 0 || num > 9)
765 return -1;
766 if (i % 2 == 0)
767 bcd_out[i/2] = num;
768 else
769 bcd_out[i/2] |= (num << 4);
770 }
771
772 return 0;
773}
774
Harald Welte702d8702008-12-26 20:25:35 +0000775/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000776int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
777{
Harald Welte8470bf22008-12-25 23:28:35 +0000778 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000779 struct abis_rsl_dchan_hdr *dh;
Harald Welte362322e2009-02-15 14:36:38 +0000780 u_int8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000781
782 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
783 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
784 dh->chan_nr = RSL_CHAN_PCH_AGCH;
785
Harald Welte362322e2009-02-15 14:36:38 +0000786 switch (bts->type) {
787 case GSM_BTS_TYPE_BS11:
788 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
789 break;
790 default:
791 /* If phase 2, construct a FULL_IMM_ASS_INFO */
792 pad_macblock(buf, val, len);
793 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
794 break;
795 }
Harald Welte52b1f982008-12-23 20:25:15 +0000796
Harald Welte8470bf22008-12-25 23:28:35 +0000797 msg->trx = bts->c0;
798
799 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000800}
801
Harald Welte67fa91b2009-08-10 09:51:40 +0200802/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200803int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200804{
805 struct msgb *msg = rsl_msgb_alloc();
806 struct abis_rsl_dchan_hdr *dh;
807
808 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
809 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200810 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte67fa91b2009-08-10 09:51:40 +0200811 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte31c48932009-08-10 10:07:33 +0200812 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200813
Harald Welte3c456d02009-08-10 11:26:14 +0200814 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
815 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
816
817 msg->trx = lchan->ts->trx;
818
Harald Welte67fa91b2009-08-10 09:51:40 +0200819 return abis_rsl_sendmsg(msg);
820}
821
822
Harald Welte8470bf22008-12-25 23:28:35 +0000823/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000824/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000825int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000826{
Harald Welte8470bf22008-12-25 23:28:35 +0000827 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000828 struct abis_rsl_rll_hdr *rh;
829
Harald Welte8470bf22008-12-25 23:28:35 +0000830 if (msg->lchan == NULL) {
831 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
832 return -EINVAL;
833 }
Harald Welte52b1f982008-12-23 20:25:15 +0000834
Harald Welte8470bf22008-12-25 23:28:35 +0000835 /* First push the L3 IE tag and length */
Harald Welte4b634542008-12-27 01:55:51 +0000836 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
Harald Welte8470bf22008-12-25 23:28:35 +0000837
838 /* Then push the RSL header */
Harald Welte52b1f982008-12-23 20:25:15 +0000839 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
840 init_llm_hdr(rh, RSL_MT_DATA_REQ);
Harald Welte4a543e82009-02-28 13:17:55 +0000841 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
Harald Welte8470bf22008-12-25 23:28:35 +0000842 rh->chan_nr = lchan2chan_nr(msg->lchan);
843 rh->link_id = link_id;
Harald Welte52b1f982008-12-23 20:25:15 +0000844
Harald Welte8470bf22008-12-25 23:28:35 +0000845 msg->trx = msg->lchan->ts->trx;
846
847 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000848}
849
Harald Welteedcc5272009-08-09 13:47:35 +0200850/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
851/* Chapter 8.3.1 */
852int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
853{
854 struct msgb *msg = rsl_msgb_alloc();
855 struct abis_rsl_rll_hdr *rh;
856
857 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte1c409272009-08-09 14:13:58 +0200858 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteedcc5272009-08-09 13:47:35 +0200859 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
860 rh->chan_nr = lchan2chan_nr(lchan);
861 rh->link_id = link_id;
862
863 msg->trx = lchan->ts->trx;
864
865 return abis_rsl_sendmsg(msg);
866}
867
Harald Welted2dc1de2009-08-08 13:15:07 +0200868/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
869 This is what higher layers should call. The BTS then responds with
870 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
871 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
872 lchan_free() */
873int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
874{
875 struct msgb *msg = rsl_msgb_alloc();
876 struct abis_rsl_rll_hdr *rh;
877
878 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
879 init_llm_hdr(rh, RSL_MT_REL_REQ);
880 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
881 rh->chan_nr = lchan2chan_nr(lchan);
882 rh->link_id = link_id;
Harald Welte6c3d2ed2009-08-10 00:19:36 +0200883 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welted2dc1de2009-08-08 13:15:07 +0200884
885 msg->trx = lchan->ts->trx;
886
887 return abis_rsl_sendmsg(msg);
888}
889
Harald Welte702d8702008-12-26 20:25:35 +0000890/* Chapter 8.4.2: Channel Activate Acknowledge */
891static int rsl_rx_chan_act_ack(struct msgb *msg)
892{
893 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
894
895 /* BTS has confirmed channel activation, we now need
896 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000897 if (rslh->ie_chan != RSL_IE_CHAN_NR)
898 return -EINVAL;
899
Harald Welte4b634542008-12-27 01:55:51 +0000900 return 0;
901}
Harald Welte702d8702008-12-26 20:25:35 +0000902
Harald Welte4b634542008-12-27 01:55:51 +0000903/* Chapter 8.4.3: Channel Activate NACK */
904static int rsl_rx_chan_act_nack(struct msgb *msg)
905{
Harald Welte6dab0552009-05-01 17:21:37 +0000906 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
907 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000908
Harald Welte6dab0552009-05-01 17:21:37 +0000909 /* BTS has rejected channel activation ?!? */
910 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000911 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000912
913 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
914 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte8830e072009-07-28 17:58:09 +0200915 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
916 TLVP_LEN(&tp, RSL_IE_CAUSE));
917
Harald Welte3073a9f2009-08-09 19:50:08 +0200918 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000919 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000920}
921
Harald Welte7f93cea2009-02-23 00:02:59 +0000922/* Chapter 8.4.4: Connection Failure Indication */
923static int rsl_rx_conn_fail(struct msgb *msg)
924{
925 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
926 struct tlv_parsed tp;
927
928 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte7f93cea2009-02-23 00:02:59 +0000929
930 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
931
Harald Welte8830e072009-07-28 17:58:09 +0200932 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
933 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
934 TLVP_LEN(&tp, RSL_IE_CAUSE));
935
Holger Freytherf7b2a0e2009-06-02 02:55:17 +0000936 DEBUGPC(DRSL, "RELEASING.\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000937
938 /* FIXME: only free it after channel release ACK */
Harald Welte115d1032009-08-10 11:43:22 +0200939 return rsl_rf_chan_release(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +0000940}
941
Harald Welte440fed02009-05-01 18:43:47 +0000942static int rsl_rx_meas_res(struct msgb *msg)
943{
944 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
945 struct tlv_parsed tp;
946
Harald Welte10d0e672009-06-27 02:53:10 +0200947 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte440fed02009-05-01 18:43:47 +0000948 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
949
950 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte10d0e672009-06-27 02:53:10 +0200951 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte440fed02009-05-01 18:43:47 +0000952 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
953 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte75d34a82009-05-23 06:11:13 +0000954 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte440fed02009-05-01 18:43:47 +0000955 if (len >= 3) {
956 if (val[0] & 0x40)
Harald Welte10d0e672009-06-27 02:53:10 +0200957 DEBUGPC(DMEAS, "DTXd ");
958 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000959 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte10d0e672009-06-27 02:53:10 +0200960 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000961 val[2]>>3 & 0x7, val[2] & 0x7);
962 }
963 }
964 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte10d0e672009-06-27 02:53:10 +0200965 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte440fed02009-05-01 18:43:47 +0000966 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte10d0e672009-06-27 02:53:10 +0200967 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000968 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltefe9af262009-06-20 18:44:35 +0200969 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte86c162d2009-07-12 09:45:05 +0200970 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltefe9af262009-06-20 18:44:35 +0200971 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte10d0e672009-06-27 02:53:10 +0200972 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltefe9af262009-06-20 18:44:35 +0200973 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte10d0e672009-06-27 02:53:10 +0200974 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
975 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltefe9af262009-06-20 18:44:35 +0200976 }
Harald Weltef7c43522009-06-09 20:24:21 +0000977 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte10d0e672009-06-27 02:53:10 +0200978 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freytherddd918f2009-10-22 15:43:55 +0200979 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)daef6062009-08-14 11:41:12 +0200980 return gsm0408_rcvmsg(msg, 0);
Harald Weltef7c43522009-06-09 20:24:21 +0000981 } else
Harald Welte10d0e672009-06-27 02:53:10 +0200982 DEBUGPC(DMEAS, "\n");
Harald Welte60d68f12009-06-05 20:07:43 +0000983
Harald Welte75d34a82009-05-23 06:11:13 +0000984 return 0;
Harald Welte440fed02009-05-01 18:43:47 +0000985}
986
Harald Welte52b1f982008-12-23 20:25:15 +0000987static int abis_rsl_rx_dchan(struct msgb *msg)
988{
Harald Welte8470bf22008-12-25 23:28:35 +0000989 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
990 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +0000991 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +0000992
Harald Welte8470bf22008-12-25 23:28:35 +0000993 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +0000994 ts_name = gsm_ts_name(msg->lchan->ts);
995
Harald Welte10d0e672009-06-27 02:53:10 +0200996 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
997 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000998
999 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001000 case RSL_MT_CHAN_ACTIV_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001001 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001002 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001003 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001004 case RSL_MT_CHAN_ACTIV_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001005 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001006 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001007 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001008 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001009 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001010 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001011 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001012 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001013 break;
1014 case RSL_MT_RF_CHAN_REL_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001015 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
Harald Welte2d5b6382008-12-27 19:46:06 +00001016 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001017 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001018 case RSL_MT_MODE_MODIFY_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001019 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001020 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001021 case RSL_MT_MODE_MODIFY_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001022 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001023 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001024 case RSL_MT_IPAC_PDCH_ACT_ACK:
1025 DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
1026 break;
1027 case RSL_MT_IPAC_PDCH_ACT_NACK:
1028 DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
1029 break;
1030 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1031 DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
1032 break;
1033 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1034 DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
1035 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001036 case RSL_MT_PHY_CONTEXT_CONF:
1037 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001038 case RSL_MT_TALKER_DET:
1039 case RSL_MT_LISTENER_DET:
1040 case RSL_MT_REMOTE_CODEC_CONF_REP:
1041 case RSL_MT_MR_CODEC_MOD_ACK:
1042 case RSL_MT_MR_CODEC_MOD_NACK:
1043 case RSL_MT_MR_CODEC_MOD_PER:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001044 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001045 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001046 break;
1047 default:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001048 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001049 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001050 return -EINVAL;
1051 }
Harald Weltef325eb42009-02-19 17:07:39 +00001052
Harald Welte8470bf22008-12-25 23:28:35 +00001053 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001054}
1055
Harald Welte702d8702008-12-26 20:25:35 +00001056static int rsl_rx_error_rep(struct msgb *msg)
1057{
1058 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001059 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001060
Harald Welte7f93cea2009-02-23 00:02:59 +00001061 DEBUGP(DRSL, "ERROR REPORT ");
Harald Welte8830e072009-07-28 17:58:09 +02001062
1063 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1064
1065 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1066 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1067 TLVP_LEN(&tp, RSL_IE_CAUSE));
1068
Holger Freyther79f4ae62009-06-02 03:25:04 +00001069 DEBUGPC(DRSL, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001070
1071 return 0;
1072}
1073
Harald Welte52b1f982008-12-23 20:25:15 +00001074static int abis_rsl_rx_trx(struct msgb *msg)
1075{
Harald Welte702d8702008-12-26 20:25:35 +00001076 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001077 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001078
1079 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001080 case RSL_MT_ERROR_REPORT:
1081 rc = rsl_rx_error_rep(msg);
1082 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001083 case RSL_MT_RF_RES_IND:
1084 /* interference on idle channels of TRX */
Harald Welte3cf7c3f2009-05-01 18:28:00 +00001085 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
Harald Welte8f5e2392009-02-03 12:57:37 +00001086 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001087 case RSL_MT_OVERLOAD:
1088 /* indicate CCCH / ACCH / processor overload */
Harald Weltef325eb42009-02-19 17:07:39 +00001089 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
Harald Welte52b1f982008-12-23 20:25:15 +00001090 break;
1091 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001092 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001093 rslh->msg_type);
1094 return -EINVAL;
1095 }
Harald Welte8470bf22008-12-25 23:28:35 +00001096 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001097}
1098
Harald Welteb7e81162009-08-10 00:26:10 +02001099/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1100static void t3101_expired(void *data)
1101{
1102 struct gsm_lchan *lchan = data;
1103
Harald Welte115d1032009-08-10 11:43:22 +02001104 rsl_rf_chan_release(lchan);
Harald Welteb7e81162009-08-10 00:26:10 +02001105}
1106
Harald Welte8470bf22008-12-25 23:28:35 +00001107/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001108static int rsl_rx_chan_rqd(struct msgb *msg)
1109{
Harald Welte702d8702008-12-26 20:25:35 +00001110 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001111 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1112 struct gsm48_req_ref *rqd_ref;
Harald Welte52b1f982008-12-23 20:25:15 +00001113 struct gsm48_imm_ass ia;
Harald Welte8470bf22008-12-25 23:28:35 +00001114 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001115 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001116 struct gsm_lchan *lchan;
1117 u_int8_t rqd_ta;
Holger Freyther3186bf22008-12-29 06:23:49 +00001118 int ret;
Harald Welte8470bf22008-12-25 23:28:35 +00001119
Harald Welte52b1f982008-12-23 20:25:15 +00001120 u_int16_t arfcn;
1121 u_int8_t ts_number, subch;
1122
Harald Welte8470bf22008-12-25 23:28:35 +00001123 /* parse request reference to be used in immediate assign */
1124 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1125 return -EINVAL;
1126
1127 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1128
1129 /* parse access delay and use as TA */
1130 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1131 return -EINVAL;
1132 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1133
1134 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1135 * request reference RA */
1136 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
Harald Welte2cbe0922008-12-29 04:09:31 +00001137 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1138
Harald Welte8470bf22008-12-25 23:28:35 +00001139 /* check availability / allocate channel */
1140 lchan = lchan_alloc(bts, lctype);
1141 if (!lchan) {
1142 fprintf(stderr, "CHAN RQD: no resources\n");
1143 /* FIXME: send some kind of reject ?!? */
1144 return -ENOMEM;
1145 }
1146
1147 ts_number = lchan->ts->nr;
1148 arfcn = lchan->ts->trx->arfcn;
1149 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001150
Harald Welte08d91a52009-08-30 15:37:11 +09001151 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001152 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001153 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001154 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001155 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte9943c5b2009-07-29 15:41:29 +02001156 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte52b1f982008-12-23 20:25:15 +00001157
1158 /* create IMMEDIATE ASSIGN 04.08 messge */
1159 memset(&ia, 0, sizeof(ia));
1160 ia.l2_plen = 0x2d;
1161 ia.proto_discr = GSM48_PDISC_RR;
1162 ia.msg_type = GSM48_MT_RR_IMM_ASS;
Harald Welte2d5b6382008-12-27 19:46:06 +00001163 ia.page_mode = GSM48_PM_SAME;
Harald Welte4b634542008-12-27 01:55:51 +00001164 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +00001165 ia.chan_desc.h0.h = 0;
1166 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1167 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte814c4b72009-07-21 20:55:56 +02001168 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte8470bf22008-12-25 23:28:35 +00001169 /* use request reference extracted from CHAN_RQD */
1170 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1171 ia.timing_advance = rqd_ta;
Harald Welte52b1f982008-12-23 20:25:15 +00001172 ia.mob_alloc_len = 0;
1173
Harald Welte8f5e2392009-02-03 12:57:37 +00001174 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
Holger Freyther79f4ae62009-06-02 03:25:04 +00001175 "chan_nr=0x%02x r=%s ra=0x%02x\n",
Harald Welteca64da92009-01-04 16:54:12 +00001176 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
Harald Welte4a543e82009-02-28 13:17:55 +00001177 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1178 rqd_ref->ra);
Harald Welte75a983f2008-12-27 21:34:06 +00001179
Harald Welteb7e81162009-08-10 00:26:10 +02001180 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1181 lchan->T3101.cb = t3101_expired;
1182 lchan->T3101.data = lchan;
1183 bsc_schedule_timer(&lchan->T3101, 10, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001184
Harald Welte52b1f982008-12-23 20:25:15 +00001185 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Freyther3186bf22008-12-29 06:23:49 +00001186 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1187
Harald Welte817f3c82008-12-30 14:57:59 +00001188 return ret;
Harald Welte52b1f982008-12-23 20:25:15 +00001189}
1190
Harald Welteea280442009-02-02 22:29:56 +00001191/* MS has requested a channel on the RACH */
1192static int rsl_rx_ccch_load(struct msgb *msg)
1193{
1194 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1195 u_int16_t pg_buf_space;
Holger Freyther8c563cf2009-02-03 20:08:51 +00001196 u_int16_t rach_slot_count = -1;
1197 u_int16_t rach_busy_count = -1;
1198 u_int16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001199
1200 switch (rslh->data[0]) {
1201 case RSL_IE_PAGING_LOAD:
1202 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Holger Freyther392209c2009-02-10 00:06:19 +00001203 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001204 break;
1205 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001206 if (msg->data_len >= 7) {
1207 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1208 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1209 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1210 }
Harald Welteea280442009-02-02 22:29:56 +00001211 break;
1212 default:
1213 break;
1214 }
1215
1216 return 0;
1217}
1218
Harald Welte52b1f982008-12-23 20:25:15 +00001219static int abis_rsl_rx_cchan(struct msgb *msg)
1220{
Harald Welteea280442009-02-02 22:29:56 +00001221 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001222 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001223
Harald Welte8470bf22008-12-25 23:28:35 +00001224 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1225
1226 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001227 case RSL_MT_CHAN_RQD:
1228 /* MS has requested a channel on the RACH */
1229 rc = rsl_rx_chan_rqd(msg);
1230 break;
Harald Welteea280442009-02-02 22:29:56 +00001231 case RSL_MT_CCCH_LOAD_IND:
1232 /* current load on the CCCH */
1233 rc = rsl_rx_ccch_load(msg);
1234 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001235 case RSL_MT_DELETE_IND:
1236 /* CCCH overloaded, IMM_ASSIGN was dropped */
1237 case RSL_MT_CBCH_LOAD_IND:
1238 /* current load on the CBCH */
Harald Welte8f5e2392009-02-03 12:57:37 +00001239 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1240 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001241 break;
1242 default:
1243 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001244 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001245 return -EINVAL;
1246 }
Harald Welte8470bf22008-12-25 23:28:35 +00001247
1248 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001249}
1250
Harald Welte4b634542008-12-27 01:55:51 +00001251static int rsl_rx_rll_err_ind(struct msgb *msg)
1252{
1253 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1254 u_int8_t *rlm_cause = rllh->data;
1255
Harald Welte602f2b82009-08-04 02:50:21 +02001256 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteedcc5272009-08-09 13:47:35 +02001257
1258 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte4b634542008-12-27 01:55:51 +00001259
Harald Welte81543bc2009-07-04 09:40:05 +02001260 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte115d1032009-08-10 11:43:22 +02001261 return rsl_rf_chan_release(msg->lchan);
Harald Welte81543bc2009-07-04 09:40:05 +02001262
Harald Welte4b634542008-12-27 01:55:51 +00001263 return 0;
1264}
Harald Weltef325eb42009-02-19 17:07:39 +00001265
Harald Welte52b1f982008-12-23 20:25:15 +00001266/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1267 0x02, 0x06,
1268 0x01, 0x20,
1269 0x02, 0x00,
1270 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1271
1272static int abis_rsl_rx_rll(struct msgb *msg)
1273{
1274 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001275 int rc = 0;
1276 char *ts_name;
Harald Welte (local)daef6062009-08-14 11:41:12 +02001277 u_int8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001278
1279 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001280 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)daef6062009-08-14 11:41:12 +02001281 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1282 rllh->chan_nr, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001283
1284 switch (rllh->c.msg_type) {
1285 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001286 DEBUGPC(DRLL, "DATA INDICATION\n");
Harald Welte4a543e82009-02-28 13:17:55 +00001287 if (msgb_l2len(msg) >
1288 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1289 rllh->data[0] == RSL_IE_L3_INFO) {
1290 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001291 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001292 }
Harald Welte52b1f982008-12-23 20:25:15 +00001293 break;
1294 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001295 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001296 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001297 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welteb7e81162009-08-10 00:26:10 +02001298 bsc_del_timer(&msg->lchan->T3101);
Harald Welte4a543e82009-02-28 13:17:55 +00001299 if (msgb_l2len(msg) >
1300 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1301 rllh->data[0] == RSL_IE_L3_INFO) {
1302 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001303 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001304 }
Harald Welte52b1f982008-12-23 20:25:15 +00001305 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001306 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001307 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001308 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001309 rll_indication(msg->lchan, rllh->link_id,
1310 BSC_RLLR_IND_EST_CONF);
1311 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001312 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001313 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001314 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001315 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001316 rll_indication(msg->lchan, rllh->link_id,
1317 BSC_RLLR_IND_REL_IND);
Harald Welted2dc1de2009-08-08 13:15:07 +02001318 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001319 /* FIXME: officially we need to start T3111 and wait for
1320 * some grace period */
1321 rsl_rf_chan_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001322 break;
1323 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001324 /* BTS informs us of having received UA from MS,
1325 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001326 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001327 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welted2dc1de2009-08-08 13:15:07 +02001328 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001329 /* FIXME: officially we need to start T3111 and wait for
1330 * some grace period */
1331 rsl_rf_chan_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001332 break;
1333 case RSL_MT_ERROR_IND:
1334 rc = rsl_rx_rll_err_ind(msg);
1335 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001336 case RSL_MT_UNIT_DATA_IND:
Harald Welte602f2b82009-08-04 02:50:21 +02001337 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001338 rllh->c.msg_type);
1339 break;
1340 default:
Harald Welte602f2b82009-08-04 02:50:21 +02001341 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001342 rllh->c.msg_type);
1343 }
Harald Welte8470bf22008-12-25 23:28:35 +00001344 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001345}
1346
Harald Weltef4e79f22009-07-28 18:11:56 +02001347static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1348{
Harald Weltef4e79f22009-07-28 18:11:56 +02001349 switch (tch_mode) {
1350 case GSM48_CMODE_SPEECH_V1:
1351 return 0x00;
1352 case GSM48_CMODE_SPEECH_EFR:
1353 return 0x01;
1354 case GSM48_CMODE_SPEECH_AMR:
1355 return 0x02;
1356 /* FIXME: Type1 half-rate and type3 half-rate */
1357 }
Harald Welte58ca5b72009-07-29 12:12:18 +02001358 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1359 "tch_mode == 0x%02x\n", tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001360 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001361}
1362
Harald Welte75099262009-02-16 21:12:08 +00001363/* ip.access specific RSL extensions */
1364int rsl_ipacc_bind(struct gsm_lchan *lchan)
1365{
1366 struct msgb *msg = rsl_msgb_alloc();
1367 struct abis_rsl_dchan_hdr *dh;
Harald Welte58ca5b72009-07-29 12:12:18 +02001368 u_int8_t speech_mode;
Harald Welte75099262009-02-16 21:12:08 +00001369
1370 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1371 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1372 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1373 dh->chan_nr = lchan2chan_nr(lchan);
1374
Harald Weltef4e79f22009-07-28 18:11:56 +02001375 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte58ca5b72009-07-29 12:12:18 +02001376 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1377 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001378
Harald Welte58ca5b72009-07-29 12:12:18 +02001379 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1380 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1381 dh->chan_nr, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001382
Harald Welte75099262009-02-16 21:12:08 +00001383 msg->trx = lchan->ts->trx;
1384
1385 return abis_rsl_sendmsg(msg);
1386}
1387
Harald Welte20855542009-07-12 09:50:35 +02001388int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1389 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001390{
1391 struct msgb *msg = rsl_msgb_alloc();
1392 struct abis_rsl_dchan_hdr *dh;
1393 u_int8_t *att_f8, *att_ip, *att_port;
Harald Welte58ca5b72009-07-29 12:12:18 +02001394 u_int8_t speech_mode;
Harald Weltef4e79f22009-07-28 18:11:56 +02001395 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001396
1397 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1398 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1399 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1400 dh->chan_nr = lchan2chan_nr(lchan);
1401
Harald Welte58ca5b72009-07-29 12:12:18 +02001402 /* 0x0- == both directions, 0x-1 == EFR codec */
1403 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1404
Harald Weltef4e79f22009-07-28 18:11:56 +02001405 ia.s_addr = htonl(ip);
Harald Welte58ca5b72009-07-29 12:12:18 +02001406 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1407 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Weltef4e79f22009-07-28 18:11:56 +02001408 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Welte58ca5b72009-07-29 12:12:18 +02001409 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001410
Harald Welte20855542009-07-12 09:50:35 +02001411 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welte86c162d2009-07-12 09:45:05 +02001412 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte20855542009-07-12 09:50:35 +02001413 att_f8[1] = conn_id >> 8;
1414 att_f8[2] = conn_id & 0xff;
Harald Welte75099262009-02-16 21:12:08 +00001415
1416 att_ip = msgb_put(msg, sizeof(ip)+1);
1417 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1418 att_ip[1] = ip >> 24;
1419 att_ip[2] = ip >> 16;
1420 att_ip[3] = ip >> 8;
1421 att_ip[4] = ip & 0xff;
Harald Welteda783762009-02-18 03:29:53 +00001422 //att_ip[4] = 11;
Harald Welte75099262009-02-16 21:12:08 +00001423
1424 att_port = msgb_put(msg, sizeof(port)+1);
1425 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1426 att_port[1] = port >> 8;
1427 att_port[2] = port & 0xff;
1428
Harald Welte58ca5b72009-07-29 12:12:18 +02001429 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001430 if (rtp_payload2)
1431 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1432
Harald Welte75099262009-02-16 21:12:08 +00001433 msg->trx = lchan->ts->trx;
1434
1435 return abis_rsl_sendmsg(msg);
1436}
1437
Harald Welte9c880c92009-10-24 10:29:22 +02001438int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
1439{
1440 struct msgb *msg = rsl_msgb_alloc();
1441 struct abis_rsl_dchan_hdr *dh;
1442
1443 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1444 init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
1445 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1446 dh->chan_nr = lchan2chan_nr(lchan);
1447
1448 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
1449 gsm_ts_name(lchan->ts), dh->chan_nr);
1450
1451 msg->trx = lchan->ts->trx;
1452
1453 return abis_rsl_sendmsg(msg);
1454}
1455
Harald Welte75099262009-02-16 21:12:08 +00001456static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1457{
1458 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1459 struct tlv_parsed tv;
1460 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
Harald Welte167df882009-02-17 14:35:45 +00001461 struct in_addr ip;
Harald Welte75099262009-02-16 21:12:08 +00001462 u_int16_t port, attr_f8;
1463
1464 /* the BTS has acknowledged a local bind, it now tells us the IP
1465 * address and port number to which it has bound the given logical
1466 * channel */
1467
1468 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1469 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1470 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001471 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltef325eb42009-02-19 17:07:39 +00001472 DEBUGPC(DRSL, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001473 return -EINVAL;
1474 }
Harald Welte167df882009-02-17 14:35:45 +00001475 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte75099262009-02-16 21:12:08 +00001476 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1477 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1478
Harald Weltef4e79f22009-07-28 18:11:56 +02001479 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1480 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1481
1482 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1483 ts->abis_ip.rtp_payload2 =
1484 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1485 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1486 ts->abis_ip.rtp_payload2);
1487 }
Harald Welte167df882009-02-17 14:35:45 +00001488
Harald Welte75099262009-02-16 21:12:08 +00001489 /* update our local information about this TS */
Harald Welte167df882009-02-17 14:35:45 +00001490 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1491 ts->abis_ip.bound_port = ntohs(port);
Harald Welte20855542009-07-12 09:50:35 +02001492 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte75099262009-02-16 21:12:08 +00001493
Harald Welte167df882009-02-17 14:35:45 +00001494 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1495
Harald Welte75099262009-02-16 21:12:08 +00001496 return 0;
1497}
1498
1499static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1500{
1501 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1502 struct tlv_parsed tv;
1503
1504 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001505
Harald Welte8830e072009-07-28 17:58:09 +02001506 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1507 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1508 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001509
Harald Welte888b1142009-07-28 18:02:05 +02001510 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1511
Harald Welte75099262009-02-16 21:12:08 +00001512 return 0;
1513}
1514
1515static int abis_rsl_rx_ipacc(struct msgb *msg)
1516{
1517 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1518 int rc = 0;
1519
1520 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001521 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1522 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
Harald Welte75099262009-02-16 21:12:08 +00001523
1524 switch (rllh->c.msg_type) {
1525 case RSL_MT_IPAC_BIND_ACK:
Harald Welte4a543e82009-02-28 13:17:55 +00001526 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001527 rc = abis_rsl_rx_ipacc_bindack(msg);
1528 break;
1529 case RSL_MT_IPAC_BIND_NACK:
1530 /* somehow the BTS was unable to bind the lchan to its local
1531 * port?!? */
Harald Weltef325eb42009-02-19 17:07:39 +00001532 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001533 break;
1534 case RSL_MT_IPAC_CONNECT_ACK:
1535 /* the BTS tells us that a connect operation was successful */
Harald Weltef325eb42009-02-19 17:07:39 +00001536 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001537 break;
1538 case RSL_MT_IPAC_CONNECT_NACK:
1539 /* somehow the BTS was unable to connect the lchan to a remote
1540 * port */
Harald Weltef325eb42009-02-19 17:07:39 +00001541 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001542 break;
1543 case RSL_MT_IPAC_DISCONNECT_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001544 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
Harald Welte75099262009-02-16 21:12:08 +00001545 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1546 break;
1547 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001548 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001549 break;
1550 }
Harald Welte6dab0552009-05-01 17:21:37 +00001551 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001552
1553 return rc;
1554}
1555
1556
Harald Welte52b1f982008-12-23 20:25:15 +00001557/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001558int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001559{
1560 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
Harald Welte8f5e2392009-02-03 12:57:37 +00001561 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001562
1563 switch (rslh->msg_discr & 0xfe) {
1564 case ABIS_RSL_MDISC_RLL:
1565 rc = abis_rsl_rx_rll(msg);
1566 break;
1567 case ABIS_RSL_MDISC_DED_CHAN:
1568 rc = abis_rsl_rx_dchan(msg);
1569 break;
1570 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001571 rc = abis_rsl_rx_cchan(msg);
1572 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001573 case ABIS_RSL_MDISC_TRX:
1574 rc = abis_rsl_rx_trx(msg);
1575 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001576 case ABIS_RSL_MDISC_LOC:
Harald Welte8f5e2392009-02-03 12:57:37 +00001577 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1578 rslh->msg_discr);
1579 break;
Harald Welte75099262009-02-16 21:12:08 +00001580 case ABIS_RSL_MDISC_IPACCESS:
1581 rc = abis_rsl_rx_ipacc(msg);
1582 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001583 default:
1584 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1585 rslh->msg_discr);
1586 return -EINVAL;
1587 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001588 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001589 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001590}
Holger Freyther3b72a892009-02-04 00:31:39 +00001591
1592
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001593/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Holger Freyther3b72a892009-02-04 00:31:39 +00001594int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1595{
1596 switch (ccch_conf) {
1597 case RSL_BCCH_CCCH_CONF_1_NC:
1598 return 1;
1599 case RSL_BCCH_CCCH_CONF_1_C:
1600 return 1;
1601 case RSL_BCCH_CCCH_CONF_2_NC:
1602 return 2;
1603 case RSL_BCCH_CCCH_CONF_3_NC:
1604 return 3;
1605 case RSL_BCCH_CCCH_CONF_4_NC:
1606 return 4;
1607 default:
1608 return -1;
1609 }
1610}
1611
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001612/* Section 3.3.2.3 TS 05.02 */
Holger Freyther3b72a892009-02-04 00:31:39 +00001613int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1614{
1615 switch (ccch_conf) {
1616 case RSL_BCCH_CCCH_CONF_1_NC:
1617 return 0;
1618 case RSL_BCCH_CCCH_CONF_1_C:
1619 return 1;
1620 case RSL_BCCH_CCCH_CONF_2_NC:
1621 return 0;
1622 case RSL_BCCH_CCCH_CONF_3_NC:
1623 return 0;
1624 case RSL_BCCH_CCCH_CONF_4_NC:
1625 return 0;
1626 default:
1627 return -1;
1628 }
1629}
1630
1631/* From Table 10.5.33 of GSM 04.08 */
1632int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1633{
1634 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1635 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001636 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001637 } else {
1638 return (9 - bts->chan_desc.bs_ag_blks_res)
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001639 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001640 }
1641}