blob: 219b01aa02623d9c3e1aede485e184809128a6c8 [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
Harald Welte1a79d362009-11-27 08:55:16 +0100491 if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN &&
492 lchan->tch_mode != GSM48_CMODE_SIGN)
493 DEBUGP(DRSL, "unsupported: rsl_mode == signalling, "
494 "but tch_mode != signalling\n");
495
Harald Welte9943c5b2009-07-29 15:41:29 +0200496 switch (lchan->type) {
497 case GSM_LCHAN_SDCCH:
498 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
499 break;
500 case GSM_LCHAN_TCH_F:
501 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
502 break;
503 case GSM_LCHAN_TCH_H:
504 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
505 break;
506 case GSM_LCHAN_NONE:
507 case GSM_LCHAN_UNKNOWN:
508 default:
509 return -EINVAL;
510 }
511
512 switch (lchan->tch_mode) {
513 case GSM48_CMODE_SIGN:
514 cm->chan_rate = 0;
515 break;
516 case GSM48_CMODE_SPEECH_V1:
517 cm->chan_rate = RSL_CMOD_SP_GSM1;
518 break;
519 case GSM48_CMODE_SPEECH_EFR:
520 cm->chan_rate = RSL_CMOD_SP_GSM2;
521 break;
522 case GSM48_CMODE_SPEECH_AMR:
523 cm->chan_rate = RSL_CMOD_SP_GSM3;
524 break;
525 case GSM48_CMODE_DATA_14k5:
526 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
527 break;
528 case GSM48_CMODE_DATA_12k0:
529 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
530 break;
531 case GSM48_CMODE_DATA_6k0:
532 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
533 break;
534 default:
535 return -EINVAL;
536 }
537
538 return 0;
539}
540
Harald Welte52b1f982008-12-23 20:25:15 +0000541/* Chapter 8.4.1 */
Harald Welteddab3c72009-02-28 13:19:15 +0000542#if 0
Harald Weltee79769b2009-02-07 00:48:17 +0000543int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
Harald Welte52b1f982008-12-23 20:25:15 +0000544 u_int8_t act_type,
545 struct rsl_ie_chan_mode *chan_mode,
546 struct rsl_ie_chan_ident *chan_ident,
547 u_int8_t bs_power, u_int8_t ms_power,
548 u_int8_t ta)
549{
550 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000551 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000552
553 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
554 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
555 dh->chan_nr = chan_nr;
556
557 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
558 /* For compatibility with Phase 1 */
559 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
560 (u_int8_t *) chan_mode);
561 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
Harald Welte702d8702008-12-26 20:25:35 +0000562 (u_int8_t *) chan_ident);
Harald Welte702d8702008-12-26 20:25:35 +0000563#if 0
Harald Welte52b1f982008-12-23 20:25:15 +0000564 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
565 (u_int8_t *) &encr_info);
Harald Welte702d8702008-12-26 20:25:35 +0000566#endif
Harald Welted4c9bf32009-02-15 16:56:18 +0000567 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
Harald Welte52b1f982008-12-23 20:25:15 +0000568 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
569 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
570
Harald Weltee79769b2009-02-07 00:48:17 +0000571 msg->trx = trx;
572
Harald Welte8470bf22008-12-25 23:28:35 +0000573 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000574}
Harald Welteddab3c72009-02-28 13:19:15 +0000575#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000576
Harald Welte8f5e2392009-02-03 12:57:37 +0000577int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte9943c5b2009-07-29 15:41:29 +0200578 u_int8_t ta)
Harald Welte4b634542008-12-27 01:55:51 +0000579{
580 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200581 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200582 int rc;
Harald Welte4b634542008-12-27 01:55:51 +0000583
584 u_int8_t chan_nr = lchan2chan_nr(lchan);
585 u_int16_t arfcn = lchan->ts->trx->arfcn;
586 struct rsl_ie_chan_mode cm;
587 struct rsl_ie_chan_ident ci;
588
Harald Welte9943c5b2009-07-29 15:41:29 +0200589 rc = channel_mode_from_lchan(&cm, lchan);
590 if (rc < 0)
591 return rc;
Harald Welte4b634542008-12-27 01:55:51 +0000592
Harald Welte02b0e092009-02-28 13:11:07 +0000593 memset(&ci, 0, sizeof(ci));
Harald Welte4b634542008-12-27 01:55:51 +0000594 ci.chan_desc.iei = 0x64;
595 ci.chan_desc.chan_nr = chan_nr;
Harald Welte02b0e092009-02-28 13:11:07 +0000596 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
Harald Welte4b634542008-12-27 01:55:51 +0000597 ci.chan_desc.oct4 = arfcn & 0xff;
598
Harald Welteeab33352009-06-27 03:09:08 +0200599 msg = rsl_msgb_alloc();
Harald Welte4b634542008-12-27 01:55:51 +0000600 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
601 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
602 dh->chan_nr = chan_nr;
603
604 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
605 /* For compatibility with Phase 1 */
606 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
607 (u_int8_t *) &cm);
608 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
609 (u_int8_t *) &ci);
Harald Welte08d91a52009-08-30 15:37:11 +0900610
611 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
612 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
613 rc = build_encr_info(encr_info, lchan);
614 if (rc > 0)
615 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
616 }
617
Harald Welted4c9bf32009-02-15 16:56:18 +0000618 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
619 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
Harald Welte4b634542008-12-27 01:55:51 +0000620 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
621
Harald Weltee79769b2009-02-07 00:48:17 +0000622 msg->trx = lchan->ts->trx;
623
Harald Welte4b634542008-12-27 01:55:51 +0000624 return abis_rsl_sendmsg(msg);
625}
626
Harald Welte470abb72009-07-29 11:38:15 +0200627/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welteda783762009-02-18 03:29:53 +0000628int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
629{
630 struct abis_rsl_dchan_hdr *dh;
Harald Welteeab33352009-06-27 03:09:08 +0200631 struct msgb *msg;
Harald Welte9943c5b2009-07-29 15:41:29 +0200632 int rc;
Harald Welteda783762009-02-18 03:29:53 +0000633
634 u_int8_t chan_nr = lchan2chan_nr(lchan);
635 struct rsl_ie_chan_mode cm;
636
Harald Welte9943c5b2009-07-29 15:41:29 +0200637 rc = channel_mode_from_lchan(&cm, lchan);
638 if (rc < 0)
639 return rc;
Harald Welteda783762009-02-18 03:29:53 +0000640
Harald Welteeab33352009-06-27 03:09:08 +0200641 msg = rsl_msgb_alloc();
Harald Welteda783762009-02-18 03:29:53 +0000642 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
643 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
644 dh->chan_nr = chan_nr;
645
646 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
647 (u_int8_t *) &cm);
Harald Welte08d91a52009-08-30 15:37:11 +0900648
649 if (lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
650 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
651 rc = build_encr_info(encr_info, lchan);
652 if (rc > 0)
653 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
654 }
655
Holger Hans Peter Freytherea528022009-11-18 22:57:02 +0100656 if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
657 msgb_tlv_put(msg, RSL_IE_MR_CONFIG, sizeof(lchan->mr_conf),
658 (u_int8_t *) &lchan->mr_conf);
659 }
660
Harald Welte08d91a52009-08-30 15:37:11 +0900661 msg->trx = lchan->ts->trx;
662
663 return abis_rsl_sendmsg(msg);
664}
665
666/* Chapter 8.4.6: Send the encryption command with given L3 info */
667int rsl_encryption_cmd(struct msgb *msg)
668{
669 struct abis_rsl_dchan_hdr *dh;
670 struct gsm_lchan *lchan = msg->lchan;
671 u_int8_t chan_nr = lchan2chan_nr(lchan);
672 u_int8_t encr_info[MAX_A5_KEY_LEN+2];
Sylvain Munaut82aa6842009-09-27 11:13:18 +0200673 u_int8_t l3_len = msg->len;
Harald Welte08d91a52009-08-30 15:37:11 +0900674 int rc;
675
676 /* First push the L3 IE tag and length */
677 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
678
679 /* then the link identifier (SAPI0, main sign link) */
680 msgb_tv_push(msg, RSL_IE_LINK_IDENT, 0);
681
682 /* then encryption information */
683 rc = build_encr_info(encr_info, lchan);
684 if (rc <= 0)
685 return rc;
686 msgb_tlv_push(msg, RSL_IE_ENCR_INFO, rc, encr_info);
687
688 /* and finally the DCHAN header */
689 dh = (struct abis_rsl_dchan_hdr *) msgb_push(msg, sizeof(*dh));
690 init_dchan_hdr(dh, RSL_MT_ENCR_CMD);
691 dh->chan_nr = chan_nr;
Harald Welteda783762009-02-18 03:29:53 +0000692
693 msg->trx = lchan->ts->trx;
694
695 return abis_rsl_sendmsg(msg);
696}
697
Harald Welte115d1032009-08-10 11:43:22 +0200698/* Chapter 8.4.5 / 4.6: Deactivate the SACCH after 04.08 RR CHAN RELEASE */
Harald Welteae0f2362009-07-19 18:36:49 +0200699int rsl_deact_sacch(struct gsm_lchan *lchan)
700{
701 struct abis_rsl_dchan_hdr *dh;
702 struct msgb *msg = rsl_msgb_alloc();
703
704 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
705 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
706 dh->chan_nr = lchan2chan_nr(lchan);
707
708 msg->lchan = lchan;
709 msg->trx = lchan->ts->trx;
710
711 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
712 gsm_ts_name(lchan->ts), dh->chan_nr);
713
714 return abis_rsl_sendmsg(msg);
715}
716
Harald Welte115d1032009-08-10 11:43:22 +0200717/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
718int rsl_rf_chan_release(struct gsm_lchan *lchan)
Harald Welte52b1f982008-12-23 20:25:15 +0000719{
720 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000721 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000722
723 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
724 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
Harald Welte8470bf22008-12-25 23:28:35 +0000725 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +0000726
Harald Welte8470bf22008-12-25 23:28:35 +0000727 msg->lchan = lchan;
728 msg->trx = lchan->ts->trx;
729
Harald Welte115d1032009-08-10 11:43:22 +0200730 DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
Harald Weltef325eb42009-02-19 17:07:39 +0000731 gsm_ts_name(lchan->ts), dh->chan_nr);
Harald Welte2d5b6382008-12-27 19:46:06 +0000732
Harald Welte115d1032009-08-10 11:43:22 +0200733 /* BTS will respond by RF CHAN REL ACK */
Harald Welte8470bf22008-12-25 23:28:35 +0000734 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000735}
736
737int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
738 u_int8_t *ms_ident, u_int8_t chan_needed)
739{
740 struct abis_rsl_dchan_hdr *dh;
Harald Welte8470bf22008-12-25 23:28:35 +0000741 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000742
743 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
744 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
745 dh->chan_nr = RSL_CHAN_PCH_AGCH;
746
747 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
Harald Welte255539c2008-12-28 02:26:27 +0000748 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
Harald Welte52b1f982008-12-23 20:25:15 +0000749 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
750
Harald Welte8470bf22008-12-25 23:28:35 +0000751 msg->trx = bts->c0;
752
753 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000754}
755
Holger Freyther7448a532009-01-04 20:18:23 +0000756int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
757 struct gsm_subscriber *subscr)
758{
Holger Freytherca362a62009-01-04 21:05:01 +0000759#if 0
Holger Freyther7448a532009-01-04 20:18:23 +0000760 u_int8_t mi[128];
761 unsigned int mi_len;
762 u_int8_t paging_group;
Holger Freytherca362a62009-01-04 21:05:01 +0000763#endif
Holger Freyther7448a532009-01-04 20:18:23 +0000764
765 return -1;
766}
767
Harald Welte52b1f982008-12-23 20:25:15 +0000768int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
769{
770 int i, len = strlen(str_in);
771
772 for (i = 0; i < len; i++) {
773 int num = str_in[i] - 0x30;
774 if (num < 0 || num > 9)
775 return -1;
776 if (i % 2 == 0)
777 bcd_out[i/2] = num;
778 else
779 bcd_out[i/2] |= (num << 4);
780 }
781
782 return 0;
783}
784
Harald Welte702d8702008-12-26 20:25:35 +0000785/* Chapter 8.5.6 */
Harald Welte52b1f982008-12-23 20:25:15 +0000786int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
787{
Harald Welte8470bf22008-12-25 23:28:35 +0000788 struct msgb *msg = rsl_msgb_alloc();
Harald Welte52b1f982008-12-23 20:25:15 +0000789 struct abis_rsl_dchan_hdr *dh;
Harald Welte362322e2009-02-15 14:36:38 +0000790 u_int8_t buf[MACBLOCK_SIZE];
Harald Welte52b1f982008-12-23 20:25:15 +0000791
792 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
793 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
794 dh->chan_nr = RSL_CHAN_PCH_AGCH;
795
Harald Welte362322e2009-02-15 14:36:38 +0000796 switch (bts->type) {
797 case GSM_BTS_TYPE_BS11:
798 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
799 break;
800 default:
801 /* If phase 2, construct a FULL_IMM_ASS_INFO */
802 pad_macblock(buf, val, len);
803 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
804 break;
805 }
Harald Welte52b1f982008-12-23 20:25:15 +0000806
Harald Welte8470bf22008-12-25 23:28:35 +0000807 msg->trx = bts->c0;
808
809 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000810}
811
Harald Welte67fa91b2009-08-10 09:51:40 +0200812/* Send Siemens specific MS RF Power Capability Indication */
Harald Welte31c48932009-08-10 10:07:33 +0200813int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
Harald Welte67fa91b2009-08-10 09:51:40 +0200814{
815 struct msgb *msg = rsl_msgb_alloc();
816 struct abis_rsl_dchan_hdr *dh;
817
818 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
819 init_dchan_hdr(dh, RSL_MT_SIEMENS_MRPCI);
Harald Welte3c456d02009-08-10 11:26:14 +0200820 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
Harald Welte67fa91b2009-08-10 09:51:40 +0200821 dh->chan_nr = lchan2chan_nr(lchan);
Harald Welte31c48932009-08-10 10:07:33 +0200822 msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
Harald Welte67fa91b2009-08-10 09:51:40 +0200823
Harald Welte3c456d02009-08-10 11:26:14 +0200824 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
825 gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
826
827 msg->trx = lchan->ts->trx;
828
Harald Welte67fa91b2009-08-10 09:51:40 +0200829 return abis_rsl_sendmsg(msg);
830}
831
832
Harald Welte8470bf22008-12-25 23:28:35 +0000833/* Send "DATA REQUEST" message with given L3 Info payload */
Harald Welte52b1f982008-12-23 20:25:15 +0000834/* Chapter 8.3.1 */
Harald Welte8470bf22008-12-25 23:28:35 +0000835int rsl_data_request(struct msgb *msg, u_int8_t link_id)
Harald Welte52b1f982008-12-23 20:25:15 +0000836{
Harald Welte8470bf22008-12-25 23:28:35 +0000837 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000838 struct abis_rsl_rll_hdr *rh;
839
Harald Welte8470bf22008-12-25 23:28:35 +0000840 if (msg->lchan == NULL) {
841 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
842 return -EINVAL;
843 }
Harald Welte52b1f982008-12-23 20:25:15 +0000844
Harald Welte8470bf22008-12-25 23:28:35 +0000845 /* First push the L3 IE tag and length */
Harald Welte4b634542008-12-27 01:55:51 +0000846 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
Harald Welte8470bf22008-12-25 23:28:35 +0000847
848 /* Then push the RSL header */
Harald Welte52b1f982008-12-23 20:25:15 +0000849 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
850 init_llm_hdr(rh, RSL_MT_DATA_REQ);
Harald Welte4a543e82009-02-28 13:17:55 +0000851 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
Harald Welte8470bf22008-12-25 23:28:35 +0000852 rh->chan_nr = lchan2chan_nr(msg->lchan);
853 rh->link_id = link_id;
Harald Welte52b1f982008-12-23 20:25:15 +0000854
Harald Welte8470bf22008-12-25 23:28:35 +0000855 msg->trx = msg->lchan->ts->trx;
856
857 return abis_rsl_sendmsg(msg);
Harald Welte52b1f982008-12-23 20:25:15 +0000858}
859
Harald Welteedcc5272009-08-09 13:47:35 +0200860/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
861/* Chapter 8.3.1 */
862int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
863{
864 struct msgb *msg = rsl_msgb_alloc();
865 struct abis_rsl_rll_hdr *rh;
866
867 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte1c409272009-08-09 14:13:58 +0200868 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteedcc5272009-08-09 13:47:35 +0200869 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
870 rh->chan_nr = lchan2chan_nr(lchan);
871 rh->link_id = link_id;
872
873 msg->trx = lchan->ts->trx;
874
875 return abis_rsl_sendmsg(msg);
876}
877
Harald Welted2dc1de2009-08-08 13:15:07 +0200878/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
879 This is what higher layers should call. The BTS then responds with
880 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
881 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
882 lchan_free() */
883int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
884{
885 struct msgb *msg = rsl_msgb_alloc();
886 struct abis_rsl_rll_hdr *rh;
887
888 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
889 init_llm_hdr(rh, RSL_MT_REL_REQ);
890 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
891 rh->chan_nr = lchan2chan_nr(lchan);
892 rh->link_id = link_id;
Harald Welte6c3d2ed2009-08-10 00:19:36 +0200893 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welted2dc1de2009-08-08 13:15:07 +0200894
895 msg->trx = lchan->ts->trx;
896
897 return abis_rsl_sendmsg(msg);
898}
899
Harald Welte702d8702008-12-26 20:25:35 +0000900/* Chapter 8.4.2: Channel Activate Acknowledge */
901static int rsl_rx_chan_act_ack(struct msgb *msg)
902{
903 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
904
905 /* BTS has confirmed channel activation, we now need
906 * to assign the activated channel to the MS */
Harald Welte4b634542008-12-27 01:55:51 +0000907 if (rslh->ie_chan != RSL_IE_CHAN_NR)
908 return -EINVAL;
909
Harald Welte4b634542008-12-27 01:55:51 +0000910 return 0;
911}
Harald Welte702d8702008-12-26 20:25:35 +0000912
Harald Welte4b634542008-12-27 01:55:51 +0000913/* Chapter 8.4.3: Channel Activate NACK */
914static int rsl_rx_chan_act_nack(struct msgb *msg)
915{
Harald Welte6dab0552009-05-01 17:21:37 +0000916 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
917 struct tlv_parsed tp;
Harald Welte4b634542008-12-27 01:55:51 +0000918
Harald Welte6dab0552009-05-01 17:21:37 +0000919 /* BTS has rejected channel activation ?!? */
920 if (dh->ie_chan != RSL_IE_CHAN_NR)
Harald Welte4b634542008-12-27 01:55:51 +0000921 return -EINVAL;
Harald Welte6dab0552009-05-01 17:21:37 +0000922
923 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
924 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Welte8830e072009-07-28 17:58:09 +0200925 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
926 TLVP_LEN(&tp, RSL_IE_CAUSE));
927
Harald Welte3073a9f2009-08-09 19:50:08 +0200928 lchan_free(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +0000929 return 0;
Harald Welte702d8702008-12-26 20:25:35 +0000930}
931
Harald Welte7f93cea2009-02-23 00:02:59 +0000932/* Chapter 8.4.4: Connection Failure Indication */
933static int rsl_rx_conn_fail(struct msgb *msg)
934{
935 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
936 struct tlv_parsed tp;
937
938 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte7f93cea2009-02-23 00:02:59 +0000939
940 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
941
Harald Welte8830e072009-07-28 17:58:09 +0200942 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
943 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
944 TLVP_LEN(&tp, RSL_IE_CAUSE));
945
Holger Freytherf7b2a0e2009-06-02 02:55:17 +0000946 DEBUGPC(DRSL, "RELEASING.\n");
Harald Welte7f93cea2009-02-23 00:02:59 +0000947
948 /* FIXME: only free it after channel release ACK */
Harald Welte115d1032009-08-10 11:43:22 +0200949 return rsl_rf_chan_release(msg->lchan);
Harald Welte7f93cea2009-02-23 00:02:59 +0000950}
951
Harald Welte440fed02009-05-01 18:43:47 +0000952static int rsl_rx_meas_res(struct msgb *msg)
953{
954 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
955 struct tlv_parsed tp;
956
Harald Welte10d0e672009-06-27 02:53:10 +0200957 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte440fed02009-05-01 18:43:47 +0000958 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
959
960 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte10d0e672009-06-27 02:53:10 +0200961 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte440fed02009-05-01 18:43:47 +0000962 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
963 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte75d34a82009-05-23 06:11:13 +0000964 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
Harald Welte440fed02009-05-01 18:43:47 +0000965 if (len >= 3) {
966 if (val[0] & 0x40)
Harald Welte10d0e672009-06-27 02:53:10 +0200967 DEBUGPC(DMEAS, "DTXd ");
968 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000969 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte10d0e672009-06-27 02:53:10 +0200970 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000971 val[2]>>3 & 0x7, val[2] & 0x7);
972 }
973 }
974 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte10d0e672009-06-27 02:53:10 +0200975 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte440fed02009-05-01 18:43:47 +0000976 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte10d0e672009-06-27 02:53:10 +0200977 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte440fed02009-05-01 18:43:47 +0000978 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltefe9af262009-06-20 18:44:35 +0200979 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welte86c162d2009-07-12 09:45:05 +0200980 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltefe9af262009-06-20 18:44:35 +0200981 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte10d0e672009-06-27 02:53:10 +0200982 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltefe9af262009-06-20 18:44:35 +0200983 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte10d0e672009-06-27 02:53:10 +0200984 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
985 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltefe9af262009-06-20 18:44:35 +0200986 }
Harald Weltef7c43522009-06-09 20:24:21 +0000987 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte10d0e672009-06-27 02:53:10 +0200988 DEBUGPC(DMEAS, "L3\n");
Holger Hans Peter Freytherddd918f2009-10-22 15:43:55 +0200989 msg->l3h = (u_int8_t *) TLVP_VAL(&tp, RSL_IE_L3_INFO);
Harald Welte (local)daef6062009-08-14 11:41:12 +0200990 return gsm0408_rcvmsg(msg, 0);
Harald Weltef7c43522009-06-09 20:24:21 +0000991 } else
Harald Welte10d0e672009-06-27 02:53:10 +0200992 DEBUGPC(DMEAS, "\n");
Harald Welte60d68f12009-06-05 20:07:43 +0000993
Harald Welte75d34a82009-05-23 06:11:13 +0000994 return 0;
Harald Welte440fed02009-05-01 18:43:47 +0000995}
996
Harald Welte52b1f982008-12-23 20:25:15 +0000997static int abis_rsl_rx_dchan(struct msgb *msg)
998{
Harald Welte8470bf22008-12-25 23:28:35 +0000999 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1000 int rc = 0;
Harald Weltef325eb42009-02-19 17:07:39 +00001001 char *ts_name;
Harald Welte52b1f982008-12-23 20:25:15 +00001002
Harald Welte8470bf22008-12-25 23:28:35 +00001003 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001004 ts_name = gsm_ts_name(msg->lchan->ts);
1005
Harald Welte10d0e672009-06-27 02:53:10 +02001006 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
1007 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte8470bf22008-12-25 23:28:35 +00001008
1009 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001010 case RSL_MT_CHAN_ACTIV_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001011 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001012 rc = rsl_rx_chan_act_ack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001013 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001014 case RSL_MT_CHAN_ACTIV_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001015 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
Harald Welte4b634542008-12-27 01:55:51 +00001016 rc = rsl_rx_chan_act_nack(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001017 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001018 case RSL_MT_CONN_FAIL:
Harald Welte7f93cea2009-02-23 00:02:59 +00001019 rc = rsl_rx_conn_fail(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001020 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001021 case RSL_MT_MEAS_RES:
Harald Welte440fed02009-05-01 18:43:47 +00001022 rc = rsl_rx_meas_res(msg);
Harald Welte2d5b6382008-12-27 19:46:06 +00001023 break;
1024 case RSL_MT_RF_CHAN_REL_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001025 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
Harald Welte2d5b6382008-12-27 19:46:06 +00001026 lchan_free(msg->lchan);
Harald Welte8470bf22008-12-25 23:28:35 +00001027 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001028 case RSL_MT_MODE_MODIFY_ACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001029 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001030 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001031 case RSL_MT_MODE_MODIFY_NACK:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001032 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
Harald Welteda783762009-02-18 03:29:53 +00001033 break;
Harald Welte9c880c92009-10-24 10:29:22 +02001034 case RSL_MT_IPAC_PDCH_ACT_ACK:
1035 DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
1036 break;
1037 case RSL_MT_IPAC_PDCH_ACT_NACK:
1038 DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
1039 break;
1040 case RSL_MT_IPAC_PDCH_DEACT_ACK:
1041 DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
1042 break;
1043 case RSL_MT_IPAC_PDCH_DEACT_NACK:
1044 DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
1045 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001046 case RSL_MT_PHY_CONTEXT_CONF:
1047 case RSL_MT_PREPROC_MEAS_RES:
Harald Welte52b1f982008-12-23 20:25:15 +00001048 case RSL_MT_TALKER_DET:
1049 case RSL_MT_LISTENER_DET:
1050 case RSL_MT_REMOTE_CODEC_CONF_REP:
1051 case RSL_MT_MR_CODEC_MOD_ACK:
1052 case RSL_MT_MR_CODEC_MOD_NACK:
1053 case RSL_MT_MR_CODEC_MOD_PER:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001054 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001055 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001056 break;
1057 default:
Holger Freyther79f4ae62009-06-02 03:25:04 +00001058 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001059 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001060 return -EINVAL;
1061 }
Harald Weltef325eb42009-02-19 17:07:39 +00001062
Harald Welte8470bf22008-12-25 23:28:35 +00001063 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001064}
1065
Harald Welte702d8702008-12-26 20:25:35 +00001066static int rsl_rx_error_rep(struct msgb *msg)
1067{
1068 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8830e072009-07-28 17:58:09 +02001069 struct tlv_parsed tp;
Harald Welte702d8702008-12-26 20:25:35 +00001070
Harald Welte7f93cea2009-02-23 00:02:59 +00001071 DEBUGP(DRSL, "ERROR REPORT ");
Harald Welte8830e072009-07-28 17:58:09 +02001072
1073 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1074
1075 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1076 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1077 TLVP_LEN(&tp, RSL_IE_CAUSE));
1078
Holger Freyther79f4ae62009-06-02 03:25:04 +00001079 DEBUGPC(DRSL, "\n");
Harald Welte702d8702008-12-26 20:25:35 +00001080
1081 return 0;
1082}
1083
Harald Welte52b1f982008-12-23 20:25:15 +00001084static int abis_rsl_rx_trx(struct msgb *msg)
1085{
Harald Welte702d8702008-12-26 20:25:35 +00001086 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001087 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001088
1089 switch (rslh->msg_type) {
Harald Welte702d8702008-12-26 20:25:35 +00001090 case RSL_MT_ERROR_REPORT:
1091 rc = rsl_rx_error_rep(msg);
1092 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001093 case RSL_MT_RF_RES_IND:
1094 /* interference on idle channels of TRX */
Harald Welte3cf7c3f2009-05-01 18:28:00 +00001095 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
Harald Welte8f5e2392009-02-03 12:57:37 +00001096 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001097 case RSL_MT_OVERLOAD:
1098 /* indicate CCCH / ACCH / processor overload */
Harald Weltef325eb42009-02-19 17:07:39 +00001099 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
Harald Welte52b1f982008-12-23 20:25:15 +00001100 break;
1101 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001102 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001103 rslh->msg_type);
1104 return -EINVAL;
1105 }
Harald Welte8470bf22008-12-25 23:28:35 +00001106 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001107}
1108
Harald Welteb7e81162009-08-10 00:26:10 +02001109/* If T3101 expires, we never received a response to IMMEDIATE ASSIGN */
1110static void t3101_expired(void *data)
1111{
1112 struct gsm_lchan *lchan = data;
1113
Harald Welte115d1032009-08-10 11:43:22 +02001114 rsl_rf_chan_release(lchan);
Harald Welteb7e81162009-08-10 00:26:10 +02001115}
1116
Harald Welte8470bf22008-12-25 23:28:35 +00001117/* MS has requested a channel on the RACH */
Harald Welte52b1f982008-12-23 20:25:15 +00001118static int rsl_rx_chan_rqd(struct msgb *msg)
1119{
Harald Welte702d8702008-12-26 20:25:35 +00001120 struct gsm_bts *bts = msg->trx->bts;
Harald Welte8470bf22008-12-25 23:28:35 +00001121 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1122 struct gsm48_req_ref *rqd_ref;
Harald Welte52b1f982008-12-23 20:25:15 +00001123 struct gsm48_imm_ass ia;
Harald Welte8470bf22008-12-25 23:28:35 +00001124 enum gsm_chan_t lctype;
Harald Welte2cbe0922008-12-29 04:09:31 +00001125 enum gsm_chreq_reason_t chreq_reason;
Harald Welte8470bf22008-12-25 23:28:35 +00001126 struct gsm_lchan *lchan;
1127 u_int8_t rqd_ta;
Holger Freyther3186bf22008-12-29 06:23:49 +00001128 int ret;
Harald Welte8470bf22008-12-25 23:28:35 +00001129
Harald Welte52b1f982008-12-23 20:25:15 +00001130 u_int16_t arfcn;
1131 u_int8_t ts_number, subch;
1132
Harald Welte8470bf22008-12-25 23:28:35 +00001133 /* parse request reference to be used in immediate assign */
1134 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1135 return -EINVAL;
1136
1137 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1138
1139 /* parse access delay and use as TA */
1140 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1141 return -EINVAL;
1142 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1143
1144 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1145 * request reference RA */
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001146 lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
1147 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
Harald Welte2cbe0922008-12-29 04:09:31 +00001148
Harald Welte8470bf22008-12-25 23:28:35 +00001149 /* check availability / allocate channel */
1150 lchan = lchan_alloc(bts, lctype);
1151 if (!lchan) {
Holger Hans Peter Freyther0fef39a2009-11-16 15:37:05 +01001152 DEBUGP(DRSL, "CHAN RQD: no resources for %u 0x%x\n",
1153 lctype, rqd_ref->ra);
Harald Welte8470bf22008-12-25 23:28:35 +00001154 /* FIXME: send some kind of reject ?!? */
1155 return -ENOMEM;
1156 }
1157
1158 ts_number = lchan->ts->nr;
1159 arfcn = lchan->ts->trx->arfcn;
1160 subch = lchan->nr;
Harald Welte52b1f982008-12-23 20:25:15 +00001161
Harald Welte08d91a52009-08-30 15:37:11 +09001162 lchan->encr.alg_id = RSL_ENC_ALG_A5(0); /* no encryption */
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001163 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Welte0b2124b2009-08-10 00:45:40 +02001164 lchan->bs_power = 0; /* 0dB reduction, output power = Pn */
Harald Welte9943c5b2009-07-29 15:41:29 +02001165 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
Harald Welte196d0522009-08-28 23:28:28 +09001166 lchan->tch_mode = GSM48_CMODE_SIGN;
Harald Welte9943c5b2009-07-29 15:41:29 +02001167 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte52b1f982008-12-23 20:25:15 +00001168
1169 /* create IMMEDIATE ASSIGN 04.08 messge */
1170 memset(&ia, 0, sizeof(ia));
1171 ia.l2_plen = 0x2d;
1172 ia.proto_discr = GSM48_PDISC_RR;
1173 ia.msg_type = GSM48_MT_RR_IMM_ASS;
Harald Welte2d5b6382008-12-27 19:46:06 +00001174 ia.page_mode = GSM48_PM_SAME;
Harald Welte4b634542008-12-27 01:55:51 +00001175 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
Harald Welte52b1f982008-12-23 20:25:15 +00001176 ia.chan_desc.h0.h = 0;
1177 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1178 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte814c4b72009-07-21 20:55:56 +02001179 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte8470bf22008-12-25 23:28:35 +00001180 /* use request reference extracted from CHAN_RQD */
1181 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1182 ia.timing_advance = rqd_ta;
Harald Welte52b1f982008-12-23 20:25:15 +00001183 ia.mob_alloc_len = 0;
1184
Harald Welte8f5e2392009-02-03 12:57:37 +00001185 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
Holger Freyther79f4ae62009-06-02 03:25:04 +00001186 "chan_nr=0x%02x r=%s ra=0x%02x\n",
Harald Welteca64da92009-01-04 16:54:12 +00001187 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
Harald Welte4a543e82009-02-28 13:17:55 +00001188 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1189 rqd_ref->ra);
Harald Welte75a983f2008-12-27 21:34:06 +00001190
Harald Welteb7e81162009-08-10 00:26:10 +02001191 /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1192 lchan->T3101.cb = t3101_expired;
1193 lchan->T3101.data = lchan;
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001194 bsc_schedule_timer(&lchan->T3101, bts->network->T3101, 0);
Holger Freyther3186bf22008-12-29 06:23:49 +00001195
Harald Welte52b1f982008-12-23 20:25:15 +00001196 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
Holger Freyther3186bf22008-12-29 06:23:49 +00001197 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1198
Harald Welte817f3c82008-12-30 14:57:59 +00001199 return ret;
Harald Welte52b1f982008-12-23 20:25:15 +00001200}
1201
Harald Welteea280442009-02-02 22:29:56 +00001202/* MS has requested a channel on the RACH */
1203static int rsl_rx_ccch_load(struct msgb *msg)
1204{
1205 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1206 u_int16_t pg_buf_space;
Holger Freyther8c563cf2009-02-03 20:08:51 +00001207 u_int16_t rach_slot_count = -1;
1208 u_int16_t rach_busy_count = -1;
1209 u_int16_t rach_access_count = -1;
Harald Welteea280442009-02-02 22:29:56 +00001210
1211 switch (rslh->data[0]) {
1212 case RSL_IE_PAGING_LOAD:
1213 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
Holger Freyther392209c2009-02-10 00:06:19 +00001214 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
Harald Welteea280442009-02-02 22:29:56 +00001215 break;
1216 case RSL_IE_RACH_LOAD:
Holger Freyther8c563cf2009-02-03 20:08:51 +00001217 if (msg->data_len >= 7) {
1218 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1219 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1220 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1221 }
Harald Welteea280442009-02-02 22:29:56 +00001222 break;
1223 default:
1224 break;
1225 }
1226
1227 return 0;
1228}
1229
Harald Welte52b1f982008-12-23 20:25:15 +00001230static int abis_rsl_rx_cchan(struct msgb *msg)
1231{
Harald Welteea280442009-02-02 22:29:56 +00001232 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001233 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001234
Harald Welte8470bf22008-12-25 23:28:35 +00001235 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1236
1237 switch (rslh->c.msg_type) {
Harald Welte52b1f982008-12-23 20:25:15 +00001238 case RSL_MT_CHAN_RQD:
1239 /* MS has requested a channel on the RACH */
1240 rc = rsl_rx_chan_rqd(msg);
1241 break;
Harald Welteea280442009-02-02 22:29:56 +00001242 case RSL_MT_CCCH_LOAD_IND:
1243 /* current load on the CCCH */
1244 rc = rsl_rx_ccch_load(msg);
1245 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001246 case RSL_MT_DELETE_IND:
1247 /* CCCH overloaded, IMM_ASSIGN was dropped */
1248 case RSL_MT_CBCH_LOAD_IND:
1249 /* current load on the CBCH */
Harald Welte8f5e2392009-02-03 12:57:37 +00001250 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1251 "0x%02x\n", rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001252 break;
1253 default:
1254 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
Harald Welte8470bf22008-12-25 23:28:35 +00001255 rslh->c.msg_type);
Harald Welte52b1f982008-12-23 20:25:15 +00001256 return -EINVAL;
1257 }
Harald Welte8470bf22008-12-25 23:28:35 +00001258
1259 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001260}
1261
Harald Welte4b634542008-12-27 01:55:51 +00001262static int rsl_rx_rll_err_ind(struct msgb *msg)
1263{
1264 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1265 u_int8_t *rlm_cause = rllh->data;
1266
Harald Welte602f2b82009-08-04 02:50:21 +02001267 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteedcc5272009-08-09 13:47:35 +02001268
1269 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte4b634542008-12-27 01:55:51 +00001270
Harald Welte81543bc2009-07-04 09:40:05 +02001271 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
Harald Welte115d1032009-08-10 11:43:22 +02001272 return rsl_rf_chan_release(msg->lchan);
Harald Welte81543bc2009-07-04 09:40:05 +02001273
Harald Welte4b634542008-12-27 01:55:51 +00001274 return 0;
1275}
Harald Weltef325eb42009-02-19 17:07:39 +00001276
Harald Welte52b1f982008-12-23 20:25:15 +00001277/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1278 0x02, 0x06,
1279 0x01, 0x20,
1280 0x02, 0x00,
1281 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1282
1283static int abis_rsl_rx_rll(struct msgb *msg)
1284{
1285 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
Harald Weltef325eb42009-02-19 17:07:39 +00001286 int rc = 0;
1287 char *ts_name;
Harald Welte (local)daef6062009-08-14 11:41:12 +02001288 u_int8_t sapi = rllh->link_id & 7;
Harald Welte8470bf22008-12-25 23:28:35 +00001289
1290 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001291 ts_name = gsm_ts_name(msg->lchan->ts);
Harald Welte (local)daef6062009-08-14 11:41:12 +02001292 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
1293 rllh->chan_nr, sapi);
Harald Welte52b1f982008-12-23 20:25:15 +00001294
1295 switch (rllh->c.msg_type) {
1296 case RSL_MT_DATA_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001297 DEBUGPC(DRLL, "DATA INDICATION\n");
Harald Welte4a543e82009-02-28 13:17:55 +00001298 if (msgb_l2len(msg) >
1299 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1300 rllh->data[0] == RSL_IE_L3_INFO) {
1301 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001302 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001303 }
Harald Welte52b1f982008-12-23 20:25:15 +00001304 break;
1305 case RSL_MT_EST_IND:
Harald Weltef325eb42009-02-19 17:07:39 +00001306 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
Harald Welteb7e81162009-08-10 00:26:10 +02001307 /* lchan is established, stop T3101 */
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001308 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
Harald Welteb7e81162009-08-10 00:26:10 +02001309 bsc_del_timer(&msg->lchan->T3101);
Harald Welte4a543e82009-02-28 13:17:55 +00001310 if (msgb_l2len(msg) >
1311 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1312 rllh->data[0] == RSL_IE_L3_INFO) {
1313 msg->l3h = &rllh->data[3];
Harald Welte (local)daef6062009-08-14 11:41:12 +02001314 return gsm0408_rcvmsg(msg, rllh->link_id);
Harald Welte4a543e82009-02-28 13:17:55 +00001315 }
Harald Welte52b1f982008-12-23 20:25:15 +00001316 break;
Harald Welteedcc5272009-08-09 13:47:35 +02001317 case RSL_MT_EST_CONF:
Harald Welte1c409272009-08-09 14:13:58 +02001318 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001319 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_NET;
Harald Welteedcc5272009-08-09 13:47:35 +02001320 rll_indication(msg->lchan, rllh->link_id,
1321 BSC_RLLR_IND_EST_CONF);
1322 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001323 case RSL_MT_REL_IND:
Harald Welted2dc1de2009-08-08 13:15:07 +02001324 /* BTS informs us of having received DISC from MS */
Harald Welte602f2b82009-08-04 02:50:21 +02001325 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001326 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welteedcc5272009-08-09 13:47:35 +02001327 rll_indication(msg->lchan, rllh->link_id,
1328 BSC_RLLR_IND_REL_IND);
Harald Welted2dc1de2009-08-08 13:15:07 +02001329 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001330 /* FIXME: officially we need to start T3111 and wait for
1331 * some grace period */
1332 rsl_rf_chan_release(msg->lchan);
Harald Welte2d5b6382008-12-27 19:46:06 +00001333 break;
1334 case RSL_MT_REL_CONF:
Harald Welted2dc1de2009-08-08 13:15:07 +02001335 /* BTS informs us of having received UA from MS,
1336 * in response to DISC that we've sent earlier */
Harald Welte602f2b82009-08-04 02:50:21 +02001337 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Holger Hans Peter Freyther5ba6f482009-10-28 14:23:39 +01001338 msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
Harald Welted2dc1de2009-08-08 13:15:07 +02001339 /* we can now releae the channel on the BTS/Abis side */
Harald Welte115d1032009-08-10 11:43:22 +02001340 /* FIXME: officially we need to start T3111 and wait for
1341 * some grace period */
1342 rsl_rf_chan_release(msg->lchan);
Harald Welte4b634542008-12-27 01:55:51 +00001343 break;
1344 case RSL_MT_ERROR_IND:
1345 rc = rsl_rx_rll_err_ind(msg);
1346 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001347 case RSL_MT_UNIT_DATA_IND:
Harald Welte602f2b82009-08-04 02:50:21 +02001348 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001349 rllh->c.msg_type);
1350 break;
1351 default:
Harald Welte602f2b82009-08-04 02:50:21 +02001352 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte52b1f982008-12-23 20:25:15 +00001353 rllh->c.msg_type);
1354 }
Harald Welte8470bf22008-12-25 23:28:35 +00001355 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001356}
1357
Harald Weltef4e79f22009-07-28 18:11:56 +02001358static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1359{
Harald Weltef4e79f22009-07-28 18:11:56 +02001360 switch (tch_mode) {
1361 case GSM48_CMODE_SPEECH_V1:
1362 return 0x00;
1363 case GSM48_CMODE_SPEECH_EFR:
1364 return 0x01;
1365 case GSM48_CMODE_SPEECH_AMR:
1366 return 0x02;
1367 /* FIXME: Type1 half-rate and type3 half-rate */
1368 }
Harald Welte58ca5b72009-07-29 12:12:18 +02001369 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1370 "tch_mode == 0x%02x\n", tch_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001371 return 0;
Harald Weltef4e79f22009-07-28 18:11:56 +02001372}
1373
Harald Welte75099262009-02-16 21:12:08 +00001374/* ip.access specific RSL extensions */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001375int rsl_ipacc_crcx(struct gsm_lchan *lchan)
Harald Welte75099262009-02-16 21:12:08 +00001376{
1377 struct msgb *msg = rsl_msgb_alloc();
1378 struct abis_rsl_dchan_hdr *dh;
Harald Welte58ca5b72009-07-29 12:12:18 +02001379 u_int8_t speech_mode;
Harald Welte75099262009-02-16 21:12:08 +00001380
1381 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001382 init_dchan_hdr(dh, RSL_MT_IPAC_CRCX);
Harald Welte75099262009-02-16 21:12:08 +00001383 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1384 dh->chan_nr = lchan2chan_nr(lchan);
1385
Harald Weltef4e79f22009-07-28 18:11:56 +02001386 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Welte58ca5b72009-07-29 12:12:18 +02001387 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1388 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001389
Harald Welte58ca5b72009-07-29 12:12:18 +02001390 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1391 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1392 dh->chan_nr, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001393
Harald Welte75099262009-02-16 21:12:08 +00001394 msg->trx = lchan->ts->trx;
1395
1396 return abis_rsl_sendmsg(msg);
1397}
1398
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001399int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
Harald Welte20855542009-07-12 09:50:35 +02001400 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte75099262009-02-16 21:12:08 +00001401{
1402 struct msgb *msg = rsl_msgb_alloc();
1403 struct abis_rsl_dchan_hdr *dh;
1404 u_int8_t *att_f8, *att_ip, *att_port;
Harald Welte58ca5b72009-07-29 12:12:18 +02001405 u_int8_t speech_mode;
Harald Weltef4e79f22009-07-28 18:11:56 +02001406 struct in_addr ia;
Harald Welte75099262009-02-16 21:12:08 +00001407
1408 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001409 init_dchan_hdr(dh, RSL_MT_IPAC_MDCX);
Harald Welte75099262009-02-16 21:12:08 +00001410 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1411 dh->chan_nr = lchan2chan_nr(lchan);
1412
Harald Welte58ca5b72009-07-29 12:12:18 +02001413 /* 0x0- == both directions, 0x-1 == EFR codec */
1414 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1415
Harald Weltef4e79f22009-07-28 18:11:56 +02001416 ia.s_addr = htonl(ip);
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001417 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_MDCX "
Harald Welte58ca5b72009-07-29 12:12:18 +02001418 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Weltef4e79f22009-07-28 18:11:56 +02001419 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Welte58ca5b72009-07-29 12:12:18 +02001420 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001421
Harald Welte20855542009-07-12 09:50:35 +02001422 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welte86c162d2009-07-12 09:45:05 +02001423 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte20855542009-07-12 09:50:35 +02001424 att_f8[1] = conn_id >> 8;
1425 att_f8[2] = conn_id & 0xff;
Harald Welte75099262009-02-16 21:12:08 +00001426
1427 att_ip = msgb_put(msg, sizeof(ip)+1);
1428 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1429 att_ip[1] = ip >> 24;
1430 att_ip[2] = ip >> 16;
1431 att_ip[3] = ip >> 8;
1432 att_ip[4] = ip & 0xff;
Harald Welteda783762009-02-18 03:29:53 +00001433 //att_ip[4] = 11;
Harald Welte75099262009-02-16 21:12:08 +00001434
1435 att_port = msgb_put(msg, sizeof(port)+1);
1436 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1437 att_port[1] = port >> 8;
1438 att_port[2] = port & 0xff;
1439
Harald Welte58ca5b72009-07-29 12:12:18 +02001440 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Weltef4e79f22009-07-28 18:11:56 +02001441 if (rtp_payload2)
1442 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1443
Harald Welte75099262009-02-16 21:12:08 +00001444 msg->trx = lchan->ts->trx;
1445
1446 return abis_rsl_sendmsg(msg);
1447}
1448
Harald Welte9c880c92009-10-24 10:29:22 +02001449int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
1450{
1451 struct msgb *msg = rsl_msgb_alloc();
1452 struct abis_rsl_dchan_hdr *dh;
1453
1454 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1455 init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
1456 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
1457 dh->chan_nr = lchan2chan_nr(lchan);
1458
1459 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
1460 gsm_ts_name(lchan->ts), dh->chan_nr);
1461
1462 msg->trx = lchan->ts->trx;
1463
1464 return abis_rsl_sendmsg(msg);
1465}
1466
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001467static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001468{
1469 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1470 struct tlv_parsed tv;
1471 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
Harald Welte167df882009-02-17 14:35:45 +00001472 struct in_addr ip;
Harald Welte75099262009-02-16 21:12:08 +00001473 u_int16_t port, attr_f8;
1474
1475 /* the BTS has acknowledged a local bind, it now tells us the IP
1476 * address and port number to which it has bound the given logical
1477 * channel */
1478
1479 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1480 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1481 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welte86c162d2009-07-12 09:45:05 +02001482 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Weltef325eb42009-02-19 17:07:39 +00001483 DEBUGPC(DRSL, "mandatory IE missing");
Harald Welte75099262009-02-16 21:12:08 +00001484 return -EINVAL;
1485 }
Harald Welte167df882009-02-17 14:35:45 +00001486 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
Harald Welte75099262009-02-16 21:12:08 +00001487 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1488 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1489
Harald Weltef4e79f22009-07-28 18:11:56 +02001490 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1491 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1492
1493 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1494 ts->abis_ip.rtp_payload2 =
1495 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1496 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1497 ts->abis_ip.rtp_payload2);
1498 }
Harald Welte167df882009-02-17 14:35:45 +00001499
Harald Welte75099262009-02-16 21:12:08 +00001500 /* update our local information about this TS */
Harald Welte167df882009-02-17 14:35:45 +00001501 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1502 ts->abis_ip.bound_port = ntohs(port);
Harald Welte20855542009-07-12 09:50:35 +02001503 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte75099262009-02-16 21:12:08 +00001504
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001505 dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
Harald Welte167df882009-02-17 14:35:45 +00001506
Harald Welte75099262009-02-16 21:12:08 +00001507 return 0;
1508}
1509
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001510static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
Harald Welte75099262009-02-16 21:12:08 +00001511{
1512 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1513 struct tlv_parsed tv;
1514
1515 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte75099262009-02-16 21:12:08 +00001516
Harald Welte8830e072009-07-28 17:58:09 +02001517 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1518 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1519 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte75099262009-02-16 21:12:08 +00001520
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001521 dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
Harald Welte888b1142009-07-28 18:02:05 +02001522
Harald Welte75099262009-02-16 21:12:08 +00001523 return 0;
1524}
1525
1526static int abis_rsl_rx_ipacc(struct msgb *msg)
1527{
1528 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1529 int rc = 0;
1530
1531 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
Harald Weltef325eb42009-02-19 17:07:39 +00001532 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1533 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
Harald Welte75099262009-02-16 21:12:08 +00001534
1535 switch (rllh->c.msg_type) {
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001536 case RSL_MT_IPAC_CRCX_ACK:
1537 DEBUGPC(DRSL, "IPAC_CRCX_ACK ");
1538 rc = abis_rsl_rx_ipacc_crcx_ack(msg);
Harald Welte75099262009-02-16 21:12:08 +00001539 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001540 case RSL_MT_IPAC_CRCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001541 /* somehow the BTS was unable to bind the lchan to its local
1542 * port?!? */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001543 DEBUGPC(DRSL, "IPAC_CRCX_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001544 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001545 case RSL_MT_IPAC_MDCX_ACK:
Harald Welte75099262009-02-16 21:12:08 +00001546 /* the BTS tells us that a connect operation was successful */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001547 DEBUGPC(DRSL, "IPAC_MDCX_ACK ");
Harald Welte75099262009-02-16 21:12:08 +00001548 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001549 case RSL_MT_IPAC_MDCX_NACK:
Harald Welte75099262009-02-16 21:12:08 +00001550 /* somehow the BTS was unable to connect the lchan to a remote
1551 * port */
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001552 DEBUGPC(DRSL, "IPAC_MDCX_NACK ");
Harald Welte75099262009-02-16 21:12:08 +00001553 break;
Holger Hans Peter Freyther231163d2009-11-18 21:06:12 +01001554 case RSL_MT_IPAC_DLCX_IND:
1555 DEBUGPC(DRSL, "IPAC_DLCX_IND ");
1556 rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
Harald Welte75099262009-02-16 21:12:08 +00001557 break;
1558 default:
Harald Weltef325eb42009-02-19 17:07:39 +00001559 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
Harald Welte75099262009-02-16 21:12:08 +00001560 break;
1561 }
Harald Welte6dab0552009-05-01 17:21:37 +00001562 DEBUGPC(DRSL, "\n");
Harald Welte75099262009-02-16 21:12:08 +00001563
1564 return rc;
1565}
1566
1567
Harald Welte52b1f982008-12-23 20:25:15 +00001568/* Entry-point where L2 RSL from BTS enters */
Harald Welte8470bf22008-12-25 23:28:35 +00001569int abis_rsl_rcvmsg(struct msgb *msg)
Harald Welte52b1f982008-12-23 20:25:15 +00001570{
1571 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
Harald Welte8f5e2392009-02-03 12:57:37 +00001572 int rc = 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001573
1574 switch (rslh->msg_discr & 0xfe) {
1575 case ABIS_RSL_MDISC_RLL:
1576 rc = abis_rsl_rx_rll(msg);
1577 break;
1578 case ABIS_RSL_MDISC_DED_CHAN:
1579 rc = abis_rsl_rx_dchan(msg);
1580 break;
1581 case ABIS_RSL_MDISC_COM_CHAN:
Harald Welte52b1f982008-12-23 20:25:15 +00001582 rc = abis_rsl_rx_cchan(msg);
1583 break;
Harald Welte8470bf22008-12-25 23:28:35 +00001584 case ABIS_RSL_MDISC_TRX:
1585 rc = abis_rsl_rx_trx(msg);
1586 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001587 case ABIS_RSL_MDISC_LOC:
Harald Welte8f5e2392009-02-03 12:57:37 +00001588 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1589 rslh->msg_discr);
1590 break;
Harald Welte75099262009-02-16 21:12:08 +00001591 case ABIS_RSL_MDISC_IPACCESS:
1592 rc = abis_rsl_rx_ipacc(msg);
1593 break;
Harald Welte52b1f982008-12-23 20:25:15 +00001594 default:
1595 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1596 rslh->msg_discr);
1597 return -EINVAL;
1598 }
Harald Welte4f4a3902008-12-26 00:04:49 +00001599 msgb_free(msg);
Harald Welte8470bf22008-12-25 23:28:35 +00001600 return rc;
Harald Welte52b1f982008-12-23 20:25:15 +00001601}
Holger Freyther3b72a892009-02-04 00:31:39 +00001602
1603
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001604/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Holger Freyther3b72a892009-02-04 00:31:39 +00001605int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1606{
1607 switch (ccch_conf) {
1608 case RSL_BCCH_CCCH_CONF_1_NC:
1609 return 1;
1610 case RSL_BCCH_CCCH_CONF_1_C:
1611 return 1;
1612 case RSL_BCCH_CCCH_CONF_2_NC:
1613 return 2;
1614 case RSL_BCCH_CCCH_CONF_3_NC:
1615 return 3;
1616 case RSL_BCCH_CCCH_CONF_4_NC:
1617 return 4;
1618 default:
1619 return -1;
1620 }
1621}
1622
Holger Hans Peter Freyther3d571832009-07-09 20:43:16 +02001623/* Section 3.3.2.3 TS 05.02 */
Holger Freyther3b72a892009-02-04 00:31:39 +00001624int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1625{
1626 switch (ccch_conf) {
1627 case RSL_BCCH_CCCH_CONF_1_NC:
1628 return 0;
1629 case RSL_BCCH_CCCH_CONF_1_C:
1630 return 1;
1631 case RSL_BCCH_CCCH_CONF_2_NC:
1632 return 0;
1633 case RSL_BCCH_CCCH_CONF_3_NC:
1634 return 0;
1635 case RSL_BCCH_CCCH_CONF_4_NC:
1636 return 0;
1637 default:
1638 return -1;
1639 }
1640}
1641
1642/* From Table 10.5.33 of GSM 04.08 */
1643int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1644{
1645 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1646 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001647 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001648 } else {
1649 return (9 - bts->chan_desc.bs_ag_blks_res)
Holger Freyther3aa8d6c2009-02-04 02:14:45 +00001650 * (bts->chan_desc.bs_pa_mfrms + 2);
Holger Freyther3b72a892009-02-04 00:31:39 +00001651 }
1652}