blob: 1e828a98f9b1c2b7478d164b6d1a3a5d7313a71e [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>
33#include <openbsc/abis_rsl.h>
34#include <openbsc/chan_alloc.h>
Harald Welteed9a5ab2009-08-09 13:47:35 +020035#include <openbsc/bsc_rll.h>
Harald Welte59b04682009-06-10 05:40:52 +080036#include <openbsc/debug.h>
37#include <openbsc/tlv.h>
38#include <openbsc/paging.h>
39#include <openbsc/signal.h>
40
41#define RSL_ALLOC_SIZE 1024
42#define RSL_ALLOC_HEADROOM 128
43
44#define MAX(a, b) (a) >= (b) ? (a) : (b)
45
46static const struct tlv_definition rsl_att_tlvdef = {
47 .def = {
48 [RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
49 [RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
50 [RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
51 [RSL_IE_BS_POWER] = { TLV_TYPE_TV },
52 [RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
53 [RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
54 [RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
55 [RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
56 [RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
57 [RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
58 [RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
59 [RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
60 [RSL_IE_MS_POWER] = { TLV_TYPE_TV },
61 [RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
62 [RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
63 [RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
64 [RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
65 [RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
66 [RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
67 [RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
68 [RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
69 [RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
70 [RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
71 [RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
72 [RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
73 [RSL_IE_CAUSE] = { TLV_TYPE_TLV },
74 [RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
75 [RSL_IE_MSG_ID] = { TLV_TYPE_TV },
76 [RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
77 [RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
78 [RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
79 [RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
80 [RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
81 [RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
82 [RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
83 [RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
84 [RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
85 [RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
86 [RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
87 [RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
88 [RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
89 [RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
90 [RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
91 [RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
92 [RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
93 [RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
94 [RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
95 [RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
96 [RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
97 [RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
98 [RSL_IE_UIC] = { TLV_TYPE_TLV },
99 [RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
100 [RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
101 [RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
102 [RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
103 [RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
104 [RSL_IE_RTD] = { TLV_TYPE_TV },
105 [RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
106 [RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
Harald Welte1610d302009-07-12 09:56:39 +0200107 [RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
108 [RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800109 [RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
110 [RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welte1610d302009-07-12 09:56:39 +0200111 [RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800112 [RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
Harald Welteb9498952009-07-12 09:45:05 +0200113 [RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200114 [RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
Harald Welteb9498952009-07-12 09:45:05 +0200115 [RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
Harald Welte1610d302009-07-12 09:56:39 +0200116 [RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
117 [RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
118 [RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
Harald Welteb9498952009-07-12 09:45:05 +0200119 [RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
Harald Welte1610d302009-07-12 09:56:39 +0200120 [RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
121 [RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +0800122 },
123};
124#define rsl_tlv_parse(dec, buf, len) \
125 tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
126
127static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
128{
129 /* mask off the transparent bit ? */
130 msg_type &= 0xfe;
131
132 if ((msg_type & 0xf0) == 0x00)
133 return ABIS_RSL_MDISC_RLL;
134 if ((msg_type & 0xf0) == 0x10) {
135 if (msg_type >= 0x19 && msg_type <= 0x22)
136 return ABIS_RSL_MDISC_TRX;
137 else
138 return ABIS_RSL_MDISC_COM_CHAN;
139 }
140 if ((msg_type & 0xe0) == 0x20)
141 return ABIS_RSL_MDISC_DED_CHAN;
142
143 return ABIS_RSL_MDISC_LOC;
144}
145
146static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
147 u_int8_t msg_type)
148{
149 dh->c.msg_discr = mdisc_by_msgtype(msg_type);
150 dh->c.msg_type = msg_type;
151 dh->ie_chan = RSL_IE_CHAN_NR;
152}
153
154static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
155 u_int8_t msg_type)
156{
157 /* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
158 dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
159 dh->c.msg_type = msg_type;
160 dh->ie_chan = RSL_IE_CHAN_NR;
161 dh->ie_link_id = RSL_IE_LINK_IDENT;
162}
163
164
165/* encode channel number as per Section 9.3.1 */
166u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
167{
168 u_int8_t ret;
169
170 ret = (timeslot & 0x07) | type;
171
172 switch (type) {
173 case RSL_CHAN_Lm_ACCHs:
174 subch &= 0x01;
175 break;
176 case RSL_CHAN_SDCCH4_ACCH:
177 subch &= 0x07;
178 break;
179 case RSL_CHAN_SDCCH8_ACCH:
180 subch &= 0x07;
181 break;
182 default:
183 /* no subchannels allowed */
184 subch = 0x00;
185 break;
186 }
187 ret |= (subch << 3);
188
189 return ret;
190}
191
192/* determine logical channel based on TRX and channel number IE */
193struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
194{
195 struct gsm_lchan *lchan;
196 u_int8_t ts_nr = chan_nr & 0x07;
197 u_int8_t cbits = chan_nr >> 3;
198 u_int8_t lch_idx;
199 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
200
201 if (cbits == 0x01) {
202 lch_idx = 0; /* TCH/F */
203 if (ts->pchan != GSM_PCHAN_TCH_F)
204 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
205 chan_nr, ts->pchan);
206 } else if ((cbits & 0x1e) == 0x02) {
207 lch_idx = cbits & 0x1; /* TCH/H */
208 if (ts->pchan != GSM_PCHAN_TCH_H)
209 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
210 chan_nr, ts->pchan);
211 } else if ((cbits & 0x1c) == 0x04) {
212 lch_idx = cbits & 0x3; /* SDCCH/4 */
213 if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
214 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
215 chan_nr, ts->pchan);
216 } else if ((cbits & 0x18) == 0x08) {
217 lch_idx = cbits & 0x7; /* SDCCH/8 */
218 if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C)
219 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
220 chan_nr, ts->pchan);
221 } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
222 lch_idx = 0;
223 if (ts->pchan != GSM_PCHAN_CCCH &&
224 ts->pchan != GSM_PCHAN_CCCH_SDCCH4)
225 fprintf(stderr, "chan_nr=0x%02x but pchan=%u\n",
226 chan_nr, ts->pchan);
227 /* FIXME: we should not return first sdcch4 !!! */
228 } else {
229 fprintf(stderr, "unknown chan_nr=0x%02x\n", chan_nr);
230 return NULL;
231 }
232
233 lchan = &ts->lchan[lch_idx];
234
235 return lchan;
236}
237
238u_int8_t lchan2chan_nr(struct gsm_lchan *lchan)
239{
240 struct gsm_bts_trx_ts *ts = lchan->ts;
241 u_int8_t cbits, chan_nr;
242
243 switch (ts->pchan) {
244 case GSM_PCHAN_TCH_F:
245 cbits = 0x01;
246 break;
247 case GSM_PCHAN_TCH_H:
248 cbits = 0x02;
249 cbits += lchan->nr;
250 break;
251 case GSM_PCHAN_CCCH_SDCCH4:
252 cbits = 0x04;
253 cbits += lchan->nr;
254 break;
255 case GSM_PCHAN_SDCCH8_SACCH8C:
256 cbits = 0x08;
257 cbits += lchan->nr;
258 break;
259 default:
260 case GSM_PCHAN_CCCH:
261 cbits = 0x10;
262 break;
263 }
264
265 chan_nr = (cbits << 3) | (ts->nr & 0x7);
266
267 return chan_nr;
268}
269
270/* As per TS 03.03 Section 2.2, the IMSI has 'not more than 15 digits' */
271u_int64_t str_to_imsi(const char *imsi_str)
272{
273 u_int64_t ret;
274
275 ret = strtoull(imsi_str, NULL, 10);
276
277 return ret;
278}
279
280/* Table 5 Clause 7 TS 05.02 */
281unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res)
282{
283 if (!bs_ccch_sdcch_comb)
284 return 9 - bs_ag_blks_res;
285 else
286 return 3 - bs_ag_blks_res;
287}
288
289/* Chapter 6.5.2 of TS 05.02 */
290unsigned int get_ccch_group(u_int64_t imsi, unsigned int bs_cc_chans,
291 unsigned int n_pag_blocks)
292{
293 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
294}
295
296/* Chapter 6.5.2 of TS 05.02 */
297unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
298 int n_pag_blocks)
299{
300 return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
301}
302
303static struct msgb *rsl_msgb_alloc(void)
304{
Harald Welte9cfc9352009-06-26 19:39:35 +0200305 return msgb_alloc_headroom(RSL_ALLOC_SIZE, RSL_ALLOC_HEADROOM,
306 "RSL");
Harald Welte59b04682009-06-10 05:40:52 +0800307}
308
309#define MACBLOCK_SIZE 23
310static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len)
311{
312 memcpy(out, in, len);
313
314 if (len < MACBLOCK_SIZE)
315 memset(out+len, 0x2b, MACBLOCK_SIZE-len);
316}
317
Harald Weltef1a168d2009-07-28 17:58:09 +0200318static const char *rsl_err_vals[0xff] = {
319 [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
320 [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
321 [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
322 [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
323 [RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
324 [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
Harald Welteb1717e92009-08-04 02:31:05 +0200325 [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
Harald Weltef1a168d2009-07-28 17:58:09 +0200326 [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
327 [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
328 [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
329 [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
330 [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
331 [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
332 [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
333 [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
334 [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
335 [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
336 [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
337 [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
338 [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
339 [RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
340 [RSL_ERR_MSG_TYPE] = "Message Type Error",
341 [RSL_ERR_MSG_SEQ] = "Message Sequence Error",
342 [RSL_ERR_IE_ERROR] = "General IE error",
343 [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
344 [RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
345 [RSL_ERR_IE_NONEXIST] = "IE non-existent",
346 [RSL_ERR_IE_LENGTH] = "IE length error",
347 [RSL_ERR_IE_CONTENT] = "IE content error",
348 [RSL_ERR_PROTO] = "Protocol error, unspecified",
349 [RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
350};
351
352static const char *rsl_err_name(u_int8_t err)
Harald Welte59b04682009-06-10 05:40:52 +0800353{
Harald Weltef1a168d2009-07-28 17:58:09 +0200354 if (rsl_err_vals[err])
355 return rsl_err_vals[err];
356 else
357 return "unknown";
358}
359
360static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
361{
Harald Welte59b04682009-06-10 05:40:52 +0800362 int i;
363
Harald Weltef1a168d2009-07-28 17:58:09 +0200364 DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
365 cause_v[0], rsl_err_name(cause_v[0]));
366 for (i = 1; i < cause_len-1; i++)
367 DEBUGPC(DRSL, "%02x ", cause_v[i]);
Harald Welte59b04682009-06-10 05:40:52 +0800368}
369
370/* Send a BCCH_INFO message as per Chapter 8.5.1 */
371int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
372 const u_int8_t *data, int len)
373{
374 struct abis_rsl_dchan_hdr *dh;
375 struct msgb *msg = rsl_msgb_alloc();
376
377 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof*dh);
378 init_dchan_hdr(dh, RSL_MT_BCCH_INFO);
379 dh->chan_nr = RSL_CHAN_BCCH;
380
381 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
382 msgb_tlv_put(msg, RSL_IE_FULL_BCCH_INFO, len, data);
383
384 msg->trx = trx;
385
386 return abis_rsl_sendmsg(msg);
387}
388
389int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
390 const u_int8_t *data, int len)
391{
392 struct abis_rsl_common_hdr *ch;
393 struct msgb *msg = rsl_msgb_alloc();
394
395 ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));
396 ch->msg_discr = ABIS_RSL_MDISC_TRX;
397 ch->msg_type = RSL_MT_SACCH_FILL;
398
399 msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type);
400 msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data);
401
402 msg->trx = trx;
403
404 return abis_rsl_sendmsg(msg);
405}
406
Harald Welte91afe4c2009-06-20 18:15:19 +0200407int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db)
408{
409 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200410 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200411 u_int8_t chan_nr = lchan2chan_nr(lchan);
412
413 db = abs(db);
414 if (db > 30)
415 return -EINVAL;
416
Harald Welteed831842009-06-27 03:09:08 +0200417 msg = rsl_msgb_alloc();
418
Harald Welte91afe4c2009-06-20 18:15:19 +0200419 lchan->bs_power = db/2;
420 if (fpc)
421 lchan->bs_power |= 0x10;
422
423 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
424 init_dchan_hdr(dh, RSL_MT_BS_POWER_CONTROL);
425 dh->chan_nr = chan_nr;
426
427 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
428
429 msg->trx = lchan->ts->trx;
430
431 return abis_rsl_sendmsg(msg);
432}
433
434/* determine power control level for given dBm value, as indicated
435 * by the tables in chapter 4.1.1 of GSM TS 05.05 */
436static int ms_pwr_ctl_lvl(struct gsm_bts *bts, unsigned int dbm)
437{
438 switch (bts->band) {
439 case GSM_BAND_400:
440 case GSM_BAND_900:
441 case GSM_BAND_850:
442 if (dbm >= 39)
443 return 0;
444 else if (dbm < 5)
445 return 19;
446 else
447 return 2 + ((39 - dbm) / 2);
448 break;
449 case GSM_BAND_1800:
450 if (dbm >= 36)
451 return 29;
452 else if (dbm >= 34)
453 return 30;
454 else if (dbm >= 32)
455 return 31;
456 else
457 return (30 - dbm) / 2;
458 break;
459 case GSM_BAND_1900:
460 if (dbm >= 33)
461 return 30;
462 else if (dbm >= 32)
463 return 31;
464 else
465 return (30 - dbm) / 2;
466 break;
467 }
468 return -EINVAL;
469}
470
Harald Weltea1467eb2009-06-20 18:44:35 +0200471static int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl)
472{
473 lvl &= 0x1f;
474
475 switch (band) {
476 case GSM_BAND_400:
477 case GSM_BAND_900:
478 case GSM_BAND_850:
479 if (lvl < 2)
480 return 39;
481 else if (lvl < 20)
482 return 39 - ((lvl - 2) * 2) ;
483 else
484 return 5;
485 break;
486 case GSM_BAND_1800:
487 if (lvl < 16)
488 return 30 - (lvl * 2);
489 else if (lvl < 29)
490 return 0;
491 else
492 return 36 - ((lvl - 29) * 2);
493 break;
494 case GSM_BAND_1900:
495 if (lvl < 16)
496 return 30 - (lvl * 2);
497 else if (lvl < 30)
498 return -EINVAL;
499 else
500 return 33 - (lvl - 30);
501 break;
502 }
503 return -EINVAL;
504}
505
Harald Welte91afe4c2009-06-20 18:15:19 +0200506int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
507{
508 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200509 struct msgb *msg;
Harald Welte91afe4c2009-06-20 18:15:19 +0200510 u_int8_t chan_nr = lchan2chan_nr(lchan);
511 int ctl_lvl;
512
513 ctl_lvl = ms_pwr_ctl_lvl(lchan->ts->trx->bts, dbm);
514 if (ctl_lvl < 0)
515 return ctl_lvl;
516
Harald Welteed831842009-06-27 03:09:08 +0200517 msg = rsl_msgb_alloc();
518
Harald Welte91afe4c2009-06-20 18:15:19 +0200519 lchan->ms_power = ctl_lvl;
520
521 if (fpc)
522 lchan->ms_power |= 0x20;
523
524 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
525 init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
526 dh->chan_nr = chan_nr;
527
528 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
529
530 msg->trx = lchan->ts->trx;
531
532 return abis_rsl_sendmsg(msg);
533}
534
Harald Welte39274f42009-07-29 15:41:29 +0200535static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
536 struct gsm_lchan *lchan)
537{
538 memset(cm, 0, sizeof(cm));
539
540 /* FIXME: what to do with data calls ? */
541 cm->dtx_dtu = 0x00;
542
543 /* set TCH Speech/Data */
544 cm->spd_ind = lchan->rsl_cmode;
545
546 switch (lchan->type) {
547 case GSM_LCHAN_SDCCH:
548 cm->chan_rt = RSL_CMOD_CRT_SDCCH;
549 break;
550 case GSM_LCHAN_TCH_F:
551 cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
552 break;
553 case GSM_LCHAN_TCH_H:
554 cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
555 break;
556 case GSM_LCHAN_NONE:
557 case GSM_LCHAN_UNKNOWN:
558 default:
559 return -EINVAL;
560 }
561
562 switch (lchan->tch_mode) {
563 case GSM48_CMODE_SIGN:
564 cm->chan_rate = 0;
565 break;
566 case GSM48_CMODE_SPEECH_V1:
567 cm->chan_rate = RSL_CMOD_SP_GSM1;
568 break;
569 case GSM48_CMODE_SPEECH_EFR:
570 cm->chan_rate = RSL_CMOD_SP_GSM2;
571 break;
572 case GSM48_CMODE_SPEECH_AMR:
573 cm->chan_rate = RSL_CMOD_SP_GSM3;
574 break;
575 case GSM48_CMODE_DATA_14k5:
576 cm->chan_rate = RSL_CMOD_SP_NT_14k5;
577 break;
578 case GSM48_CMODE_DATA_12k0:
579 cm->chan_rate = RSL_CMOD_SP_NT_12k0;
580 break;
581 case GSM48_CMODE_DATA_6k0:
582 cm->chan_rate = RSL_CMOD_SP_NT_6k0;
583 break;
584 default:
585 return -EINVAL;
586 }
587
588 return 0;
589}
590
Harald Welte59b04682009-06-10 05:40:52 +0800591/* Chapter 8.4.1 */
592#if 0
593int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
594 u_int8_t act_type,
595 struct rsl_ie_chan_mode *chan_mode,
596 struct rsl_ie_chan_ident *chan_ident,
597 u_int8_t bs_power, u_int8_t ms_power,
598 u_int8_t ta)
599{
600 struct abis_rsl_dchan_hdr *dh;
601 struct msgb *msg = rsl_msgb_alloc();
602
603 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
604 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
605 dh->chan_nr = chan_nr;
606
607 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
608 /* For compatibility with Phase 1 */
609 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode),
610 (u_int8_t *) chan_mode);
611 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
612 (u_int8_t *) chan_ident);
613#if 0
614 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
615 (u_int8_t *) &encr_info);
616#endif
617 msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
618 msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
619 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
620
621 msg->trx = trx;
622
623 return abis_rsl_sendmsg(msg);
624}
625#endif
626
627int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
Harald Welte39274f42009-07-29 15:41:29 +0200628 u_int8_t ta)
Harald Welte59b04682009-06-10 05:40:52 +0800629{
630 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200631 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200632 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800633
634 u_int8_t chan_nr = lchan2chan_nr(lchan);
635 u_int16_t arfcn = lchan->ts->trx->arfcn;
636 struct rsl_ie_chan_mode cm;
637 struct rsl_ie_chan_ident ci;
638
Harald Welte39274f42009-07-29 15:41:29 +0200639 rc = channel_mode_from_lchan(&cm, lchan);
640 if (rc < 0)
641 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800642
643 memset(&ci, 0, sizeof(ci));
644 ci.chan_desc.iei = 0x64;
645 ci.chan_desc.chan_nr = chan_nr;
646 ci.chan_desc.oct3 = (lchan->ts->trx->bts->tsc << 5) | ((arfcn & 0x3ff) >> 8);
647 ci.chan_desc.oct4 = arfcn & 0xff;
648
Harald Welteed831842009-06-27 03:09:08 +0200649 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800650 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
651 init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
652 dh->chan_nr = chan_nr;
653
654 msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
655 /* For compatibility with Phase 1 */
656 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
657 (u_int8_t *) &cm);
658 msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
659 (u_int8_t *) &ci);
660#if 0
661 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
662 (u_int8_t *) &encr_info);
663#endif
664 msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);
665 msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
666 msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
667
668 msg->trx = lchan->ts->trx;
669
670 return abis_rsl_sendmsg(msg);
671}
672
Harald Welte8e770492009-07-29 11:38:15 +0200673/* Chapter 8.4.9: Modify channel mode on BTS side */
Harald Welte59b04682009-06-10 05:40:52 +0800674int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
675{
676 struct abis_rsl_dchan_hdr *dh;
Harald Welteed831842009-06-27 03:09:08 +0200677 struct msgb *msg;
Harald Welte39274f42009-07-29 15:41:29 +0200678 int rc;
Harald Welte59b04682009-06-10 05:40:52 +0800679
680 u_int8_t chan_nr = lchan2chan_nr(lchan);
681 struct rsl_ie_chan_mode cm;
682
Harald Welte39274f42009-07-29 15:41:29 +0200683 rc = channel_mode_from_lchan(&cm, lchan);
684 if (rc < 0)
685 return rc;
Harald Welte59b04682009-06-10 05:40:52 +0800686
Harald Welteed831842009-06-27 03:09:08 +0200687 msg = rsl_msgb_alloc();
Harald Welte59b04682009-06-10 05:40:52 +0800688 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
689 init_dchan_hdr(dh, RSL_MT_MODE_MODIFY_REQ);
690 dh->chan_nr = chan_nr;
691
692 msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
693 (u_int8_t *) &cm);
694#if 0
695 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
696 (u_int8_t *) &encr_info);
697#endif
698
699 msg->trx = lchan->ts->trx;
700
701 return abis_rsl_sendmsg(msg);
702}
703
Harald Welteafe3c232009-07-19 18:36:49 +0200704/* Chapter 8.4.5 */
705int rsl_deact_sacch(struct gsm_lchan *lchan)
706{
707 struct abis_rsl_dchan_hdr *dh;
708 struct msgb *msg = rsl_msgb_alloc();
709
710 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
711 init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH);
712 dh->chan_nr = lchan2chan_nr(lchan);
713
714 msg->lchan = lchan;
715 msg->trx = lchan->ts->trx;
716
717 DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
718 gsm_ts_name(lchan->ts), dh->chan_nr);
719
720 return abis_rsl_sendmsg(msg);
721}
722
Harald Welte59b04682009-06-10 05:40:52 +0800723/* Chapter 9.1.7 of 04.08 */
724int rsl_chan_release(struct gsm_lchan *lchan)
725{
726 struct abis_rsl_dchan_hdr *dh;
727 struct msgb *msg = rsl_msgb_alloc();
728
729 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
730 init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
731 dh->chan_nr = lchan2chan_nr(lchan);
732
733 msg->lchan = lchan;
734 msg->trx = lchan->ts->trx;
735
736 DEBUGP(DRSL, "Channel Release CMD channel=%s chan_nr=0x%02x\n",
737 gsm_ts_name(lchan->ts), dh->chan_nr);
738
739 return abis_rsl_sendmsg(msg);
740}
741
742int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
743 u_int8_t *ms_ident, u_int8_t chan_needed)
744{
745 struct abis_rsl_dchan_hdr *dh;
746 struct msgb *msg = rsl_msgb_alloc();
747
748 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
749 init_dchan_hdr(dh, RSL_MT_PAGING_CMD);
750 dh->chan_nr = RSL_CHAN_PCH_AGCH;
751
752 msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
753 msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
754 msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
755
756 msg->trx = bts->c0;
757
758 return abis_rsl_sendmsg(msg);
759}
760
761int rsl_paging_cmd_subscr(struct gsm_bts *bts, u_int8_t chan_need,
762 struct gsm_subscriber *subscr)
763{
764#if 0
765 u_int8_t mi[128];
766 unsigned int mi_len;
767 u_int8_t paging_group;
768#endif
769
770 return -1;
771}
772
773int imsi_str2bcd(u_int8_t *bcd_out, const char *str_in)
774{
775 int i, len = strlen(str_in);
776
777 for (i = 0; i < len; i++) {
778 int num = str_in[i] - 0x30;
779 if (num < 0 || num > 9)
780 return -1;
781 if (i % 2 == 0)
782 bcd_out[i/2] = num;
783 else
784 bcd_out[i/2] |= (num << 4);
785 }
786
787 return 0;
788}
789
790/* Chapter 8.5.6 */
791int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val)
792{
793 struct msgb *msg = rsl_msgb_alloc();
794 struct abis_rsl_dchan_hdr *dh;
795 u_int8_t buf[MACBLOCK_SIZE];
796
797 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
798 init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
799 dh->chan_nr = RSL_CHAN_PCH_AGCH;
800
801 switch (bts->type) {
802 case GSM_BTS_TYPE_BS11:
803 msgb_tlv_put(msg, RSL_IE_IMM_ASS_INFO, len, val);
804 break;
805 default:
806 /* If phase 2, construct a FULL_IMM_ASS_INFO */
807 pad_macblock(buf, val, len);
808 msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
809 break;
810 }
811
812 msg->trx = bts->c0;
813
814 return abis_rsl_sendmsg(msg);
815}
816
817/* Send "DATA REQUEST" message with given L3 Info payload */
818/* Chapter 8.3.1 */
819int rsl_data_request(struct msgb *msg, u_int8_t link_id)
820{
821 u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
822 struct abis_rsl_rll_hdr *rh;
823
824 if (msg->lchan == NULL) {
825 fprintf(stderr, "cannot send DATA REQUEST to unknown lchan\n");
826 return -EINVAL;
827 }
828
829 /* First push the L3 IE tag and length */
830 msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
831
832 /* Then push the RSL header */
833 rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
834 init_llm_hdr(rh, RSL_MT_DATA_REQ);
835 rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
836 rh->chan_nr = lchan2chan_nr(msg->lchan);
837 rh->link_id = link_id;
838
839 msg->trx = msg->lchan->ts->trx;
840
841 return abis_rsl_sendmsg(msg);
842}
843
Harald Welteed9a5ab2009-08-09 13:47:35 +0200844/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
845/* Chapter 8.3.1 */
846int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
847{
848 struct msgb *msg = rsl_msgb_alloc();
849 struct abis_rsl_rll_hdr *rh;
850
851 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
852 init_llm_hdr(rh, RSL_MT_REL_REQ);
853 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
854 rh->chan_nr = lchan2chan_nr(lchan);
855 rh->link_id = link_id;
856
857 msg->trx = lchan->ts->trx;
858
859 return abis_rsl_sendmsg(msg);
860}
861
Harald Welte0f2e3c12009-08-08 13:15:07 +0200862/* Chapter 8.3.7 Request the release of multiframe mode of RLL connection.
863 This is what higher layers should call. The BTS then responds with
864 RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
865 which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
866 lchan_free() */
867int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
868{
869 struct msgb *msg = rsl_msgb_alloc();
870 struct abis_rsl_rll_hdr *rh;
871
872 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
873 init_llm_hdr(rh, RSL_MT_REL_REQ);
874 //rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
875 rh->chan_nr = lchan2chan_nr(lchan);
876 rh->link_id = link_id;
877
878 msg->trx = lchan->ts->trx;
879
880 return abis_rsl_sendmsg(msg);
881}
882
Harald Welte59b04682009-06-10 05:40:52 +0800883/* Chapter 8.4.2: Channel Activate Acknowledge */
884static int rsl_rx_chan_act_ack(struct msgb *msg)
885{
886 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
887
888 /* BTS has confirmed channel activation, we now need
889 * to assign the activated channel to the MS */
890 if (rslh->ie_chan != RSL_IE_CHAN_NR)
891 return -EINVAL;
892
893 return 0;
894}
895
896/* Chapter 8.4.3: Channel Activate NACK */
897static int rsl_rx_chan_act_nack(struct msgb *msg)
898{
899 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
900 struct tlv_parsed tp;
901
902 /* BTS has rejected channel activation ?!? */
903 if (dh->ie_chan != RSL_IE_CHAN_NR)
904 return -EINVAL;
905
906 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
907 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
Harald Weltef1a168d2009-07-28 17:58:09 +0200908 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
909 TLVP_LEN(&tp, RSL_IE_CAUSE));
910
Harald Welte59b04682009-06-10 05:40:52 +0800911 return 0;
912}
913
914/* Chapter 8.4.4: Connection Failure Indication */
915static int rsl_rx_conn_fail(struct msgb *msg)
916{
917 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
918 struct tlv_parsed tp;
919
920 DEBUGPC(DRSL, "CONNECTION FAIL: ");
Harald Welte59b04682009-06-10 05:40:52 +0800921
922 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
923
Harald Weltef1a168d2009-07-28 17:58:09 +0200924 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
925 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
926 TLVP_LEN(&tp, RSL_IE_CAUSE));
927
Harald Welte59b04682009-06-10 05:40:52 +0800928 if (msg->trx->bts->type == GSM_BTS_TYPE_BS11) {
929 /* FIXME: we have no idea what cause 0x18 is !!! */
930 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE) &&
931 TLVP_LEN(&tp, RSL_IE_CAUSE) >= 1 &&
932 *TLVP_VAL(&tp, RSL_IE_CAUSE) == 0x18) {
Harald Weltedf0c6502009-07-04 10:05:51 +0200933 DEBUGPC(DRSL, "Cause 0x18 IGNORING\n");
934 return 0;
Harald Welte59b04682009-06-10 05:40:52 +0800935 }
936 }
937
938 DEBUGPC(DRSL, "RELEASING.\n");
939
940 /* FIXME: only free it after channel release ACK */
941 return rsl_chan_release(msg->lchan);
942}
943
944static int rsl_rx_meas_res(struct msgb *msg)
945{
946 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
947 struct tlv_parsed tp;
948
Harald Welte02993682009-06-27 02:53:10 +0200949 DEBUGPC(DMEAS, "MEASUREMENT RESULT ");
Harald Welte59b04682009-06-10 05:40:52 +0800950 rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
951
952 if (TLVP_PRESENT(&tp, RSL_IE_MEAS_RES_NR))
Harald Welte02993682009-06-27 02:53:10 +0200953 DEBUGPC(DMEAS, "NR=%d ", *TLVP_VAL(&tp, RSL_IE_MEAS_RES_NR));
Harald Welte59b04682009-06-10 05:40:52 +0800954 if (TLVP_PRESENT(&tp, RSL_IE_UPLINK_MEAS)) {
955 u_int8_t len = TLVP_LEN(&tp, RSL_IE_UPLINK_MEAS);
956 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_UPLINK_MEAS);
957 if (len >= 3) {
958 if (val[0] & 0x40)
Harald Welte02993682009-06-27 02:53:10 +0200959 DEBUGPC(DMEAS, "DTXd ");
960 DEBUGPC(DMEAS, "RXL-FULL-up=%d RXL-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800961 val[0] & 0x3f, val[1] & 0x3f);
Harald Welte02993682009-06-27 02:53:10 +0200962 DEBUGPC(DMEAS, "RXQ-FULL-up=%d RXQ-SUB-up=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800963 val[2]>>3 & 0x7, val[2] & 0x7);
964 }
965 }
966 if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER))
Harald Welte02993682009-06-27 02:53:10 +0200967 DEBUGPC(DMEAS, "BS_POWER=%d ", *TLVP_VAL(&tp, RSL_IE_BS_POWER));
Harald Welte59b04682009-06-10 05:40:52 +0800968 if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET))
Harald Welte02993682009-06-27 02:53:10 +0200969 DEBUGPC(DMEAS, "MS_TO=%d ",
Harald Welte59b04682009-06-10 05:40:52 +0800970 *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET));
Harald Weltea1467eb2009-06-20 18:44:35 +0200971 if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) {
Harald Welteb9498952009-07-12 09:45:05 +0200972 const u_int8_t *val = TLVP_VAL(&tp, RSL_IE_L1_INFO);
Harald Weltea1467eb2009-06-20 18:44:35 +0200973 u_int8_t pwr_lvl = val[0] >> 3;
Harald Welte02993682009-06-27 02:53:10 +0200974 DEBUGPC(DMEAS, "L1_MS_PWR=%ddBm ",
Harald Weltea1467eb2009-06-20 18:44:35 +0200975 ms_pwr_dbm(msg->trx->bts->band, pwr_lvl));
Harald Welte02993682009-06-27 02:53:10 +0200976 DEBUGPC(DMEAS, "L1_FPC=%u ", val[0] & 0x04 ? 1 : 0);
977 DEBUGPC(DMEAS, "L1_TA=%u ", val[1]);
Harald Weltea1467eb2009-06-20 18:44:35 +0200978 }
Harald Welte59b04682009-06-10 05:40:52 +0800979 if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
Harald Welte02993682009-06-27 02:53:10 +0200980 DEBUGPC(DMEAS, "L3\n");
Harald Welte59b04682009-06-10 05:40:52 +0800981 msg->l3h = TLVP_VAL(&tp, RSL_IE_L3_INFO);
982 return gsm0408_rcvmsg(msg);
983 } else
Harald Welte02993682009-06-27 02:53:10 +0200984 DEBUGPC(DMEAS, "\n");
Harald Welte59b04682009-06-10 05:40:52 +0800985
986 return 0;
987}
988
989static int abis_rsl_rx_dchan(struct msgb *msg)
990{
991 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
992 int rc = 0;
993 char *ts_name;
994
995 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
996 ts_name = gsm_ts_name(msg->lchan->ts);
997
Harald Welte02993682009-06-27 02:53:10 +0200998 if (rslh->c.msg_type != RSL_MT_MEAS_RES)
999 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
Harald Welte59b04682009-06-10 05:40:52 +08001000
1001 switch (rslh->c.msg_type) {
1002 case RSL_MT_CHAN_ACTIV_ACK:
1003 DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
1004 rc = rsl_rx_chan_act_ack(msg);
1005 break;
1006 case RSL_MT_CHAN_ACTIV_NACK:
1007 DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
1008 rc = rsl_rx_chan_act_nack(msg);
1009 break;
1010 case RSL_MT_CONN_FAIL:
1011 rc = rsl_rx_conn_fail(msg);
1012 break;
1013 case RSL_MT_MEAS_RES:
1014 rc = rsl_rx_meas_res(msg);
1015 break;
1016 case RSL_MT_RF_CHAN_REL_ACK:
1017 DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
1018 lchan_free(msg->lchan);
1019 break;
1020 case RSL_MT_MODE_MODIFY_ACK:
1021 DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
1022 break;
1023 case RSL_MT_MODE_MODIFY_NACK:
1024 DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
1025 break;
1026 case RSL_MT_PHY_CONTEXT_CONF:
1027 case RSL_MT_PREPROC_MEAS_RES:
1028 case RSL_MT_TALKER_DET:
1029 case RSL_MT_LISTENER_DET:
1030 case RSL_MT_REMOTE_CODEC_CONF_REP:
1031 case RSL_MT_MR_CODEC_MOD_ACK:
1032 case RSL_MT_MR_CODEC_MOD_NACK:
1033 case RSL_MT_MR_CODEC_MOD_PER:
1034 DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
1035 rslh->c.msg_type);
1036 break;
1037 default:
1038 DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
1039 rslh->c.msg_type);
1040 return -EINVAL;
1041 }
1042
1043 return rc;
1044}
1045
1046static int rsl_rx_error_rep(struct msgb *msg)
1047{
1048 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
Harald Weltef1a168d2009-07-28 17:58:09 +02001049 struct tlv_parsed tp;
Harald Welte59b04682009-06-10 05:40:52 +08001050
1051 DEBUGP(DRSL, "ERROR REPORT ");
Harald Weltef1a168d2009-07-28 17:58:09 +02001052
1053 rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
1054
1055 if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
1056 print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
1057 TLVP_LEN(&tp, RSL_IE_CAUSE));
1058
Harald Welte59b04682009-06-10 05:40:52 +08001059 DEBUGPC(DRSL, "\n");
1060
1061 return 0;
1062}
1063
1064static int abis_rsl_rx_trx(struct msgb *msg)
1065{
1066 struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
1067 int rc = 0;
1068
1069 switch (rslh->msg_type) {
1070 case RSL_MT_ERROR_REPORT:
1071 rc = rsl_rx_error_rep(msg);
1072 break;
1073 case RSL_MT_RF_RES_IND:
1074 /* interference on idle channels of TRX */
1075 //DEBUGP(DRSL, "TRX: RF Interference Indication\n");
1076 break;
1077 case RSL_MT_OVERLOAD:
1078 /* indicate CCCH / ACCH / processor overload */
1079 DEBUGP(DRSL, "TRX: CCCH/ACCH/CPU Overload\n");
1080 break;
1081 default:
1082 DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
1083 rslh->msg_type);
1084 return -EINVAL;
1085 }
1086 return rc;
1087}
1088
1089/* MS has requested a channel on the RACH */
1090static int rsl_rx_chan_rqd(struct msgb *msg)
1091{
1092 struct gsm_bts *bts = msg->trx->bts;
1093 struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
1094 struct gsm48_req_ref *rqd_ref;
1095 struct gsm48_imm_ass ia;
1096 enum gsm_chan_t lctype;
1097 enum gsm_chreq_reason_t chreq_reason;
1098 struct gsm_lchan *lchan;
1099 u_int8_t rqd_ta;
1100 int ret;
1101
1102 u_int16_t arfcn;
1103 u_int8_t ts_number, subch;
1104
1105 /* parse request reference to be used in immediate assign */
1106 if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)
1107 return -EINVAL;
1108
1109 rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
1110
1111 /* parse access delay and use as TA */
1112 if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)
1113 return -EINVAL;
1114 rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
1115
1116 /* determine channel type (SDCCH/TCH_F/TCH_H) based on
1117 * request reference RA */
1118 lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
1119 chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
1120
1121 /* check availability / allocate channel */
1122 lchan = lchan_alloc(bts, lctype);
1123 if (!lchan) {
1124 fprintf(stderr, "CHAN RQD: no resources\n");
1125 /* FIXME: send some kind of reject ?!? */
1126 return -ENOMEM;
1127 }
1128
1129 ts_number = lchan->ts->nr;
1130 arfcn = lchan->ts->trx->arfcn;
1131 subch = lchan->nr;
1132
Harald Welte24fc0f82009-08-04 02:31:55 +02001133 lchan->ms_power = ms_pwr_ctl_lvl(bts, 20 /* dBm == 100mW */);
1134 lchan->bs_power = 0x0f; /* 30dB reduction */
Harald Welte39274f42009-07-29 15:41:29 +02001135 lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
1136 rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
Harald Welte59b04682009-06-10 05:40:52 +08001137
1138 /* create IMMEDIATE ASSIGN 04.08 messge */
1139 memset(&ia, 0, sizeof(ia));
1140 ia.l2_plen = 0x2d;
1141 ia.proto_discr = GSM48_PDISC_RR;
1142 ia.msg_type = GSM48_MT_RR_IMM_ASS;
1143 ia.page_mode = GSM48_PM_SAME;
1144 ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
1145 ia.chan_desc.h0.h = 0;
1146 ia.chan_desc.h0.arfcn_high = arfcn >> 8;
1147 ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
Harald Welte63d23c82009-07-21 20:55:56 +02001148 ia.chan_desc.h0.tsc = bts->tsc;
Harald Welte59b04682009-06-10 05:40:52 +08001149 /* use request reference extracted from CHAN_RQD */
1150 memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref));
1151 ia.timing_advance = rqd_ta;
1152 ia.mob_alloc_len = 0;
1153
1154 DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
1155 "chan_nr=0x%02x r=%s ra=0x%02x\n",
1156 arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
1157 ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
1158 rqd_ref->ra);
1159
1160 /* FIXME: Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
1161
1162 /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */
1163 ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia);
1164
1165 return ret;
1166}
1167
1168/* MS has requested a channel on the RACH */
1169static int rsl_rx_ccch_load(struct msgb *msg)
1170{
1171 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1172 u_int16_t pg_buf_space;
1173 u_int16_t rach_slot_count = -1;
1174 u_int16_t rach_busy_count = -1;
1175 u_int16_t rach_access_count = -1;
1176
1177 switch (rslh->data[0]) {
1178 case RSL_IE_PAGING_LOAD:
1179 pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
1180 paging_update_buffer_space(msg->trx->bts, pg_buf_space);
1181 break;
1182 case RSL_IE_RACH_LOAD:
1183 if (msg->data_len >= 7) {
1184 rach_slot_count = rslh->data[2] << 8 | rslh->data[3];
1185 rach_busy_count = rslh->data[4] << 8 | rslh->data[5];
1186 rach_access_count = rslh->data[6] << 8 | rslh->data[7];
1187 }
1188 break;
1189 default:
1190 break;
1191 }
1192
1193 return 0;
1194}
1195
1196static int abis_rsl_rx_cchan(struct msgb *msg)
1197{
1198 struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
1199 int rc = 0;
1200
1201 msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
1202
1203 switch (rslh->c.msg_type) {
1204 case RSL_MT_CHAN_RQD:
1205 /* MS has requested a channel on the RACH */
1206 rc = rsl_rx_chan_rqd(msg);
1207 break;
1208 case RSL_MT_CCCH_LOAD_IND:
1209 /* current load on the CCCH */
1210 rc = rsl_rx_ccch_load(msg);
1211 break;
1212 case RSL_MT_DELETE_IND:
1213 /* CCCH overloaded, IMM_ASSIGN was dropped */
1214 case RSL_MT_CBCH_LOAD_IND:
1215 /* current load on the CBCH */
1216 fprintf(stderr, "Unimplemented Abis RSL TRX message type "
1217 "0x%02x\n", rslh->c.msg_type);
1218 break;
1219 default:
1220 fprintf(stderr, "Unknown Abis RSL TRX message type 0x%02x\n",
1221 rslh->c.msg_type);
1222 return -EINVAL;
1223 }
1224
1225 return rc;
1226}
1227
1228static int rsl_rx_rll_err_ind(struct msgb *msg)
1229{
1230 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1231 u_int8_t *rlm_cause = rllh->data;
1232
Harald Welteb6601442009-08-04 02:50:21 +02001233 DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
Harald Welteed9a5ab2009-08-09 13:47:35 +02001234
1235 rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
Harald Welte59b04682009-06-10 05:40:52 +08001236
Harald Welte692f5852009-07-04 09:40:05 +02001237 if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
1238 return rsl_chan_release(msg->lchan);
1239
Harald Welte59b04682009-06-10 05:40:52 +08001240 return 0;
1241}
1242
1243/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
1244 0x02, 0x06,
1245 0x01, 0x20,
1246 0x02, 0x00,
1247 0x0b, 0x00, 0x0f, 0x05, 0x08, ... */
1248
1249static int abis_rsl_rx_rll(struct msgb *msg)
1250{
1251 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1252 int rc = 0;
1253 char *ts_name;
1254
1255 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1256 ts_name = gsm_ts_name(msg->lchan->ts);
1257 DEBUGP(DRLL, "channel=%s chan_nr=0x%02x ", ts_name, rllh->chan_nr);
1258
1259 switch (rllh->c.msg_type) {
1260 case RSL_MT_DATA_IND:
1261 DEBUGPC(DRLL, "DATA INDICATION\n");
1262 if (msgb_l2len(msg) >
1263 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1264 rllh->data[0] == RSL_IE_L3_INFO) {
1265 msg->l3h = &rllh->data[3];
1266 return gsm0408_rcvmsg(msg);
1267 }
1268 break;
1269 case RSL_MT_EST_IND:
1270 DEBUGPC(DRLL, "ESTABLISH INDICATION\n");
1271 if (msgb_l2len(msg) >
1272 sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
1273 rllh->data[0] == RSL_IE_L3_INFO) {
1274 msg->l3h = &rllh->data[3];
1275 return gsm0408_rcvmsg(msg);
1276 }
1277 break;
Harald Welteed9a5ab2009-08-09 13:47:35 +02001278 case RSL_MT_EST_CONF:
1279 DEBUGPC(DRLL, "ESTABLISH CONFIRMATION\n");
1280 rll_indication(msg->lchan, rllh->link_id,
1281 BSC_RLLR_IND_EST_CONF);
1282 break;
Harald Welte59b04682009-06-10 05:40:52 +08001283 case RSL_MT_REL_IND:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001284 /* BTS informs us of having received DISC from MS */
Harald Welteb6601442009-08-04 02:50:21 +02001285 DEBUGPC(DRLL, "RELEASE INDICATION\n");
Harald Welteed9a5ab2009-08-09 13:47:35 +02001286 rll_indication(msg->lchan, rllh->link_id,
1287 BSC_RLLR_IND_REL_IND);
Harald Welte0f2e3c12009-08-08 13:15:07 +02001288 /* we can now releae the channel on the BTS/Abis side */
1289 rsl_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001290 break;
1291 case RSL_MT_REL_CONF:
Harald Welte0f2e3c12009-08-08 13:15:07 +02001292 /* BTS informs us of having received UA from MS,
1293 * in response to DISC that we've sent earlier */
Harald Welteb6601442009-08-04 02:50:21 +02001294 DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
Harald Welte0f2e3c12009-08-08 13:15:07 +02001295 /* we can now releae the channel on the BTS/Abis side */
1296 rsl_chan_release(msg->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08001297 break;
1298 case RSL_MT_ERROR_IND:
Harald Welte59b04682009-06-10 05:40:52 +08001299 rc = rsl_rx_rll_err_ind(msg);
1300 break;
1301 case RSL_MT_UNIT_DATA_IND:
Harald Welteb6601442009-08-04 02:50:21 +02001302 DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001303 rllh->c.msg_type);
1304 break;
1305 default:
Harald Welteb6601442009-08-04 02:50:21 +02001306 DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
Harald Welte59b04682009-06-10 05:40:52 +08001307 rllh->c.msg_type);
1308 }
Harald Welte59b04682009-06-10 05:40:52 +08001309 return rc;
1310}
1311
Harald Welte98d79f92009-07-28 18:11:56 +02001312static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
1313{
Harald Welte98d79f92009-07-28 18:11:56 +02001314 switch (tch_mode) {
1315 case GSM48_CMODE_SPEECH_V1:
1316 return 0x00;
1317 case GSM48_CMODE_SPEECH_EFR:
1318 return 0x01;
1319 case GSM48_CMODE_SPEECH_AMR:
1320 return 0x02;
1321 /* FIXME: Type1 half-rate and type3 half-rate */
1322 }
Harald Weltefb4a9e92009-07-29 12:12:18 +02001323 DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
1324 "tch_mode == 0x%02x\n", tch_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001325 return 0;
Harald Welte98d79f92009-07-28 18:11:56 +02001326}
1327
Harald Welte59b04682009-06-10 05:40:52 +08001328/* ip.access specific RSL extensions */
1329int rsl_ipacc_bind(struct gsm_lchan *lchan)
1330{
1331 struct msgb *msg = rsl_msgb_alloc();
1332 struct abis_rsl_dchan_hdr *dh;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001333 u_int8_t speech_mode;
Harald Welte59b04682009-06-10 05:40:52 +08001334
1335 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1336 init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
1337 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1338 dh->chan_nr = lchan2chan_nr(lchan);
1339
Harald Welte98d79f92009-07-28 18:11:56 +02001340 /* 0x1- == receive-only, 0x-1 == EFR codec */
Harald Weltefb4a9e92009-07-29 12:12:18 +02001341 speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1342 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001343
Harald Weltefb4a9e92009-07-29 12:12:18 +02001344 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
1345 "speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
1346 dh->chan_nr, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001347
Harald Welte59b04682009-06-10 05:40:52 +08001348 msg->trx = lchan->ts->trx;
1349
1350 return abis_rsl_sendmsg(msg);
1351}
1352
Harald Welte8cdeaad2009-07-12 09:50:35 +02001353int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
1354 u_int16_t conn_id, u_int8_t rtp_payload2)
Harald Welte59b04682009-06-10 05:40:52 +08001355{
1356 struct msgb *msg = rsl_msgb_alloc();
1357 struct abis_rsl_dchan_hdr *dh;
1358 u_int8_t *att_f8, *att_ip, *att_port;
Harald Weltefb4a9e92009-07-29 12:12:18 +02001359 u_int8_t speech_mode;
Harald Welte98d79f92009-07-28 18:11:56 +02001360 struct in_addr ia;
Harald Welte59b04682009-06-10 05:40:52 +08001361
1362 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
1363 init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT);
1364 dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
1365 dh->chan_nr = lchan2chan_nr(lchan);
1366
Harald Weltefb4a9e92009-07-29 12:12:18 +02001367 /* 0x0- == both directions, 0x-1 == EFR codec */
1368 speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
1369
Harald Welte98d79f92009-07-28 18:11:56 +02001370 ia.s_addr = htonl(ip);
Harald Weltefb4a9e92009-07-29 12:12:18 +02001371 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
1372 "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
Harald Welte98d79f92009-07-28 18:11:56 +02001373 gsm_ts_name(lchan->ts), dh->chan_nr,
Harald Weltefb4a9e92009-07-29 12:12:18 +02001374 inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001375
Harald Welte8cdeaad2009-07-12 09:50:35 +02001376 att_f8 = msgb_put(msg, sizeof(conn_id)+1);
Harald Welteb9498952009-07-12 09:45:05 +02001377 att_f8[0] = RSL_IE_IPAC_CONN_ID;
Harald Welte8cdeaad2009-07-12 09:50:35 +02001378 att_f8[1] = conn_id >> 8;
1379 att_f8[2] = conn_id & 0xff;
Harald Welte59b04682009-06-10 05:40:52 +08001380
1381 att_ip = msgb_put(msg, sizeof(ip)+1);
1382 att_ip[0] = RSL_IE_IPAC_REMOTE_IP;
1383 att_ip[1] = ip >> 24;
1384 att_ip[2] = ip >> 16;
1385 att_ip[3] = ip >> 8;
1386 att_ip[4] = ip & 0xff;
1387 //att_ip[4] = 11;
1388
1389 att_port = msgb_put(msg, sizeof(port)+1);
1390 att_port[0] = RSL_IE_IPAC_REMOTE_PORT;
1391 att_port[1] = port >> 8;
1392 att_port[2] = port & 0xff;
1393
Harald Weltefb4a9e92009-07-29 12:12:18 +02001394 msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
Harald Welte98d79f92009-07-28 18:11:56 +02001395 if (rtp_payload2)
1396 msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
1397
Harald Welte59b04682009-06-10 05:40:52 +08001398 msg->trx = lchan->ts->trx;
1399
1400 return abis_rsl_sendmsg(msg);
1401}
1402
1403static int abis_rsl_rx_ipacc_bindack(struct msgb *msg)
1404{
1405 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1406 struct tlv_parsed tv;
1407 struct gsm_bts_trx_ts *ts = msg->lchan->ts;
1408 struct in_addr ip;
1409 u_int16_t port, attr_f8;
1410
1411 /* the BTS has acknowledged a local bind, it now tells us the IP
1412 * address and port number to which it has bound the given logical
1413 * channel */
1414
1415 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
1416 if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) ||
1417 !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) ||
Harald Welteb9498952009-07-12 09:45:05 +02001418 !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) {
Harald Welte59b04682009-06-10 05:40:52 +08001419 DEBUGPC(DRSL, "mandatory IE missing");
1420 return -EINVAL;
1421 }
1422 ip.s_addr = *((u_int32_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_IP));
1423 port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT));
1424 attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8));
1425
Harald Welte98d79f92009-07-28 18:11:56 +02001426 DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ",
1427 inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
1428
1429 if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
1430 ts->abis_ip.rtp_payload2 =
1431 *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
1432 DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
1433 ts->abis_ip.rtp_payload2);
1434 }
Harald Welte59b04682009-06-10 05:40:52 +08001435
1436 /* update our local information about this TS */
1437 ts->abis_ip.bound_ip = ntohl(ip.s_addr);
1438 ts->abis_ip.bound_port = ntohs(port);
Harald Welte8cdeaad2009-07-12 09:50:35 +02001439 ts->abis_ip.conn_id = ntohs(attr_f8);
Harald Welte59b04682009-06-10 05:40:52 +08001440
1441 dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan);
1442
1443 return 0;
1444}
1445
1446static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg)
1447{
1448 struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
1449 struct tlv_parsed tv;
1450
1451 rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
Harald Welte59b04682009-06-10 05:40:52 +08001452
Harald Weltef1a168d2009-07-28 17:58:09 +02001453 if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
1454 print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
1455 TLVP_LEN(&tv, RSL_IE_CAUSE));
Harald Welte59b04682009-06-10 05:40:52 +08001456
Harald Welteba4e58d2009-07-28 18:02:05 +02001457 dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan);
1458
Harald Welte59b04682009-06-10 05:40:52 +08001459 return 0;
1460}
1461
1462static int abis_rsl_rx_ipacc(struct msgb *msg)
1463{
1464 struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
1465 int rc = 0;
1466
1467 msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
1468 DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
1469 gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
1470
1471 switch (rllh->c.msg_type) {
1472 case RSL_MT_IPAC_BIND_ACK:
1473 DEBUGPC(DRSL, "IPAC_BIND_ACK ");
1474 rc = abis_rsl_rx_ipacc_bindack(msg);
1475 break;
1476 case RSL_MT_IPAC_BIND_NACK:
1477 /* somehow the BTS was unable to bind the lchan to its local
1478 * port?!? */
1479 DEBUGPC(DRSL, "IPAC_BIND_NACK ");
1480 break;
1481 case RSL_MT_IPAC_CONNECT_ACK:
1482 /* the BTS tells us that a connect operation was successful */
1483 DEBUGPC(DRSL, "IPAC_CONNECT_ACK ");
1484 break;
1485 case RSL_MT_IPAC_CONNECT_NACK:
1486 /* somehow the BTS was unable to connect the lchan to a remote
1487 * port */
1488 DEBUGPC(DRSL, "IPAC_CONNECT_NACK ");
1489 break;
1490 case RSL_MT_IPAC_DISCONNECT_IND:
1491 DEBUGPC(DRSL, "IPAC_DISCONNECT_IND ");
1492 rc = abis_rsl_rx_ipacc_disc_ind(msg);
1493 break;
1494 default:
1495 DEBUGPC(DRSL, "Unknown ip.access msg_type 0x%02x", rllh->c.msg_type);
1496 break;
1497 }
1498 DEBUGPC(DRSL, "\n");
1499
1500 return rc;
1501}
1502
1503
1504/* Entry-point where L2 RSL from BTS enters */
1505int abis_rsl_rcvmsg(struct msgb *msg)
1506{
1507 struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
1508 int rc = 0;
1509
1510 switch (rslh->msg_discr & 0xfe) {
1511 case ABIS_RSL_MDISC_RLL:
1512 rc = abis_rsl_rx_rll(msg);
1513 break;
1514 case ABIS_RSL_MDISC_DED_CHAN:
1515 rc = abis_rsl_rx_dchan(msg);
1516 break;
1517 case ABIS_RSL_MDISC_COM_CHAN:
1518 rc = abis_rsl_rx_cchan(msg);
1519 break;
1520 case ABIS_RSL_MDISC_TRX:
1521 rc = abis_rsl_rx_trx(msg);
1522 break;
1523 case ABIS_RSL_MDISC_LOC:
1524 fprintf(stderr, "unimplemented RSL msg disc 0x%02x\n",
1525 rslh->msg_discr);
1526 break;
1527 case ABIS_RSL_MDISC_IPACCESS:
1528 rc = abis_rsl_rx_ipacc(msg);
1529 break;
1530 default:
1531 fprintf(stderr, "unknown RSL message discriminator 0x%02x\n",
1532 rslh->msg_discr);
1533 return -EINVAL;
1534 }
1535 msgb_free(msg);
1536 return rc;
1537}
1538
1539
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001540/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
Harald Welte59b04682009-06-10 05:40:52 +08001541int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
1542{
1543 switch (ccch_conf) {
1544 case RSL_BCCH_CCCH_CONF_1_NC:
1545 return 1;
1546 case RSL_BCCH_CCCH_CONF_1_C:
1547 return 1;
1548 case RSL_BCCH_CCCH_CONF_2_NC:
1549 return 2;
1550 case RSL_BCCH_CCCH_CONF_3_NC:
1551 return 3;
1552 case RSL_BCCH_CCCH_CONF_4_NC:
1553 return 4;
1554 default:
1555 return -1;
1556 }
1557}
1558
Holger Hans Peter Freyther4e0fdfd2009-07-09 20:43:16 +02001559/* Section 3.3.2.3 TS 05.02 */
Harald Welte59b04682009-06-10 05:40:52 +08001560int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
1561{
1562 switch (ccch_conf) {
1563 case RSL_BCCH_CCCH_CONF_1_NC:
1564 return 0;
1565 case RSL_BCCH_CCCH_CONF_1_C:
1566 return 1;
1567 case RSL_BCCH_CCCH_CONF_2_NC:
1568 return 0;
1569 case RSL_BCCH_CCCH_CONF_3_NC:
1570 return 0;
1571 case RSL_BCCH_CCCH_CONF_4_NC:
1572 return 0;
1573 default:
1574 return -1;
1575 }
1576}
1577
1578/* From Table 10.5.33 of GSM 04.08 */
1579int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
1580{
1581 if (bts->chan_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C) {
1582 return MAX(1, (3 - bts->chan_desc.bs_ag_blks_res))
1583 * (bts->chan_desc.bs_pa_mfrms + 2);
1584 } else {
1585 return (9 - bts->chan_desc.bs_ag_blks_res)
1586 * (bts->chan_desc.bs_pa_mfrms + 2);
1587 }
1588}