blob: 2312e8abe799d22c317951858acc86449e6f7cc0 [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
2 * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
3
4/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
5 * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
6 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <errno.h>
30#include <time.h>
31#include <netinet/in.h>
32
33#include <openbsc/db.h>
34#include <openbsc/msgb.h>
35#include <openbsc/tlv.h>
36#include <openbsc/debug.h>
37#include <openbsc/gsm_data.h>
38#include <openbsc/gsm_subscriber.h>
39#include <openbsc/gsm_04_11.h>
40#include <openbsc/gsm_04_08.h>
41#include <openbsc/abis_rsl.h>
42#include <openbsc/chan_alloc.h>
43#include <openbsc/paging.h>
44#include <openbsc/signal.h>
45#include <openbsc/trau_frame.h>
46#include <openbsc/trau_mux.h>
Harald Weltea8379772009-06-20 22:36:41 +020047#include <openbsc/talloc.h>
Harald Welte59b04682009-06-10 05:40:52 +080048
49#define GSM48_ALLOC_SIZE 1024
50#define GSM48_ALLOC_HEADROOM 128
51
Harald Welteb8a18b52009-06-10 12:08:54 +080052#define GSM_MAX_FACILITY 128
53#define GSM_MAX_SSVERSION 128
54#define GSM_MAX_USERUSER 128
55
Harald Weltea8379772009-06-20 22:36:41 +020056static void *tall_locop_ctx;
57static void *tall_trans_ctx;
58
Harald Welte59b04682009-06-10 05:40:52 +080059static const struct tlv_definition rsl_att_tlvdef = {
60 .def = {
61 [GSM48_IE_MOBILE_ID] = { TLV_TYPE_TLV },
62 [GSM48_IE_NAME_LONG] = { TLV_TYPE_TLV },
63 [GSM48_IE_NAME_SHORT] = { TLV_TYPE_TLV },
64 [GSM48_IE_UTC] = { TLV_TYPE_TV },
65 [GSM48_IE_NET_TIME_TZ] = { TLV_TYPE_FIXED, 7 },
66 [GSM48_IE_LSA_IDENT] = { TLV_TYPE_TLV },
67
68 [GSM48_IE_BEARER_CAP] = { TLV_TYPE_TLV },
69 [GSM48_IE_CAUSE] = { TLV_TYPE_TLV },
70 [GSM48_IE_CC_CAP] = { TLV_TYPE_TLV },
71 [GSM48_IE_ALERT] = { TLV_TYPE_TLV },
72 [GSM48_IE_FACILITY] = { TLV_TYPE_TLV },
73 [GSM48_IE_PROGR_IND] = { TLV_TYPE_TLV },
74 [GSM48_IE_AUX_STATUS] = { TLV_TYPE_TLV },
Harald Welteb8a18b52009-06-10 12:08:54 +080075 [GSM48_IE_NOTIFY] = { TLV_TYPE_TV },
Harald Welte59b04682009-06-10 05:40:52 +080076 [GSM48_IE_KPD_FACILITY] = { TLV_TYPE_TV },
77 [GSM48_IE_SIGNAL] = { TLV_TYPE_TV },
Harald Welteb8a18b52009-06-10 12:08:54 +080078 [GSM48_IE_CONN_BCD] = { TLV_TYPE_TLV },
79 [GSM48_IE_CONN_SUB] = { TLV_TYPE_TLV },
Harald Welte59b04682009-06-10 05:40:52 +080080 [GSM48_IE_CALLING_BCD] = { TLV_TYPE_TLV },
81 [GSM48_IE_CALLING_SUB] = { TLV_TYPE_TLV },
82 [GSM48_IE_CALLED_BCD] = { TLV_TYPE_TLV },
83 [GSM48_IE_CALLED_SUB] = { TLV_TYPE_TLV },
84 [GSM48_IE_REDIR_BCD] = { TLV_TYPE_TLV },
85 [GSM48_IE_REDIR_SUB] = { TLV_TYPE_TLV },
86 [GSM48_IE_LOWL_COMPAT] = { TLV_TYPE_TLV },
87 [GSM48_IE_HIGHL_COMPAT] = { TLV_TYPE_TLV },
88 [GSM48_IE_USER_USER] = { TLV_TYPE_TLV },
89 [GSM48_IE_SS_VERS] = { TLV_TYPE_TLV },
90 [GSM48_IE_MORE_DATA] = { TLV_TYPE_T },
91 [GSM48_IE_CLIR_SUPP] = { TLV_TYPE_T },
92 [GSM48_IE_CLIR_INVOC] = { TLV_TYPE_T },
93 [GSM48_IE_REV_C_SETUP] = { TLV_TYPE_T },
Harald Welteb8a18b52009-06-10 12:08:54 +080094 [GSM48_IE_REPEAT_CIR] = { TLV_TYPE_T },
95 [GSM48_IE_REPEAT_SEQ] = { TLV_TYPE_T },
Harald Welte59b04682009-06-10 05:40:52 +080096 /* FIXME: more elements */
97 },
98};
99
100static const char *rr_cause_names[] = {
101 [GSM48_RR_CAUSE_NORMAL] = "Normal event",
102 [GSM48_RR_CAUSE_ABNORMAL_UNSPEC] = "Abnormal release, unspecified",
103 [GSM48_RR_CAUSE_ABNORMAL_UNACCT] = "Abnormal release, channel unacceptable",
104 [GSM48_RR_CAUSE_ABNORMAL_TIMER] = "Abnormal release, timer expired",
105 [GSM48_RR_CAUSE_ABNORMAL_NOACT] = "Abnormal release, no activity on radio path",
106 [GSM48_RR_CAUSE_PREMPTIVE_REL] = "Preemptive release",
107 [GSM48_RR_CAUSE_HNDOVER_IMP] = "Handover impossible, timing advance out of range",
108 [GSM48_RR_CAUSE_CHAN_MODE_UNACCT] = "Channel mode unacceptable",
109 [GSM48_RR_CAUSE_FREQ_NOT_IMPL] = "Frequency not implemented",
110 [GSM48_RR_CAUSE_CALL_CLEARED] = "Call already cleared",
111 [GSM48_RR_CAUSE_SEMANT_INCORR] = "Semantically incorrect message",
112 [GSM48_RR_CAUSE_INVALID_MAND_INF] = "Invalid mandatory information",
113 [GSM48_RR_CAUSE_MSG_TYPE_N] = "Message type non-existant or not implemented",
114 [GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT] = "Message type not compatible with protocol state",
115 [GSM48_RR_CAUSE_COND_IE_ERROR] = "Conditional IE error",
116 [GSM48_RR_CAUSE_NO_CELL_ALLOC_A] = "No cell allocation available",
117 [GSM48_RR_CAUSE_PROT_ERROR_UNSPC] = "Protocol error unspecified",
118};
119
Harald Welte03740842009-06-10 23:11:52 +0800120static const char *cc_state_names[] = {
121 "NULL",
122 "INITIATED",
123 "illegal state 2",
124 "MO_CALL_PROC",
125 "CALL_DELIVERED",
126 "illegal state 5",
127 "CALL_PRESENT",
128 "CALL_RECEIVED",
129 "CONNECT_REQUEST",
130 "MO_TERM_CALL_CONF",
131 "ACTIVE",
132 "DISCONNECT_REQ",
133 "DISCONNECT_IND",
134 "illegal state 13",
135 "illegal state 14",
136 "illegal state 15",
137 "illegal state 16",
138 "illegal state 17",
139 "illegal state 18",
140 "RELEASE_REQ",
141 "illegal state 20",
142 "illegal state 21",
143 "illegal state 22",
144 "illegal state 23",
145 "illegal state 24",
146 "illegal state 25",
147 "MO_ORIG_MODIFY",
148 "MO_TERM_MODIFY",
149 "CONNECT_IND",
150 "illegal state 29",
151 "illegal state 30",
152 "illegal state 31",
153};
154
155static const char *cc_msg_names[] = {
156 "unknown 0x00",
157 "ALERTING",
158 "CALL_PROC",
159 "PROGRESS",
160 "ESTAB",
161 "SETUP",
162 "ESTAB_CONF",
163 "CONNECT",
164 "CALL_CONF",
165 "START_CC",
166 "unknown 0x0a",
167 "RECALL",
168 "unknown 0x0c",
169 "unknown 0x0d",
170 "EMERG_SETUP",
171 "CONNECT_ACK",
172 "USER_INFO",
173 "unknown 0x11",
174 "unknown 0x12",
175 "MODIFY_REJECT",
176 "unknown 0x14",
177 "unknown 0x15",
178 "unknown 0x16",
179 "MODIFY",
180 "HOLD",
181 "HOLD_ACK",
182 "HOLD_REJ",
183 "unknown 0x1b",
184 "RETR",
185 "RETR_ACK",
186 "RETR_REJ",
187 "MODIFY_COMPL",
188 "unknown 0x20",
189 "unknown 0x21",
190 "unknown 0x22",
191 "unknown 0x23",
192 "unknown 0x24",
193 "DISCONNECT",
194 "unknown 0x26",
195 "unknown 0x27",
196 "unknown 0x28",
197 "unknown 0x29",
198 "RELEASE_COMPL",
199 "unknown 0x2b",
200 "unknown 0x2c",
201 "RELEASE",
202 "unknown 0x2e",
203 "unknown 0x2f",
204 "unknown 0x30",
205 "STOP_DTMF",
206 "STOP_DTMF_ACK",
207 "unknown 0x33",
208 "STATUS_ENQ",
209 "START_DTMF",
210 "START_DTMF_ACK",
211 "START_DTMF_REJ",
212 "unknown 0x38",
213 "CONG_CTRL",
214 "FACILITY",
215 "unknown 0x3b",
216 "STATUS",
217 "unknown 0x3c",
218 "NOTIFY",
219 "unknown 0x3f",
220};
221
Harald Welte59b04682009-06-10 05:40:52 +0800222static char strbuf[64];
223
224static const char *rr_cause_name(u_int8_t cause)
225{
226 if (cause < ARRAY_SIZE(rr_cause_names) &&
227 rr_cause_names[cause])
228 return rr_cause_names[cause];
229
230 snprintf(strbuf, sizeof(strbuf), "0x%02x", cause);
231 return strbuf;
232}
233
234static void parse_meas_rep(struct gsm_meas_rep *rep, const u_int8_t *data,
235 int len)
236{
237 memset(rep, 0, sizeof(*rep));
238
239 if (data[0] & 0x80)
240 rep->flags |= MEAS_REP_F_BA1;
241 if (data[0] & 0x40)
242 rep->flags |= MEAS_REP_F_DTX;
243 if (data[1] & 0x40)
244 rep->flags |= MEAS_REP_F_VALID;
245
246 rep->rxlev_full = data[0] & 0x3f;
247 rep->rxlev_sub = data[1] & 0x3f;
248 rep->rxqual_full = (data[3] >> 4) & 0x7;
249 rep->rxqual_sub = (data[3] >> 1) & 0x7;
250 rep->num_cell = data[4] >> 6 | ((data[3] & 0x01) << 2);
251 if (rep->num_cell < 1)
252 return;
253
254 /* an encoding nightmare in perfection */
255
256 rep->cell[0].rxlev = data[4] & 0x3f;
257 rep->cell[0].bcch_freq = data[5] >> 2;
258 rep->cell[0].bsic = ((data[5] & 0x03) << 3) | (data[6] >> 5);
259 if (rep->num_cell < 2)
260 return;
261
262 rep->cell[1].rxlev = ((data[6] & 0x1f) << 1) | (data[7] >> 7);
263 rep->cell[1].bcch_freq = (data[7] >> 2) & 0x1f;
264 rep->cell[1].bsic = ((data[7] & 0x03) << 4) | (data[8] >> 4);
265 if (rep->num_cell < 3)
266 return;
267
268 rep->cell[2].rxlev = ((data[8] & 0x0f) << 2) | (data[9] >> 6);
269 rep->cell[2].bcch_freq = (data[9] >> 1) & 0x1f;
270 rep->cell[2].bsic = ((data[9] & 0x01) << 6) | (data[10] >> 3);
271 if (rep->num_cell < 4)
272 return;
273
274 rep->cell[3].rxlev = ((data[10] & 0x07) << 3) | (data[11] >> 5);
275 rep->cell[3].bcch_freq = data[11] & 0x1f;
276 rep->cell[3].bsic = data[12] >> 2;
277 if (rep->num_cell < 5)
278 return;
279
280 rep->cell[4].rxlev = ((data[12] & 0x03) << 4) | (data[13] >> 4);
281 rep->cell[4].bcch_freq = ((data[13] & 0xf) << 1) | (data[14] >> 7);
282 rep->cell[4].bsic = (data[14] >> 1) & 0x3f;
283 if (rep->num_cell < 6)
284 return;
285
286 rep->cell[5].rxlev = ((data[14] & 0x01) << 5) | (data[15] >> 3);
287 rep->cell[5].bcch_freq = ((data[15] & 0x07) << 2) | (data[16] >> 6);
288 rep->cell[5].bsic = data[16] & 0x3f;
289}
290
291int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi);
292static int gsm48_tx_simple(struct gsm_lchan *lchan,
293 u_int8_t pdisc, u_int8_t msg_type);
294static void schedule_reject(struct gsm_lchan *lchan);
Harald Welte03740842009-06-10 23:11:52 +0800295void free_trans(struct gsm_trans *trans);
Harald Welte59b04682009-06-10 05:40:52 +0800296
297struct gsm_lai {
298 u_int16_t mcc;
299 u_int16_t mnc;
300 u_int16_t lac;
301};
302
303static int authorize_everonye = 0;
304void gsm0408_allow_everyone(int everyone)
305{
306 printf("Allowing everyone?\n");
307 authorize_everonye = everyone;
308}
309
310static int reject_cause = 0;
311void gsm0408_set_reject_cause(int cause)
312{
313 reject_cause = cause;
314}
315
Harald Welte03740842009-06-10 23:11:52 +0800316static u_int32_t new_callref = 0x80000001;
317
Harald Welte59b04682009-06-10 05:40:52 +0800318static int authorize_subscriber(struct gsm_loc_updating_operation *loc,
319 struct gsm_subscriber *subscriber)
320{
321 if (!subscriber)
322 return 0;
323
324 /*
325 * Do not send accept yet as more information should arrive. Some
326 * phones will not send us the information and we will have to check
327 * what we want to do with that.
328 */
329 if (loc && (loc->waiting_for_imsi || loc->waiting_for_imei))
330 return 0;
331
332 if (authorize_everonye)
333 return 1;
334
335 return subscriber->authorized;
336}
337
338static void release_loc_updating_req(struct gsm_lchan *lchan)
339{
340 if (!lchan->loc_operation)
341 return;
342
343 bsc_del_timer(&lchan->loc_operation->updating_timer);
Harald Weltea8379772009-06-20 22:36:41 +0200344 talloc_free(lchan->loc_operation);
Harald Welte59b04682009-06-10 05:40:52 +0800345 lchan->loc_operation = 0;
346 put_lchan(lchan);
347}
348
349static void allocate_loc_updating_req(struct gsm_lchan *lchan)
350{
351 use_lchan(lchan);
352 release_loc_updating_req(lchan);
353
Harald Weltea8379772009-06-20 22:36:41 +0200354 if (!tall_locop_ctx)
355 tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 1,
356 "loc_updating_oper");
Harald Welte857e00d2009-06-26 20:25:23 +0200357 lchan->loc_operation = talloc_zero(tall_locop_ctx,
358 struct gsm_loc_updating_operation);
Harald Welte59b04682009-06-10 05:40:52 +0800359}
360
361static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg)
362{
363 u_int32_t tmsi;
364
365 if (authorize_subscriber(lchan->loc_operation, lchan->subscr)) {
366 db_subscriber_alloc_tmsi(lchan->subscr);
367 subscr_update(lchan->subscr, msg->trx->bts, GSM_SUBSCRIBER_UPDATE_ATTACHED);
368 tmsi = strtoul(lchan->subscr->tmsi, NULL, 10);
369 release_loc_updating_req(lchan);
370 return gsm0408_loc_upd_acc(msg->lchan, tmsi);
371 }
372
373 return 0;
374}
375
376static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal,
377 void *handler_data, void *signal_data)
378{
Harald Welte03740842009-06-10 23:11:52 +0800379 struct gsm_trans *trans, *temp;
380
Harald Welte59b04682009-06-10 05:40:52 +0800381 if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
382 return 0;
383
384 /*
385 * Cancel any outstanding location updating request
386 * operation taking place on the lchan.
387 */
Harald Welte12560da2009-07-04 09:35:21 +0200388 struct gsm_lchan *lchan = (struct gsm_lchan *)signal_data;
Harald Welte1ff81b52009-06-26 20:17:06 +0200389 if (!lchan)
390 return 0;
391
Harald Welte59b04682009-06-10 05:40:52 +0800392 release_loc_updating_req(lchan);
393
Harald Welte03740842009-06-10 23:11:52 +0800394 /* Free all transactions that are associated with the released lchan */
395 llist_for_each_entry_safe(trans, temp, &lchan->ts->trx->bts->network->trans_list, entry) {
396 if (trans->lchan == lchan)
397 free_trans(trans);
398 }
399
Harald Welte59b04682009-06-10 05:40:52 +0800400 return 0;
401}
402
403/*
404 * This will be ran by the linker when loading the DSO. We use it to
405 * do system initialization, e.g. registration of signal handlers.
406 */
407static __attribute__((constructor)) void on_dso_load_0408(void)
408{
409 register_signal_handler(SS_LCHAN, gsm0408_handle_lchan_signal, NULL);
410}
411
412static void to_bcd(u_int8_t *bcd, u_int16_t val)
413{
414 bcd[2] = val % 10;
415 val = val / 10;
416 bcd[1] = val % 10;
417 val = val / 10;
418 bcd[0] = val % 10;
419 val = val / 10;
420}
421
422void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
423 u_int16_t mnc, u_int16_t lac)
424{
425 u_int8_t bcd[3];
426
427 to_bcd(bcd, mcc);
428 lai48->digits[0] = bcd[0] | (bcd[1] << 4);
429 lai48->digits[1] = bcd[2];
430
431 to_bcd(bcd, mnc);
432 /* FIXME: do we need three-digit MNC? See Table 10.5.3 */
433#if 0
434 lai48->digits[1] |= bcd[2] << 4;
435 lai48->digits[2] = bcd[0] | (bcd[1] << 4);
436#else
437 lai48->digits[1] |= 0xf << 4;
438 lai48->digits[2] = bcd[1] | (bcd[2] << 4);
439#endif
440
441 lai48->lac = htons(lac);
442}
443
444#define TMSI_LEN 5
445#define MID_TMSI_LEN (TMSI_LEN + 2)
446
447int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi)
448{
449 u_int32_t *tptr = (u_int32_t *) &buf[3];
450
451 buf[0] = GSM48_IE_MOBILE_ID;
452 buf[1] = TMSI_LEN;
453 buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
454 *tptr = htonl(tmsi);
455
456 return 7;
457}
458
459static const char bcd_num_digits[] = {
460 '0', '1', '2', '3', '4', '5', '6', '7',
461 '8', '9', '*', '#', 'a', 'b', 'c', '\0'
462};
463
Harald Welteb8a18b52009-06-10 12:08:54 +0800464/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
465int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
466 int h_len)
Harald Welte59b04682009-06-10 05:40:52 +0800467{
468 u_int8_t in_len = bcd_lv[0];
469 int i;
470
Harald Welteb8a18b52009-06-10 12:08:54 +0800471 for (i = 1 + h_len; i <= in_len; i++) {
Harald Welte59b04682009-06-10 05:40:52 +0800472 /* lower nibble */
473 output_len--;
474 if (output_len <= 1)
475 break;
476 *output++ = bcd_num_digits[bcd_lv[i] & 0xf];
477
478 /* higher nibble */
479 output_len--;
480 if (output_len <= 1)
481 break;
482 *output++ = bcd_num_digits[bcd_lv[i] >> 4];
483 }
484 if (output_len >= 1)
485 *output++ = '\0';
486
Harald Welteb8a18b52009-06-10 12:08:54 +0800487 return 0;
Harald Welte59b04682009-06-10 05:40:52 +0800488}
489
490/* convert a single ASCII character to call-control BCD */
491static int asc_to_bcd(const char asc)
492{
493 int i;
494
495 for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) {
496 if (bcd_num_digits[i] == asc)
497 return i;
498 }
499 return -EINVAL;
500}
501
Harald Welteb8a18b52009-06-10 12:08:54 +0800502/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
Harald Welte59b04682009-06-10 05:40:52 +0800503int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
Harald Welteb8a18b52009-06-10 12:08:54 +0800504 int h_len, const char *input)
Harald Welte59b04682009-06-10 05:40:52 +0800505{
506 int in_len = strlen(input);
507 int i;
Harald Welteb8a18b52009-06-10 12:08:54 +0800508 u_int8_t *bcd_cur = bcd_lv + 1 + h_len;
Harald Welte59b04682009-06-10 05:40:52 +0800509
510 /* two digits per byte, plus type byte */
Harald Welteb8a18b52009-06-10 12:08:54 +0800511 bcd_lv[0] = in_len/2 + h_len;
Harald Welte59b04682009-06-10 05:40:52 +0800512 if (in_len % 2)
513 bcd_lv[0]++;
514
Harald Welteb8a18b52009-06-10 12:08:54 +0800515 if (bcd_lv[0] > max_len)
516 return -EIO;
Harald Welte59b04682009-06-10 05:40:52 +0800517
518 for (i = 0; i < in_len; i++) {
519 int rc = asc_to_bcd(input[i]);
520 if (rc < 0)
521 return rc;
522 if (i % 2 == 0)
523 *bcd_cur = rc;
524 else
525 *bcd_cur++ |= (rc << 4);
526 }
527 /* append padding nibble in case of odd length */
528 if (i % 2)
529 *bcd_cur++ |= 0xf0;
530
531 /* return how many bytes we used */
532 return (bcd_cur - bcd_lv);
533}
534
Harald Welteb8a18b52009-06-10 12:08:54 +0800535/* decode 'bearer capability' */
Harald Welte03740842009-06-10 23:11:52 +0800536static int decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
Harald Welteb8a18b52009-06-10 12:08:54 +0800537 const u_int8_t *lv)
538{
539 u_int8_t in_len = lv[0];
540 int i, s;
541
542 if (in_len < 1)
543 return -EINVAL;
544
Harald Welte03740842009-06-10 23:11:52 +0800545 bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */
Harald Welteb8a18b52009-06-10 12:08:54 +0800546
547 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800548 bcap->transfer = lv[1] & 0x07;
549 bcap->mode = (lv[1] & 0x08) >> 3;
550 bcap->coding = (lv[1] & 0x10) >> 4;
551 bcap->radio = (lv[1] & 0x60) >> 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800552
553 i = 1;
554 s = 0;
555 while(!(lv[i] & 0x80)) {
556 i++; /* octet 3a etc */
557 if (in_len < i)
558 return 0;
Harald Welte03740842009-06-10 23:11:52 +0800559 bcap->speech_ver[s++] = lv[i] & 0x0f;
560 bcap->speech_ver[s] = -1; /* end of list */
Harald Welteb8a18b52009-06-10 12:08:54 +0800561 if (i == 2) /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800562 bcap->speech_ctm = (lv[i] & 0x20) >> 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800563 if (s == 7) /* maximum speech versions + end of list */
564 return 0;
565 }
566
567 return 0;
568}
569
570/* encode 'bearer capability' */
Harald Welte03740842009-06-10 23:11:52 +0800571static int encode_bearer_cap(struct msgb *msg, int lv_only,
572 const struct gsm_mncc_bearer_cap *bcap)
Harald Welteb8a18b52009-06-10 12:08:54 +0800573{
574 u_int8_t lv[32 + 1];
575 int i, s;
576
Harald Welte03740842009-06-10 23:11:52 +0800577 lv[1] = bcap->transfer;
578 lv[1] |= bcap->mode << 3;
579 lv[1] |= bcap->coding << 4;
580 lv[1] |= bcap->radio << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800581
582 i = 1;
Harald Welte03740842009-06-10 23:11:52 +0800583 for (s = 0; bcap->speech_ver[s] >= 0; s++) {
Harald Welteb8a18b52009-06-10 12:08:54 +0800584 i++; /* octet 3a etc */
Harald Welte03740842009-06-10 23:11:52 +0800585 lv[i] = bcap->speech_ver[s];
Harald Welteb8a18b52009-06-10 12:08:54 +0800586 if (i == 2) /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800587 lv[i] |= bcap->speech_ctm << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800588 }
589 lv[i] |= 0x80; /* last IE of octet 3 etc */
590
591 lv[0] = i;
592 if (lv_only)
593 msgb_lv_put(msg, lv[0], lv+1);
594 else
595 msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1);
596
597 return 0;
598}
599
600/* decode 'call control cap' */
Harald Welte03740842009-06-10 23:11:52 +0800601static int decode_cccap(struct gsm_mncc_cccap *ccap, const u_int8_t *lv)
Harald Welteb8a18b52009-06-10 12:08:54 +0800602{
603 u_int8_t in_len = lv[0];
604
605 if (in_len < 1)
606 return -EINVAL;
607
608 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800609 ccap->dtmf = lv[1] & 0x01;
610 ccap->pcp = (lv[1] & 0x02) >> 1;
Harald Welteb8a18b52009-06-10 12:08:54 +0800611
612 return 0;
613}
614
615/* decode 'called party BCD number' */
Harald Welte03740842009-06-10 23:11:52 +0800616static int decode_called(struct gsm_mncc_number *called,
617 const u_int8_t *lv)
Harald Welteb8a18b52009-06-10 12:08:54 +0800618{
619 u_int8_t in_len = lv[0];
620
621 if (in_len < 1)
622 return -EINVAL;
623
624 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800625 called->plan = lv[1] & 0x0f;
626 called->type = (lv[1] & 0x70) >> 4;
Harald Welteb8a18b52009-06-10 12:08:54 +0800627
628 /* octet 4..N */
Harald Welte03740842009-06-10 23:11:52 +0800629 decode_bcd_number(called->number, sizeof(called->number), lv, 1);
Harald Welteb8a18b52009-06-10 12:08:54 +0800630
631 return 0;
632}
633
634/* encode 'called party BCD number' */
Harald Welte03740842009-06-10 23:11:52 +0800635static int encode_called(struct msgb *msg,
636 const struct gsm_mncc_number *called)
Harald Welteb8a18b52009-06-10 12:08:54 +0800637{
638 u_int8_t lv[18];
639 int ret;
640
641 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800642 lv[1] = called->plan;
643 lv[1] |= called->type << 4;
Harald Welteb8a18b52009-06-10 12:08:54 +0800644
645 /* octet 4..N, octet 2 */
Harald Welte03740842009-06-10 23:11:52 +0800646 ret = encode_bcd_number(lv, sizeof(lv), 1, called->number);
Harald Welteb8a18b52009-06-10 12:08:54 +0800647 if (ret < 0)
648 return ret;
649
650 msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1);
651
652 return 0;
653}
654
655/* encode callerid of various IEs */
Harald Welte03740842009-06-10 23:11:52 +0800656static int encode_callerid(struct msgb *msg, int ie,
657 const struct gsm_mncc_number *callerid)
Harald Welteb8a18b52009-06-10 12:08:54 +0800658{
659 u_int8_t lv[13];
660 int h_len = 1;
661 int ret;
662
663 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800664 lv[1] = callerid->plan;
665 lv[1] |= callerid->type << 4;
Harald Welteb8a18b52009-06-10 12:08:54 +0800666
Harald Welte03740842009-06-10 23:11:52 +0800667 if (callerid->present || callerid->screen) {
Harald Welteb8a18b52009-06-10 12:08:54 +0800668 /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800669 lv[2] = callerid->screen;
670 lv[2] |= callerid->present << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800671 lv[2] |= 0x80;
672 h_len++;
673 } else
674 lv[1] |= 0x80;
675
676 /* octet 4..N, octet 2 */
Harald Welte03740842009-06-10 23:11:52 +0800677 ret = encode_bcd_number(lv, sizeof(lv), h_len, callerid->number);
Harald Welteb8a18b52009-06-10 12:08:54 +0800678 if (ret < 0)
679 return ret;
680
681 msgb_tlv_put(msg, ie, lv[0], lv+1);
682
683 return 0;
684}
685
686/* decode 'cause' */
Harald Welte03740842009-06-10 23:11:52 +0800687static int decode_cause(struct gsm_mncc_cause *cause,
Harald Welteb8a18b52009-06-10 12:08:54 +0800688 const u_int8_t *lv)
689{
690 u_int8_t in_len = lv[0];
691 int i;
692
693 if (in_len < 2)
694 return -EINVAL;
695
Harald Welte03740842009-06-10 23:11:52 +0800696 cause->diag_len = 0;
Harald Welteb8a18b52009-06-10 12:08:54 +0800697
698 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800699 cause->location = lv[1] & 0x0f;
700 cause->coding = (lv[1] & 0x60) >> 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800701
702 i = 1;
703 if (!(lv[i] & 0x80)) {
704 i++; /* octet 3a */
705 if (in_len < i+1)
706 return 0;
Harald Welte03740842009-06-10 23:11:52 +0800707 cause->rec = 1;
708 cause->rec_val = lv[i] & 0x7f;
Harald Welteb8a18b52009-06-10 12:08:54 +0800709
710 }
711 i++;
712
713 /* octet 4 */
Harald Welte03740842009-06-10 23:11:52 +0800714 cause->value = lv[i] & 0x7f;
Harald Welteb8a18b52009-06-10 12:08:54 +0800715 i++;
716
717 if (in_len < i) /* no diag */
718 return 0;
719
720 if (in_len - (i-1) > 32) /* maximum 32 octets */
721 return 0;
722
723 /* octet 5-N */
Harald Welte03740842009-06-10 23:11:52 +0800724 memcpy(cause->diag, lv + i, in_len - (i-1));
725 cause->diag_len = in_len - (i-1);
Harald Welteb8a18b52009-06-10 12:08:54 +0800726
727 return 0;
728}
729
730/* encode 'cause' */
Harald Welte03740842009-06-10 23:11:52 +0800731static int encode_cause(struct msgb *msg, int lv_only,
732 const struct gsm_mncc_cause *cause)
Harald Welteb8a18b52009-06-10 12:08:54 +0800733{
734 u_int8_t lv[32+4];
735 int i;
736
Harald Welte03740842009-06-10 23:11:52 +0800737 if (cause->diag_len > 32)
Harald Welteb8a18b52009-06-10 12:08:54 +0800738 return -EINVAL;
739
740 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800741 lv[1] = cause->location;
742 lv[1] |= cause->coding << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800743
744 i = 1;
Harald Welte03740842009-06-10 23:11:52 +0800745 if (cause->rec) {
Harald Welteb8a18b52009-06-10 12:08:54 +0800746 i++; /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800747 lv[i] = cause->rec_val;
Harald Welteb8a18b52009-06-10 12:08:54 +0800748 }
749 lv[i] |= 0x80; /* end of octet 3 */
750
751 /* octet 4 */
752 i++;
Harald Welte03740842009-06-10 23:11:52 +0800753 lv[i] = 0x80 | cause->value;
Harald Welteb8a18b52009-06-10 12:08:54 +0800754
755 /* octet 5-N */
Harald Welte03740842009-06-10 23:11:52 +0800756 if (cause->diag_len) {
757 memcpy(lv + i, cause->diag, cause->diag_len);
758 i += cause->diag_len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800759 }
760
761 lv[0] = i;
762 if (lv_only)
763 msgb_lv_put(msg, lv[0], lv+1);
764 else
765 msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1);
766
767 return 0;
768}
769
770/* encode 'calling number' */
Harald Welte03740842009-06-10 23:11:52 +0800771static int encode_calling(struct msgb *msg,
772 const struct gsm_mncc_number *calling)
Harald Welteb8a18b52009-06-10 12:08:54 +0800773{
Harald Welte03740842009-06-10 23:11:52 +0800774 return encode_callerid(msg, GSM48_IE_CALLING_BCD, calling);
Harald Welteb8a18b52009-06-10 12:08:54 +0800775}
776
777/* encode 'connected number' */
Harald Welte03740842009-06-10 23:11:52 +0800778static int encode_connected(struct msgb *msg,
779 const struct gsm_mncc_number *connected)
Harald Welteb8a18b52009-06-10 12:08:54 +0800780{
Harald Welte03740842009-06-10 23:11:52 +0800781 return encode_callerid(msg, GSM48_IE_CONN_BCD, connected);
Harald Welteb8a18b52009-06-10 12:08:54 +0800782}
783
784/* encode 'redirecting number' */
Harald Welte03740842009-06-10 23:11:52 +0800785static int encode_redirecting(struct msgb *msg,
786 const struct gsm_mncc_number *redirecting)
Harald Welteb8a18b52009-06-10 12:08:54 +0800787{
Harald Welte03740842009-06-10 23:11:52 +0800788 return encode_callerid(msg, GSM48_IE_REDIR_BCD, redirecting);
Harald Welteb8a18b52009-06-10 12:08:54 +0800789}
790
791/* decode 'facility' */
Harald Welte03740842009-06-10 23:11:52 +0800792static int decode_facility(struct gsm_mncc_facility *facility,
Harald Welteb8a18b52009-06-10 12:08:54 +0800793 const u_int8_t *lv)
794{
795 u_int8_t in_len = lv[0];
796
797 if (in_len < 1)
798 return -EINVAL;
799
Harald Welte03740842009-06-10 23:11:52 +0800800 if (in_len > sizeof(facility->info))
Harald Welteb8a18b52009-06-10 12:08:54 +0800801 return -EINVAL;
802
Harald Welte03740842009-06-10 23:11:52 +0800803 memcpy(facility->info, lv+1, in_len);
804 facility->len = in_len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800805
806 return 0;
807}
808
809/* encode 'facility' */
Harald Welte03740842009-06-10 23:11:52 +0800810static int encode_facility(struct msgb *msg, int lv_only,
811 const struct gsm_mncc_facility *facility)
Harald Welteb8a18b52009-06-10 12:08:54 +0800812{
813 u_int8_t lv[GSM_MAX_FACILITY + 1];
814
Harald Welte03740842009-06-10 23:11:52 +0800815 if (facility->len < 1 || facility->len > GSM_MAX_FACILITY)
Harald Welteb8a18b52009-06-10 12:08:54 +0800816 return -EINVAL;
817
Harald Welte03740842009-06-10 23:11:52 +0800818 memcpy(lv+1, facility->info, facility->len);
819 lv[0] = facility->len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800820 if (lv_only)
821 msgb_lv_put(msg, lv[0], lv+1);
822 else
823 msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1);
824
825 return 0;
826}
827
828/* decode 'notify' */
829static int decode_notify(int *notify, const u_int8_t *v)
830{
831 *notify = v[0] & 0x7f;
832
833 return 0;
834}
835
836/* encode 'notify' */
837static int encode_notify(struct msgb *msg, int notify)
838{
839 msgb_v_put(msg, notify | 0x80);
840
841 return 0;
842}
843
844/* encode 'signal' */
845static int encode_signal(struct msgb *msg, int signal)
846{
847 msgb_tv_put(msg, GSM48_IE_SIGNAL, signal);
848
849 return 0;
850}
851
852/* decode 'keypad' */
853static int decode_keypad(int *keypad, const u_int8_t *lv)
854{
855 u_int8_t in_len = lv[0];
856
857 if (in_len < 1)
858 return -EINVAL;
859
860 *keypad = lv[1] & 0x7f;
861
862 return 0;
863}
864
865/* encode 'keypad' */
866static int encode_keypad(struct msgb *msg, int keypad)
867{
868 msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad);
869
870 return 0;
871}
872
873/* decode 'progress' */
Harald Welte03740842009-06-10 23:11:52 +0800874static int decode_progress(struct gsm_mncc_progress *progress,
Harald Welteb8a18b52009-06-10 12:08:54 +0800875 const u_int8_t *lv)
876{
877 u_int8_t in_len = lv[0];
878
879 if (in_len < 2)
880 return -EINVAL;
881
Harald Welte03740842009-06-10 23:11:52 +0800882 progress->coding = (lv[1] & 0x60) >> 5;
883 progress->location = lv[1] & 0x0f;
884 progress->descr = lv[2] & 0x7f;
Harald Welteb8a18b52009-06-10 12:08:54 +0800885
886 return 0;
887}
888
889/* encode 'progress' */
Harald Welte03740842009-06-10 23:11:52 +0800890static int encode_progress(struct msgb *msg, int lv_only,
891 const struct gsm_mncc_progress *p)
Harald Welteb8a18b52009-06-10 12:08:54 +0800892{
893 u_int8_t lv[3];
894
895 lv[0] = 2;
Harald Welte03740842009-06-10 23:11:52 +0800896 lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf);
897 lv[2] = 0x80 | (p->descr & 0x7f);
Harald Welteb8a18b52009-06-10 12:08:54 +0800898 if (lv_only)
899 msgb_lv_put(msg, lv[0], lv+1);
900 else
901 msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1);
902
903 return 0;
904}
905
906/* decode 'user-user' */
Harald Welte03740842009-06-10 23:11:52 +0800907static int decode_useruser(struct gsm_mncc_useruser *uu,
Harald Welteb8a18b52009-06-10 12:08:54 +0800908 const u_int8_t *lv)
909{
910 u_int8_t in_len = lv[0];
Harald Welte03740842009-06-10 23:11:52 +0800911 char *info = uu->info;
912 int info_len = sizeof(uu->info);
Harald Welteb8a18b52009-06-10 12:08:54 +0800913 int i;
914
915 if (in_len < 1)
916 return -EINVAL;
917
Harald Welte03740842009-06-10 23:11:52 +0800918 uu->proto = lv[1];
Harald Welteb8a18b52009-06-10 12:08:54 +0800919
920 for (i = 2; i <= in_len; i++) {
921 info_len--;
922 if (info_len <= 1)
923 break;
924 *info++ = lv[i];
925 }
926 if (info_len >= 1)
927 *info++ = '\0';
928
929 return 0;
930}
931
932/* encode 'useruser' */
Harald Welte03740842009-06-10 23:11:52 +0800933static int encode_useruser(struct msgb *msg, int lv_only,
934 const struct gsm_mncc_useruser *uu)
Harald Welteb8a18b52009-06-10 12:08:54 +0800935{
936 u_int8_t lv[GSM_MAX_USERUSER + 2];
937
Harald Welte03740842009-06-10 23:11:52 +0800938 if (strlen(uu->info) > GSM_MAX_USERUSER)
Harald Welteb8a18b52009-06-10 12:08:54 +0800939 return -EINVAL;
940
Harald Welte03740842009-06-10 23:11:52 +0800941 lv[0] = 1 + strlen(uu->info);
942 lv[1] = uu->proto;
943 memcpy(lv + 2, uu->info, strlen(uu->info));
Harald Welteb8a18b52009-06-10 12:08:54 +0800944 if (lv_only)
945 msgb_lv_put(msg, lv[0], lv+1);
946 else
947 msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1);
948
949 return 0;
950}
951
952/* decode 'ss version' */
Harald Welte03740842009-06-10 23:11:52 +0800953static int decode_ssversion(struct gsm_mncc_ssversion *ssv,
Harald Welteb8a18b52009-06-10 12:08:54 +0800954 const u_int8_t *lv)
955{
956 u_int8_t in_len = lv[0];
957
Harald Welte03740842009-06-10 23:11:52 +0800958 if (in_len < 1 || in_len < sizeof(ssv->info))
Harald Welteb8a18b52009-06-10 12:08:54 +0800959 return -EINVAL;
960
Harald Welte03740842009-06-10 23:11:52 +0800961 memcpy(ssv->info, lv + 1, in_len);
962 ssv->len = in_len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800963
964 return 0;
965}
966
967/* encode 'more data' */
968static int encode_more(struct msgb *msg)
969{
970 u_int8_t *ie;
971
972 ie = msgb_put(msg, 1);
973 ie[0] = GSM48_IE_MORE_DATA;
974
975 return 0;
976}
977
Harald Welte59b04682009-06-10 05:40:52 +0800978struct msgb *gsm48_msgb_alloc(void)
979{
Harald Welte9cfc9352009-06-26 19:39:35 +0200980 return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
981 "GSM 04.08");
Harald Welte59b04682009-06-10 05:40:52 +0800982}
983
984int gsm48_sendmsg(struct msgb *msg)
985{
Harald Welte59b04682009-06-10 05:40:52 +0800986 if (msg->lchan) {
Harald Welte03740842009-06-10 23:11:52 +0800987 struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data;
Harald Welte59b04682009-06-10 05:40:52 +0800988 msg->trx = msg->lchan->ts->trx;
989
Harald Welte03740842009-06-10 23:11:52 +0800990 if ((gh->proto_discr & GSM48_PDISC_MASK) == GSM48_PDISC_CC)
991 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x) "
992 "Sending '%s' to MS.\n", msg->trx->bts->nr,
993 msg->trx->nr, msg->lchan->ts->nr,
994 gh->proto_discr & 0xf0,
995 cc_msg_names[gh->msg_type & 0x3f]);
996 else
997 DEBUGP(DCC, "(bts %d trx %d ts %d pd %02x) "
998 "Sending 0x%02x to MS.\n", msg->trx->bts->nr,
999 msg->trx->nr, msg->lchan->ts->nr,
1000 gh->proto_discr, gh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +08001001 }
1002
1003 msg->l3h = msg->data;
1004
1005 return rsl_data_request(msg, 0);
1006}
1007
Harald Welte59b04682009-06-10 05:40:52 +08001008/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
1009int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
1010{
1011 struct msgb *msg = gsm48_msgb_alloc();
1012 struct gsm48_hdr *gh;
1013
1014 msg->lchan = lchan;
1015
1016 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
1017 gh->proto_discr = GSM48_PDISC_MM;
1018 gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT;
1019 gh->data[0] = cause;
1020
1021 DEBUGP(DMM, "-> LOCATION UPDATING REJECT on channel: %d\n", lchan->nr);
1022
1023 return gsm48_sendmsg(msg);
1024}
1025
1026/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
1027int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
1028{
1029 struct gsm_bts *bts = lchan->ts->trx->bts;
1030 struct msgb *msg = gsm48_msgb_alloc();
1031 struct gsm48_hdr *gh;
1032 struct gsm48_loc_area_id *lai;
1033 u_int8_t *mid;
1034 int ret;
1035
1036 msg->lchan = lchan;
1037
1038 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1039 gh->proto_discr = GSM48_PDISC_MM;
1040 gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT;
1041
1042 lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
1043 gsm0408_generate_lai(lai, bts->network->country_code,
1044 bts->network->network_code, bts->location_area_code);
1045
1046 mid = msgb_put(msg, MID_TMSI_LEN);
1047 generate_mid_from_tmsi(mid, tmsi);
1048
1049 DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
1050
1051 ret = gsm48_sendmsg(msg);
1052
1053 ret = gsm48_tx_mm_info(lchan);
1054
1055 return ret;
1056}
1057
1058static char bcd2char(u_int8_t bcd)
1059{
1060 if (bcd < 0xa)
1061 return '0' + bcd;
1062 else
1063 return 'A' + (bcd - 0xa);
1064}
1065
1066/* Convert Mobile Identity (10.5.1.4) to string */
1067static int mi_to_string(char *string, int str_len, u_int8_t *mi, int mi_len)
1068{
1069 int i;
1070 u_int8_t mi_type;
1071 char *str_cur = string;
1072 u_int32_t tmsi;
1073
1074 mi_type = mi[0] & GSM_MI_TYPE_MASK;
1075
1076 switch (mi_type) {
1077 case GSM_MI_TYPE_NONE:
1078 break;
1079 case GSM_MI_TYPE_TMSI:
1080 /* Table 10.5.4.3, reverse generate_mid_from_tmsi */
1081 if (mi_len == TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {
1082 memcpy(&tmsi, &mi[1], 4);
1083 tmsi = ntohl(tmsi);
1084 return snprintf(string, str_len, "%u", tmsi);
1085 }
1086 break;
1087 case GSM_MI_TYPE_IMSI:
1088 case GSM_MI_TYPE_IMEI:
1089 case GSM_MI_TYPE_IMEISV:
1090 *str_cur++ = bcd2char(mi[0] >> 4);
1091
1092 for (i = 1; i < mi_len; i++) {
1093 if (str_cur + 2 >= string + str_len)
1094 return str_cur - string;
1095 *str_cur++ = bcd2char(mi[i] & 0xf);
1096 /* skip last nibble in last input byte when GSM_EVEN */
1097 if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
1098 *str_cur++ = bcd2char(mi[i] >> 4);
1099 }
1100 break;
1101 default:
1102 break;
1103 }
1104 *str_cur++ = '\0';
1105
1106 return str_cur - string;
1107}
1108
1109/* Transmit Chapter 9.2.10 Identity Request */
1110static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type)
1111{
1112 struct msgb *msg = gsm48_msgb_alloc();
1113 struct gsm48_hdr *gh;
1114
1115 msg->lchan = lchan;
1116
1117 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
1118 gh->proto_discr = GSM48_PDISC_MM;
1119 gh->msg_type = GSM48_MT_MM_ID_REQ;
1120 gh->data[0] = id_type;
1121
1122 return gsm48_sendmsg(msg);
1123}
1124
1125#define MI_SIZE 32
1126
1127/* Parse Chapter 9.2.11 Identity Response */
1128static int mm_rx_id_resp(struct msgb *msg)
1129{
1130 struct gsm48_hdr *gh = msgb_l3(msg);
1131 struct gsm_lchan *lchan = msg->lchan;
1132 u_int8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
1133 char mi_string[MI_SIZE];
1134
1135 mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
1136 DEBUGP(DMM, "IDENTITY RESPONSE: mi_type=0x%02x MI(%s)\n",
1137 mi_type, mi_string);
1138
Harald Welte59b04682009-06-10 05:40:52 +08001139 switch (mi_type) {
1140 case GSM_MI_TYPE_IMSI:
1141 if (!lchan->subscr)
1142 lchan->subscr = db_create_subscriber(mi_string);
1143 if (lchan->loc_operation)
1144 lchan->loc_operation->waiting_for_imsi = 0;
1145 break;
1146 case GSM_MI_TYPE_IMEI:
1147 case GSM_MI_TYPE_IMEISV:
1148 /* update subscribe <-> IMEI mapping */
1149 if (lchan->subscr)
1150 db_subscriber_assoc_imei(lchan->subscr, mi_string);
1151 if (lchan->loc_operation)
1152 lchan->loc_operation->waiting_for_imei = 0;
1153 break;
1154 }
1155
1156 /* Check if we can let the mobile station enter */
1157 return gsm0408_authorize(lchan, msg);
1158}
1159
1160
1161static void loc_upd_rej_cb(void *data)
1162{
1163 struct gsm_lchan *lchan = data;
1164
1165 release_loc_updating_req(lchan);
1166 gsm0408_loc_upd_rej(lchan, reject_cause);
1167 lchan_auto_release(lchan);
1168}
1169
1170static void schedule_reject(struct gsm_lchan *lchan)
1171{
1172 lchan->loc_operation->updating_timer.cb = loc_upd_rej_cb;
1173 lchan->loc_operation->updating_timer.data = lchan;
1174 bsc_schedule_timer(&lchan->loc_operation->updating_timer, 5, 0);
1175}
1176
1177static const char *lupd_name(u_int8_t type)
1178{
1179 switch (type) {
1180 case GSM48_LUPD_NORMAL:
1181 return "NORMAL";
1182 case GSM48_LUPD_PERIODIC:
1183 return "PEROIDOC";
1184 case GSM48_LUPD_IMSI_ATT:
1185 return "IMSI ATTACH";
1186 default:
1187 return "UNKNOWN";
1188 }
1189}
1190
1191#define MI_SIZE 32
1192/* Chapter 9.2.15: Receive Location Updating Request */
1193static int mm_rx_loc_upd_req(struct msgb *msg)
1194{
1195 struct gsm48_hdr *gh = msgb_l3(msg);
1196 struct gsm48_loc_upd_req *lu;
Harald Welte03740842009-06-10 23:11:52 +08001197 struct gsm_subscriber *subscr = NULL;
Harald Welte59b04682009-06-10 05:40:52 +08001198 struct gsm_lchan *lchan = msg->lchan;
1199 u_int8_t mi_type;
1200 char mi_string[MI_SIZE];
1201 int rc;
1202
1203 lu = (struct gsm48_loc_upd_req *) gh->data;
1204
1205 mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
1206
1207 mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
1208
Harald Welte79639662009-06-27 02:58:43 +02001209 DEBUGPC(DMM, "mi_type=0x%02x MI(%s) type=%s ", mi_type, mi_string,
Harald Welte59b04682009-06-10 05:40:52 +08001210 lupd_name(lu->type));
1211
1212 /*
1213 * Pseudo Spoof detection: Just drop a second/concurrent
1214 * location updating request.
1215 */
1216 if (lchan->loc_operation) {
Harald Welte79639662009-06-27 02:58:43 +02001217 DEBUGPC(DMM, "ignoring request due an existing one: %p.\n",
Harald Welte59b04682009-06-10 05:40:52 +08001218 lchan->loc_operation);
1219 gsm0408_loc_upd_rej(lchan, GSM48_REJECT_PROTOCOL_ERROR);
1220 return 0;
1221 }
1222
1223 allocate_loc_updating_req(lchan);
1224
1225 switch (mi_type) {
1226 case GSM_MI_TYPE_IMSI:
Harald Welte79639662009-06-27 02:58:43 +02001227 DEBUGPC(DMM, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001228 /* we always want the IMEI, too */
Harald Welte59b04682009-06-10 05:40:52 +08001229 rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEI);
1230 lchan->loc_operation->waiting_for_imei = 1;
1231
1232 /* look up subscriber based on IMSI */
1233 subscr = db_create_subscriber(mi_string);
1234 break;
1235 case GSM_MI_TYPE_TMSI:
Harald Welte79639662009-06-27 02:58:43 +02001236 DEBUGPC(DMM, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001237 /* we always want the IMEI, too */
Harald Welte59b04682009-06-10 05:40:52 +08001238 rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEI);
1239 lchan->loc_operation->waiting_for_imei = 1;
1240
1241 /* look up the subscriber based on TMSI, request IMSI if it fails */
1242 subscr = subscr_get_by_tmsi(mi_string);
1243 if (!subscr) {
1244 /* send IDENTITY REQUEST message to get IMSI */
Harald Welte59b04682009-06-10 05:40:52 +08001245 rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI);
1246 lchan->loc_operation->waiting_for_imsi = 1;
1247 }
1248 break;
1249 case GSM_MI_TYPE_IMEI:
1250 case GSM_MI_TYPE_IMEISV:
1251 /* no sim card... FIXME: what to do ? */
Harald Welte79639662009-06-27 02:58:43 +02001252 DEBUGPC(DMM, "unimplemented mobile identity type\n");
Harald Welte59b04682009-06-10 05:40:52 +08001253 break;
1254 default:
Harald Welte79639662009-06-27 02:58:43 +02001255 DEBUGPC(DMM, "unknown mobile identity type\n");
Harald Welte59b04682009-06-10 05:40:52 +08001256 break;
1257 }
1258
Harald Welteccd69362009-07-04 10:18:00 +02001259 /* schedule the reject timer */
1260 schedule_reject(lchan);
1261
Harald Welte03740842009-06-10 23:11:52 +08001262 if (!subscr) {
Harald Welte79639662009-06-27 02:58:43 +02001263 DEBUGPC(DRR, "<- Can't find any subscriber for this ID\n");
Harald Welte03740842009-06-10 23:11:52 +08001264 /* FIXME: request id? close channel? */
1265 return -EINVAL;
1266 }
1267
Harald Welte59b04682009-06-10 05:40:52 +08001268 lchan->subscr = subscr;
1269
Harald Welteccd69362009-07-04 10:18:00 +02001270 /* check if we can let the subscriber into our network immediately
1271 * or if we need to wait for identity responses. */
Harald Welte59b04682009-06-10 05:40:52 +08001272 return gsm0408_authorize(lchan, msg);
1273}
1274
1275/* 9.1.5 Channel mode modify */
1276int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode)
1277{
1278 struct msgb *msg = gsm48_msgb_alloc();
1279 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1280 struct gsm48_chan_mode_modify *cmm =
1281 (struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm));
1282 u_int16_t arfcn = lchan->ts->trx->arfcn & 0x3ff;
1283
1284 DEBUGP(DRR, "-> CHANNEL MODE MODIFY mode=0x%02x\n", mode);
1285
1286 lchan->tch_mode = mode;
1287 msg->lchan = lchan;
1288 gh->proto_discr = GSM48_PDISC_RR;
1289 gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF;
1290
1291 /* fill the channel information element, this code
1292 * should probably be shared with rsl_rx_chan_rqd() */
1293 cmm->chan_desc.chan_nr = lchan2chan_nr(lchan);
1294 cmm->chan_desc.h0.tsc = lchan->ts->trx->bts->tsc;
1295 cmm->chan_desc.h0.h = 0;
1296 cmm->chan_desc.h0.arfcn_high = arfcn >> 8;
1297 cmm->chan_desc.h0.arfcn_low = arfcn & 0xff;
1298 cmm->mode = mode;
1299
1300 return gsm48_sendmsg(msg);
1301}
1302
Harald Welte03740842009-06-10 23:11:52 +08001303#if 0
1304static u_int8_t to_bcd8(u_int8_t val)
1305{
1306 return ((val / 10) << 4) | (val % 10);
1307}
1308#endif
1309
Harald Welte59b04682009-06-10 05:40:52 +08001310/* Section 9.2.15a */
1311int gsm48_tx_mm_info(struct gsm_lchan *lchan)
1312{
1313 struct msgb *msg = gsm48_msgb_alloc();
1314 struct gsm48_hdr *gh;
1315 struct gsm_network *net = lchan->ts->trx->bts->network;
1316 u_int8_t *ptr8;
1317 u_int16_t *ptr16;
1318 int name_len;
1319 int i;
Harald Welte03740842009-06-10 23:11:52 +08001320#if 0
1321 time_t cur_t;
1322 struct tm* cur_time;
1323 int tz15min;
1324#endif
Harald Welte59b04682009-06-10 05:40:52 +08001325
1326 msg->lchan = lchan;
1327
1328 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1329 gh->proto_discr = GSM48_PDISC_MM;
1330 gh->msg_type = GSM48_MT_MM_INFO;
1331
1332 if (net->name_long) {
1333 name_len = strlen(net->name_long);
1334 /* 10.5.3.5a */
1335 ptr8 = msgb_put(msg, 3);
1336 ptr8[0] = GSM48_IE_NAME_LONG;
1337 ptr8[1] = name_len*2 +1;
1338 ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
1339
1340 ptr16 = (u_int16_t *) msgb_put(msg, name_len*2);
1341 for (i = 0; i < name_len; i++)
1342 ptr16[i] = htons(net->name_long[i]);
1343
1344 /* FIXME: Use Cell Broadcast, not UCS-2, since
1345 * UCS-2 is only supported by later revisions of the spec */
1346 }
1347
1348 if (net->name_short) {
1349 name_len = strlen(net->name_short);
1350 /* 10.5.3.5a */
1351 ptr8 = (u_int8_t *) msgb_put(msg, 3);
1352 ptr8[0] = GSM48_IE_NAME_LONG;
1353 ptr8[1] = name_len*2 + 1;
1354 ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
1355
1356 ptr16 = (u_int16_t *) msgb_put(msg, name_len*2);
1357 for (i = 0; i < name_len; i++)
1358 ptr16[i] = htons(net->name_short[i]);
1359 }
1360
1361#if 0
Harald Welte59b04682009-06-10 05:40:52 +08001362 /* Section 10.5.3.9 */
1363 cur_t = time(NULL);
Harald Welte03740842009-06-10 23:11:52 +08001364 cur_time = gmtime(&cur_t);
Harald Welte59b04682009-06-10 05:40:52 +08001365 ptr8 = msgb_put(msg, 8);
1366 ptr8[0] = GSM48_IE_NET_TIME_TZ;
1367 ptr8[1] = to_bcd8(cur_time->tm_year % 100);
1368 ptr8[2] = to_bcd8(cur_time->tm_mon);
1369 ptr8[3] = to_bcd8(cur_time->tm_mday);
1370 ptr8[4] = to_bcd8(cur_time->tm_hour);
1371 ptr8[5] = to_bcd8(cur_time->tm_min);
1372 ptr8[6] = to_bcd8(cur_time->tm_sec);
1373 /* 02.42: coded as BCD encoded signed value in units of 15 minutes */
1374 tz15min = (cur_time->tm_gmtoff)/(60*15);
Harald Welte03740842009-06-10 23:11:52 +08001375 ptr8[7] = to_bcd8(tz15min);
Harald Welte59b04682009-06-10 05:40:52 +08001376 if (tz15min < 0)
Harald Welte03740842009-06-10 23:11:52 +08001377 ptr8[7] |= 0x80;
Harald Welte59b04682009-06-10 05:40:52 +08001378#endif
1379
1380 return gsm48_sendmsg(msg);
1381}
1382
1383static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
1384{
1385 DEBUGP(DMM, "-> CM SERVICE ACK\n");
1386 return gsm48_tx_simple(lchan, GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_ACC);
1387}
1388
1389/* 9.2.6 CM service reject */
1390static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan,
1391 enum gsm48_reject_value value)
1392{
1393 struct msgb *msg = gsm48_msgb_alloc();
1394 struct gsm48_hdr *gh;
1395
1396 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
1397
1398 msg->lchan = lchan;
1399 use_lchan(lchan);
1400
1401 gh->proto_discr = GSM48_PDISC_MM;
1402 gh->msg_type = GSM48_MT_MM_CM_SERV_REJ;
1403 gh->data[0] = value;
1404 DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);
1405
1406 return gsm48_sendmsg(msg);
1407}
1408
1409
1410/*
1411 * Handle CM Service Requests
1412 * a) Verify that the packet is long enough to contain the information
1413 * we require otherwsie reject with INCORRECT_MESSAGE
1414 * b) Try to parse the TMSI. If we do not have one reject
1415 * c) Check that we know the subscriber with the TMSI otherwise reject
1416 * with a HLR cause
1417 * d) Set the subscriber on the gsm_lchan and accept
1418 */
1419static int gsm48_rx_mm_serv_req(struct msgb *msg)
1420{
1421 u_int8_t mi_type;
1422 char mi_string[MI_SIZE];
1423
1424 struct gsm_subscriber *subscr;
1425 struct gsm48_hdr *gh = msgb_l3(msg);
1426 struct gsm48_service_request *req =
1427 (struct gsm48_service_request *)gh->data;
1428 /* unfortunately in Phase1 the classmar2 length is variable */
1429 u_int8_t classmark2_len = gh->data[1];
1430 u_int8_t *classmark2 = gh->data+2;
1431 u_int8_t mi_len = *(classmark2 + classmark2_len);
1432 u_int8_t *mi = (classmark2 + classmark2_len + 1);
1433
1434 DEBUGP(DMM, "<- CM SERVICE REQUEST ");
1435 if (msg->data_len < sizeof(struct gsm48_service_request*)) {
1436 DEBUGPC(DMM, "wrong sized message\n");
1437 return gsm48_tx_mm_serv_rej(msg->lchan,
1438 GSM48_REJECT_INCORRECT_MESSAGE);
1439 }
1440
1441 if (msg->data_len < req->mi_len + 6) {
1442 DEBUGPC(DMM, "does not fit in packet\n");
1443 return gsm48_tx_mm_serv_rej(msg->lchan,
1444 GSM48_REJECT_INCORRECT_MESSAGE);
1445 }
1446
1447 mi_type = mi[0] & GSM_MI_TYPE_MASK;
1448 if (mi_type != GSM_MI_TYPE_TMSI) {
1449 DEBUGPC(DMM, "mi_type is not TMSI: %d\n", mi_type);
1450 return gsm48_tx_mm_serv_rej(msg->lchan,
1451 GSM48_REJECT_INCORRECT_MESSAGE);
1452 }
1453
1454 mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
1455 DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
1456 req->cm_service_type, mi_type, mi_string);
1457
1458 subscr = subscr_get_by_tmsi(mi_string);
1459
1460 /* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
1461 if (!subscr)
1462 return gsm48_tx_mm_serv_rej(msg->lchan,
1463 GSM48_REJECT_IMSI_UNKNOWN_IN_HLR);
1464
1465 if (!msg->lchan->subscr)
1466 msg->lchan->subscr = subscr;
1467 else if (msg->lchan->subscr != subscr) {
1468 DEBUGP(DMM, "<- CM Channel already owned by someone else?\n");
1469 subscr_put(subscr);
1470 }
1471
1472 subscr->classmark2_len = classmark2_len;
1473 memcpy(subscr->classmark2, classmark2, classmark2_len);
1474
1475 return gsm48_tx_mm_serv_ack(msg->lchan);
1476}
1477
1478static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg)
1479{
1480 struct gsm48_hdr *gh = msgb_l3(msg);
1481 struct gsm48_imsi_detach_ind *idi =
1482 (struct gsm48_imsi_detach_ind *) gh->data;
1483 u_int8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK;
1484 char mi_string[MI_SIZE];
Harald Welte03740842009-06-10 23:11:52 +08001485 struct gsm_subscriber *subscr = NULL;
Harald Welte59b04682009-06-10 05:40:52 +08001486
1487 mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len);
1488 DEBUGP(DMM, "IMSI DETACH INDICATION: mi_type=0x%02x MI(%s): ",
1489 mi_type, mi_string);
1490
1491 switch (mi_type) {
1492 case GSM_MI_TYPE_TMSI:
1493 subscr = subscr_get_by_tmsi(mi_string);
1494 break;
1495 case GSM_MI_TYPE_IMSI:
1496 subscr = subscr_get_by_imsi(mi_string);
1497 break;
1498 case GSM_MI_TYPE_IMEI:
1499 case GSM_MI_TYPE_IMEISV:
1500 /* no sim card... FIXME: what to do ? */
1501 DEBUGPC(DMM, "unimplemented mobile identity type\n");
1502 break;
1503 default:
1504 DEBUGPC(DMM, "unknown mobile identity type\n");
1505 break;
1506 }
1507
1508 if (subscr) {
1509 subscr_update(subscr, msg->trx->bts,
1510 GSM_SUBSCRIBER_UPDATE_DETACHED);
1511 DEBUGP(DMM, "Subscriber: %s\n",
1512 subscr->name ? subscr->name : subscr->imsi);
1513 subscr_put(subscr);
1514 } else
1515 DEBUGP(DMM, "Unknown Subscriber ?!?\n");
1516
Harald Welte59b04682009-06-10 05:40:52 +08001517 return 0;
1518}
1519
1520static int gsm48_rx_mm_status(struct msgb *msg)
1521{
1522 struct gsm48_hdr *gh = msgb_l3(msg);
1523
1524 DEBUGP(DMM, "MM STATUS (reject cause 0x%02x)\n", gh->data[0]);
1525
1526 return 0;
1527}
1528
1529/* Receive a GSM 04.08 Mobility Management (MM) message */
1530static int gsm0408_rcv_mm(struct msgb *msg)
1531{
1532 struct gsm48_hdr *gh = msgb_l3(msg);
Harald Welte03740842009-06-10 23:11:52 +08001533 int rc = 0;
Harald Welte59b04682009-06-10 05:40:52 +08001534
1535 switch (gh->msg_type & 0xbf) {
1536 case GSM48_MT_MM_LOC_UPD_REQUEST:
Harald Welte79639662009-06-27 02:58:43 +02001537 DEBUGP(DMM, "LOCATION UPDATING REQUEST: ");
Harald Welte59b04682009-06-10 05:40:52 +08001538 rc = mm_rx_loc_upd_req(msg);
1539 break;
1540 case GSM48_MT_MM_ID_RESP:
1541 rc = mm_rx_id_resp(msg);
1542 break;
1543 case GSM48_MT_MM_CM_SERV_REQ:
1544 rc = gsm48_rx_mm_serv_req(msg);
1545 break;
1546 case GSM48_MT_MM_STATUS:
1547 rc = gsm48_rx_mm_status(msg);
1548 break;
1549 case GSM48_MT_MM_TMSI_REALL_COMPL:
1550 DEBUGP(DMM, "TMSI Reallocation Completed. Subscriber: %s\n",
1551 msg->lchan->subscr ?
1552 msg->lchan->subscr->imsi :
1553 "unknown subscriber");
1554 break;
1555 case GSM48_MT_MM_IMSI_DETACH_IND:
1556 rc = gsm48_rx_mm_imsi_detach_ind(msg);
1557 break;
1558 case GSM48_MT_MM_CM_REEST_REQ:
1559 DEBUGP(DMM, "CM REESTABLISH REQUEST: Not implemented\n");
1560 break;
1561 case GSM48_MT_MM_AUTH_RESP:
1562 DEBUGP(DMM, "AUTHENTICATION RESPONSE: Not implemented\n");
1563 break;
1564 default:
1565 fprintf(stderr, "Unknown GSM 04.08 MM msg type 0x%02x\n",
1566 gh->msg_type);
1567 break;
1568 }
1569
1570 return rc;
1571}
1572
1573/* Receive a PAGING RESPONSE message from the MS */
1574static int gsm48_rr_rx_pag_resp(struct msgb *msg)
1575{
1576 struct gsm48_hdr *gh = msgb_l3(msg);
1577 u_int8_t *classmark2_lv = gh->data + 1;
1578 u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv;
1579 u_int8_t mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
1580 char mi_string[MI_SIZE];
Harald Welte03740842009-06-10 23:11:52 +08001581 struct gsm_subscriber *subscr = NULL;
Harald Welte59b04682009-06-10 05:40:52 +08001582 struct paging_signal_data sig_data;
1583 int rc = 0;
1584
1585 mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, *mi_lv);
1586 DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
1587 mi_type, mi_string);
1588 switch (mi_type) {
1589 case GSM_MI_TYPE_TMSI:
1590 subscr = subscr_get_by_tmsi(mi_string);
1591 break;
1592 case GSM_MI_TYPE_IMSI:
1593 subscr = subscr_get_by_imsi(mi_string);
1594 break;
1595 }
1596
1597 if (!subscr) {
1598 DEBUGP(DRR, "<- Can't find any subscriber for this ID\n");
1599 /* FIXME: request id? close channel? */
1600 return -EINVAL;
1601 }
1602 DEBUGP(DRR, "<- Channel was requested by %s\n",
1603 subscr->name ? subscr->name : subscr->imsi);
1604
1605 subscr->classmark2_len = *classmark2_lv;
1606 memcpy(subscr->classmark2, classmark2_lv+1, *classmark2_lv);
1607
1608 if (!msg->lchan->subscr) {
1609 msg->lchan->subscr = subscr;
1610 } else if (msg->lchan->subscr != subscr) {
1611 DEBUGP(DRR, "<- Channel already owned by someone else?\n");
1612 subscr_put(subscr);
1613 return -EINVAL;
1614 } else {
1615 DEBUGP(DRR, "<- Channel already owned by us\n");
1616 subscr_put(subscr);
1617 subscr = msg->lchan->subscr;
1618 }
1619
1620 sig_data.subscr = subscr;
1621 sig_data.bts = msg->lchan->ts->trx->bts;
1622 sig_data.lchan = msg->lchan;
1623
1624 dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
Harald Welte876312f2009-06-10 11:21:55 +08001625
1626 /* Stop paging on the bts we received the paging response */
Harald Welte59b04682009-06-10 05:40:52 +08001627 paging_request_stop(msg->trx->bts, subscr, msg->lchan);
1628
1629 /* FIXME: somehow signal the completion of the PAGING to
1630 * the entity that requested the paging */
1631
1632 return rc;
1633}
1634
1635static int gsm48_rx_rr_classmark(struct msgb *msg)
1636{
1637 struct gsm48_hdr *gh = msgb_l3(msg);
1638 struct gsm_subscriber *subscr = msg->lchan->subscr;
1639 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1640 u_int8_t cm2_len, cm3_len = 0;
1641 u_int8_t *cm2, *cm3 = NULL;
1642
1643 DEBUGP(DRR, "CLASSMARK CHANGE ");
1644
1645 /* classmark 2 */
1646 cm2_len = gh->data[0];
1647 cm2 = &gh->data[1];
1648 DEBUGPC(DRR, "CM2(len=%u) ", cm2_len);
1649
1650 if (payload_len > cm2_len + 1) {
1651 /* we must have a classmark3 */
1652 if (gh->data[cm2_len+1] != 0x20) {
1653 DEBUGPC(DRR, "ERR CM3 TAG\n");
1654 return -EINVAL;
1655 }
1656 if (cm2_len > 3) {
1657 DEBUGPC(DRR, "CM2 too long!\n");
1658 return -EINVAL;
1659 }
1660
1661 cm3_len = gh->data[cm2_len+2];
1662 cm3 = &gh->data[cm2_len+3];
1663 if (cm3_len > 14) {
1664 DEBUGPC(DRR, "CM3 len %u too long!\n", cm3_len);
1665 return -EINVAL;
1666 }
1667 DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len);
1668 }
1669 if (subscr) {
1670 subscr->classmark2_len = cm2_len;
1671 memcpy(subscr->classmark2, cm2, cm2_len);
1672 if (cm3) {
1673 subscr->classmark3_len = cm3_len;
1674 memcpy(subscr->classmark3, cm3, cm3_len);
1675 }
1676 }
1677
1678 /* FIXME: store the classmark2/3 values with the equipment register */
1679
1680 return 0;
1681}
1682
1683static int gsm48_rx_rr_status(struct msgb *msg)
1684{
1685 struct gsm48_hdr *gh = msgb_l3(msg);
1686
1687 DEBUGP(DRR, "STATUS rr_cause = %s\n",
1688 rr_cause_name(gh->data[0]));
1689
1690 return 0;
1691}
1692
1693static int gsm48_rx_rr_meas_rep(struct msgb *msg)
1694{
1695 struct gsm48_hdr *gh = msgb_l3(msg);
1696 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1697 static struct gsm_meas_rep meas_rep;
1698
Harald Welte02993682009-06-27 02:53:10 +02001699 DEBUGP(DMEAS, "MEASUREMENT REPORT ");
Harald Welte59b04682009-06-10 05:40:52 +08001700 parse_meas_rep(&meas_rep, gh->data, payload_len);
1701 if (meas_rep.flags & MEAS_REP_F_DTX)
Harald Welte02993682009-06-27 02:53:10 +02001702 DEBUGPC(DMEAS, "DTX ");
Harald Welte59b04682009-06-10 05:40:52 +08001703 if (meas_rep.flags & MEAS_REP_F_BA1)
Harald Welte02993682009-06-27 02:53:10 +02001704 DEBUGPC(DMEAS, "BA1 ");
Harald Welte59b04682009-06-10 05:40:52 +08001705 if (!(meas_rep.flags & MEAS_REP_F_VALID))
Harald Welte02993682009-06-27 02:53:10 +02001706 DEBUGPC(DMEAS, "NOT VALID ");
Harald Welte59b04682009-06-10 05:40:52 +08001707 else
Harald Welte02993682009-06-27 02:53:10 +02001708 DEBUGPC(DMEAS, "FULL(lev=%u, qual=%u) SUB(lev=%u, qual=%u) ",
Harald Welte59b04682009-06-10 05:40:52 +08001709 meas_rep.rxlev_full, meas_rep.rxqual_full, meas_rep.rxlev_sub,
1710 meas_rep.rxqual_sub);
1711
Harald Welte02993682009-06-27 02:53:10 +02001712 DEBUGPC(DMEAS, "NUM_NEIGH=%u\n", meas_rep.num_cell);
Harald Welte59b04682009-06-10 05:40:52 +08001713
1714 /* FIXME: put the results somwhere */
1715
1716 return 0;
1717}
1718
1719/* Receive a GSM 04.08 Radio Resource (RR) message */
1720static int gsm0408_rcv_rr(struct msgb *msg)
1721{
1722 struct gsm48_hdr *gh = msgb_l3(msg);
1723 int rc = 0;
1724
1725 switch (gh->msg_type) {
1726 case GSM48_MT_RR_CLSM_CHG:
1727 rc = gsm48_rx_rr_classmark(msg);
1728 break;
1729 case GSM48_MT_RR_GPRS_SUSP_REQ:
1730 DEBUGP(DRR, "GRPS SUSPEND REQUEST\n");
1731 break;
1732 case GSM48_MT_RR_PAG_RESP:
1733 rc = gsm48_rr_rx_pag_resp(msg);
1734 break;
1735 case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
1736 DEBUGP(DRR, "CHANNEL MODE MODIFY ACK\n");
1737 rc = rsl_chan_mode_modify_req(msg->lchan);
1738 break;
1739 case GSM48_MT_RR_STATUS:
1740 rc = gsm48_rx_rr_status(msg);
1741 break;
1742 case GSM48_MT_RR_MEAS_REP:
1743 rc = gsm48_rx_rr_meas_rep(msg);
1744 break;
1745 default:
1746 fprintf(stderr, "Unimplemented GSM 04.08 RR msg type 0x%02x\n",
1747 gh->msg_type);
1748 break;
1749 }
1750
1751 return rc;
1752}
1753
1754/* 7.1.7 and 9.1.7 Channel release*/
1755int gsm48_send_rr_release(struct gsm_lchan *lchan)
1756{
1757 struct msgb *msg = gsm48_msgb_alloc();
1758 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1759 u_int8_t *cause;
1760
1761 msg->lchan = lchan;
1762 gh->proto_discr = GSM48_PDISC_RR;
1763 gh->msg_type = GSM48_MT_RR_CHAN_REL;
1764
1765 cause = msgb_put(msg, 1);
1766 cause[0] = GSM48_RR_CAUSE_NORMAL;
1767
1768 DEBUGP(DRR, "Sending Channel Release: Chan: Number: %d Type: %d\n",
1769 lchan->nr, lchan->type);
1770
1771 return gsm48_sendmsg(msg);
1772}
1773
1774/* Call Control */
1775
1776/* The entire call control code is written in accordance with Figure 7.10c
1777 * for 'very early assignment', i.e. we allocate a TCH/F during IMMEDIATE
1778 * ASSIGN, then first use that TCH/F for signalling and later MODE MODIFY
1779 * it for voice */
1780
Harald Welte03740842009-06-10 23:11:52 +08001781static void new_cc_state(struct gsm_trans *trans, int state)
1782{
1783 if (state > 31 || state < 0)
1784 return;
1785
1786 DEBUGP(DCC, "new state %s -> %s\n",
1787 cc_state_names[trans->state], cc_state_names[state]);
1788
1789 trans->state = state;
1790}
1791
1792static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg)
Harald Welte59b04682009-06-10 05:40:52 +08001793{
1794 struct msgb *msg = gsm48_msgb_alloc();
1795 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1796 u_int8_t *cause, *call_state;
1797
Harald Welte03740842009-06-10 23:11:52 +08001798 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
1799 msg->lchan = trans->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001800 gh->msg_type = GSM48_MT_CC_STATUS;
1801
1802 cause = msgb_put(msg, 3);
1803 cause[0] = 2;
1804 cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
1805 cause[2] = 0x80 | 30; /* response to status inquiry */
1806
1807 call_state = msgb_put(msg, 1);
1808 call_state[0] = 0xc0 | 0x00;
1809
1810 return gsm48_sendmsg(msg);
1811}
1812
1813static int gsm48_tx_simple(struct gsm_lchan *lchan,
1814 u_int8_t pdisc, u_int8_t msg_type)
1815{
1816 struct msgb *msg = gsm48_msgb_alloc();
1817 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1818
1819 msg->lchan = lchan;
1820
1821 gh->proto_discr = pdisc;
1822 gh->msg_type = msg_type;
1823
1824 return gsm48_sendmsg(msg);
1825}
1826
Harald Welte03740842009-06-10 23:11:52 +08001827static void gsm48_stop_cc_timer(struct gsm_trans *trans)
1828{
1829 if (bsc_timer_pending(&trans->cc_timer)) {
1830 DEBUGP(DCC, "stopping pending timer T%x\n", trans->Tcurrent);
1831 bsc_del_timer(&trans->cc_timer);
1832 trans->Tcurrent = 0;
1833 }
1834}
1835
1836static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
1837 int msg_type, struct gsm_mncc *mncc)
1838{
1839 struct msgb *msg;
1840
1841 if (trans)
1842 if (trans->lchan)
1843 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
1844 "Sending '%s' to MNCC.\n",
1845 trans->lchan->ts->trx->bts->nr,
1846 trans->lchan->ts->trx->nr,
1847 trans->lchan->ts->nr, trans->transaction_id,
1848 (trans->subscr)?(trans->subscr->extension):"-",
1849 get_mncc_name(msg_type));
1850 else
1851 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
1852 "Sending '%s' to MNCC.\n",
1853 (trans->subscr)?(trans->subscr->extension):"-",
1854 get_mncc_name(msg_type));
1855 else
1856 DEBUGP(DCC, "(bts - trx - ts - ti -- sub -) "
1857 "Sending '%s' to MNCC.\n", get_mncc_name(msg_type));
1858
1859 mncc->msg_type = msg_type;
1860
Harald Welte9cfc9352009-06-26 19:39:35 +02001861 msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
Harald Welte03740842009-06-10 23:11:52 +08001862 if (!msg)
1863 return -ENOMEM;
1864 memcpy(msg->data, mncc, sizeof(struct gsm_mncc));
1865 msgb_enqueue(&net->upqueue, msg);
1866
1867 return 0;
1868}
1869
1870int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans,
1871 u_int32_t callref, int location, int value)
1872{
1873 struct gsm_mncc rel;
1874
Harald Weltecb0595f2009-06-12 01:54:08 +08001875 memset(&rel, 0, sizeof(rel));
Harald Welte03740842009-06-10 23:11:52 +08001876 rel.callref = callref;
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08001877 mncc_set_cause(&rel, location, value);
Harald Welte03740842009-06-10 23:11:52 +08001878 return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
1879}
1880
1881void free_trans(struct gsm_trans *trans)
1882{
1883 struct gsm_bts *bts;
1884
1885 gsm48_stop_cc_timer(trans);
1886
1887 /* send release to L4, if callref still exists */
1888 if (trans->callref) {
1889 /* Ressource unavailable */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08001890 mncc_release_ind(trans->network, trans, trans->callref,
1891 GSM48_CAUSE_LOC_PRN_S_LU,
1892 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08001893 if (trans->state != GSM_CSTATE_NULL)
1894 new_cc_state(trans, GSM_CSTATE_NULL);
1895 }
1896
1897 if (!trans->lchan && trans->subscr && trans->subscr->net) {
1898 /* Stop paging on all bts' */
1899 bts = NULL;
1900 do {
1901 bts = gsm_bts_by_lac(trans->subscr->net,
1902 trans->subscr->lac, bts);
1903 if (!bts)
1904 break;
1905 /* Stop paging */
1906 paging_request_stop(bts, trans->subscr, NULL);
1907 } while (1);
1908 }
1909
1910 if (trans->lchan) {
1911 trau_mux_unmap(&trans->lchan->ts->e1_link, trans->callref);
1912 put_lchan(trans->lchan);
1913 }
1914
1915 if (trans->subscr)
1916 subscr_put(trans->subscr);
1917
1918 if (trans->state != GSM_CSTATE_NULL)
1919 new_cc_state(trans, GSM_CSTATE_NULL);
1920
1921 llist_del(&trans->entry);
1922
Harald Weltea8379772009-06-20 22:36:41 +02001923 talloc_free(trans);
Harald Welte03740842009-06-10 23:11:52 +08001924}
1925
1926static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
1927
Harald Welte59b04682009-06-10 05:40:52 +08001928/* call-back from paging the B-end of the connection */
1929static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
1930 struct msgb *msg, void *_lchan, void *param)
1931{
1932 struct gsm_lchan *lchan = _lchan;
Harald Welte03740842009-06-10 23:11:52 +08001933 struct gsm_subscriber *subscr = param;
1934 struct gsm_trans *transt, *tmp;
1935 struct gsm_network *net;
Harald Welte1ff81b52009-06-26 20:17:06 +02001936
Harald Welte59b04682009-06-10 05:40:52 +08001937 if (hooknum != GSM_HOOK_RR_PAGING)
1938 return -EINVAL;
Harald Welte03740842009-06-10 23:11:52 +08001939
1940 if (!subscr)
1941 return -EINVAL;
1942 net = subscr->net;
1943 if (!net) {
1944 DEBUGP(DCC, "Error Network not set!\n");
1945 return -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08001946 }
1947
Harald Welte03740842009-06-10 23:11:52 +08001948 /* check all tranactions (without lchan) for subscriber */
1949 llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) {
1950 if (transt->subscr != subscr || transt->lchan)
1951 continue;
1952 switch (event) {
1953 case GSM_PAGING_SUCCEEDED:
1954 if (!lchan) // paranoid
1955 break;
1956 DEBUGP(DCC, "Paging subscr %s succeeded!\n",
1957 subscr->extension);
1958 /* Assign lchan */
1959 if (!transt->lchan) {
1960 transt->lchan = lchan;
1961 use_lchan(lchan);
1962 }
1963 /* send SETUP request to called party */
1964 gsm48_cc_tx_setup(transt, &transt->cc_msg);
1965 if (is_ipaccess_bts(lchan->ts->trx->bts))
1966 rsl_ipacc_bind(lchan);
1967 break;
1968 case GSM_PAGING_EXPIRED:
1969 DEBUGP(DCC, "Paging subscr %s expired!\n",
1970 subscr->extension);
1971 /* Temporarily out of order */
1972 mncc_release_ind(transt->network, transt, transt->callref,
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08001973 GSM48_CAUSE_LOC_PRN_S_LU,
1974 GSM48_CC_CAUSE_DEST_OOO);
Harald Welte03740842009-06-10 23:11:52 +08001975 transt->callref = 0;
1976 free_trans(transt);
1977 break;
1978 }
1979 }
Harald Welte59b04682009-06-10 05:40:52 +08001980 return 0;
1981}
1982
Harald Welte59b04682009-06-10 05:40:52 +08001983/* map two ipaccess RTP streams onto each other */
1984static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
1985{
1986 struct gsm_bts *bts = lchan->ts->trx->bts;
1987 struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts;
1988 struct gsm_bts_trx_ts *ts;
1989
1990 DEBUGP(DCC, "Setting up TCH map between (bts=%u,trx=%u,ts=%u) and (bts=%u,trx=%u,ts=%u)\n",
1991 bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1992 remote_bts->nr, remote_lchan->ts->trx->nr, remote_lchan->ts->nr);
1993
1994 if (bts->type != remote_bts->type) {
1995 DEBUGP(DCC, "Cannot switch calls between different BTS types yet\n");
1996 return -EINVAL;
1997 }
1998
1999 switch (bts->type) {
2000 case GSM_BTS_TYPE_NANOBTS_900:
2001 case GSM_BTS_TYPE_NANOBTS_1800:
2002 ts = remote_lchan->ts;
2003 rsl_ipacc_connect(lchan, ts->abis_ip.bound_ip, ts->abis_ip.bound_port,
2004 lchan->ts->abis_ip.attr_f8, ts->abis_ip.attr_fc);
2005
2006 ts = lchan->ts;
2007 rsl_ipacc_connect(remote_lchan, ts->abis_ip.bound_ip, ts->abis_ip.bound_port,
2008 remote_lchan->ts->abis_ip.attr_f8, ts->abis_ip.attr_fc);
2009 break;
2010 case GSM_BTS_TYPE_BS11:
2011 trau_mux_map_lchan(lchan, remote_lchan);
2012 break;
2013 default:
2014 DEBUGP(DCC, "Unknown BTS type %u\n", bts->type);
2015 break;
2016 }
2017
2018 return 0;
2019}
2020
Harald Welte03740842009-06-10 23:11:52 +08002021static struct gsm_trans *get_trans_ref(struct gsm_network *net, u_int32_t callref)
Harald Welte59b04682009-06-10 05:40:52 +08002022{
Harald Welte03740842009-06-10 23:11:52 +08002023 struct gsm_trans *trans;
2024 llist_for_each_entry(trans, &net->trans_list, entry) {
2025 if (trans->callref == callref)
2026 return trans;
2027 }
2028 return NULL;
Harald Welte59b04682009-06-10 05:40:52 +08002029}
2030
Harald Welte03740842009-06-10 23:11:52 +08002031/* bridge channels of two transactions */
2032static int tch_bridge(struct gsm_network *net, u_int32_t *refs)
Harald Welte59b04682009-06-10 05:40:52 +08002033{
Harald Welte03740842009-06-10 23:11:52 +08002034 struct gsm_trans *trans1 = get_trans_ref(net, refs[0]);
2035 struct gsm_trans *trans2 = get_trans_ref(net, refs[1]);
Harald Welte59b04682009-06-10 05:40:52 +08002036
Harald Welte03740842009-06-10 23:11:52 +08002037 if (!trans1 || !trans2)
Harald Welte59b04682009-06-10 05:40:52 +08002038 return -EIO;
2039
Harald Welte03740842009-06-10 23:11:52 +08002040 if (!trans1->lchan || !trans2->lchan)
2041 return -EIO;
2042
2043 /* through-connect channel */
2044 return tch_map(trans1->lchan, trans2->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002045}
2046
Harald Welte03740842009-06-10 23:11:52 +08002047/* enable receive of channels to upqueue */
2048static int tch_recv(struct gsm_network *net, struct gsm_mncc *data, int enable)
2049{
2050 struct gsm_trans *trans;
Harald Welte59b04682009-06-10 05:40:52 +08002051
Harald Welte03740842009-06-10 23:11:52 +08002052 /* Find callref */
2053 trans = get_trans_ref(net, data->callref);
2054 if (!trans)
2055 return -EIO;
2056 if (!trans->lchan)
2057 return 0;
2058
2059 // todo IPACCESS
2060 if (enable)
2061 return trau_recv_lchan(trans->lchan, data->callref);
2062 return trau_mux_unmap(NULL, data->callref);
2063}
2064
2065/* send a frame to channel */
2066static int tch_frame(struct gsm_network *net, struct gsm_trau_frame *frame)
2067{
2068 struct gsm_trans *trans;
2069
2070 /* Find callref */
2071 trans = get_trans_ref(net, frame->callref);
2072 if (!trans)
2073 return -EIO;
2074 if (!trans->lchan)
2075 return 0;
2076 if (trans->lchan->type != GSM_LCHAN_TCH_F &&
2077 trans->lchan->type != GSM_LCHAN_TCH_H)
2078 return 0;
2079
2080 // todo IPACCESS
2081 return trau_send_lchan(trans->lchan,
2082 (struct decoded_trau_frame *)frame->data);
2083}
2084
2085
2086static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
2087{
2088 DEBUGP(DCC, "-> STATUS ENQ\n");
2089 return gsm48_cc_tx_status(trans, msg);
2090}
2091
2092static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
2093static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);
2094
2095static void gsm48_cc_timeout(void *arg)
2096{
2097 struct gsm_trans *trans = arg;
2098 int disconnect = 0, release = 0;
Harald Weltebbc636a2009-06-11 14:23:20 +08002099 int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
2100 int mo_location = GSM48_CAUSE_LOC_USER;
2101 int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
2102 int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
Harald Welte03740842009-06-10 23:11:52 +08002103 struct gsm_mncc mo_rel, l4_rel;
2104
2105 memset(&mo_rel, 0, sizeof(struct gsm_mncc));
2106 mo_rel.callref = trans->callref;
2107 memset(&l4_rel, 0, sizeof(struct gsm_mncc));
2108 l4_rel.callref = trans->callref;
2109
2110 switch(trans->Tcurrent) {
2111 case 0x303:
2112 release = 1;
Harald Weltebbc636a2009-06-11 14:23:20 +08002113 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
Harald Welte03740842009-06-10 23:11:52 +08002114 break;
2115 case 0x310:
2116 disconnect = 1;
Harald Weltebbc636a2009-06-11 14:23:20 +08002117 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
Harald Welte03740842009-06-10 23:11:52 +08002118 break;
2119 case 0x313:
2120 disconnect = 1;
2121 /* unknown, did not find it in the specs */
2122 break;
2123 case 0x301:
2124 disconnect = 1;
Harald Weltebbc636a2009-06-11 14:23:20 +08002125 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
Harald Welte03740842009-06-10 23:11:52 +08002126 break;
2127 case 0x308:
2128 if (!trans->T308_second) {
2129 /* restart T308 a second time */
2130 gsm48_cc_tx_release(trans, &trans->cc_msg);
2131 trans->T308_second = 1;
2132 break; /* stay in release state */
2133 }
2134 free_trans(trans);
2135 return;
2136// release = 1;
2137// l4_cause = 14;
2138// break;
2139 case 0x306:
2140 release = 1;
2141 mo_cause = trans->cc_msg.cause.value;
2142 mo_location = trans->cc_msg.cause.location;
2143 break;
2144 case 0x323:
2145 disconnect = 1;
2146 break;
2147 default:
2148 release = 1;
2149 }
2150
2151 if (release && trans->callref) {
2152 /* process release towards layer 4 */
2153 mncc_release_ind(trans->network, trans, trans->callref,
2154 l4_location, l4_cause);
2155 trans->callref = 0;
2156 }
2157
2158 if (disconnect && trans->callref) {
2159 /* process disconnect towards layer 4 */
2160 mncc_set_cause(&l4_rel, l4_location, l4_cause);
2161 mncc_recvmsg(trans->network, trans, MNCC_DISC_IND, &l4_rel);
2162 }
2163
2164 /* process disconnect towards mobile station */
2165 if (disconnect || release) {
2166 mncc_set_cause(&mo_rel, mo_location, mo_cause);
2167 mo_rel.cause.diag[0] = ((trans->Tcurrent & 0xf00) >> 8) + '0';
2168 mo_rel.cause.diag[1] = ((trans->Tcurrent & 0x0f0) >> 4) + '0';
2169 mo_rel.cause.diag[2] = (trans->Tcurrent & 0x00f) + '0';
2170 mo_rel.cause.diag_len = 3;
2171
2172 if (disconnect)
2173 gsm48_cc_tx_disconnect(trans, &mo_rel);
2174 if (release)
2175 gsm48_cc_tx_release(trans, &mo_rel);
2176 }
2177
2178}
2179
2180static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
2181 int sec, int micro)
2182{
2183 DEBUGP(DCC, "starting timer T%x with %d seconds\n", current, sec);
2184 trans->cc_timer.cb = gsm48_cc_timeout;
2185 trans->cc_timer.data = trans;
2186 bsc_schedule_timer(&trans->cc_timer, sec, micro);
2187 trans->Tcurrent = current;
2188}
2189
2190static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
2191{
2192 struct gsm48_hdr *gh = msgb_l3(msg);
2193 u_int8_t msg_type = gh->msg_type & 0xbf;
2194 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2195 struct tlv_parsed tp;
2196 struct gsm_mncc setup;
2197
2198 memset(&setup, 0, sizeof(struct gsm_mncc));
2199 setup.callref = trans->callref;
2200 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2201 /* emergency setup is identified by msg_type */
2202 if (msg_type == GSM48_MT_CC_EMERG_SETUP)
2203 setup.emergency = 1;
2204
2205 /* use subscriber as calling party number */
2206 if (trans->subscr) {
2207 setup.fields |= MNCC_F_CALLING;
2208 strncpy(setup.calling.number, trans->subscr->extension,
2209 sizeof(setup.calling.number)-1);
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02002210 strncpy(setup.imsi, trans->subscr->imsi,
2211 sizeof(setup.imsi)-1);
Harald Welte03740842009-06-10 23:11:52 +08002212 }
2213 /* bearer capability */
2214 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
2215 setup.fields |= MNCC_F_BEARER_CAP;
2216 decode_bearer_cap(&setup.bearer_cap,
2217 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
2218 }
2219 /* facility */
2220 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2221 setup.fields |= MNCC_F_FACILITY;
2222 decode_facility(&setup.facility,
2223 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2224 }
2225 /* called party bcd number */
2226 if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
2227 setup.fields |= MNCC_F_CALLED;
2228 decode_called(&setup.called,
2229 TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
2230 }
2231 /* user-user */
2232 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2233 setup.fields |= MNCC_F_USERUSER;
2234 decode_useruser(&setup.useruser,
2235 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2236 }
2237 /* ss-version */
2238 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2239 setup.fields |= MNCC_F_SSVERSION;
2240 decode_ssversion(&setup.ssversion,
2241 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2242 }
2243 /* CLIR suppression */
2244 if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_SUPP))
2245 setup.clir.sup = 1;
2246 /* CLIR invocation */
2247 if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_INVOC))
2248 setup.clir.inv = 1;
2249 /* cc cap */
2250 if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
2251 setup.fields |= MNCC_F_CCCAP;
2252 decode_cccap(&setup.cccap,
2253 TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
2254 }
2255
2256 if (is_ipaccess_bts(msg->trx->bts))
2257 rsl_ipacc_bind(msg->lchan);
2258
2259 new_cc_state(trans, GSM_CSTATE_INITIATED);
2260
2261 /* indicate setup to MNCC */
2262 mncc_recvmsg(trans->network, trans, MNCC_SETUP_IND, &setup);
2263
2264 return 0;
2265}
2266
2267static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
Harald Welte59b04682009-06-10 05:40:52 +08002268{
2269 struct msgb *msg = gsm48_msgb_alloc();
2270 struct gsm48_hdr *gh;
Harald Welte03740842009-06-10 23:11:52 +08002271 struct gsm_mncc *setup = arg;
2272 struct gsm_trans *transt;
2273 u_int16_t trans_id_mask = 0;
2274 int rc, i;
Harald Welte59b04682009-06-10 05:40:52 +08002275
2276 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2277
Harald Welte03740842009-06-10 23:11:52 +08002278 /* transaction id must not be assigned */
2279 if (trans->transaction_id != 0xff) { /* unasssigned */
2280 DEBUGP(DCC, "TX Setup with assigned transaction. "
2281 "This is not allowed!\n");
2282 /* Temporarily out of order */
2283 rc = mncc_release_ind(trans->network, trans, trans->callref,
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08002284 GSM48_CAUSE_LOC_PRN_S_LU,
2285 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08002286 trans->callref = 0;
2287 free_trans(trans);
2288 return rc;
2289 }
2290
2291 /* Get free transaction_id */
2292 llist_for_each_entry(transt, &trans->network->trans_list, entry) {
2293 /* Transaction of our lchan? */
2294 if (transt->lchan == trans->lchan &&
2295 transt->transaction_id != 0xff)
2296 trans_id_mask |= (1 << (transt->transaction_id >> 4));
2297 }
2298 /* Assign free transaction ID */
2299 if ((trans_id_mask & 0x007f) == 0x7f) {
2300 /* no free transaction ID */
2301 rc = mncc_release_ind(trans->network, trans, trans->callref,
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08002302 GSM48_CAUSE_LOC_PRN_S_LU,
2303 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08002304 trans->callref = 0;
2305 free_trans(trans);
2306 return rc;
2307 }
2308 for (i = 0; i < 7; i++) {
2309 if ((trans_id_mask & (1 << i)) == 0) {
2310 trans->transaction_id = i << 4; /* flag = 0 */
2311 break;
2312 }
2313 }
Harald Welte59b04682009-06-10 05:40:52 +08002314
Harald Welte03740842009-06-10 23:11:52 +08002315 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2316 msg->lchan = trans->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08002317 gh->msg_type = GSM48_MT_CC_SETUP;
2318
Harald Welte03740842009-06-10 23:11:52 +08002319 gsm48_start_cc_timer(trans, 0x303, GSM48_T303);
Harald Welte59b04682009-06-10 05:40:52 +08002320
Harald Welte03740842009-06-10 23:11:52 +08002321 /* bearer capability */
2322 if (setup->fields & MNCC_F_BEARER_CAP)
2323 encode_bearer_cap(msg, 0, &setup->bearer_cap);
2324 /* facility */
2325 if (setup->fields & MNCC_F_FACILITY)
2326 encode_facility(msg, 0, &setup->facility);
2327 /* progress */
2328 if (setup->fields & MNCC_F_PROGRESS)
2329 encode_progress(msg, 0, &setup->progress);
2330 /* calling party BCD number */
2331 if (setup->fields & MNCC_F_CALLING)
2332 encode_calling(msg, &setup->calling);
2333 /* called party BCD number */
2334 if (setup->fields & MNCC_F_CALLED)
2335 encode_called(msg, &setup->called);
2336 /* user-user */
2337 if (setup->fields & MNCC_F_USERUSER)
2338 encode_useruser(msg, 0, &setup->useruser);
2339 /* redirecting party BCD number */
2340 if (setup->fields & MNCC_F_REDIRECTING)
2341 encode_redirecting(msg, &setup->redirecting);
2342 /* signal */
2343 if (setup->fields & MNCC_F_SIGNAL)
2344 encode_signal(msg, setup->signal);
2345
2346 new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);
Harald Welte59b04682009-06-10 05:40:52 +08002347
2348 return gsm48_sendmsg(msg);
2349}
2350
Harald Welte03740842009-06-10 23:11:52 +08002351static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
2352{
2353 struct gsm48_hdr *gh = msgb_l3(msg);
2354 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2355 struct tlv_parsed tp;
2356 struct gsm_mncc call_conf;
2357
2358 gsm48_stop_cc_timer(trans);
2359 gsm48_start_cc_timer(trans, 0x310, GSM48_T310);
2360
2361 memset(&call_conf, 0, sizeof(struct gsm_mncc));
2362 call_conf.callref = trans->callref;
2363 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2364#if 0
2365 /* repeat */
2366 if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR))
2367 call_conf.repeat = 1;
2368 if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ))
2369 call_conf.repeat = 2;
2370#endif
2371 /* bearer capability */
2372 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
2373 call_conf.fields |= MNCC_F_BEARER_CAP;
2374 decode_bearer_cap(&call_conf.bearer_cap,
2375 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
2376 }
2377 /* cause */
2378 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2379 call_conf.fields |= MNCC_F_CAUSE;
2380 decode_cause(&call_conf.cause,
2381 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2382 }
2383 /* cc cap */
2384 if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
2385 call_conf.fields |= MNCC_F_CCCAP;
2386 decode_cccap(&call_conf.cccap,
2387 TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
2388 }
2389
2390 new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
2391
2392 return mncc_recvmsg(trans->network, trans, MNCC_CALL_CONF_IND, &call_conf);
2393}
2394
2395static int gsm48_cc_tx_call_proc(struct gsm_trans *trans, void *arg)
2396{
2397 struct gsm_mncc *proceeding = arg;
2398 struct msgb *msg = gsm48_msgb_alloc();
2399 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2400
2401 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2402 msg->lchan = trans->lchan;
2403 gh->msg_type = GSM48_MT_CC_CALL_PROC;
2404
2405 new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC);
2406
2407 /* bearer capability */
2408 if (proceeding->fields & MNCC_F_BEARER_CAP)
2409 encode_bearer_cap(msg, 0, &proceeding->bearer_cap);
2410 /* facility */
2411 if (proceeding->fields & MNCC_F_FACILITY)
2412 encode_facility(msg, 0, &proceeding->facility);
2413 /* progress */
2414 if (proceeding->fields & MNCC_F_PROGRESS)
2415 encode_progress(msg, 0, &proceeding->progress);
2416
2417 return gsm48_sendmsg(msg);
2418}
2419
2420static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
2421{
2422 struct gsm48_hdr *gh = msgb_l3(msg);
2423 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2424 struct tlv_parsed tp;
2425 struct gsm_mncc alerting;
2426
2427 gsm48_stop_cc_timer(trans);
2428 gsm48_start_cc_timer(trans, 0x301, GSM48_T301);
2429
2430 memset(&alerting, 0, sizeof(struct gsm_mncc));
2431 alerting.callref = trans->callref;
2432 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2433 /* facility */
2434 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2435 alerting.fields |= MNCC_F_FACILITY;
2436 decode_facility(&alerting.facility,
2437 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2438 }
2439
2440 /* progress */
2441 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
2442 alerting.fields |= MNCC_F_PROGRESS;
2443 decode_progress(&alerting.progress,
2444 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
2445 }
2446 /* ss-version */
2447 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2448 alerting.fields |= MNCC_F_SSVERSION;
2449 decode_ssversion(&alerting.ssversion,
2450 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2451 }
2452
2453 new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
2454
2455 return mncc_recvmsg(trans->network, trans, MNCC_ALERT_IND, &alerting);
2456}
2457
2458static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
2459{
2460 struct gsm_mncc *alerting = arg;
2461 struct msgb *msg = gsm48_msgb_alloc();
2462 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2463
2464 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2465 msg->lchan = trans->lchan;
2466 gh->msg_type = GSM48_MT_CC_ALERTING;
2467
2468 /* facility */
2469 if (alerting->fields & MNCC_F_FACILITY)
2470 encode_facility(msg, 0, &alerting->facility);
2471 /* progress */
2472 if (alerting->fields & MNCC_F_PROGRESS)
2473 encode_progress(msg, 0, &alerting->progress);
2474 /* user-user */
2475 if (alerting->fields & MNCC_F_USERUSER)
2476 encode_useruser(msg, 0, &alerting->useruser);
2477
2478 new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);
2479
2480 return gsm48_sendmsg(msg);
2481}
2482
2483static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg)
2484{
2485 struct gsm_mncc *progress = arg;
2486 struct msgb *msg = gsm48_msgb_alloc();
2487 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2488
2489 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2490 msg->lchan = trans->lchan;
2491 gh->msg_type = GSM48_MT_CC_PROGRESS;
2492
2493 /* progress */
2494 encode_progress(msg, 1, &progress->progress);
2495 /* user-user */
2496 if (progress->fields & MNCC_F_USERUSER)
2497 encode_useruser(msg, 0, &progress->useruser);
2498
2499 return gsm48_sendmsg(msg);
2500}
2501
2502static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
2503{
2504 struct gsm_mncc *connect = arg;
2505 struct msgb *msg = gsm48_msgb_alloc();
2506 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2507
2508 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2509 msg->lchan = trans->lchan;
2510 gh->msg_type = GSM48_MT_CC_CONNECT;
2511
2512 gsm48_stop_cc_timer(trans);
2513 gsm48_start_cc_timer(trans, 0x313, GSM48_T313);
2514
2515 /* facility */
2516 if (connect->fields & MNCC_F_FACILITY)
2517 encode_facility(msg, 0, &connect->facility);
2518 /* progress */
2519 if (connect->fields & MNCC_F_PROGRESS)
2520 encode_progress(msg, 0, &connect->progress);
2521 /* connected number */
2522 if (connect->fields & MNCC_F_CONNECTED)
2523 encode_connected(msg, &connect->connected);
2524 /* user-user */
2525 if (connect->fields & MNCC_F_USERUSER)
2526 encode_useruser(msg, 0, &connect->useruser);
2527
2528 new_cc_state(trans, GSM_CSTATE_CONNECT_IND);
2529
2530 return gsm48_sendmsg(msg);
2531}
2532
2533static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
2534{
2535 struct gsm48_hdr *gh = msgb_l3(msg);
2536 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2537 struct tlv_parsed tp;
2538 struct gsm_mncc connect;
2539
2540 gsm48_stop_cc_timer(trans);
2541
2542 memset(&connect, 0, sizeof(struct gsm_mncc));
2543 connect.callref = trans->callref;
2544 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2545 /* use subscriber as connected party number */
2546 if (trans->subscr) {
2547 connect.fields |= MNCC_F_CONNECTED;
2548 strncpy(connect.connected.number, trans->subscr->extension,
2549 sizeof(connect.connected.number)-1);
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02002550 strncpy(connect.imsi, trans->subscr->imsi,
2551 sizeof(connect.imsi)-1);
Harald Welte03740842009-06-10 23:11:52 +08002552 }
2553 /* facility */
2554 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2555 connect.fields |= MNCC_F_FACILITY;
2556 decode_facility(&connect.facility,
2557 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2558 }
2559 /* user-user */
2560 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2561 connect.fields |= MNCC_F_USERUSER;
2562 decode_useruser(&connect.useruser,
2563 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2564 }
2565 /* ss-version */
2566 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2567 connect.fields |= MNCC_F_SSVERSION;
2568 decode_ssversion(&connect.ssversion,
2569 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2570 }
2571
2572 new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
2573
2574 return mncc_recvmsg(trans->network, trans, MNCC_SETUP_CNF, &connect);
2575}
2576
2577
2578static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
2579{
2580 struct gsm_mncc connect_ack;
2581
2582 gsm48_stop_cc_timer(trans);
2583
2584 new_cc_state(trans, GSM_CSTATE_ACTIVE);
2585
2586 memset(&connect_ack, 0, sizeof(struct gsm_mncc));
2587 connect_ack.callref = trans->callref;
2588 return mncc_recvmsg(trans->network, trans, MNCC_SETUP_COMPL_IND,
2589 &connect_ack);
2590}
2591
2592static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg)
2593{
2594 struct msgb *msg = gsm48_msgb_alloc();
2595 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2596
2597 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2598 msg->lchan = trans->lchan;
2599 gh->msg_type = GSM48_MT_CC_CONNECT_ACK;
2600
2601 new_cc_state(trans, GSM_CSTATE_ACTIVE);
2602
2603 return gsm48_sendmsg(msg);
2604}
2605
2606static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
2607{
2608 struct gsm48_hdr *gh = msgb_l3(msg);
2609 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2610 struct tlv_parsed tp;
2611 struct gsm_mncc disc;
2612
2613 gsm48_stop_cc_timer(trans);
2614
2615 new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ);
2616
2617 memset(&disc, 0, sizeof(struct gsm_mncc));
2618 disc.callref = trans->callref;
2619 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_CAUSE, 0);
2620 /* cause */
2621 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2622 disc.fields |= MNCC_F_CAUSE;
2623 decode_cause(&disc.cause,
2624 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2625 }
2626 /* facility */
2627 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2628 disc.fields |= MNCC_F_FACILITY;
2629 decode_facility(&disc.facility,
2630 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2631 }
2632 /* user-user */
2633 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2634 disc.fields |= MNCC_F_USERUSER;
2635 decode_useruser(&disc.useruser,
2636 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2637 }
2638 /* ss-version */
2639 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2640 disc.fields |= MNCC_F_SSVERSION;
2641 decode_ssversion(&disc.ssversion,
2642 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2643 }
2644
2645 return mncc_recvmsg(trans->network, trans, MNCC_DISC_IND, &disc);
2646
2647}
2648
Harald Weltebbc636a2009-06-11 14:23:20 +08002649static struct gsm_mncc_cause default_cause = {
2650 .location = GSM48_CAUSE_LOC_PRN_S_LU,
2651 .coding = 0,
2652 .rec = 0,
2653 .rec_val = 0,
2654 .value = GSM48_CC_CAUSE_NORMAL_UNSPEC,
2655 .diag_len = 0,
2656 .diag = { 0 },
2657};
Harald Welte03740842009-06-10 23:11:52 +08002658
2659static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
2660{
2661 struct gsm_mncc *disc = arg;
2662 struct msgb *msg = gsm48_msgb_alloc();
2663 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2664
2665 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2666 msg->lchan = trans->lchan;
2667 gh->msg_type = GSM48_MT_CC_DISCONNECT;
2668
2669 gsm48_stop_cc_timer(trans);
2670 gsm48_start_cc_timer(trans, 0x306, GSM48_T306);
2671
2672 /* cause */
2673 if (disc->fields & MNCC_F_CAUSE)
2674 encode_cause(msg, 1, &disc->cause);
2675 else
2676 encode_cause(msg, 1, &default_cause);
2677
2678 /* facility */
2679 if (disc->fields & MNCC_F_FACILITY)
2680 encode_facility(msg, 0, &disc->facility);
2681 /* progress */
2682 if (disc->fields & MNCC_F_PROGRESS)
2683 encode_progress(msg, 0, &disc->progress);
2684 /* user-user */
2685 if (disc->fields & MNCC_F_USERUSER)
2686 encode_useruser(msg, 0, &disc->useruser);
2687
2688 /* store disconnect cause for T306 expiry */
2689 memcpy(&trans->cc_msg, disc, sizeof(struct gsm_mncc));
2690
2691 new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND);
2692
2693 return gsm48_sendmsg(msg);
2694}
2695
2696static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
2697{
2698 struct gsm48_hdr *gh = msgb_l3(msg);
2699 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2700 struct tlv_parsed tp;
2701 struct gsm_mncc rel;
2702 int rc;
2703
2704 gsm48_stop_cc_timer(trans);
2705
2706 memset(&rel, 0, sizeof(struct gsm_mncc));
2707 rel.callref = trans->callref;
2708 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2709 /* cause */
2710 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2711 rel.fields |= MNCC_F_CAUSE;
2712 decode_cause(&rel.cause,
2713 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2714 }
2715 /* facility */
2716 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2717 rel.fields |= MNCC_F_FACILITY;
2718 decode_facility(&rel.facility,
2719 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2720 }
2721 /* user-user */
2722 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2723 rel.fields |= MNCC_F_USERUSER;
2724 decode_useruser(&rel.useruser,
2725 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2726 }
2727 /* ss-version */
2728 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2729 rel.fields |= MNCC_F_SSVERSION;
2730 decode_ssversion(&rel.ssversion,
2731 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2732 }
2733
2734 if (trans->state == GSM_CSTATE_RELEASE_REQ) {
2735 /* release collision 5.4.5 */
2736 rc = mncc_recvmsg(trans->network, trans, MNCC_REL_CNF, &rel);
2737 } else {
2738 rc = gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC | trans->transaction_id,
2739 GSM48_MT_CC_RELEASE_COMPL);
2740 rc = mncc_recvmsg(trans->network, trans, MNCC_REL_IND, &rel);
2741 }
2742
2743 new_cc_state(trans, GSM_CSTATE_NULL);
2744
2745 trans->callref = 0;
2746 free_trans(trans);
2747
2748 return rc;
2749}
2750
2751static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg)
2752{
2753 struct gsm_mncc *rel = arg;
2754 struct msgb *msg = gsm48_msgb_alloc();
2755 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2756
2757 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2758 msg->lchan = trans->lchan;
2759 gh->msg_type = GSM48_MT_CC_RELEASE;
2760
2761 trans->callref = 0;
2762
2763 gsm48_stop_cc_timer(trans);
2764 gsm48_start_cc_timer(trans, 0x308, GSM48_T308);
2765
2766 /* cause */
2767 if (rel->fields & MNCC_F_CAUSE)
2768 encode_cause(msg, 0, &rel->cause);
2769 /* facility */
2770 if (rel->fields & MNCC_F_FACILITY)
2771 encode_facility(msg, 0, &rel->facility);
2772 /* user-user */
2773 if (rel->fields & MNCC_F_USERUSER)
2774 encode_useruser(msg, 0, &rel->useruser);
2775
2776 trans->T308_second = 0;
2777 memcpy(&trans->cc_msg, rel, sizeof(struct gsm_mncc));
2778
2779 if (trans->state != GSM_CSTATE_RELEASE_REQ)
2780 new_cc_state(trans, GSM_CSTATE_RELEASE_REQ);
2781
2782 return gsm48_sendmsg(msg);
2783}
2784
2785static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
2786{
2787 struct gsm48_hdr *gh = msgb_l3(msg);
2788 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2789 struct tlv_parsed tp;
2790 struct gsm_mncc rel;
2791 int rc = 0;
2792
2793 gsm48_stop_cc_timer(trans);
2794
2795 memset(&rel, 0, sizeof(struct gsm_mncc));
2796 rel.callref = trans->callref;
2797 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2798 /* cause */
2799 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2800 rel.fields |= MNCC_F_CAUSE;
2801 decode_cause(&rel.cause,
2802 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2803 }
2804 /* facility */
2805 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2806 rel.fields |= MNCC_F_FACILITY;
2807 decode_facility(&rel.facility,
2808 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2809 }
2810 /* user-user */
2811 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2812 rel.fields |= MNCC_F_USERUSER;
2813 decode_useruser(&rel.useruser,
2814 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2815 }
2816 /* ss-version */
2817 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2818 rel.fields |= MNCC_F_SSVERSION;
2819 decode_ssversion(&rel.ssversion,
2820 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2821 }
2822
2823 if (trans->callref) {
2824 switch (trans->state) {
2825 case GSM_CSTATE_CALL_PRESENT:
2826 rc = mncc_recvmsg(trans->network, trans,
2827 MNCC_REJ_IND, &rel);
2828 break;
2829 case GSM_CSTATE_RELEASE_REQ:
2830 rc = mncc_recvmsg(trans->network, trans,
2831 MNCC_REL_CNF, &rel);
2832 break;
2833 default:
2834 rc = mncc_recvmsg(trans->network, trans,
2835 MNCC_REL_IND, &rel);
2836 }
2837 }
2838
2839 trans->callref = 0;
2840 free_trans(trans);
2841
2842 return rc;
2843}
2844
2845static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg)
2846{
2847 struct gsm_mncc *rel = arg;
2848 struct msgb *msg = gsm48_msgb_alloc();
2849 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2850
2851 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2852 msg->lchan = trans->lchan;
2853 gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
2854
2855 trans->callref = 0;
2856
2857 gsm48_stop_cc_timer(trans);
2858
2859 /* cause */
2860 if (rel->fields & MNCC_F_CAUSE)
2861 encode_cause(msg, 0, &rel->cause);
2862 /* facility */
2863 if (rel->fields & MNCC_F_FACILITY)
2864 encode_facility(msg, 0, &rel->facility);
2865 /* user-user */
2866 if (rel->fields & MNCC_F_USERUSER)
2867 encode_useruser(msg, 0, &rel->useruser);
2868
2869 free_trans(trans);
2870
2871 return gsm48_sendmsg(msg);
2872}
2873
2874static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg)
2875{
2876 struct gsm48_hdr *gh = msgb_l3(msg);
2877 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2878 struct tlv_parsed tp;
2879 struct gsm_mncc fac;
2880
2881 memset(&fac, 0, sizeof(struct gsm_mncc));
2882 fac.callref = trans->callref;
2883 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_FACILITY, 0);
2884 /* facility */
2885 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2886 fac.fields |= MNCC_F_FACILITY;
2887 decode_facility(&fac.facility,
2888 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2889 }
2890 /* ss-version */
2891 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2892 fac.fields |= MNCC_F_SSVERSION;
2893 decode_ssversion(&fac.ssversion,
2894 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2895 }
2896
2897 return mncc_recvmsg(trans->network, trans, MNCC_FACILITY_IND, &fac);
2898}
2899
2900static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg)
2901{
2902 struct gsm_mncc *fac = arg;
2903 struct msgb *msg = gsm48_msgb_alloc();
2904 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2905
2906 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2907 msg->lchan = trans->lchan;
2908 gh->msg_type = GSM48_MT_CC_FACILITY;
2909
2910 /* facility */
2911 encode_facility(msg, 1, &fac->facility);
2912
2913 return gsm48_sendmsg(msg);
2914}
2915
2916static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg)
2917{
2918 struct gsm_mncc hold;
2919
2920 memset(&hold, 0, sizeof(struct gsm_mncc));
2921 hold.callref = trans->callref;
2922 return mncc_recvmsg(trans->network, trans, MNCC_HOLD_IND, &hold);
2923}
2924
2925static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg)
2926{
2927 struct msgb *msg = gsm48_msgb_alloc();
2928 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2929
2930 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2931 msg->lchan = trans->lchan;
2932 gh->msg_type = GSM48_MT_CC_HOLD_ACK;
2933
2934 return gsm48_sendmsg(msg);
2935}
2936
2937static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg)
2938{
2939 struct gsm_mncc *hold_rej = arg;
2940 struct msgb *msg = gsm48_msgb_alloc();
2941 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2942
2943 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2944 msg->lchan = trans->lchan;
2945 gh->msg_type = GSM48_MT_CC_HOLD_REJ;
2946
2947 /* cause */
2948 if (hold_rej->fields & MNCC_F_CAUSE)
2949 encode_cause(msg, 1, &hold_rej->cause);
2950 else
2951 encode_cause(msg, 1, &default_cause);
2952
2953 return gsm48_sendmsg(msg);
2954}
2955
2956static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg)
2957{
2958 struct gsm_mncc retrieve;
2959
2960 memset(&retrieve, 0, sizeof(struct gsm_mncc));
2961 retrieve.callref = trans->callref;
2962 return mncc_recvmsg(trans->network, trans, MNCC_RETRIEVE_IND, &retrieve);
2963}
2964
2965static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg)
2966{
2967 struct msgb *msg = gsm48_msgb_alloc();
2968 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2969
2970 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2971 msg->lchan = trans->lchan;
2972 gh->msg_type = GSM48_MT_CC_RETR_ACK;
2973
2974 return gsm48_sendmsg(msg);
2975}
2976
2977static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg)
2978{
2979 struct gsm_mncc *retrieve_rej = arg;
2980 struct msgb *msg = gsm48_msgb_alloc();
2981 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2982
2983 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2984 msg->lchan = trans->lchan;
2985 gh->msg_type = GSM48_MT_CC_RETR_REJ;
2986
2987 /* cause */
2988 if (retrieve_rej->fields & MNCC_F_CAUSE)
2989 encode_cause(msg, 1, &retrieve_rej->cause);
2990 else
2991 encode_cause(msg, 1, &default_cause);
2992
2993 return gsm48_sendmsg(msg);
2994}
2995
2996static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg)
2997{
2998 struct gsm48_hdr *gh = msgb_l3(msg);
2999 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3000 struct tlv_parsed tp;
3001 struct gsm_mncc dtmf;
3002
3003 memset(&dtmf, 0, sizeof(struct gsm_mncc));
3004 dtmf.callref = trans->callref;
3005 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
3006 /* keypad facility */
3007 if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) {
3008 dtmf.fields |= MNCC_F_KEYPAD;
3009 decode_keypad(&dtmf.keypad,
3010 TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1);
3011 }
3012
3013 return mncc_recvmsg(trans->network, trans, MNCC_START_DTMF_IND, &dtmf);
3014}
3015
3016static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg)
3017{
3018 struct gsm_mncc *dtmf = arg;
3019 struct msgb *msg = gsm48_msgb_alloc();
3020 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3021
3022 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3023 msg->lchan = trans->lchan;
3024 gh->msg_type = GSM48_MT_CC_START_DTMF_ACK;
3025
3026 /* keypad */
3027 if (dtmf->fields & MNCC_F_KEYPAD)
3028 encode_keypad(msg, dtmf->keypad);
3029
3030 return gsm48_sendmsg(msg);
3031}
3032
3033static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg)
3034{
3035 struct gsm_mncc *dtmf = arg;
3036 struct msgb *msg = gsm48_msgb_alloc();
3037 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3038
3039 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3040 msg->lchan = trans->lchan;
3041 gh->msg_type = GSM48_MT_CC_START_DTMF_REJ;
3042
3043 /* cause */
3044 if (dtmf->fields & MNCC_F_CAUSE)
3045 encode_cause(msg, 1, &dtmf->cause);
3046 else
3047 encode_cause(msg, 1, &default_cause);
3048
3049 return gsm48_sendmsg(msg);
3050}
3051
3052static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg)
3053{
3054 struct msgb *msg = gsm48_msgb_alloc();
3055 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3056
3057 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3058 msg->lchan = trans->lchan;
3059 gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK;
3060
3061 return gsm48_sendmsg(msg);
3062}
3063
3064static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg)
3065{
3066 struct gsm_mncc dtmf;
3067
3068 memset(&dtmf, 0, sizeof(struct gsm_mncc));
3069 dtmf.callref = trans->callref;
3070
3071 return mncc_recvmsg(trans->network, trans, MNCC_STOP_DTMF_IND, &dtmf);
3072}
3073
3074static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
3075{
3076 struct gsm48_hdr *gh = msgb_l3(msg);
3077 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3078 struct tlv_parsed tp;
3079 struct gsm_mncc modify;
3080
3081 memset(&modify, 0, sizeof(struct gsm_mncc));
3082 modify.callref = trans->callref;
3083 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
3084 /* bearer capability */
3085 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
3086 modify.fields |= MNCC_F_BEARER_CAP;
3087 decode_bearer_cap(&modify.bearer_cap,
3088 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
3089 }
3090
3091 new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
3092
3093 return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_IND, &modify);
3094}
3095
3096static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg)
3097{
3098 struct gsm_mncc *modify = arg;
3099 struct msgb *msg = gsm48_msgb_alloc();
3100 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3101
3102 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3103 msg->lchan = trans->lchan;
3104 gh->msg_type = GSM48_MT_CC_MODIFY;
3105
3106 gsm48_start_cc_timer(trans, 0x323, GSM48_T323);
3107
3108 /* bearer capability */
3109 encode_bearer_cap(msg, 1, &modify->bearer_cap);
3110
3111 new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY);
3112
3113 return gsm48_sendmsg(msg);
3114}
3115
3116static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg)
3117{
3118 struct gsm48_hdr *gh = msgb_l3(msg);
3119 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3120 struct tlv_parsed tp;
3121 struct gsm_mncc modify;
3122
3123 gsm48_stop_cc_timer(trans);
3124
3125 memset(&modify, 0, sizeof(struct gsm_mncc));
3126 modify.callref = trans->callref;
3127 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
3128 /* bearer capability */
3129 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
3130 modify.fields |= MNCC_F_BEARER_CAP;
3131 decode_bearer_cap(&modify.bearer_cap,
3132 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
3133 }
3134
3135 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3136
3137 return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_CNF, &modify);
3138}
3139
3140static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg)
3141{
3142 struct gsm_mncc *modify = arg;
3143 struct msgb *msg = gsm48_msgb_alloc();
3144 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3145
3146 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3147 msg->lchan = trans->lchan;
3148 gh->msg_type = GSM48_MT_CC_MODIFY_COMPL;
3149
3150 /* bearer capability */
3151 encode_bearer_cap(msg, 1, &modify->bearer_cap);
3152
3153 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3154
3155 return gsm48_sendmsg(msg);
3156}
3157
3158static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
3159{
3160 struct gsm48_hdr *gh = msgb_l3(msg);
3161 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3162 struct tlv_parsed tp;
3163 struct gsm_mncc modify;
3164
3165 gsm48_stop_cc_timer(trans);
3166
3167 memset(&modify, 0, sizeof(struct gsm_mncc));
3168 modify.callref = trans->callref;
3169 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE);
3170 /* bearer capability */
3171 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
3172 modify.fields |= GSM48_IE_BEARER_CAP;
3173 decode_bearer_cap(&modify.bearer_cap,
3174 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
3175 }
3176 /* cause */
3177 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
3178 modify.fields |= MNCC_F_CAUSE;
3179 decode_cause(&modify.cause,
3180 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
3181 }
3182
3183 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3184
3185 return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_REJ, &modify);
3186}
3187
3188static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg)
3189{
3190 struct gsm_mncc *modify = arg;
3191 struct msgb *msg = gsm48_msgb_alloc();
3192 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3193
3194 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3195 msg->lchan = trans->lchan;
3196 gh->msg_type = GSM48_MT_CC_MODIFY_REJECT;
3197
3198 /* bearer capability */
3199 encode_bearer_cap(msg, 1, &modify->bearer_cap);
3200 /* cause */
3201 encode_cause(msg, 1, &modify->cause);
3202
3203 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3204
3205 return gsm48_sendmsg(msg);
3206}
3207
3208static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg)
3209{
3210 struct gsm_mncc *notify = arg;
3211 struct msgb *msg = gsm48_msgb_alloc();
3212 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3213
3214 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3215 msg->lchan = trans->lchan;
3216 gh->msg_type = GSM48_MT_CC_NOTIFY;
3217
3218 /* notify */
3219 encode_notify(msg, notify->notify);
3220
3221 return gsm48_sendmsg(msg);
3222}
3223
3224static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg)
3225{
3226 struct gsm48_hdr *gh = msgb_l3(msg);
3227 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3228// struct tlv_parsed tp;
3229 struct gsm_mncc notify;
3230
3231 memset(&notify, 0, sizeof(struct gsm_mncc));
3232 notify.callref = trans->callref;
3233// tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len);
3234 if (payload_len >= 1)
3235 decode_notify(&notify.notify, gh->data);
3236
3237 return mncc_recvmsg(trans->network, trans, MNCC_NOTIFY_IND, &notify);
3238}
3239
3240static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg)
3241{
3242 struct gsm_mncc *user = arg;
3243 struct msgb *msg = gsm48_msgb_alloc();
3244 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3245
3246 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3247 msg->lchan = trans->lchan;
3248 gh->msg_type = GSM48_MT_CC_USER_INFO;
3249
3250 /* user-user */
3251 if (user->fields & MNCC_F_USERUSER)
3252 encode_useruser(msg, 1, &user->useruser);
3253 /* more data */
3254 if (user->more)
3255 encode_more(msg);
3256
3257 return gsm48_sendmsg(msg);
3258}
3259
3260static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
3261{
3262 struct gsm48_hdr *gh = msgb_l3(msg);
3263 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3264 struct tlv_parsed tp;
3265 struct gsm_mncc user;
3266
3267 memset(&user, 0, sizeof(struct gsm_mncc));
3268 user.callref = trans->callref;
3269 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_USER_USER, 0);
3270 /* user-user */
3271 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
3272 user.fields |= MNCC_F_USERUSER;
3273 decode_useruser(&user.useruser,
3274 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
3275 }
3276 /* more data */
3277 if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA))
3278 user.more = 1;
3279
3280 return mncc_recvmsg(trans->network, trans, MNCC_USERINFO_IND, &user);
3281}
3282
3283static int gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
3284{
3285 struct gsm_mncc *mode = arg;
3286
3287 return gsm48_tx_chan_mode_modify(trans->lchan, mode->lchan_mode);
3288}
3289
3290static struct downstate {
3291 u_int32_t states;
3292 int type;
3293 int (*rout) (struct gsm_trans *trans, void *arg);
3294} downstatelist[] = {
3295 /* mobile originating call establishment */
3296 {SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.2 */
3297 MNCC_CALL_PROC_REQ, gsm48_cc_tx_call_proc},
3298 {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.2 | 5.2.1.5 */
3299 MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
3300 {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) | SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.2 | 5.2.1.6 | 5.2.1.6 */
3301 MNCC_SETUP_RSP, gsm48_cc_tx_connect},
3302 {SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.4.2 */
3303 MNCC_PROGRESS_REQ, gsm48_cc_tx_progress},
3304 /* mobile terminating call establishment */
3305 {SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
3306 MNCC_SETUP_REQ, gsm48_cc_tx_setup},
3307 {SBIT(GSM_CSTATE_CONNECT_REQUEST),
3308 MNCC_SETUP_COMPL_REQ, gsm48_cc_tx_connect_ack},
3309 /* signalling during call */
3310 {SBIT(GSM_CSTATE_ACTIVE),
3311 MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
3312 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
3313 MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
3314 {ALL_STATES,
3315 MNCC_START_DTMF_RSP, gsm48_cc_tx_start_dtmf_ack},
3316 {ALL_STATES,
3317 MNCC_START_DTMF_REJ, gsm48_cc_tx_start_dtmf_rej},
3318 {ALL_STATES,
3319 MNCC_STOP_DTMF_RSP, gsm48_cc_tx_stop_dtmf_ack},
3320 {SBIT(GSM_CSTATE_ACTIVE),
3321 MNCC_HOLD_CNF, gsm48_cc_tx_hold_ack},
3322 {SBIT(GSM_CSTATE_ACTIVE),
3323 MNCC_HOLD_REJ, gsm48_cc_tx_hold_rej},
3324 {SBIT(GSM_CSTATE_ACTIVE),
3325 MNCC_RETRIEVE_CNF, gsm48_cc_tx_retrieve_ack},
3326 {SBIT(GSM_CSTATE_ACTIVE),
3327 MNCC_RETRIEVE_REJ, gsm48_cc_tx_retrieve_rej},
3328 {SBIT(GSM_CSTATE_ACTIVE),
3329 MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
3330 {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
3331 MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
3332 {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
3333 MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
3334 {SBIT(GSM_CSTATE_ACTIVE),
3335 MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
3336 /* clearing */
3337 {SBIT(GSM_CSTATE_INITIATED),
3338 MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
3339 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) - SBIT(GSM_CSTATE_RELEASE_REQ) - SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.4 */
3340 MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
3341 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
3342 MNCC_REL_REQ, gsm48_cc_tx_release},
3343 /* special */
3344 {ALL_STATES,
3345 MNCC_LCHAN_MODIFY, gsm48_lchan_modify},
3346};
3347
3348#define DOWNSLLEN \
3349 (sizeof(downstatelist) / sizeof(struct downstate))
3350
3351
3352int mncc_send(struct gsm_network *net, int msg_type, void *arg)
3353{
3354 int i, j, k, l, rc = 0;
3355 struct gsm_trans *trans = NULL, *transt;
3356 struct gsm_subscriber *subscr;
3357 struct gsm_lchan *lchan = NULL, *lchant;
3358 struct gsm_bts *bts = NULL;
3359 struct gsm_bts_trx *trx;
3360 struct gsm_bts_trx_ts *ts;
3361 struct gsm_mncc *data = arg, rel;
3362
3363 /* handle special messages */
3364 switch(msg_type) {
3365 case MNCC_BRIDGE:
3366 return tch_bridge(net, arg);
3367 case MNCC_FRAME_DROP:
3368 return tch_recv(net, arg, 0);
3369 case MNCC_FRAME_RECV:
3370 return tch_recv(net, arg, 1);
3371 case GSM_TRAU_FRAME:
3372 return tch_frame(net, arg);
3373 }
3374
3375 memset(&rel, 0, sizeof(struct gsm_mncc));
3376 rel.callref = data->callref;
3377
3378 /* Find callref */
3379 trans = get_trans_ref(net, data->callref);
3380
3381 /* Callref unknown */
3382 if (!trans) {
Harald Welte6e1536e2009-07-04 10:11:24 +02003383 if (msg_type != MNCC_SETUP_REQ) {
Harald Welte03740842009-06-10 23:11:52 +08003384 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3385 "Received '%s' from MNCC with "
3386 "unknown callref %d\n", data->called.number,
3387 get_mncc_name(msg_type), data->callref);
3388 /* Invalid call reference */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003389 return mncc_release_ind(net, NULL, data->callref,
3390 GSM48_CAUSE_LOC_PRN_S_LU,
3391 GSM48_CC_CAUSE_INVAL_TRANS_ID);
Harald Welte03740842009-06-10 23:11:52 +08003392 }
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02003393 if (!data->called.number[0] && !data->imsi[0]) {
3394 DEBUGP(DCC, "(bts - trx - ts - ti) "
3395 "Received '%s' from MNCC with "
3396 "no number or IMSI\n", get_mncc_name(msg_type));
3397 /* Invalid number */
3398 return mncc_release_ind(net, NULL, data->callref,
3399 GSM48_CAUSE_LOC_PRN_S_LU,
3400 GSM48_CC_CAUSE_INV_NR_FORMAT);
3401 }
Harald Welte03740842009-06-10 23:11:52 +08003402 /* New transaction due to setup, find subscriber */
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02003403 if (data->called.number[0])
3404 subscr = subscr_get_by_extension(data->called.number);
3405 else
3406 subscr = subscr_get_by_imsi(data->imsi);
Harald Welte03740842009-06-10 23:11:52 +08003407 /* If subscriber is not found */
3408 if (!subscr) {
3409 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3410 "Received '%s' from MNCC with "
3411 "unknown subscriber %s\n", data->called.number,
3412 get_mncc_name(msg_type), data->called.number);
3413 /* Unknown subscriber */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003414 return mncc_release_ind(net, NULL, data->callref,
3415 GSM48_CAUSE_LOC_PRN_S_LU,
3416 GSM48_CC_CAUSE_UNASSIGNED_NR);
Harald Welte03740842009-06-10 23:11:52 +08003417 }
3418 /* If subscriber is not "attached" */
3419 if (!subscr->lac) {
3420 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3421 "Received '%s' from MNCC with "
3422 "detached subscriber %s\n", data->called.number,
3423 get_mncc_name(msg_type), data->called.number);
3424 subscr_put(subscr);
3425 /* Temporarily out of order */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003426 return mncc_release_ind(net, NULL, data->callref,
3427 GSM48_CAUSE_LOC_PRN_S_LU,
3428 GSM48_CC_CAUSE_DEST_OOO);
Harald Welte03740842009-06-10 23:11:52 +08003429 }
3430 /* Create transaction */
Harald Welte1ff81b52009-06-26 20:17:06 +02003431 if (!(trans = talloc_zero(tall_trans_ctx, struct gsm_trans))) {
Harald Welte03740842009-06-10 23:11:52 +08003432 DEBUGP(DCC, "No memory for trans.\n");
3433 subscr_put(subscr);
3434 /* Ressource unavailable */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003435 mncc_release_ind(net, NULL, data->callref,
3436 GSM48_CAUSE_LOC_PRN_S_LU,
3437 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08003438 return -ENOMEM;
3439 }
3440 trans->callref = data->callref;
3441 trans->network = net;
3442 trans->transaction_id = 0xff; /* unassigned */
3443 llist_add_tail(&trans->entry, &net->trans_list);
3444 /* Assign subscriber to transaction */
3445 trans->subscr = subscr;
3446 /* Find lchan */
3447 for (i = 0; i < net->num_bts; i++) {
Harald Weltee712a5f2009-06-21 16:17:15 +02003448 bts = gsm_bts_num(net, i);
Harald Welte03740842009-06-10 23:11:52 +08003449 for (j = 0; j < bts->num_trx; j++) {
Harald Weltee712a5f2009-06-21 16:17:15 +02003450 trx = gsm_bts_trx_num(bts, j);
Harald Welte03740842009-06-10 23:11:52 +08003451 for (k = 0; k < TRX_NR_TS; k++) {
3452 ts = &trx->ts[k];
3453 for (l = 0; l < TS_MAX_LCHAN; l++) {
3454 lchant = &ts->lchan[l];
3455 if (lchant->subscr == subscr) {
3456 lchan = lchant;
3457 break;
3458 }
3459 }
3460 }
3461 }
3462 }
3463
3464 /* If subscriber has no lchan */
3465 if (!lchan) {
3466 /* find transaction with this subscriber already paging */
3467 llist_for_each_entry(transt, &net->trans_list, entry) {
3468 /* Transaction of our lchan? */
3469 if (transt == trans ||
3470 transt->subscr != subscr)
3471 continue;
3472 DEBUGP(DCC, "(bts %d trx - ts - ti -- sub %s) "
3473 "Received '%s' from MNCC with "
3474 "unallocated channel, paging already "
3475 "started.\n", bts->nr,
3476 data->called.number,
3477 get_mncc_name(msg_type));
3478 return 0;
3479 }
3480 /* store setup informations until paging was successfull */
3481 memcpy(&trans->cc_msg, data, sizeof(struct gsm_mncc));
3482 /* start paging subscriber on all BTS with her location */
3483 subscr->net = net;
3484 bts = NULL;
3485 do {
3486 bts = gsm_bts_by_lac(net, subscr->lac, bts);
3487 if (!bts)
3488 break;
3489 DEBUGP(DCC, "(bts %d trx - ts - ti -- sub %s) "
3490 "Received '%s' from MNCC with "
3491 "unallocated channel, paging.\n",
3492 bts->nr, data->called.number,
3493 get_mncc_name(msg_type));
3494 /* Trigger paging */
Harald Weltecb0595f2009-06-12 01:54:08 +08003495 paging_request(net, subscr, RSL_CHANNEED_TCH_F,
Harald Welte03740842009-06-10 23:11:52 +08003496 setup_trig_pag_evt, subscr);
3497 } while (1);
3498 return 0;
3499 }
3500 /* Assign lchan */
3501 trans->lchan = lchan;
3502 use_lchan(lchan);
3503 }
3504 lchan = trans->lchan;
3505
3506 /* if paging did not respond yet */
3507 if (!lchan) {
3508 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3509 "Received '%s' from MNCC in paging state\n",
3510 (trans->subscr)?(trans->subscr->extension):"-",
3511 get_mncc_name(msg_type));
Harald Weltebbc636a2009-06-11 14:23:20 +08003512 mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
3513 GSM48_CC_CAUSE_NORM_CALL_CLEAR);
Harald Welte03740842009-06-10 23:11:52 +08003514 if (msg_type == MNCC_REL_REQ)
3515 rc = mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
3516 else
3517 rc = mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
3518 trans->callref = 0;
3519 free_trans(trans);
3520 return rc;
3521 }
3522
3523 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
3524 "Received '%s' from MNCC in state %d (%s)\n",
3525 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
3526 trans->transaction_id,
3527 (lchan->subscr)?(lchan->subscr->extension):"-",
3528 get_mncc_name(msg_type), trans->state,
3529 cc_state_names[trans->state]);
3530
3531 /* Find function for current state and message */
3532 for (i = 0; i < DOWNSLLEN; i++)
3533 if ((msg_type == downstatelist[i].type)
3534 && ((1 << trans->state) & downstatelist[i].states))
3535 break;
3536 if (i == DOWNSLLEN) {
3537 DEBUGP(DCC, "Message unhandled at this state.\n");
3538 return 0;
3539 }
3540
3541 rc = downstatelist[i].rout(trans, arg);
3542
3543 return rc;
3544}
3545
3546
3547static struct datastate {
3548 u_int32_t states;
3549 int type;
3550 int (*rout) (struct gsm_trans *trans, struct msgb *msg);
3551} datastatelist[] = {
3552 /* mobile originating call establishment */
3553 {SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
3554 GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
3555 {SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
3556 GSM48_MT_CC_EMERG_SETUP, gsm48_cc_rx_setup},
3557 {SBIT(GSM_CSTATE_CONNECT_IND), /* 5.2.1.2 */
3558 GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
3559 /* mobile terminating call establishment */
3560 {SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.2 */
3561 GSM48_MT_CC_CALL_CONF, gsm48_cc_rx_call_conf},
3562 {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* ???? | 5.2.2.3.2 */
3563 GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
3564 {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) | SBIT(GSM_CSTATE_CALL_RECEIVED), /* (5.2.2.6) | 5.2.2.6 | 5.2.2.6 */
3565 GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
3566 /* signalling during call */
3567 {ALL_STATES - SBIT(GSM_CSTATE_NULL),
3568 GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
3569 {SBIT(GSM_CSTATE_ACTIVE),
3570 GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
3571 {ALL_STATES,
3572 GSM48_MT_CC_START_DTMF, gsm48_cc_rx_start_dtmf},
3573 {ALL_STATES,
3574 GSM48_MT_CC_STOP_DTMF, gsm48_cc_rx_stop_dtmf},
3575 {ALL_STATES,
3576 GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
3577 {SBIT(GSM_CSTATE_ACTIVE),
3578 GSM48_MT_CC_HOLD, gsm48_cc_rx_hold},
3579 {SBIT(GSM_CSTATE_ACTIVE),
3580 GSM48_MT_CC_RETR, gsm48_cc_rx_retrieve},
3581 {SBIT(GSM_CSTATE_ACTIVE),
3582 GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
3583 {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
3584 GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
3585 {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
3586 GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
3587 {SBIT(GSM_CSTATE_ACTIVE),
3588 GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
3589 /* clearing */
3590 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
3591 GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
3592 {ALL_STATES - SBIT(GSM_CSTATE_NULL), /* 5.4.4.1.2.2 */
3593 GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
3594 {ALL_STATES, /* 5.4.3.4 */
3595 GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
3596};
3597
3598#define DATASLLEN \
3599 (sizeof(datastatelist) / sizeof(struct datastate))
3600
Harald Welte59b04682009-06-10 05:40:52 +08003601static int gsm0408_rcv_cc(struct msgb *msg)
3602{
3603 struct gsm48_hdr *gh = msgb_l3(msg);
3604 u_int8_t msg_type = gh->msg_type & 0xbf;
Harald Welte03740842009-06-10 23:11:52 +08003605 u_int8_t transaction_id = (gh->proto_discr & 0xf0) ^ 0x80; /* flip */
3606 struct gsm_lchan *lchan = msg->lchan;
3607 struct gsm_trans *trans = NULL, *transt;
3608 struct gsm_network *net = lchan->ts->trx->bts->network;
3609 int i, rc = 0;
Harald Welte59b04682009-06-10 05:40:52 +08003610
Harald Welte03740842009-06-10 23:11:52 +08003611 if (msg_type & 0x80) {
3612 DEBUGP(DCC, "MSG 0x%2x not defined for PD error\n", msg_type);
3613 return -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08003614 }
Harald Welte03740842009-06-10 23:11:52 +08003615
3616 /* Find transaction */
3617 llist_for_each_entry(transt, &net->trans_list, entry) {
3618 /* Transaction of our lchan? */
3619 if (transt->lchan == lchan
3620 && transt->transaction_id == transaction_id) {
3621 trans = transt;
3622 }
3623 }
3624
3625 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
3626 "Received '%s' from MS in state %d (%s)\n",
3627 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
3628 transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-",
3629 cc_msg_names[msg_type], trans?(trans->state):0,
3630 cc_state_names[trans?(trans->state):0]);
3631
3632 /* Create transaction */
3633 if (!trans) {
3634 DEBUGP(DCC, "Unknown transaction ID %02x, "
3635 "creating new trans.\n", transaction_id);
3636 /* Create transaction */
Harald Weltea1d5b232009-06-26 19:42:28 +02003637 if (!(trans = talloc_zero(tall_trans_ctx, struct gsm_trans))) {
Harald Welte03740842009-06-10 23:11:52 +08003638 DEBUGP(DCC, "No memory for trans.\n");
3639 rc = gsm48_tx_simple(msg->lchan,
3640 GSM48_PDISC_CC | transaction_id,
3641 GSM48_MT_CC_RELEASE_COMPL);
3642 return -ENOMEM;
3643 }
3644 llist_add_tail(&trans->entry, &net->trans_list);
3645 /* Assign transaction */
3646 trans->callref = new_callref++;
3647 trans->network = net;
3648 trans->transaction_id = transaction_id;
3649 trans->lchan = lchan;
3650 use_lchan(lchan);
3651 if (lchan->subscr) {
3652 trans->subscr = lchan->subscr;
3653 subscr_get(trans->subscr);
3654 }
3655 }
3656
3657 /* find function for current state and message */
3658 for (i = 0; i < DATASLLEN; i++)
3659 if ((msg_type == datastatelist[i].type)
3660 && ((1 << trans->state) & datastatelist[i].states))
3661 break;
3662 if (i == DATASLLEN) {
3663 DEBUGP(DCC, "Message unhandled at this state.\n");
3664 return 0;
3665 }
3666
3667 rc = datastatelist[i].rout(trans, msg);
Harald Welte59b04682009-06-10 05:40:52 +08003668
3669 return rc;
3670}
3671
3672/* here we pass in a msgb from the RSL->RLL. We expect the l3 pointer to be set */
3673int gsm0408_rcvmsg(struct msgb *msg)
3674{
3675 struct gsm48_hdr *gh = msgb_l3(msg);
3676 u_int8_t pdisc = gh->proto_discr & 0x0f;
3677 int rc = 0;
3678
3679 switch (pdisc) {
3680 case GSM48_PDISC_CC:
3681 rc = gsm0408_rcv_cc(msg);
3682 break;
3683 case GSM48_PDISC_MM:
3684 rc = gsm0408_rcv_mm(msg);
3685 break;
3686 case GSM48_PDISC_RR:
3687 rc = gsm0408_rcv_rr(msg);
3688 break;
3689 case GSM48_PDISC_SMS:
3690 rc = gsm0411_rcv_sms(msg);
3691 break;
3692 case GSM48_PDISC_MM_GPRS:
3693 case GSM48_PDISC_SM_GPRS:
3694 fprintf(stderr, "Unimplemented GSM 04.08 discriminator 0x%02d\n",
3695 pdisc);
3696 break;
3697 default:
3698 fprintf(stderr, "Unknown GSM 04.08 discriminator 0x%02d\n",
3699 pdisc);
3700 break;
3701 }
3702
3703 return rc;
3704}
3705
Harald Welte59b04682009-06-10 05:40:52 +08003706/* Section 9.1.8 / Table 9.9 */
3707struct chreq {
3708 u_int8_t val;
3709 u_int8_t mask;
3710 enum chreq_type type;
3711};
3712
3713/* If SYSTEM INFORMATION TYPE 4 NECI bit == 1 */
3714static const struct chreq chreq_type_neci1[] = {
3715 { 0xa0, 0xe0, CHREQ_T_EMERG_CALL },
3716 { 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_F },
3717 { 0x68, 0xfc, CHREQ_T_CALL_REEST_TCH_H },
3718 { 0x6c, 0xfc, CHREQ_T_CALL_REEST_TCH_H_DBL },
3719 { 0xe0, 0xe0, CHREQ_T_SDCCH },
3720 { 0x40, 0xf0, CHREQ_T_VOICE_CALL_TCH_H },
3721 { 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H },
3722 { 0x00, 0xf0, CHREQ_T_LOCATION_UPD },
3723 { 0x10, 0xf0, CHREQ_T_SDCCH },
3724 { 0x80, 0xe0, CHREQ_T_PAG_R_ANY },
3725 { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F },
3726 { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH },
3727};
3728
3729/* If SYSTEM INFORMATION TYPE 4 NECI bit == 0 */
3730static const struct chreq chreq_type_neci0[] = {
3731 { 0xa0, 0xe0, CHREQ_T_EMERG_CALL },
3732 { 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_H },
3733 { 0xe0, 0xe0, CHREQ_T_TCH_F },
3734 { 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H },
3735 { 0x00, 0xe0, CHREQ_T_LOCATION_UPD },
3736 { 0x80, 0xe0, CHREQ_T_PAG_R_ANY },
3737 { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F },
3738 { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH },
3739};
3740
3741static const enum gsm_chan_t ctype_by_chreq[] = {
3742 [CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_F,
3743 [CHREQ_T_CALL_REEST_TCH_F] = GSM_LCHAN_TCH_F,
3744 [CHREQ_T_CALL_REEST_TCH_H] = GSM_LCHAN_TCH_H,
3745 [CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_LCHAN_TCH_H,
3746 [CHREQ_T_SDCCH] = GSM_LCHAN_SDCCH,
3747 [CHREQ_T_TCH_F] = GSM_LCHAN_TCH_F,
3748 [CHREQ_T_VOICE_CALL_TCH_H] = GSM_LCHAN_TCH_H,
3749 [CHREQ_T_DATA_CALL_TCH_H] = GSM_LCHAN_TCH_H,
3750 [CHREQ_T_LOCATION_UPD] = GSM_LCHAN_SDCCH,
3751 [CHREQ_T_PAG_R_ANY] = GSM_LCHAN_SDCCH,
3752 [CHREQ_T_PAG_R_TCH_F] = GSM_LCHAN_TCH_F,
3753 [CHREQ_T_PAG_R_TCH_FH] = GSM_LCHAN_TCH_F,
3754};
3755
3756static const enum gsm_chreq_reason_t reason_by_chreq[] = {
3757 [CHREQ_T_EMERG_CALL] = GSM_CHREQ_REASON_EMERG,
3758 [CHREQ_T_CALL_REEST_TCH_F] = GSM_CHREQ_REASON_CALL,
3759 [CHREQ_T_CALL_REEST_TCH_H] = GSM_CHREQ_REASON_CALL,
3760 [CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_CHREQ_REASON_CALL,
3761 [CHREQ_T_SDCCH] = GSM_CHREQ_REASON_OTHER,
3762 [CHREQ_T_TCH_F] = GSM_CHREQ_REASON_OTHER,
3763 [CHREQ_T_VOICE_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER,
3764 [CHREQ_T_DATA_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER,
3765 [CHREQ_T_LOCATION_UPD] = GSM_CHREQ_REASON_LOCATION_UPD,
3766 [CHREQ_T_PAG_R_ANY] = GSM_CHREQ_REASON_PAG,
3767 [CHREQ_T_PAG_R_TCH_F] = GSM_CHREQ_REASON_PAG,
3768 [CHREQ_T_PAG_R_TCH_FH] = GSM_CHREQ_REASON_PAG,
3769};
3770
3771enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra)
3772{
3773 int i;
3774 /* FIXME: determine if we set NECI = 0 in the BTS SI4 */
3775
3776 for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) {
3777 const struct chreq *chr = &chreq_type_neci0[i];
3778 if ((ra & chr->mask) == chr->val)
3779 return ctype_by_chreq[chr->type];
3780 }
3781 fprintf(stderr, "Unknown CHANNEL REQUEST RQD 0x%02x\n", ra);
3782 return GSM_LCHAN_SDCCH;
3783}
3784
3785enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra)
3786{
3787 int i;
3788 /* FIXME: determine if we set NECI = 0 in the BTS SI4 */
3789
3790 for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) {
3791 const struct chreq *chr = &chreq_type_neci0[i];
3792 if ((ra & chr->mask) == chr->val)
3793 return reason_by_chreq[chr->type];
3794 }
3795 fprintf(stderr, "Unknown CHANNEL REQUEST REASON 0x%02x\n", ra);
3796 return GSM_CHREQ_REASON_OTHER;
3797}
Harald Welte03740842009-06-10 23:11:52 +08003798
3799/* dequeue messages to layer 4 */
3800int bsc_upqueue(struct gsm_network *net)
3801{
3802 struct gsm_mncc *mncc;
3803 struct msgb *msg;
3804 int work = 0;
3805
3806 if (net)
3807 while ((msg = msgb_dequeue(&net->upqueue))) {
3808 mncc = (struct gsm_mncc *)msg->data;
3809 if (net->mncc_recv)
3810 net->mncc_recv(net, mncc->msg_type, mncc);
3811 work = 1; /* work done */
Harald Weltebaf4d3a2009-06-26 19:40:48 +02003812 talloc_free(msg);
Harald Welte03740842009-06-10 23:11:52 +08003813 }
3814
3815 return work;
3816}