blob: da12d93734c5ba8e9b20e7a061c0fe7f5cc05a7b [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 */
205 if (ts->pchan != GSM_PCHAN_TCH_F)
206 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
207 chan_nr, ts->pchan);
208 } else if ((cbits & 0x1e) == 0x02) {
209 lch_idx = cbits & 0x1; /* TCH/H */
210 if (ts->pchan != GSM_PCHAN_TCH_H)
211 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
212 chan_nr, ts->pchan);
213 } else if ((cbits & 0x1c) == 0x04) {
214 lch_idx = cbits & 0x3; /* SDCCH/4 */
215 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
216 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
217 chan_nr, ts->pchan);
218 } else if ((cbits & 0x18) == 0x08) {
219 lch_idx = cbits & 0x7; /* SDCCH/8 */
220 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
221 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
222 chan_nr, ts->pchan);
223 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
224 lch_idx = 0;
225 if (ts->pchan != GSM_PCHAN_CCCH &&
226 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
227 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
228 chan_nr, ts->pchan);
229 /* FIXME: we should not return first sdcch4 !!! */
230 } else {
231 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
232 return NULL;
233 }
234
235 lchan = &ts->lchan[lch_idx];
236
237 return lchan;
238}
239
240u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
241{
242 struct gsm_bts_trx_ts *ts = lchan->ts;
243 u_int8_t cbits, chan_nr;
244
245 switch (ts->pchan) {
246 case GSM_PCHAN_TCH_F:
247 cbits = 0x01;
248 break;
249 case GSM_PCHAN_TCH_H:
250 cbits = 0x02;
251 cbits += lchan->nr;
252 break;
253 case GSM_PCHAN_CCCH_SDCCH4:
254 cbits = 0x04;
255 cbits += lchan->nr;
256 break;
257 case GSM_PCHAN_SDCCH8_SACCH8C:
258 cbits = 0x08;
259 cbits += lchan->nr;
260 break;
261 default:
262 case GSM_PCHAN_CCCH:
263 cbits = 0x10;
264 break;
265 }
266
267 chan_nr = (cbits << 3) | (ts->nr & 0x7);
268
269 return chan_nr;
270}
271
Harald Welte52b1f982008-12-23 20:25:15 +0000272/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
273u_int64_t str_to_imsi(const char *imsi_str)
274{
275 u_int64_t ret;
276
277 ret = strtoull(imsi_str, NULL, 10);
278
279 return ret;
280}
281
282/* Table 5 Clause 7 TS 05.02 */
283unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
284{
285 if (!bs_ccch_sdcch_comb)
286 return 9 - bs_ag_blks_res;
287 else
288 return 3 - bs_ag_blks_res;
289}
290
291/* Chapter 6.5.2 of TS 05.02 */
292unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
293 unsigned int n_pag_blocks)
294{
295 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
296}
297
298/* Chapter 6.5.2 of TS 05.02 */
299unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
300 int n_pag_blocks)
301{
302 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
303}
304
Harald Welte8470bf22008-12-25 23:28:35 +0000305static struct msgb *rsl_msgb_alloc(void)
306{
Harald Welte966636f2009-06-26 19:39:35 +0200307 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
308 "RSL");
Harald Welte8470bf22008-12-25 23:28:35 +0000309}
310
Harald Welte362322e2009-02-15 14:36:38 +0000311#define MACBLOCK_SIZE 23
312static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
313{
314 memcpy(out, in, len);
315
316 if (len < MACBLOCK_SIZE)
317 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
318}
319
Harald Welte08d91a52009-08-30 15:37:11 +0900320/* Chapter 9.3.7: Encryption Information */
321static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
322{
323 *out++ = lchan->encr.alg_id & 0xff;
324 if (lchan->encr.key_len)
325 memcpy(out, lchan->encr.key, lchan->encr.key_len);
326 return lchan->encr.key_len + 1;
327}
328
329
Harald Welte8830e072009-07-28 17:58:09 +0200330static const char *rsl_err_vals[0xff] = {
331 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
332 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
333 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
334 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
335 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
336 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welte2da86292009-08-04 02:31:05 +0200337 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Welte8830e072009-07-28 17:58:09 +0200338 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
339 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
340 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
341 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
342 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
343 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
344 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
345 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
346 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
347 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
348 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
349 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
350 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
351 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
352 [RSL_ERR_MSG_TYPE] = "Message Type Error",
353 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
354 [RSL_ERR_IE_ERROR] = "General IE error",
355 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
356 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
357 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
358 [RSL_ERR_IE_LENGTH] = "IE length error",
359 [RSL_ERR_IE_CONTENT] = "IE content error",
360 [RSL_ERR_PROTO] = "Protocol error, unspecified",
361 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
362};
363
364static const char *rsl_err_name(u_int8_t err)
Harald Welte7f93cea2009-02-23 00:02:59 +0000365{
Harald Welte8830e072009-07-28 17:58:09 +0200366 if (rsl_err_vals[err])
367 return rsl_err_vals[err];
368 else
369 return "unknown";
370}
371
372static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
373{
Harald Welte7f93cea2009-02-23 00:02:59 +0000374 int i;
375
Harald Welte8830e072009-07-28 17:58:09 +0200376 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
377 cause_v[0], rsl_err_name(cause_v[0]));
378 for (i = 1; i < cause_len-1; i++)
379 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte7f93cea2009-02-23 00:02:59 +0000380}
381
Harald Welte52b1f982008-12-23 20:25:15 +0000382/* Send a BCCH_INFO message as per Chapter 8.5.1 */
Harald Weltee79769b2009-02-07 00:48:17 +0000383int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000384 const u_int8_t *data, int len)
385{
386 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000387 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000388
389 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
390 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
391 dh->chan_nr = RSL_CHAN_BCCH;
392
393 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
394 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
395
Harald Weltee79769b2009-02-07 00:48:17 +0000396 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000397
398 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000399}
400
Harald Weltee79769b2009-02-07 00:48:17 +0000401int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
Harald Welte52b1f982008-12-23 20:25:15 +0000402 const u_int8_t *data, int len)
403{
404 struct abis_rsl_common_hdr *ch;
Harald Welte8470bf22008-12-25 23:28:35 +0000405 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000406
407 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
408 ch->msg_discr = ABIS_RSL_MDISC_TRX;
409 ch->msg_type = RSL_MT_SACCH_FILL;
410
411 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
Harald Welte702d8702008-12-26 20:25:35 +0000412 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
Harald Welte52b1f982008-12-23 20:25:15 +0000413
Harald Weltee79769b2009-02-07 00:48:17 +0000414 msg->trx = trx;
Harald Welte8470bf22008-12-25 23:28:35 +0000415
416 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000417}
418
Harald Weltefcd24452009-06-20 18:15:19 +0200419int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
420{
421 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200422 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200423 u_int8_t chan_nr = lchan2chan_nr(lchan);
424
425 db = abs(db);
426 if (db > 30)
427 return -EINVAL;
428
Harald Welteeab33352009-06-27 03:09:08 +0200429 msg = rsl_msgb_alloc();
430
Harald Weltefcd24452009-06-20 18:15:19 +0200431 lchan->bs_power = db/2;
432 if (fpc)
433 lchan->bs_power |= 0x10;
434
435 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
436 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
437 dh->chan_nr = chan_nr;
438
439 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
440
441 msg->trx = lchan->ts->trx;
442
443 return abis_rsl_sendmsg(msg);
444}
445
Harald Weltefcd24452009-06-20 18:15:19 +0200446int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
447{
448 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200449 struct msgb *msg;
Harald Weltefcd24452009-06-20 18:15:19 +0200450 u_int8_t chan_nr = lchan2chan_nr(lchan);
451 int ctl_lvl;
452
Harald Welte66b6a8d2009-08-09 14:45:18 +0200453 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Weltefcd24452009-06-20 18:15:19 +0200454 if (ctl_lvl < 0)
455 return ctl_lvl;
456
Harald Welteeab33352009-06-27 03:09:08 +0200457 msg = rsl_msgb_alloc();
458
Harald Weltefcd24452009-06-20 18:15:19 +0200459 lchan->ms_power = ctl_lvl;
460
461 if (fpc)
462 lchan->ms_power |= 0x20;
463
464 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
465 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
466 dh->chan_nr = chan_nr;
467
468 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
469
470 msg->trx = lchan->ts->trx;
471
472 return abis_rsl_sendmsg(msg);
473}
474
Harald Welte9943c5b2009-07-29 15:41:29 +0200475static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
476 struct gsm_lchan *lchan)
477{
478 memset(cm, 0, sizeof(cm));
479
480 /* FIXME: what to do with data calls ? */
481 cm->dtx_dtu = 0x00;
482
483 /* set TCH Speech/Data */
484 cm->spd_ind = lchan->rsl_cmode;
485
486 switch (lchan->type) {
487 case GSM_LCHAN_SDCCH:
488 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
489 break;
490 case GSM_LCHAN_TCH_F:
491 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
492 break;
493 case GSM_LCHAN_TCH_H:
494 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
495 break;
496 case GSM_LCHAN_NONE:
497 case GSM_LCHAN_UNKNOWN:
498 default:
499 return -EINVAL;
500 }
501
502 switch (lchan->tch_mode) {
503 case GSM48_CMODE_SIGN:
504 cm->chan_rate = 0;
505 break;
506 case GSM48_CMODE_SPEECH_V1:
507 cm->chan_rate = RSL_CMOD_SP_GSM1;
508 break;
509 case GSM48_CMODE_SPEECH_EFR:
510 cm->chan_rate = RSL_CMOD_SP_GSM2;
511 break;
512 case GSM48_CMODE_SPEECH_AMR:
513 cm->chan_rate = RSL_CMOD_SP_GSM3;
514 break;
515 case GSM48_CMODE_DATA_14k5:
516 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
517 break;
518 case GSM48_CMODE_DATA_12k0:
519 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
520 break;
521 case GSM48_CMODE_DATA_6k0:
522 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
523 break;
524 default:
525 return -EINVAL;
526 }
527
528 return 0;
529}
530
Harald Welte52b1f982008-12-23 20:25:15 +0000531/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000532#if 0
Harald Weltee79769b2009-02-07 00:48:17 +0000533int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
Harald Welte52b1f982008-12-23 20:25:15 +0000534 u_int8_t act_type,
535 struct rsl_ie_chan_mode *chan_mode,
536 struct rsl_ie_chan_ident *chan_ident,
537 u_int8_t bs_power, u_int8_t ms_power,
538 u_int8_t ta)
539{
540 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000541 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000542
543 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
544 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
545 dh->chan_nr = chan_nr;
546
547 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
548 /* For compatibility with Phase 1 */
549 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
550 (u_int8_t *) chan_mode);
551 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Harald Welte702d8702008-12-26 20:25:35 +0000552 (u_int8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000553#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000554 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
555 (u_int8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000556#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000557 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000558 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
559 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
560
Harald Weltee79769b2009-02-07 00:48:17 +0000561 msg->trx = trx;
562
Harald Welte8470bf22008-12-25 23:28:35 +0000563 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000564}
Harald Welteddab3c72009-02-28 13:19:15 +0000565#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000566
Harald Welte8f5e2392009-02-03 12:57:37 +0000567int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte9943c5b2009-07-29 15:41:29 +0200568 u_int8_t ta)
Harald Welte4b634542008-12-27 01:55:51 +0000569{
570 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200571 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200572 int rc;
Harald Welte4b634542008-12-27 01:55:51 +0000573
574 u_int8_t chan_nr = lchan2chan_nr(lchan);
575 u_int16_t arfcn = lchan->ts->trx->arfcn;
576 struct rsl_ie_chan_mode cm;
577 struct rsl_ie_chan_ident ci;
578
Harald Welte9943c5b2009-07-29 15:41:29 +0200579 rc = channel_mode_from_lchan(&cm, lchan);
580 if (rc < 0)
581 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000582
Harald Welte02b0e092009-02-28 13:11:07 +0000583 memset(&ci, 0, sizeof(ci));
Harald Welte4b634542008-12-27 01:55:51 +0000584 ci.chan_desc.iei = 0x64;
585 ci.chan_desc.chan_nr = chan_nr;
Harald Welte02b0e092009-02-28 13:11:07 +0000586 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
Harald Welte4b634542008-12-27 01:55:51 +0000587 ci.chan_desc.oct4 = arfcn & 0xff;
588
Harald Welteeab33352009-06-27 03:09:08 +0200589 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000590 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
591 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
592 dh->chan_nr = chan_nr;
593
594 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
595 /* For compatibility with Phase 1 */
596 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
597 (u_int8_t *) &cm);
598 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
599 (u_int8_t *) &ci);
Harald Welte08d91a52009-08-30 15:37:11 +0900600
601 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
602 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
603 rc = build_encr_info(encr_info, lchan);
604 if (rc > 0)
605 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
606 }
607
Harald Welted4c9bf32009-02-15 16:56:18 +0000608 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
609 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000610 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
611
Harald Weltee79769b2009-02-07 00:48:17 +0000612 msg->trx = lchan->ts->trx;
613
Harald Welte4b634542008-12-27 01:55:51 +0000614 return abis_rsl_sendmsg(msg);
615}
616
Harald Welte470abb72009-07-29 11:38:15 +0200617/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000618int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
619{
620 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200621 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200622 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000623
624 u_int8_t chan_nr = lchan2chan_nr(lchan);
625 struct rsl_ie_chan_mode cm;
626
Harald Welte9943c5b2009-07-29 15:41:29 +0200627 rc = channel_mode_from_lchan(&cm, lchan);
628 if (rc < 0)
629 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000630
Harald Welteeab33352009-06-27 03:09:08 +0200631 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000632 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
633 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
634 dh->chan_nr = chan_nr;
635
636 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
637 (u_int8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900638
639 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
640 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
641 rc = build_encr_info(encr_info, lchan);
642 if (rc > 0)
643 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
644 }
645
646 msg->trx = lchan->ts->trx;
647
648 return abis_rsl_sendmsg(msg);
649}
650
651/* Chapter 8.4.6: Send the encryption command with given L3 info */
652int rsl_encryption_cmd(struct msgb *msg)
653{
654 struct abis_rsl_dchan_hdr *dh;
655 struct gsm_lchan *lchan = msg->lchan;
656 u_int8_t chan_nr = lchan2chan_nr(lchan);
657 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut82aa6842009-09-27 11:13:18 +0200658 u_int8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900659 int rc;
660
661 /* First push the L3 IE tag and length */
662 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
663
664 /* then the link identifier (SAPI0, main sign link) */
665 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
666
667 /* then encryption information */
668 rc = build_encr_info(encr_info, lchan);
669 if (rc <= 0)
670 return rc;
671 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
672
673 /* and finally the DCHAN header */
674 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
675 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
676 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000677
678 msg->trx = lchan->ts->trx;
679
680 return abis_rsl_sendmsg(msg);
681}
682
Harald Welte115d1032009-08-10 11:43:22 +0200683/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200684int rsl_deact_sacch(struct gsm_lchan *lchan)
685{
686 struct abis_rsl_dchan_hdr *dh;
687 struct msgb *msg = rsl_msgb_alloc();
688
689 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
690 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
691 dh->chan_nr = lchan2chan_nr(lchan);
692
693 msg->lchan = lchan;
694 msg->trx = lchan->ts->trx;
695
696 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
697 gsm_ts_name(lchan->ts), dh->chan_nr);
698
699 return abis_rsl_sendmsg(msg);
700}
701
Harald Welte115d1032009-08-10 11:43:22 +0200702/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
703int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte52b1f982008-12-23 20:25:15 +0000704{
705 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000706 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000707
708 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
709 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000710 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000711
Harald Welte8470bf22008-12-25 23:28:35 +0000712 msg->lchan = lchan;
713 msg->trx = lchan->ts->trx;
714
Harald Welte115d1032009-08-10 11:43:22 +0200715 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Weltef325eb42009-02-19 17:07:39 +0000716 gsm_ts_name(lchan->ts), dh->chan_nr);
Harald Welte2d5b6382008-12-27 19:46:06 +0000717
Harald Welte115d1032009-08-10 11:43:22 +0200718 /* BTS will respond by RF CHAN REL ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000719 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000720}
721
722int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
723 u_int8_t *ms_ident, u_int8_t chan_needed)
724{
725 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000726 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000727
728 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
729 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
730 dh->chan_nr = RSL_CHAN_PCH_AGCH;
731
732 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000733 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000734 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
735
Harald Welte8470bf22008-12-25 23:28:35 +0000736 msg->trx = bts->c0;
737
738 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000739}
740
Holger Freyther7448a532009-01-04 20:18:23 +0000741int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
742 struct gsm_subscriber *subscr)
743{
Holger Freytherca362a62009-01-04 21:05:01 +0000744#if 0
Holger Freyther7448a532009-01-04 20:18:23 +0000745 u_int8_t mi[128];
746 unsigned int mi_len;
747 u_int8_t paging_group;
Holger Freytherca362a62009-01-04 21:05:01 +0000748#endif
Holger Freyther7448a532009-01-04 20:18:23 +0000749
750 return -1;
751}
752
Harald Welte52b1f982008-12-23 20:25:15 +0000753int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
754{
755 int i, len = strlen(str_in);
756
757 for (i = 0; i < len; i++) {
758 int num = str_in[i] - 0x30;
759 if (num < 0 || num > 9)
760 return -1;
761 if (i % 2 == 0)
762 bcd_out[i/2] = num;
763 else
764 bcd_out[i/2] |= (num << 4);
765 }
766
767 return 0;
768}
769
Harald Welte702d8702008-12-26 20:25:35 +0000770/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000771int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
772{
Harald Welte8470bf22008-12-25 23:28:35 +0000773 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000774 struct abis_rsl_dchan_hdr *dh;
Harald Welte362322e2009-02-15 14:36:38 +0000775 u_int8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000776
777 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
778 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
779 dh->chan_nr = RSL_CHAN_PCH_AGCH;
780
Harald Welte362322e2009-02-15 14:36:38 +0000781 switch (bts->type) {
782 case GSM_BTS_TYPE_BS11:
783 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
784 break;
785 default:
786 /* If phase 2, construct a FULL_IMM_ASS_INFO */
787 pad_macblock(buf, val, len);
788 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
789 break;
790 }
Harald Welte52b1f982008-12-23 20:25:15 +0000791
Harald Welte8470bf22008-12-25 23:28:35 +0000792 msg->trx = bts->c0;
793
794 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000795}
796
Harald Welte67fa91b2009-08-10 09:51:40 +0200797/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200798int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200799{
800 struct msgb *msg = rsl_msgb_alloc();
801 struct abis_rsl_dchan_hdr *dh;
802
803 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
804 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200805 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte67fa91b2009-08-10 09:51:40 +0200806 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte31c48932009-08-10 10:07:33 +0200807 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200808
Harald Welte3c456d02009-08-10 11:26:14 +0200809 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
810 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
811
812 msg->trx = lchan->ts->trx;
813
Harald Welte67fa91b2009-08-10 09:51:40 +0200814 return abis_rsl_sendmsg(msg);
815}
816
817
Harald Welte8470bf22008-12-25 23:28:35 +0000818/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000819/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000820int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000821{
Harald Welte8470bf22008-12-25 23:28:35 +0000822 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000823 struct abis_rsl_rll_hdr *rh;
824
Harald Welte8470bf22008-12-25 23:28:35 +0000825 if (msg->lchan == NULL) {
826 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
827 return -EINVAL;
828 }
Harald Welte52b1f982008-12-23 20:25:15 +0000829
Harald Welte8470bf22008-12-25 23:28:35 +0000830 /* First push the L3 IE tag and length */
Harald Welte4b634542008-12-27 01:55:51 +0000831 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
Harald Welte8470bf22008-12-25 23:28:35 +0000832
833 /* Then push the RSL header */
Harald Welte52b1f982008-12-23 20:25:15 +0000834 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
835 init_llm_hdr(rh, RSL_MT_DATA_REQ);
Harald Welte4a543e82009-02-28 13:17:55 +0000836 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
Harald Welte8470bf22008-12-25 23:28:35 +0000837 rh->chan_nr = lchan2chan_nr(msg->lchan);
838 rh->link_id = link_id;
Harald Welte52b1f982008-12-23 20:25:15 +0000839
Harald Welte8470bf22008-12-25 23:28:35 +0000840 msg->trx = msg->lchan->ts->trx;
841
842 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000843}
844
Harald Welteedcc5272009-08-09 13:47:35 +0200845/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
846/* Chapter 8.3.1 */
847int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
848{
849 struct msgb *msg = rsl_msgb_alloc();
850 struct abis_rsl_rll_hdr *rh;
851
852 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte1c409272009-08-09 14:13:58 +0200853 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteedcc5272009-08-09 13:47:35 +0200854 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
855 rh->chan_nr = lchan2chan_nr(lchan);
856 rh->link_id = link_id;
857
858 msg->trx = lchan->ts->trx;
859
860 return abis_rsl_sendmsg(msg);
861}
862
Harald Welted2dc1de2009-08-08 13:15:07 +0200863/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
864 This is what higher layers should call. The BTS then responds with
865 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
866 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
867 lchan_free() */
868int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
869{
870 struct msgb *msg = rsl_msgb_alloc();
871 struct abis_rsl_rll_hdr *rh;
872
873 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
874 init_llm_hdr(rh, RSL_MT_REL_REQ);
875 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
876 rh->chan_nr = lchan2chan_nr(lchan);
877 rh->link_id = link_id;
Harald Welte6c3d2ed2009-08-10 00:19:36 +0200878 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welted2dc1de2009-08-08 13:15:07 +0200879
880 msg->trx = lchan->ts->trx;
881
882 return abis_rsl_sendmsg(msg);
883}
884
Harald Welte702d8702008-12-26 20:25:35 +0000885/* Chapter 8.4.2: Channel Activate Acknowledge */
886static int rsl_rx_chan_act_ack(struct msgb *msg)
887{
888 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
889
890 /* BTS has confirmed channel activation, we now need
891 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000892 if (rslh->ie_chan != RSL_IE_CHAN_NR)
893 return -EINVAL;
894
Harald Welte4b634542008-12-27 01:55:51 +0000895 return 0;
896}
Harald Welte702d8702008-12-26 20:25:35 +0000897
Harald Welte4b634542008-12-27 01:55:51 +0000898/* Chapter 8.4.3: Channel Activate NACK */
899static int rsl_rx_chan_act_nack(struct msgb *msg)
900{
Harald Welte6dab0552009-05-01 17:21:37 +0000901 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
902 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000903
Harald Welte6dab0552009-05-01 17:21:37 +0000904 /* BTS has rejected channel activation ?!? */
905 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000906 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000907
908 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
909 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte8830e072009-07-28 17:58:09 +0200910 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
911 TLVP_LEN(&tp, RSL_IE_CAUSE));
912
Harald Welte3073a9f2009-08-09 19:50:08 +0200913 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000914 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000915}
916
Harald Welte7f93cea2009-02-23 00:02:59 +0000917/* Chapter 8.4.4: Connection Failure Indication */
918static int rsl_rx_conn_fail(struct msgb *msg)
919{
920 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
921 struct tlv_parsed tp;
922
923 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte7f93cea2009-02-23 00:02:59 +0000924
925 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
926
Harald Welte8830e072009-07-28 17:58:09 +0200927 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
928 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
929 TLVP_LEN(&tp, RSL_IE_CAUSE));
930
Holger Freytherf7b2a0e2009-06-02 02:55:17 +0000931 DEBUGPC(DRSL, "RELEASING.\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000932
933 /* FIXME: only free it after channel release ACK */
Harald Welte115d1032009-08-10 11:43:22 +0200934 return rsl_rf_chan_release(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +0000935}
936
Harald Welte440fed02009-05-01 18:43:47 +0000937static int rsl_rx_meas_res(struct msgb *msg)
938{
939 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
940 struct tlv_parsed tp;
941
Harald Welte10d0e672009-06-27 02:53:10 +0200942 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte440fed02009-05-01 18:43:47 +0000943 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
944
945 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte10d0e672009-06-27 02:53:10 +0200946 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte440fed02009-05-01 18:43:47 +0000947 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
948 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte75d34a82009-05-23 06:11:13 +0000949 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte440fed02009-05-01 18:43:47 +0000950 if (len >= 3) {
951 if (val[0] & 0x40)
Harald Welte10d0e672009-06-27 02:53:10 +0200952 DEBUGPC(DMEAS, "DTXd ");
953 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000954 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte10d0e672009-06-27 02:53:10 +0200955 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000956 val[2]>>3 & 0x7, val[2] & 0x7);
957 }
958 }
959 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte10d0e672009-06-27 02:53:10 +0200960 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte440fed02009-05-01 18:43:47 +0000961 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte10d0e672009-06-27 02:53:10 +0200962 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000963 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltefe9af262009-06-20 18:44:35 +0200964 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte86c162d2009-07-12 09:45:05 +0200965 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltefe9af262009-06-20 18:44:35 +0200966 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte10d0e672009-06-27 02:53:10 +0200967 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltefe9af262009-06-20 18:44:35 +0200968 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte10d0e672009-06-27 02:53:10 +0200969 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
970 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltefe9af262009-06-20 18:44:35 +0200971 }
Harald Weltef7c43522009-06-09 20:24:21 +0000972 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte10d0e672009-06-27 02:53:10 +0200973 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freytherddd918f2009-10-22 15:43:55 +0200974 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)daef6062009-08-14 11:41:12 +0200975 return gsm0408_rcvmsg(msg, 0);
Harald Weltef7c43522009-06-09 20:24:21 +0000976 } else
Harald Welte10d0e672009-06-27 02:53:10 +0200977 DEBUGPC(DMEAS, "\n");
Harald Welte60d68f12009-06-05 20:07:43 +0000978
Harald Welte75d34a82009-05-23 06:11:13 +0000979 return 0;
Harald Welte440fed02009-05-01 18:43:47 +0000980}
981
Harald Welte52b1f982008-12-23 20:25:15 +0000982static int abis_rsl_rx_dchan(struct msgb *msg)
983{
Harald Welte8470bf22008-12-25 23:28:35 +0000984 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
985 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +0000986 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +0000987
Harald Welte8470bf22008-12-25 23:28:35 +0000988 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +0000989 ts_name = gsm_ts_name(msg->lchan->ts);
990
Harald Welte10d0e672009-06-27 02:53:10 +0200991 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
992 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +0000993
994 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +0000995 case RSL_MT_CHAN_ACTIV_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +0000996 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
Harald Welte4b634542008-12-27 01:55:51 +0000997 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +0000998 break;
Harald Welte52b1f982008-12-23 20:25:15 +0000999 case RSL_MT_CHAN_ACTIV_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001000 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001001 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001002 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001003 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001004 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001005 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001006 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001007 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001008 break;
1009 case RSL_MT_RF_CHAN_REL_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001010 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
Harald Welte2d5b6382008-12-27 19:46:06 +00001011 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001012 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001013 case RSL_MT_MODE_MODIFY_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001014 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001015 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001016 case RSL_MT_MODE_MODIFY_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001017 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001018 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001019 case RSL_MT_PHY_CONTEXT_CONF:
1020 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001021 case RSL_MT_TALKER_DET:
1022 case RSL_MT_LISTENER_DET:
1023 case RSL_MT_REMOTE_CODEC_CONF_REP:
1024 case RSL_MT_MR_CODEC_MOD_ACK:
1025 case RSL_MT_MR_CODEC_MOD_NACK:
1026 case RSL_MT_MR_CODEC_MOD_PER:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001027 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001028 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001029 break;
1030 default:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001031 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001032 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001033 return -EINVAL;
1034 }
Harald Weltef325eb42009-02-19 17:07:39 +00001035
Harald Welte8470bf22008-12-25 23:28:35 +00001036 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001037}
1038
Harald Welte702d8702008-12-26 20:25:35 +00001039static int rsl_rx_error_rep(struct msgb *msg)
1040{
1041 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001042 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001043
Harald Welte7f93cea2009-02-23 00:02:59 +00001044 DEBUGP(DRSL, "ERROR REPORT ");
Harald Welte8830e072009-07-28 17:58:09 +02001045
1046 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1047
1048 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1049 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1050 TLVP_LEN(&tp, RSL_IE_CAUSE));
1051
Holger Freyther79f4ae62009-06-02 03:25:04 +00001052 DEBUGPC(DRSL, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001053
1054 return 0;
1055}
1056
Harald Welte52b1f982008-12-23 20:25:15 +00001057static int abis_rsl_rx_trx(struct msgb *msg)
1058{
Harald Welte702d8702008-12-26 20:25:35 +00001059 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001060 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001061
1062 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001063 case RSL_MT_ERROR_REPORT:
1064 rc = rsl_rx_error_rep(msg);
1065 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001066 case RSL_MT_RF_RES_IND:
1067 /* interference on idle channels of TRX */
Harald Welte3cf7c3f2009-05-01 18:28:00 +00001068 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
Harald Welte8f5e2392009-02-03 12:57:37 +00001069 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001070 case RSL_MT_OVERLOAD:
1071 /* indicate CCCH / ACCH / processor overload */
Harald Weltef325eb42009-02-19 17:07:39 +00001072 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
Harald Welte52b1f982008-12-23 20:25:15 +00001073 break;
1074 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001075 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001076 rslh->msg_type);
1077 return -EINVAL;
1078 }
Harald Welte8470bf22008-12-25 23:28:35 +00001079 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001080}
1081
Harald Welteb7e81162009-08-10 00:26:10 +02001082/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1083static void t3101_expired(void *data)
1084{
1085 struct gsm_lchan *lchan = data;
1086
Harald Welte115d1032009-08-10 11:43:22 +02001087 rsl_rf_chan_release(lchan);
Harald Welteb7e81162009-08-10 00:26:10 +02001088}
1089
Harald Welte8470bf22008-12-25 23:28:35 +00001090/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001091static int rsl_rx_chan_rqd(struct msgb *msg)
1092{
Harald Welte702d8702008-12-26 20:25:35 +00001093 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001094 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1095 struct gsm48_req_ref *rqd_ref;
Harald Welte52b1f982008-12-23 20:25:15 +00001096 struct gsm48_imm_ass ia;
Harald Welte8470bf22008-12-25 23:28:35 +00001097 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001098 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001099 struct gsm_lchan *lchan;
1100 u_int8_t rqd_ta;
Holger Freyther3186bf22008-12-29 06:23:49 +00001101 int ret;
Harald Welte8470bf22008-12-25 23:28:35 +00001102
Harald Welte52b1f982008-12-23 20:25:15 +00001103 u_int16_t arfcn;
1104 u_int8_t ts_number, subch;
1105
Harald Welte8470bf22008-12-25 23:28:35 +00001106 /* parse request reference to be used in immediate assign */
1107 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1108 return -EINVAL;
1109
1110 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1111
1112 /* parse access delay and use as TA */
1113 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1114 return -EINVAL;
1115 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1116
1117 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1118 * request reference RA */
1119 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
Harald Welte2cbe0922008-12-29 04:09:31 +00001120 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1121
Harald Welte8470bf22008-12-25 23:28:35 +00001122 /* check availability / allocate channel */
1123 lchan = lchan_alloc(bts, lctype);
1124 if (!lchan) {
1125 fprintf(stderr, "CHAN RQD: no resources\n");
1126 /* FIXME: send some kind of reject ?!? */
1127 return -ENOMEM;
1128 }
1129
1130 ts_number = lchan->ts->nr;
1131 arfcn = lchan->ts->trx->arfcn;
1132 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001133
Harald Welte08d91a52009-08-30 15:37:11 +09001134 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001135 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001136 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001137 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001138 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte9943c5b2009-07-29 15:41:29 +02001139 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte52b1f982008-12-23 20:25:15 +00001140
1141 /* create IMMEDIATE ASSIGN 04.08 messge */
1142 memset(&ia, 0, sizeof(ia));
1143 ia.l2_plen = 0x2d;
1144 ia.proto_discr = GSM48_PDISC_RR;
1145 ia.msg_type = GSM48_MT_RR_IMM_ASS;
Harald Welte2d5b6382008-12-27 19:46:06 +00001146 ia.page_mode = GSM48_PM_SAME;
Harald Welte4b634542008-12-27 01:55:51 +00001147 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +00001148 ia.chan_desc.h0.h = 0;
1149 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1150 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte814c4b72009-07-21 20:55:56 +02001151 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte8470bf22008-12-25 23:28:35 +00001152 /* use request reference extracted from CHAN_RQD */
1153 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1154 ia.timing_advance = rqd_ta;
Harald Welte52b1f982008-12-23 20:25:15 +00001155 ia.mob_alloc_len = 0;
1156
Harald Welte8f5e2392009-02-03 12:57:37 +00001157 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
Holger Freyther79f4ae62009-06-02 03:25:04 +00001158 "chan_nr=0x%02x r=%s ra=0x%02x\n",
Harald Welteca64da92009-01-04 16:54:12 +00001159 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
Harald Welte4a543e82009-02-28 13:17:55 +00001160 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1161 rqd_ref->ra);
Harald Welte75a983f2008-12-27 21:34:06 +00001162
Harald Welteb7e81162009-08-10 00:26:10 +02001163 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1164 lchan->T3101.cb = t3101_expired;
1165 lchan->T3101.data = lchan;
1166 bsc_schedule_timer(&lchan->T3101, 10, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001167
Harald Welte52b1f982008-12-23 20:25:15 +00001168 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Freyther3186bf22008-12-29 06:23:49 +00001169 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1170
Harald Welte817f3c82008-12-30 14:57:59 +00001171 return ret;
Harald Welte52b1f982008-12-23 20:25:15 +00001172}
1173
Harald Welteea280442009-02-02 22:29:56 +00001174/* MS has requested a channel on the RACH */
1175static int rsl_rx_ccch_load(struct msgb *msg)
1176{
1177 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1178 u_int16_t pg_buf_space;
Holger Freyther8c563cf2009-02-03 20:08:51 +00001179 u_int16_t rach_slot_count = -1;
1180 u_int16_t rach_busy_count = -1;
1181 u_int16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001182
1183 switch (rslh->data[0]) {
1184 case RSL_IE_PAGING_LOAD:
1185 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Holger Freyther392209c2009-02-10 00:06:19 +00001186 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001187 break;
1188 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001189 if (msg->data_len >= 7) {
1190 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1191 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1192 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1193 }
Harald Welteea280442009-02-02 22:29:56 +00001194 break;
1195 default:
1196 break;
1197 }
1198
1199 return 0;
1200}
1201
Harald Welte52b1f982008-12-23 20:25:15 +00001202static int abis_rsl_rx_cchan(struct msgb *msg)
1203{
Harald Welteea280442009-02-02 22:29:56 +00001204 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001205 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001206
Harald Welte8470bf22008-12-25 23:28:35 +00001207 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1208
1209 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001210 case RSL_MT_CHAN_RQD:
1211 /* MS has requested a channel on the RACH */
1212 rc = rsl_rx_chan_rqd(msg);
1213 break;
Harald Welteea280442009-02-02 22:29:56 +00001214 case RSL_MT_CCCH_LOAD_IND:
1215 /* current load on the CCCH */
1216 rc = rsl_rx_ccch_load(msg);
1217 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001218 case RSL_MT_DELETE_IND:
1219 /* CCCH overloaded, IMM_ASSIGN was dropped */
1220 case RSL_MT_CBCH_LOAD_IND:
1221 /* current load on the CBCH */
Harald Welte8f5e2392009-02-03 12:57:37 +00001222 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1223 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001224 break;
1225 default:
1226 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001227 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001228 return -EINVAL;
1229 }
Harald Welte8470bf22008-12-25 23:28:35 +00001230
1231 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001232}
1233
Harald Welte4b634542008-12-27 01:55:51 +00001234static int rsl_rx_rll_err_ind(struct msgb *msg)
1235{
1236 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1237 u_int8_t *rlm_cause = rllh->data;
1238
Harald Welte602f2b82009-08-04 02:50:21 +02001239 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteedcc5272009-08-09 13:47:35 +02001240
1241 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte4b634542008-12-27 01:55:51 +00001242
Harald Welte81543bc2009-07-04 09:40:05 +02001243 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte115d1032009-08-10 11:43:22 +02001244 return rsl_rf_chan_release(msg->lchan);
Harald Welte81543bc2009-07-04 09:40:05 +02001245
Harald Welte4b634542008-12-27 01:55:51 +00001246 return 0;
1247}
Harald Weltef325eb42009-02-19 17:07:39 +00001248
Harald Welte52b1f982008-12-23 20:25:15 +00001249/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1250 0x02, 0x06,
1251 0x01, 0x20,
1252 0x02, 0x00,
1253 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1254
1255static int abis_rsl_rx_rll(struct msgb *msg)
1256{
1257 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001258 int rc = 0;
1259 char *ts_name;
Harald Welte (local)daef6062009-08-14 11:41:12 +02001260 u_int8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001261
1262 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001263 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)daef6062009-08-14 11:41:12 +02001264 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1265 rllh->chan_nr, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001266
1267 switch (rllh->c.msg_type) {
1268 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001269 DEBUGPC(DRLL, "DATA INDICATION\n");
Harald Welte4a543e82009-02-28 13:17:55 +00001270 if (msgb_l2len(msg) >
1271 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1272 rllh->data[0] == RSL_IE_L3_INFO) {
1273 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001274 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001275 }
Harald Welte52b1f982008-12-23 20:25:15 +00001276 break;
1277 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001278 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001279 /* lchan is established, stop T3101 */
1280 bsc_del_timer(&msg->lchan->T3101);
Harald Welte4a543e82009-02-28 13:17:55 +00001281 if (msgb_l2len(msg) >
1282 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1283 rllh->data[0] == RSL_IE_L3_INFO) {
1284 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001285 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001286 }
Harald Welte52b1f982008-12-23 20:25:15 +00001287 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001288 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001289 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Harald Welteedcc5272009-08-09 13:47:35 +02001290 rll_indication(msg->lchan, rllh->link_id,
1291 BSC_RLLR_IND_EST_CONF);
1292 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001293 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001294 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001295 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteedcc5272009-08-09 13:47:35 +02001296 rll_indication(msg->lchan, rllh->link_id,
1297 BSC_RLLR_IND_REL_IND);
Harald Welted2dc1de2009-08-08 13:15:07 +02001298 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001299 /* FIXME: officially we need to start T3111 and wait for
1300 * some grace period */
1301 rsl_rf_chan_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001302 break;
1303 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001304 /* BTS informs us of having received UA from MS,
1305 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001306 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welted2dc1de2009-08-08 13:15:07 +02001307 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001308 /* FIXME: officially we need to start T3111 and wait for
1309 * some grace period */
1310 rsl_rf_chan_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001311 break;
1312 case RSL_MT_ERROR_IND:
1313 rc = rsl_rx_rll_err_ind(msg);
1314 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001315 case RSL_MT_UNIT_DATA_IND:
Harald Welte602f2b82009-08-04 02:50:21 +02001316 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001317 rllh->c.msg_type);
1318 break;
1319 default:
Harald Welte602f2b82009-08-04 02:50:21 +02001320 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001321 rllh->c.msg_type);
1322 }
Harald Welte8470bf22008-12-25 23:28:35 +00001323 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001324}
1325
Harald Weltef4e79f22009-07-28 18:11:56 +02001326static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1327{
Harald Weltef4e79f22009-07-28 18:11:56 +02001328 switch (tch_mode) {
1329 case GSM48_CMODE_SPEECH_V1:
1330 return 0x00;
1331 case GSM48_CMODE_SPEECH_EFR:
1332 return 0x01;
1333 case GSM48_CMODE_SPEECH_AMR:
1334 return 0x02;
1335 /* FIXME: Type1 half-rate and type3 half-rate */
1336 }
Harald Welte58ca5b72009-07-29 12:12:18 +02001337 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1338 "tch_mode == 0x%02x\n", tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001339 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001340}
1341
Harald Welte75099262009-02-16 21:12:08 +00001342/* ip.access specific RSL extensions */
1343int rsl_ipacc_bind(struct gsm_lchan *lchan)
1344{
1345 struct msgb *msg = rsl_msgb_alloc();
1346 struct abis_rsl_dchan_hdr *dh;
Harald Welte58ca5b72009-07-29 12:12:18 +02001347 u_int8_t speech_mode;
Harald Welte75099262009-02-16 21:12:08 +00001348
1349 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1350 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1351 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1352 dh->chan_nr = lchan2chan_nr(lchan);
1353
Harald Weltef4e79f22009-07-28 18:11:56 +02001354 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte58ca5b72009-07-29 12:12:18 +02001355 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1356 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001357
Harald Welte58ca5b72009-07-29 12:12:18 +02001358 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1359 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1360 dh->chan_nr, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001361
Harald Welte75099262009-02-16 21:12:08 +00001362 msg->trx = lchan->ts->trx;
1363
1364 return abis_rsl_sendmsg(msg);
1365}
1366
Harald Welte20855542009-07-12 09:50:35 +02001367int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1368 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001369{
1370 struct msgb *msg = rsl_msgb_alloc();
1371 struct abis_rsl_dchan_hdr *dh;
1372 u_int8_t *att_f8, *att_ip, *att_port;
Harald Welte58ca5b72009-07-29 12:12:18 +02001373 u_int8_t speech_mode;
Harald Weltef4e79f22009-07-28 18:11:56 +02001374 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001375
1376 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1377 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1378 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1379 dh->chan_nr = lchan2chan_nr(lchan);
1380
Harald Welte58ca5b72009-07-29 12:12:18 +02001381 /* 0x0- == both directions, 0x-1 == EFR codec */
1382 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1383
Harald Weltef4e79f22009-07-28 18:11:56 +02001384 ia.s_addr = htonl(ip);
Harald Welte58ca5b72009-07-29 12:12:18 +02001385 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1386 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Weltef4e79f22009-07-28 18:11:56 +02001387 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Welte58ca5b72009-07-29 12:12:18 +02001388 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001389
Harald Welte20855542009-07-12 09:50:35 +02001390 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welte86c162d2009-07-12 09:45:05 +02001391 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte20855542009-07-12 09:50:35 +02001392 att_f8[1] = conn_id >> 8;
1393 att_f8[2] = conn_id & 0xff;
Harald Welte75099262009-02-16 21:12:08 +00001394
1395 att_ip = msgb_put(msg, sizeof(ip)+1);
1396 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1397 att_ip[1] = ip >> 24;
1398 att_ip[2] = ip >> 16;
1399 att_ip[3] = ip >> 8;
1400 att_ip[4] = ip & 0xff;
Harald Welteda783762009-02-18 03:29:53 +00001401 //att_ip[4] = 11;
Harald Welte75099262009-02-16 21:12:08 +00001402
1403 att_port = msgb_put(msg, sizeof(port)+1);
1404 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1405 att_port[1] = port >> 8;
1406 att_port[2] = port & 0xff;
1407
Harald Welte58ca5b72009-07-29 12:12:18 +02001408 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001409 if (rtp_payload2)
1410 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1411
Harald Welte75099262009-02-16 21:12:08 +00001412 msg->trx = lchan->ts->trx;
1413
1414 return abis_rsl_sendmsg(msg);
1415}
1416
1417static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1418{
1419 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1420 struct tlv_parsed tv;
1421 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
Harald Welte167df882009-02-17 14:35:45 +00001422 struct in_addr ip;
Harald Welte75099262009-02-16 21:12:08 +00001423 u_int16_t port, attr_f8;
1424
1425 /* the BTS has acknowledged a local bind, it now tells us the IP
1426 * address and port number to which it has bound the given logical
1427 * channel */
1428
1429 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1430 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1431 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001432 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltef325eb42009-02-19 17:07:39 +00001433 DEBUGPC(DRSL, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001434 return -EINVAL;
1435 }
Harald Welte167df882009-02-17 14:35:45 +00001436 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte75099262009-02-16 21:12:08 +00001437 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1438 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1439
Harald Weltef4e79f22009-07-28 18:11:56 +02001440 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1441 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1442
1443 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1444 ts->abis_ip.rtp_payload2 =
1445 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1446 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1447 ts->abis_ip.rtp_payload2);
1448 }
Harald Welte167df882009-02-17 14:35:45 +00001449
Harald Welte75099262009-02-16 21:12:08 +00001450 /* update our local information about this TS */
Harald Welte167df882009-02-17 14:35:45 +00001451 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1452 ts->abis_ip.bound_port = ntohs(port);
Harald Welte20855542009-07-12 09:50:35 +02001453 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte75099262009-02-16 21:12:08 +00001454
Harald Welte167df882009-02-17 14:35:45 +00001455 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1456
Harald Welte75099262009-02-16 21:12:08 +00001457 return 0;
1458}
1459
1460static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1461{
1462 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1463 struct tlv_parsed tv;
1464
1465 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001466
Harald Welte8830e072009-07-28 17:58:09 +02001467 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1468 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1469 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001470
Harald Welte888b1142009-07-28 18:02:05 +02001471 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1472
Harald Welte75099262009-02-16 21:12:08 +00001473 return 0;
1474}
1475
1476static int abis_rsl_rx_ipacc(struct msgb *msg)
1477{
1478 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1479 int rc = 0;
1480
1481 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001482 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1483 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
Harald Welte75099262009-02-16 21:12:08 +00001484
1485 switch (rllh->c.msg_type) {
1486 case RSL_MT_IPAC_BIND_ACK:
Harald Welte4a543e82009-02-28 13:17:55 +00001487 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001488 rc = abis_rsl_rx_ipacc_bindack(msg);
1489 break;
1490 case RSL_MT_IPAC_BIND_NACK:
1491 /* somehow the BTS was unable to bind the lchan to its local
1492 * port?!? */
Harald Weltef325eb42009-02-19 17:07:39 +00001493 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001494 break;
1495 case RSL_MT_IPAC_CONNECT_ACK:
1496 /* the BTS tells us that a connect operation was successful */
Harald Weltef325eb42009-02-19 17:07:39 +00001497 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001498 break;
1499 case RSL_MT_IPAC_CONNECT_NACK:
1500 /* somehow the BTS was unable to connect the lchan to a remote
1501 * port */
Harald Weltef325eb42009-02-19 17:07:39 +00001502 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001503 break;
1504 case RSL_MT_IPAC_DISCONNECT_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001505 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
Harald Welte75099262009-02-16 21:12:08 +00001506 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1507 break;
1508 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001509 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001510 break;
1511 }
Harald Welte6dab0552009-05-01 17:21:37 +00001512 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001513
1514 return rc;
1515}
1516
1517
Harald Welte52b1f982008-12-23 20:25:15 +00001518/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001519int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001520{
1521 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
Harald Welte8f5e2392009-02-03 12:57:37 +00001522 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001523
1524 switch (rslh->msg_discr & 0xfe) {
1525 case ABIS_RSL_MDISC_RLL:
1526 rc = abis_rsl_rx_rll(msg);
1527 break;
1528 case ABIS_RSL_MDISC_DED_CHAN:
1529 rc = abis_rsl_rx_dchan(msg);
1530 break;
1531 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001532 rc = abis_rsl_rx_cchan(msg);
1533 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001534 case ABIS_RSL_MDISC_TRX:
1535 rc = abis_rsl_rx_trx(msg);
1536 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001537 case ABIS_RSL_MDISC_LOC:
Harald Welte8f5e2392009-02-03 12:57:37 +00001538 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1539 rslh->msg_discr);
1540 break;
Harald Welte75099262009-02-16 21:12:08 +00001541 case ABIS_RSL_MDISC_IPACCESS:
1542 rc = abis_rsl_rx_ipacc(msg);
1543 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001544 default:
1545 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1546 rslh->msg_discr);
1547 return -EINVAL;
1548 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001549 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001550 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001551}
Holger Freyther3b72a892009-02-04 00:31:39 +00001552
1553
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001554/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Holger Freyther3b72a892009-02-04 00:31:39 +00001555int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1556{
1557 switch (ccch_conf) {
1558 case RSL_BCCH_CCCH_CONF_1_NC:
1559 return 1;
1560 case RSL_BCCH_CCCH_CONF_1_C:
1561 return 1;
1562 case RSL_BCCH_CCCH_CONF_2_NC:
1563 return 2;
1564 case RSL_BCCH_CCCH_CONF_3_NC:
1565 return 3;
1566 case RSL_BCCH_CCCH_CONF_4_NC:
1567 return 4;
1568 default:
1569 return -1;
1570 }
1571}
1572
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001573/* Section 3.3.2.3 TS 05.02 */
Holger Freyther3b72a892009-02-04 00:31:39 +00001574int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1575{
1576 switch (ccch_conf) {
1577 case RSL_BCCH_CCCH_CONF_1_NC:
1578 return 0;
1579 case RSL_BCCH_CCCH_CONF_1_C:
1580 return 1;
1581 case RSL_BCCH_CCCH_CONF_2_NC:
1582 return 0;
1583 case RSL_BCCH_CCCH_CONF_3_NC:
1584 return 0;
1585 case RSL_BCCH_CCCH_CONF_4_NC:
1586 return 0;
1587 default:
1588 return -1;
1589 }
1590}
1591
1592/* From Table 10.5.33 of GSM 04.08 */
1593int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1594{
1595 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1596 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001597 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001598 } else {
1599 return (9 - bts->chan_desc.bs_ag_blks_res)
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001600 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001601 }
1602}