blob: 50aebc3b9cebcd7f9c75a63b93ae4655d8649cba [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* GSM Radio Signalling Link messages on the A-bis interface
2 * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
3
4/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <sys/types.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30
31#include <openbsc/gsm_data.h>
32#include <openbsc/gsm_04_08.h>
Harald Weltec4dcda02009-08-09 14:45:18 +020033#include <openbsc/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080034#include <openbsc/abis_rsl.h>
35#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020036#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080037#include <openbsc/debug.h>
38#include <openbsc/tlv.h>
39#include <openbsc/paging.h>
40#include <openbsc/signal.h>
41
42#define RSL_ALLOC_SIZE 1024
43#define RSL_ALLOC_HEADROOM 128
44
45#define MAX(a, b) (a) >= (b) ? (a) : (b)
46
47static const struct tlv_definition rsl_att_tlvdef = {
48 .def = {
49 [RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
50 [RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
51 [RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
52 [RSL_IE_BS_POWER] = { TLV_TYPE_TV },
53 [RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
54 [RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
55 [RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
56 [RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
57 [RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
58 [RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
59 [RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
60 [RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
61 [RSL_IE_MS_POWER] = { TLV_TYPE_TV },
62 [RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
63 [RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
64 [RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
65 [RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
66 [RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
67 [RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
68 [RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
69 [RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
70 [RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
71 [RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
72 [RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
73 [RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
74 [RSL_IE_CAUSE] = { TLV_TYPE_TLV },
75 [RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
76 [RSL_IE_MSG_ID] = { TLV_TYPE_TV },
77 [RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
78 [RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
79 [RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
80 [RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
81 [RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
82 [RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
83 [RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
84 [RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
85 [RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
86 [RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
87 [RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
88 [RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
89 [RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
90 [RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
91 [RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
92 [RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
93 [RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
94 [RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
95 [RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
96 [RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
97 [RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
98 [RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
99 [RSL_IE_UIC] = { TLV_TYPE_TLV },
100 [RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
101 [RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
102 [RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
103 [RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
104 [RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
105 [RSL_IE_RTD] = { TLV_TYPE_TV },
106 [RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
107 [RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
Harald Welte1610d302009-07-12 09:56:39 +0200108 [RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
109 [RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800110 [RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
111 [RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welte1610d302009-07-12 09:56:39 +0200112 [RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800113 [RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welteb9498952009-07-12 09:45:05 +0200114 [RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200115 [RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
Harald Welteb9498952009-07-12 09:45:05 +0200116 [RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
Harald Welte1610d302009-07-12 09:56:39 +0200117 [RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
118 [RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
119 [RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
Harald Welteb9498952009-07-12 09:45:05 +0200120 [RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200121 [RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
122 [RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800123 },
124};
125#define rsl_tlv_parse(dec, buf, len) \
126 tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
127
128static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
129{
130 /* mask off the transparent bit ? */
131 msg_type &= 0xfe;
132
133 if ((msg_type & 0xf0) == 0x00)
134 return ABIS_RSL_MDISC_RLL;
135 if ((msg_type & 0xf0) == 0x10) {
136 if (msg_type >= 0x19 && msg_type <= 0x22)
137 return ABIS_RSL_MDISC_TRX;
138 else
139 return ABIS_RSL_MDISC_COM_CHAN;
140 }
141 if ((msg_type & 0xe0) == 0x20)
142 return ABIS_RSL_MDISC_DED_CHAN;
143
144 return ABIS_RSL_MDISC_LOC;
145}
146
147static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
148 u_int8_t msg_type)
149{
150 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
151 dh->c.msg_type = msg_type;
152 dh->ie_chan = RSL_IE_CHAN_NR;
153}
154
155static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
156 u_int8_t msg_type)
157{
158 /* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
159 dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
160 dh->c.msg_type = msg_type;
161 dh->ie_chan = RSL_IE_CHAN_NR;
162 dh->ie_link_id = RSL_IE_LINK_IDENT;
163}
164
165
166/* encode channel number as per Section 9.3.1 */
167u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
168{
169 u_int8_t ret;
170
171 ret = (timeslot & 0x07) | type;
172
173 switch (type) {
174 case RSL_CHAN_Lm_ACCHs:
175 subch &= 0x01;
176 break;
177 case RSL_CHAN_SDCCH4_ACCH:
178 subch &= 0x07;
179 break;
180 case RSL_CHAN_SDCCH8_ACCH:
181 subch &= 0x07;
182 break;
183 default:
184 /* no subchannels allowed */
185 subch = 0x00;
186 break;
187 }
188 ret |= (subch << 3);
189
190 return ret;
191}
192
193/* determine logical channel based on TRX and channel number IE */
194struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
195{
196 struct gsm_lchan *lchan;
197 u_int8_t ts_nr = chan_nr & 0x07;
198 u_int8_t cbits = chan_nr >> 3;
199 u_int8_t lch_idx;
200 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
201
202 if (cbits == 0x01) {
203 lch_idx = 0; /* TCH/F */
204 if (ts->pchan != GSM_PCHAN_TCH_F)
205 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
206 chan_nr, ts->pchan);
207 } else if ((cbits & 0x1e) == 0x02) {
208 lch_idx = cbits & 0x1; /* TCH/H */
209 if (ts->pchan != GSM_PCHAN_TCH_H)
210 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
211 chan_nr, ts->pchan);
212 } else if ((cbits & 0x1c) == 0x04) {
213 lch_idx = cbits & 0x3; /* SDCCH/4 */
214 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
215 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
216 chan_nr, ts->pchan);
217 } else if ((cbits & 0x18) == 0x08) {
218 lch_idx = cbits & 0x7; /* SDCCH/8 */
219 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
220 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
221 chan_nr, ts->pchan);
222 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
223 lch_idx = 0;
224 if (ts->pchan != GSM_PCHAN_CCCH &&
225 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
226 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
227 chan_nr, ts->pchan);
228 /* FIXME: we should not return first sdcch4 !!! */
229 } else {
230 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
231 return NULL;
232 }
233
234 lchan = &ts->lchan[lch_idx];
235
236 return lchan;
237}
238
239u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
240{
241 struct gsm_bts_trx_ts *ts = lchan->ts;
242 u_int8_t cbits, chan_nr;
243
244 switch (ts->pchan) {
245 case GSM_PCHAN_TCH_F:
246 cbits = 0x01;
247 break;
248 case GSM_PCHAN_TCH_H:
249 cbits = 0x02;
250 cbits += lchan->nr;
251 break;
252 case GSM_PCHAN_CCCH_SDCCH4:
253 cbits = 0x04;
254 cbits += lchan->nr;
255 break;
256 case GSM_PCHAN_SDCCH8_SACCH8C:
257 cbits = 0x08;
258 cbits += lchan->nr;
259 break;
260 default:
261 case GSM_PCHAN_CCCH:
262 cbits = 0x10;
263 break;
264 }
265
266 chan_nr = (cbits << 3) | (ts->nr & 0x7);
267
268 return chan_nr;
269}
270
271/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
272u_int64_t str_to_imsi(const char *imsi_str)
273{
274 u_int64_t ret;
275
276 ret = strtoull(imsi_str, NULL, 10);
277
278 return ret;
279}
280
281/* Table 5 Clause 7 TS 05.02 */
282unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
283{
284 if (!bs_ccch_sdcch_comb)
285 return 9 - bs_ag_blks_res;
286 else
287 return 3 - bs_ag_blks_res;
288}
289
290/* Chapter 6.5.2 of TS 05.02 */
291unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
292 unsigned int n_pag_blocks)
293{
294 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
295}
296
297/* Chapter 6.5.2 of TS 05.02 */
298unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
299 int n_pag_blocks)
300{
301 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
302}
303
304static struct msgb *rsl_msgb_alloc(void)
305{
Harald Welte9cfc9352009-06-26 19:39:35 +0200306 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
307 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800308}
309
310#define MACBLOCK_SIZE 23
311static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
312{
313 memcpy(out, in, len);
314
315 if (len < MACBLOCK_SIZE)
316 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
317}
318
Harald Weltef1a168d2009-07-28 17:58:09 +0200319static const char *rsl_err_vals[0xff] = {
320 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
321 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
322 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
323 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
324 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
325 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welteb1717e92009-08-04 02:31:05 +0200326 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Weltef1a168d2009-07-28 17:58:09 +0200327 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
328 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
329 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
330 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
331 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
332 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
333 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
334 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
335 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
336 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
337 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
338 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
339 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
340 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
341 [RSL_ERR_MSG_TYPE] = "Message Type Error",
342 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
343 [RSL_ERR_IE_ERROR] = "General IE error",
344 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
345 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
346 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
347 [RSL_ERR_IE_LENGTH] = "IE length error",
348 [RSL_ERR_IE_CONTENT] = "IE content error",
349 [RSL_ERR_PROTO] = "Protocol error, unspecified",
350 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
351};
352
353static const char *rsl_err_name(u_int8_t err)
Harald Welte59b04682009-06-10 05:40:52 +0800354{
Harald Weltef1a168d2009-07-28 17:58:09 +0200355 if (rsl_err_vals[err])
356 return rsl_err_vals[err];
357 else
358 return "unknown";
359}
360
361static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
362{
Harald Welte59b04682009-06-10 05:40:52 +0800363 int i;
364
Harald Weltef1a168d2009-07-28 17:58:09 +0200365 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
366 cause_v[0], rsl_err_name(cause_v[0]));
367 for (i = 1; i < cause_len-1; i++)
368 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800369}
370
371/* Send a BCCH_INFO message as per Chapter 8.5.1 */
372int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
373 const u_int8_t *data, int len)
374{
375 struct abis_rsl_dchan_hdr *dh;
376 struct msgb *msg = rsl_msgb_alloc();
377
378 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
379 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
380 dh->chan_nr = RSL_CHAN_BCCH;
381
382 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
383 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
384
385 msg->trx = trx;
386
387 return abis_rsl_sendmsg(msg);
388}
389
390int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
391 const u_int8_t *data, int len)
392{
393 struct abis_rsl_common_hdr *ch;
394 struct msgb *msg = rsl_msgb_alloc();
395
396 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
397 ch->msg_discr = ABIS_RSL_MDISC_TRX;
398 ch->msg_type = RSL_MT_SACCH_FILL;
399
400 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
401 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
402
403 msg->trx = trx;
404
405 return abis_rsl_sendmsg(msg);
406}
407
Harald Welte91afe4c2009-06-20 18:15:19 +0200408int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
409{
410 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200411 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200412 u_int8_t chan_nr = lchan2chan_nr(lchan);
413
414 db = abs(db);
415 if (db > 30)
416 return -EINVAL;
417
Harald Welteed831842009-06-27 03:09:08 +0200418 msg = rsl_msgb_alloc();
419
Harald Welte91afe4c2009-06-20 18:15:19 +0200420 lchan->bs_power = db/2;
421 if (fpc)
422 lchan->bs_power |= 0x10;
423
424 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
425 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
426 dh->chan_nr = chan_nr;
427
428 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
429
430 msg->trx = lchan->ts->trx;
431
432 return abis_rsl_sendmsg(msg);
433}
434
Harald Welte91afe4c2009-06-20 18:15:19 +0200435int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
436{
437 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200438 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200439 u_int8_t chan_nr = lchan2chan_nr(lchan);
440 int ctl_lvl;
441
Harald Weltec4dcda02009-08-09 14:45:18 +0200442 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, dbm);
Harald Welte91afe4c2009-06-20 18:15:19 +0200443 if (ctl_lvl < 0)
444 return ctl_lvl;
445
Harald Welteed831842009-06-27 03:09:08 +0200446 msg = rsl_msgb_alloc();
447
Harald Welte91afe4c2009-06-20 18:15:19 +0200448 lchan->ms_power = ctl_lvl;
449
450 if (fpc)
451 lchan->ms_power |= 0x20;
452
453 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
454 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
455 dh->chan_nr = chan_nr;
456
457 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
458
459 msg->trx = lchan->ts->trx;
460
461 return abis_rsl_sendmsg(msg);
462}
463
Harald Welte39274f42009-07-29 15:41:29 +0200464static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
465 struct gsm_lchan *lchan)
466{
467 memset(cm, 0, sizeof(cm));
468
469 /* FIXME: what to do with data calls ? */
470 cm->dtx_dtu = 0x00;
471
472 /* set TCH Speech/Data */
473 cm->spd_ind = lchan->rsl_cmode;
474
475 switch (lchan->type) {
476 case GSM_LCHAN_SDCCH:
477 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
478 break;
479 case GSM_LCHAN_TCH_F:
480 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
481 break;
482 case GSM_LCHAN_TCH_H:
483 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
484 break;
485 case GSM_LCHAN_NONE:
486 case GSM_LCHAN_UNKNOWN:
487 default:
488 return -EINVAL;
489 }
490
491 switch (lchan->tch_mode) {
492 case GSM48_CMODE_SIGN:
493 cm->chan_rate = 0;
494 break;
495 case GSM48_CMODE_SPEECH_V1:
496 cm->chan_rate = RSL_CMOD_SP_GSM1;
497 break;
498 case GSM48_CMODE_SPEECH_EFR:
499 cm->chan_rate = RSL_CMOD_SP_GSM2;
500 break;
501 case GSM48_CMODE_SPEECH_AMR:
502 cm->chan_rate = RSL_CMOD_SP_GSM3;
503 break;
504 case GSM48_CMODE_DATA_14k5:
505 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
506 break;
507 case GSM48_CMODE_DATA_12k0:
508 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
509 break;
510 case GSM48_CMODE_DATA_6k0:
511 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
512 break;
513 default:
514 return -EINVAL;
515 }
516
517 return 0;
518}
519
Harald Welte59b04682009-06-10 05:40:52 +0800520/* Chapter 8.4.1 */
521#if 0
522int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
523 u_int8_t act_type,
524 struct rsl_ie_chan_mode *chan_mode,
525 struct rsl_ie_chan_ident *chan_ident,
526 u_int8_t bs_power, u_int8_t ms_power,
527 u_int8_t ta)
528{
529 struct abis_rsl_dchan_hdr *dh;
530 struct msgb *msg = rsl_msgb_alloc();
531
532 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
533 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
534 dh->chan_nr = chan_nr;
535
536 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
537 /* For compatibility with Phase 1 */
538 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
539 (u_int8_t *) chan_mode);
540 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
541 (u_int8_t *) chan_ident);
542#if 0
543 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
544 (u_int8_t *) &encr_info);
545#endif
546 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
547 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
548 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
549
550 msg->trx = trx;
551
552 return abis_rsl_sendmsg(msg);
553}
554#endif
555
556int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte39274f42009-07-29 15:41:29 +0200557 u_int8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800558{
559 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200560 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200561 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800562
563 u_int8_t chan_nr = lchan2chan_nr(lchan);
564 u_int16_t arfcn = lchan->ts->trx->arfcn;
565 struct rsl_ie_chan_mode cm;
566 struct rsl_ie_chan_ident ci;
567
Harald Welte39274f42009-07-29 15:41:29 +0200568 rc = channel_mode_from_lchan(&cm, lchan);
569 if (rc < 0)
570 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800571
572 memset(&ci, 0, sizeof(ci));
573 ci.chan_desc.iei = 0x64;
574 ci.chan_desc.chan_nr = chan_nr;
575 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
576 ci.chan_desc.oct4 = arfcn & 0xff;
577
Harald Welteed831842009-06-27 03:09:08 +0200578 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800579 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
580 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
581 dh->chan_nr = chan_nr;
582
583 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
584 /* For compatibility with Phase 1 */
585 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
586 (u_int8_t *) &cm);
587 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
588 (u_int8_t *) &ci);
589#if 0
590 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
591 (u_int8_t *) &encr_info);
592#endif
593 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
594 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
595 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
596
597 msg->trx = lchan->ts->trx;
598
599 return abis_rsl_sendmsg(msg);
600}
601
Harald Welte8e770492009-07-29 11:38:15 +0200602/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800603int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
604{
605 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200606 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200607 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800608
609 u_int8_t chan_nr = lchan2chan_nr(lchan);
610 struct rsl_ie_chan_mode cm;
611
Harald Welte39274f42009-07-29 15:41:29 +0200612 rc = channel_mode_from_lchan(&cm, lchan);
613 if (rc < 0)
614 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800615
Harald Welteed831842009-06-27 03:09:08 +0200616 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800617 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
618 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
619 dh->chan_nr = chan_nr;
620
621 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
622 (u_int8_t *) &cm);
623#if 0
624 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
625 (u_int8_t *) &encr_info);
626#endif
627
628 msg->trx = lchan->ts->trx;
629
630 return abis_rsl_sendmsg(msg);
631}
632
Harald Welteafe3c232009-07-19 18:36:49 +0200633/* Chapter 8.4.5 */
634int rsl_deact_sacch(struct gsm_lchan *lchan)
635{
636 struct abis_rsl_dchan_hdr *dh;
637 struct msgb *msg = rsl_msgb_alloc();
638
639 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
640 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
641 dh->chan_nr = lchan2chan_nr(lchan);
642
643 msg->lchan = lchan;
644 msg->trx = lchan->ts->trx;
645
646 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
647 gsm_ts_name(lchan->ts), dh->chan_nr);
648
649 return abis_rsl_sendmsg(msg);
650}
651
Harald Welte59b04682009-06-10 05:40:52 +0800652/* Chapter 9.1.7 of 04.08 */
653int rsl_chan_release(struct gsm_lchan *lchan)
654{
655 struct abis_rsl_dchan_hdr *dh;
656 struct msgb *msg = rsl_msgb_alloc();
657
658 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
659 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
660 dh->chan_nr = lchan2chan_nr(lchan);
661
662 msg->lchan = lchan;
663 msg->trx = lchan->ts->trx;
664
665 DEBUGP(DRSL, "Channel Release CMD channel=%s chan_nr=0x%02x\n",
666 gsm_ts_name(lchan->ts), dh->chan_nr);
667
668 return abis_rsl_sendmsg(msg);
669}
670
671int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
672 u_int8_t *ms_ident, u_int8_t chan_needed)
673{
674 struct abis_rsl_dchan_hdr *dh;
675 struct msgb *msg = rsl_msgb_alloc();
676
677 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
678 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
679 dh->chan_nr = RSL_CHAN_PCH_AGCH;
680
681 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
682 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
683 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
684
685 msg->trx = bts->c0;
686
687 return abis_rsl_sendmsg(msg);
688}
689
690int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
691 struct gsm_subscriber *subscr)
692{
693#if 0
694 u_int8_t mi[128];
695 unsigned int mi_len;
696 u_int8_t paging_group;
697#endif
698
699 return -1;
700}
701
702int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
703{
704 int i, len = strlen(str_in);
705
706 for (i = 0; i < len; i++) {
707 int num = str_in[i] - 0x30;
708 if (num < 0 || num > 9)
709 return -1;
710 if (i % 2 == 0)
711 bcd_out[i/2] = num;
712 else
713 bcd_out[i/2] |= (num << 4);
714 }
715
716 return 0;
717}
718
719/* Chapter 8.5.6 */
720int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
721{
722 struct msgb *msg = rsl_msgb_alloc();
723 struct abis_rsl_dchan_hdr *dh;
724 u_int8_t buf[MACBLOCK_SIZE];
725
726 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
727 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
728 dh->chan_nr = RSL_CHAN_PCH_AGCH;
729
730 switch (bts->type) {
731 case GSM_BTS_TYPE_BS11:
732 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
733 break;
734 default:
735 /* If phase 2, construct a FULL_IMM_ASS_INFO */
736 pad_macblock(buf, val, len);
737 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
738 break;
739 }
740
741 msg->trx = bts->c0;
742
743 return abis_rsl_sendmsg(msg);
744}
745
746/* Send "DATA REQUEST" message with given L3 Info payload */
747/* Chapter 8.3.1 */
748int rsl_data_request(struct msgb *msg, u_int8_t link_id)
749{
750 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
751 struct abis_rsl_rll_hdr *rh;
752
753 if (msg->lchan == NULL) {
754 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
755 return -EINVAL;
756 }
757
758 /* First push the L3 IE tag and length */
759 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
760
761 /* Then push the RSL header */
762 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
763 init_llm_hdr(rh, RSL_MT_DATA_REQ);
764 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
765 rh->chan_nr = lchan2chan_nr(msg->lchan);
766 rh->link_id = link_id;
767
768 msg->trx = msg->lchan->ts->trx;
769
770 return abis_rsl_sendmsg(msg);
771}
772
Harald Welteed9a5ab2009-08-09 13:47:35 +0200773/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
774/* Chapter 8.3.1 */
775int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
776{
777 struct msgb *msg = rsl_msgb_alloc();
778 struct abis_rsl_rll_hdr *rh;
779
780 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
Harald Welte61402172009-08-09 14:13:58 +0200781 init_llm_hdr(rh, RSL_MT_EST_REQ);
Harald Welteed9a5ab2009-08-09 13:47:35 +0200782 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
783 rh->chan_nr = lchan2chan_nr(lchan);
784 rh->link_id = link_id;
785
786 msg->trx = lchan->ts->trx;
787
788 return abis_rsl_sendmsg(msg);
789}
790
Harald Welte0f2e3c12009-08-08 13:15:07 +0200791/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
792 This is what higher layers should call. The BTS then responds with
793 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
794 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
795 lchan_free() */
796int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
797{
798 struct msgb *msg = rsl_msgb_alloc();
799 struct abis_rsl_rll_hdr *rh;
800
801 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
802 init_llm_hdr(rh, RSL_MT_REL_REQ);
803 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
804 rh->chan_nr = lchan2chan_nr(lchan);
805 rh->link_id = link_id;
Harald Weltead738562009-08-10 00:19:36 +0200806 msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
Harald Welte0f2e3c12009-08-08 13:15:07 +0200807
808 msg->trx = lchan->ts->trx;
809
810 return abis_rsl_sendmsg(msg);
811}
812
Harald Welte59b04682009-06-10 05:40:52 +0800813/* Chapter 8.4.2: Channel Activate Acknowledge */
814static int rsl_rx_chan_act_ack(struct msgb *msg)
815{
816 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
817
818 /* BTS has confirmed channel activation, we now need
819 * to assign the activated channel to the MS */
820 if (rslh->ie_chan != RSL_IE_CHAN_NR)
821 return -EINVAL;
822
823 return 0;
824}
825
826/* Chapter 8.4.3: Channel Activate NACK */
827static int rsl_rx_chan_act_nack(struct msgb *msg)
828{
829 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
830 struct tlv_parsed tp;
831
832 /* BTS has rejected channel activation ?!? */
833 if (dh->ie_chan != RSL_IE_CHAN_NR)
834 return -EINVAL;
835
836 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
837 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200838 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
839 TLVP_LEN(&tp, RSL_IE_CAUSE));
840
Harald Weltecddb9802009-08-09 19:50:08 +0200841 lchan_free(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800842 return 0;
843}
844
845/* Chapter 8.4.4: Connection Failure Indication */
846static int rsl_rx_conn_fail(struct msgb *msg)
847{
848 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
849 struct tlv_parsed tp;
850
851 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800852
853 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
854
Harald Weltef1a168d2009-07-28 17:58:09 +0200855 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
856 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
857 TLVP_LEN(&tp, RSL_IE_CAUSE));
858
Harald Welte59b04682009-06-10 05:40:52 +0800859 if (msg->trx->bts->type == GSM_BTS_TYPE_BS11) {
860 /* FIXME: we have no idea what cause 0x18 is !!! */
861 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE) &&
862 TLVP_LEN(&tp, RSL_IE_CAUSE) >= 1 &&
863 *TLVP_VAL(&tp, RSL_IE_CAUSE) == 0x18) {
Harald Weltedf0c6502009-07-04 10:05:51 +0200864 DEBUGPC(DRSL, "Cause 0x18 IGNORING\n");
865 return 0;
Harald Welte59b04682009-06-10 05:40:52 +0800866 }
867 }
868
869 DEBUGPC(DRSL, "RELEASING.\n");
870
871 /* FIXME: only free it after channel release ACK */
872 return rsl_chan_release(msg->lchan);
873}
874
875static int rsl_rx_meas_res(struct msgb *msg)
876{
877 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
878 struct tlv_parsed tp;
879
Harald Welte02993682009-06-27 02:53:10 +0200880 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800881 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
882
883 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200884 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800885 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
886 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
887 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
888 if (len >= 3) {
889 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200890 DEBUGPC(DMEAS, "DTXd ");
891 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800892 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200893 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800894 val[2]>>3 & 0x7, val[2] & 0x7);
895 }
896 }
897 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200898 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800899 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200900 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800901 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200902 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200903 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200904 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200905 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200906 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200907 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
908 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200909 }
Harald Welte59b04682009-06-10 05:40:52 +0800910 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200911 DEBUGPC(DMEAS, "L3\n");
Harald Welte59b04682009-06-10 05:40:52 +0800912 msg->l3h = TLVP_VAL(&tp, RSL_IE_L3_INFO);
913 return gsm0408_rcvmsg(msg);
914 } else
Harald Welte02993682009-06-27 02:53:10 +0200915 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800916
917 return 0;
918}
919
920static int abis_rsl_rx_dchan(struct msgb *msg)
921{
922 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
923 int rc = 0;
924 char *ts_name;
925
926 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
927 ts_name = gsm_ts_name(msg->lchan->ts);
928
Harald Welte02993682009-06-27 02:53:10 +0200929 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
930 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800931
932 switch (rslh->c.msg_type) {
933 case RSL_MT_CHAN_ACTIV_ACK:
934 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
935 rc = rsl_rx_chan_act_ack(msg);
936 break;
937 case RSL_MT_CHAN_ACTIV_NACK:
938 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
939 rc = rsl_rx_chan_act_nack(msg);
940 break;
941 case RSL_MT_CONN_FAIL:
942 rc = rsl_rx_conn_fail(msg);
943 break;
944 case RSL_MT_MEAS_RES:
945 rc = rsl_rx_meas_res(msg);
946 break;
947 case RSL_MT_RF_CHAN_REL_ACK:
948 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
949 lchan_free(msg->lchan);
950 break;
951 case RSL_MT_MODE_MODIFY_ACK:
952 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
953 break;
954 case RSL_MT_MODE_MODIFY_NACK:
955 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
956 break;
957 case RSL_MT_PHY_CONTEXT_CONF:
958 case RSL_MT_PREPROC_MEAS_RES:
959 case RSL_MT_TALKER_DET:
960 case RSL_MT_LISTENER_DET:
961 case RSL_MT_REMOTE_CODEC_CONF_REP:
962 case RSL_MT_MR_CODEC_MOD_ACK:
963 case RSL_MT_MR_CODEC_MOD_NACK:
964 case RSL_MT_MR_CODEC_MOD_PER:
965 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
966 rslh->c.msg_type);
967 break;
968 default:
969 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
970 rslh->c.msg_type);
971 return -EINVAL;
972 }
973
974 return rc;
975}
976
977static int rsl_rx_error_rep(struct msgb *msg)
978{
979 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +0200980 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +0800981
982 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +0200983
984 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
985
986 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
987 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
988 TLVP_LEN(&tp, RSL_IE_CAUSE));
989
Harald Welte59b04682009-06-10 05:40:52 +0800990 DEBUGPC(DRSL, "\n");
991
992 return 0;
993}
994
995static int abis_rsl_rx_trx(struct msgb *msg)
996{
997 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
998 int rc = 0;
999
1000 switch (rslh->msg_type) {
1001 case RSL_MT_ERROR_REPORT:
1002 rc = rsl_rx_error_rep(msg);
1003 break;
1004 case RSL_MT_RF_RES_IND:
1005 /* interference on idle channels of TRX */
1006 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1007 break;
1008 case RSL_MT_OVERLOAD:
1009 /* indicate CCCH / ACCH / processor overload */
1010 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1011 break;
1012 default:
1013 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1014 rslh->msg_type);
1015 return -EINVAL;
1016 }
1017 return rc;
1018}
1019
1020/* MS has requested a channel on the RACH */
1021static int rsl_rx_chan_rqd(struct msgb *msg)
1022{
1023 struct gsm_bts *bts = msg->trx->bts;
1024 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1025 struct gsm48_req_ref *rqd_ref;
1026 struct gsm48_imm_ass ia;
1027 enum gsm_chan_t lctype;
1028 enum gsm_chreq_reason_t chreq_reason;
1029 struct gsm_lchan *lchan;
1030 u_int8_t rqd_ta;
1031 int ret;
1032
1033 u_int16_t arfcn;
1034 u_int8_t ts_number, subch;
1035
1036 /* parse request reference to be used in immediate assign */
1037 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1038 return -EINVAL;
1039
1040 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1041
1042 /* parse access delay and use as TA */
1043 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1044 return -EINVAL;
1045 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1046
1047 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1048 * request reference RA */
1049 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
1050 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1051
1052 /* check availability / allocate channel */
1053 lchan = lchan_alloc(bts, lctype);
1054 if (!lchan) {
1055 fprintf(stderr, "CHAN RQD: no resources\n");
1056 /* FIXME: send some kind of reject ?!? */
1057 return -ENOMEM;
1058 }
1059
1060 ts_number = lchan->ts->nr;
1061 arfcn = lchan->ts->trx->arfcn;
1062 subch = lchan->nr;
1063
Harald Weltec4dcda02009-08-09 14:45:18 +02001064 lchan->ms_power = ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte24fc0f82009-08-04 02:31:55 +02001065 lchan->bs_power = 0x0f; /* 30dB reduction */
Harald Welte39274f42009-07-29 15:41:29 +02001066 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
1067 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001068
1069 /* create IMMEDIATE ASSIGN 04.08 messge */
1070 memset(&ia, 0, sizeof(ia));
1071 ia.l2_plen = 0x2d;
1072 ia.proto_discr = GSM48_PDISC_RR;
1073 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1074 ia.page_mode = GSM48_PM_SAME;
1075 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1076 ia.chan_desc.h0.h = 0;
1077 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1078 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001079 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001080 /* use request reference extracted from CHAN_RQD */
1081 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1082 ia.timing_advance = rqd_ta;
1083 ia.mob_alloc_len = 0;
1084
1085 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1086 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1087 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1088 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1089 rqd_ref->ra);
1090
1091 /* FIXME: Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1092
1093 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1094 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1095
1096 return ret;
1097}
1098
1099/* MS has requested a channel on the RACH */
1100static int rsl_rx_ccch_load(struct msgb *msg)
1101{
1102 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1103 u_int16_t pg_buf_space;
1104 u_int16_t rach_slot_count = -1;
1105 u_int16_t rach_busy_count = -1;
1106 u_int16_t rach_access_count = -1;
1107
1108 switch (rslh->data[0]) {
1109 case RSL_IE_PAGING_LOAD:
1110 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1111 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1112 break;
1113 case RSL_IE_RACH_LOAD:
1114 if (msg->data_len >= 7) {
1115 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1116 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1117 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1118 }
1119 break;
1120 default:
1121 break;
1122 }
1123
1124 return 0;
1125}
1126
1127static int abis_rsl_rx_cchan(struct msgb *msg)
1128{
1129 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1130 int rc = 0;
1131
1132 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1133
1134 switch (rslh->c.msg_type) {
1135 case RSL_MT_CHAN_RQD:
1136 /* MS has requested a channel on the RACH */
1137 rc = rsl_rx_chan_rqd(msg);
1138 break;
1139 case RSL_MT_CCCH_LOAD_IND:
1140 /* current load on the CCCH */
1141 rc = rsl_rx_ccch_load(msg);
1142 break;
1143 case RSL_MT_DELETE_IND:
1144 /* CCCH overloaded, IMM_ASSIGN was dropped */
1145 case RSL_MT_CBCH_LOAD_IND:
1146 /* current load on the CBCH */
1147 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1148 "0x%02x\n", rslh->c.msg_type);
1149 break;
1150 default:
1151 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1152 rslh->c.msg_type);
1153 return -EINVAL;
1154 }
1155
1156 return rc;
1157}
1158
1159static int rsl_rx_rll_err_ind(struct msgb *msg)
1160{
1161 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1162 u_int8_t *rlm_cause = rllh->data;
1163
Harald Welteb6601442009-08-04 02:50:21 +02001164 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001165
1166 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001167
Harald Welte692f5852009-07-04 09:40:05 +02001168 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
1169 return rsl_chan_release(msg->lchan);
1170
Harald Welte59b04682009-06-10 05:40:52 +08001171 return 0;
1172}
1173
1174/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1175 0x02, 0x06,
1176 0x01, 0x20,
1177 0x02, 0x00,
1178 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1179
1180static int abis_rsl_rx_rll(struct msgb *msg)
1181{
1182 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1183 int rc = 0;
1184 char *ts_name;
1185
1186 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1187 ts_name = gsm_ts_name(msg->lchan->ts);
1188 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x ", ts_name, rllh->chan_nr);
1189
1190 switch (rllh->c.msg_type) {
1191 case RSL_MT_DATA_IND:
1192 DEBUGPC(DRLL, "DATA INDICATION\n");
1193 if (msgb_l2len(msg) >
1194 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1195 rllh->data[0] == RSL_IE_L3_INFO) {
1196 msg->l3h = &rllh->data[3];
1197 return gsm0408_rcvmsg(msg);
1198 }
1199 break;
1200 case RSL_MT_EST_IND:
1201 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
1202 if (msgb_l2len(msg) >
1203 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1204 rllh->data[0] == RSL_IE_L3_INFO) {
1205 msg->l3h = &rllh->data[3];
1206 return gsm0408_rcvmsg(msg);
1207 }
1208 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001209 case RSL_MT_EST_CONF:
Harald Welte61402172009-08-09 14:13:58 +02001210 DEBUGPC(DRLL, "ESTABLISH CONFIRM\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001211 rll_indication(msg->lchan, rllh->link_id,
1212 BSC_RLLR_IND_EST_CONF);
1213 break;
Harald Welte59b04682009-06-10 05:40:52 +08001214 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001215 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001216 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001217 rll_indication(msg->lchan, rllh->link_id,
1218 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001219 /* we can now releae the channel on the BTS/Abis side */
1220 rsl_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001221 break;
1222 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001223 /* BTS informs us of having received UA from MS,
1224 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001225 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welte0f2e3c12009-08-08 13:15:07 +02001226 /* we can now releae the channel on the BTS/Abis side */
1227 rsl_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001228 break;
1229 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001230 rc = rsl_rx_rll_err_ind(msg);
1231 break;
1232 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001233 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001234 rllh->c.msg_type);
1235 break;
1236 default:
Harald Welteb6601442009-08-04 02:50:21 +02001237 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001238 rllh->c.msg_type);
1239 }
Harald Welte59b04682009-06-10 05:40:52 +08001240 return rc;
1241}
1242
Harald Welte98d79f92009-07-28 18:11:56 +02001243static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1244{
Harald Welte98d79f92009-07-28 18:11:56 +02001245 switch (tch_mode) {
1246 case GSM48_CMODE_SPEECH_V1:
1247 return 0x00;
1248 case GSM48_CMODE_SPEECH_EFR:
1249 return 0x01;
1250 case GSM48_CMODE_SPEECH_AMR:
1251 return 0x02;
1252 /* FIXME: Type1 half-rate and type3 half-rate */
1253 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001254 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1255 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001256 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001257}
1258
Harald Welte59b04682009-06-10 05:40:52 +08001259/* ip.access specific RSL extensions */
1260int rsl_ipacc_bind(struct gsm_lchan *lchan)
1261{
1262 struct msgb *msg = rsl_msgb_alloc();
1263 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001264 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001265
1266 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1267 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1268 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1269 dh->chan_nr = lchan2chan_nr(lchan);
1270
Harald Welte98d79f92009-07-28 18:11:56 +02001271 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001272 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1273 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001274
Harald Weltefb4a9e92009-07-29 12:12:18 +02001275 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1276 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1277 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001278
Harald Welte59b04682009-06-10 05:40:52 +08001279 msg->trx = lchan->ts->trx;
1280
1281 return abis_rsl_sendmsg(msg);
1282}
1283
Harald Welte8cdeaad2009-07-12 09:50:35 +02001284int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1285 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001286{
1287 struct msgb *msg = rsl_msgb_alloc();
1288 struct abis_rsl_dchan_hdr *dh;
1289 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001290 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001291 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001292
1293 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1294 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1295 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1296 dh->chan_nr = lchan2chan_nr(lchan);
1297
Harald Weltefb4a9e92009-07-29 12:12:18 +02001298 /* 0x0- == both directions, 0x-1 == EFR codec */
1299 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1300
Harald Welte98d79f92009-07-28 18:11:56 +02001301 ia.s_addr = htonl(ip);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001302 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1303 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001304 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001305 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001306
Harald Welte8cdeaad2009-07-12 09:50:35 +02001307 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001308 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001309 att_f8[1] = conn_id >> 8;
1310 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001311
1312 att_ip = msgb_put(msg, sizeof(ip)+1);
1313 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1314 att_ip[1] = ip >> 24;
1315 att_ip[2] = ip >> 16;
1316 att_ip[3] = ip >> 8;
1317 att_ip[4] = ip & 0xff;
1318 //att_ip[4] = 11;
1319
1320 att_port = msgb_put(msg, sizeof(port)+1);
1321 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1322 att_port[1] = port >> 8;
1323 att_port[2] = port & 0xff;
1324
Harald Weltefb4a9e92009-07-29 12:12:18 +02001325 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001326 if (rtp_payload2)
1327 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1328
Harald Welte59b04682009-06-10 05:40:52 +08001329 msg->trx = lchan->ts->trx;
1330
1331 return abis_rsl_sendmsg(msg);
1332}
1333
1334static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1335{
1336 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1337 struct tlv_parsed tv;
1338 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1339 struct in_addr ip;
1340 u_int16_t port, attr_f8;
1341
1342 /* the BTS has acknowledged a local bind, it now tells us the IP
1343 * address and port number to which it has bound the given logical
1344 * channel */
1345
1346 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1347 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1348 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001349 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001350 DEBUGPC(DRSL, "mandatory IE missing");
1351 return -EINVAL;
1352 }
1353 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1354 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1355 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1356
Harald Welte98d79f92009-07-28 18:11:56 +02001357 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1358 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1359
1360 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1361 ts->abis_ip.rtp_payload2 =
1362 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1363 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1364 ts->abis_ip.rtp_payload2);
1365 }
Harald Welte59b04682009-06-10 05:40:52 +08001366
1367 /* update our local information about this TS */
1368 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1369 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001370 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001371
1372 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1373
1374 return 0;
1375}
1376
1377static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1378{
1379 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1380 struct tlv_parsed tv;
1381
1382 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001383
Harald Weltef1a168d2009-07-28 17:58:09 +02001384 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1385 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1386 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001387
Harald Welteba4e58d2009-07-28 18:02:05 +02001388 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1389
Harald Welte59b04682009-06-10 05:40:52 +08001390 return 0;
1391}
1392
1393static int abis_rsl_rx_ipacc(struct msgb *msg)
1394{
1395 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1396 int rc = 0;
1397
1398 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1399 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1400 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1401
1402 switch (rllh->c.msg_type) {
1403 case RSL_MT_IPAC_BIND_ACK:
1404 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
1405 rc = abis_rsl_rx_ipacc_bindack(msg);
1406 break;
1407 case RSL_MT_IPAC_BIND_NACK:
1408 /* somehow the BTS was unable to bind the lchan to its local
1409 * port?!? */
1410 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
1411 break;
1412 case RSL_MT_IPAC_CONNECT_ACK:
1413 /* the BTS tells us that a connect operation was successful */
1414 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
1415 break;
1416 case RSL_MT_IPAC_CONNECT_NACK:
1417 /* somehow the BTS was unable to connect the lchan to a remote
1418 * port */
1419 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
1420 break;
1421 case RSL_MT_IPAC_DISCONNECT_IND:
1422 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
1423 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1424 break;
1425 default:
1426 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1427 break;
1428 }
1429 DEBUGPC(DRSL, "\n");
1430
1431 return rc;
1432}
1433
1434
1435/* Entry-point where L2 RSL from BTS enters */
1436int abis_rsl_rcvmsg(struct msgb *msg)
1437{
1438 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1439 int rc = 0;
1440
1441 switch (rslh->msg_discr & 0xfe) {
1442 case ABIS_RSL_MDISC_RLL:
1443 rc = abis_rsl_rx_rll(msg);
1444 break;
1445 case ABIS_RSL_MDISC_DED_CHAN:
1446 rc = abis_rsl_rx_dchan(msg);
1447 break;
1448 case ABIS_RSL_MDISC_COM_CHAN:
1449 rc = abis_rsl_rx_cchan(msg);
1450 break;
1451 case ABIS_RSL_MDISC_TRX:
1452 rc = abis_rsl_rx_trx(msg);
1453 break;
1454 case ABIS_RSL_MDISC_LOC:
1455 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1456 rslh->msg_discr);
1457 break;
1458 case ABIS_RSL_MDISC_IPACCESS:
1459 rc = abis_rsl_rx_ipacc(msg);
1460 break;
1461 default:
1462 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1463 rslh->msg_discr);
1464 return -EINVAL;
1465 }
1466 msgb_free(msg);
1467 return rc;
1468}
1469
1470
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001471/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001472int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1473{
1474 switch (ccch_conf) {
1475 case RSL_BCCH_CCCH_CONF_1_NC:
1476 return 1;
1477 case RSL_BCCH_CCCH_CONF_1_C:
1478 return 1;
1479 case RSL_BCCH_CCCH_CONF_2_NC:
1480 return 2;
1481 case RSL_BCCH_CCCH_CONF_3_NC:
1482 return 3;
1483 case RSL_BCCH_CCCH_CONF_4_NC:
1484 return 4;
1485 default:
1486 return -1;
1487 }
1488}
1489
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001490/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001491int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1492{
1493 switch (ccch_conf) {
1494 case RSL_BCCH_CCCH_CONF_1_NC:
1495 return 0;
1496 case RSL_BCCH_CCCH_CONF_1_C:
1497 return 1;
1498 case RSL_BCCH_CCCH_CONF_2_NC:
1499 return 0;
1500 case RSL_BCCH_CCCH_CONF_3_NC:
1501 return 0;
1502 case RSL_BCCH_CCCH_CONF_4_NC:
1503 return 0;
1504 default:
1505 return -1;
1506 }
1507}
1508
1509/* From Table 10.5.33 of GSM 04.08 */
1510int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1511{
1512 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1513 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1514 * (bts->chan_desc.bs_pa_mfrms + 2);
1515 } else {
1516 return (9 - bts->chan_desc.bs_ag_blks_res)
1517 * (bts->chan_desc.bs_pa_mfrms + 2);
1518 }
1519}