blob: 49234f8d885e4ffb89d8b7984f1c85762031676f [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");
357 lchan->loc_operation = talloc(tall_locop_ctx,
358 struct gsm_loc_updating_operation);
Harald Welte59b04682009-06-10 05:40:52 +0800359 memset(lchan->loc_operation, 0, sizeof(*lchan->loc_operation));
360}
361
362static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg)
363{
364 u_int32_t tmsi;
365
366 if (authorize_subscriber(lchan->loc_operation, lchan->subscr)) {
367 db_subscriber_alloc_tmsi(lchan->subscr);
368 subscr_update(lchan->subscr, msg->trx->bts, GSM_SUBSCRIBER_UPDATE_ATTACHED);
369 tmsi = strtoul(lchan->subscr->tmsi, NULL, 10);
370 release_loc_updating_req(lchan);
371 return gsm0408_loc_upd_acc(msg->lchan, tmsi);
372 }
373
374 return 0;
375}
376
377static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal,
378 void *handler_data, void *signal_data)
379{
Harald Welte03740842009-06-10 23:11:52 +0800380 struct gsm_trans *trans, *temp;
381
Harald Welte59b04682009-06-10 05:40:52 +0800382 if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
383 return 0;
384
385 /*
386 * Cancel any outstanding location updating request
387 * operation taking place on the lchan.
388 */
389 struct gsm_lchan *lchan = (struct gsm_lchan *)handler_data;
390 release_loc_updating_req(lchan);
391
Harald Welte03740842009-06-10 23:11:52 +0800392 /* Free all transactions that are associated with the released lchan */
393 llist_for_each_entry_safe(trans, temp, &lchan->ts->trx->bts->network->trans_list, entry) {
394 if (trans->lchan == lchan)
395 free_trans(trans);
396 }
397
Harald Welte59b04682009-06-10 05:40:52 +0800398 return 0;
399}
400
401/*
402 * This will be ran by the linker when loading the DSO. We use it to
403 * do system initialization, e.g. registration of signal handlers.
404 */
405static __attribute__((constructor)) void on_dso_load_0408(void)
406{
407 register_signal_handler(SS_LCHAN, gsm0408_handle_lchan_signal, NULL);
408}
409
410static void to_bcd(u_int8_t *bcd, u_int16_t val)
411{
412 bcd[2] = val % 10;
413 val = val / 10;
414 bcd[1] = val % 10;
415 val = val / 10;
416 bcd[0] = val % 10;
417 val = val / 10;
418}
419
420void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
421 u_int16_t mnc, u_int16_t lac)
422{
423 u_int8_t bcd[3];
424
425 to_bcd(bcd, mcc);
426 lai48->digits[0] = bcd[0] | (bcd[1] << 4);
427 lai48->digits[1] = bcd[2];
428
429 to_bcd(bcd, mnc);
430 /* FIXME: do we need three-digit MNC? See Table 10.5.3 */
431#if 0
432 lai48->digits[1] |= bcd[2] << 4;
433 lai48->digits[2] = bcd[0] | (bcd[1] << 4);
434#else
435 lai48->digits[1] |= 0xf << 4;
436 lai48->digits[2] = bcd[1] | (bcd[2] << 4);
437#endif
438
439 lai48->lac = htons(lac);
440}
441
442#define TMSI_LEN 5
443#define MID_TMSI_LEN (TMSI_LEN + 2)
444
445int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi)
446{
447 u_int32_t *tptr = (u_int32_t *) &buf[3];
448
449 buf[0] = GSM48_IE_MOBILE_ID;
450 buf[1] = TMSI_LEN;
451 buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
452 *tptr = htonl(tmsi);
453
454 return 7;
455}
456
457static const char bcd_num_digits[] = {
458 '0', '1', '2', '3', '4', '5', '6', '7',
459 '8', '9', '*', '#', 'a', 'b', 'c', '\0'
460};
461
Harald Welteb8a18b52009-06-10 12:08:54 +0800462/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
463int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
464 int h_len)
Harald Welte59b04682009-06-10 05:40:52 +0800465{
466 u_int8_t in_len = bcd_lv[0];
467 int i;
468
Harald Welteb8a18b52009-06-10 12:08:54 +0800469 for (i = 1 + h_len; i <= in_len; i++) {
Harald Welte59b04682009-06-10 05:40:52 +0800470 /* lower nibble */
471 output_len--;
472 if (output_len <= 1)
473 break;
474 *output++ = bcd_num_digits[bcd_lv[i] & 0xf];
475
476 /* higher nibble */
477 output_len--;
478 if (output_len <= 1)
479 break;
480 *output++ = bcd_num_digits[bcd_lv[i] >> 4];
481 }
482 if (output_len >= 1)
483 *output++ = '\0';
484
Harald Welteb8a18b52009-06-10 12:08:54 +0800485 return 0;
Harald Welte59b04682009-06-10 05:40:52 +0800486}
487
488/* convert a single ASCII character to call-control BCD */
489static int asc_to_bcd(const char asc)
490{
491 int i;
492
493 for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) {
494 if (bcd_num_digits[i] == asc)
495 return i;
496 }
497 return -EINVAL;
498}
499
Harald Welteb8a18b52009-06-10 12:08:54 +0800500/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
Harald Welte59b04682009-06-10 05:40:52 +0800501int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
Harald Welteb8a18b52009-06-10 12:08:54 +0800502 int h_len, const char *input)
Harald Welte59b04682009-06-10 05:40:52 +0800503{
504 int in_len = strlen(input);
505 int i;
Harald Welteb8a18b52009-06-10 12:08:54 +0800506 u_int8_t *bcd_cur = bcd_lv + 1 + h_len;
Harald Welte59b04682009-06-10 05:40:52 +0800507
508 /* two digits per byte, plus type byte */
Harald Welteb8a18b52009-06-10 12:08:54 +0800509 bcd_lv[0] = in_len/2 + h_len;
Harald Welte59b04682009-06-10 05:40:52 +0800510 if (in_len % 2)
511 bcd_lv[0]++;
512
Harald Welteb8a18b52009-06-10 12:08:54 +0800513 if (bcd_lv[0] > max_len)
514 return -EIO;
Harald Welte59b04682009-06-10 05:40:52 +0800515
516 for (i = 0; i < in_len; i++) {
517 int rc = asc_to_bcd(input[i]);
518 if (rc < 0)
519 return rc;
520 if (i % 2 == 0)
521 *bcd_cur = rc;
522 else
523 *bcd_cur++ |= (rc << 4);
524 }
525 /* append padding nibble in case of odd length */
526 if (i % 2)
527 *bcd_cur++ |= 0xf0;
528
529 /* return how many bytes we used */
530 return (bcd_cur - bcd_lv);
531}
532
Harald Welteb8a18b52009-06-10 12:08:54 +0800533/* decode 'bearer capability' */
Harald Welte03740842009-06-10 23:11:52 +0800534static int decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
Harald Welteb8a18b52009-06-10 12:08:54 +0800535 const u_int8_t *lv)
536{
537 u_int8_t in_len = lv[0];
538 int i, s;
539
540 if (in_len < 1)
541 return -EINVAL;
542
Harald Welte03740842009-06-10 23:11:52 +0800543 bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */
Harald Welteb8a18b52009-06-10 12:08:54 +0800544
545 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800546 bcap->transfer = lv[1] & 0x07;
547 bcap->mode = (lv[1] & 0x08) >> 3;
548 bcap->coding = (lv[1] & 0x10) >> 4;
549 bcap->radio = (lv[1] & 0x60) >> 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800550
551 i = 1;
552 s = 0;
553 while(!(lv[i] & 0x80)) {
554 i++; /* octet 3a etc */
555 if (in_len < i)
556 return 0;
Harald Welte03740842009-06-10 23:11:52 +0800557 bcap->speech_ver[s++] = lv[i] & 0x0f;
558 bcap->speech_ver[s] = -1; /* end of list */
Harald Welteb8a18b52009-06-10 12:08:54 +0800559 if (i == 2) /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800560 bcap->speech_ctm = (lv[i] & 0x20) >> 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800561 if (s == 7) /* maximum speech versions + end of list */
562 return 0;
563 }
564
565 return 0;
566}
567
568/* encode 'bearer capability' */
Harald Welte03740842009-06-10 23:11:52 +0800569static int encode_bearer_cap(struct msgb *msg, int lv_only,
570 const struct gsm_mncc_bearer_cap *bcap)
Harald Welteb8a18b52009-06-10 12:08:54 +0800571{
572 u_int8_t lv[32 + 1];
573 int i, s;
574
Harald Welte03740842009-06-10 23:11:52 +0800575 lv[1] = bcap->transfer;
576 lv[1] |= bcap->mode << 3;
577 lv[1] |= bcap->coding << 4;
578 lv[1] |= bcap->radio << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800579
580 i = 1;
Harald Welte03740842009-06-10 23:11:52 +0800581 for (s = 0; bcap->speech_ver[s] >= 0; s++) {
Harald Welteb8a18b52009-06-10 12:08:54 +0800582 i++; /* octet 3a etc */
Harald Welte03740842009-06-10 23:11:52 +0800583 lv[i] = bcap->speech_ver[s];
Harald Welteb8a18b52009-06-10 12:08:54 +0800584 if (i == 2) /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800585 lv[i] |= bcap->speech_ctm << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800586 }
587 lv[i] |= 0x80; /* last IE of octet 3 etc */
588
589 lv[0] = i;
590 if (lv_only)
591 msgb_lv_put(msg, lv[0], lv+1);
592 else
593 msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1);
594
595 return 0;
596}
597
598/* decode 'call control cap' */
Harald Welte03740842009-06-10 23:11:52 +0800599static int decode_cccap(struct gsm_mncc_cccap *ccap, const u_int8_t *lv)
Harald Welteb8a18b52009-06-10 12:08:54 +0800600{
601 u_int8_t in_len = lv[0];
602
603 if (in_len < 1)
604 return -EINVAL;
605
606 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800607 ccap->dtmf = lv[1] & 0x01;
608 ccap->pcp = (lv[1] & 0x02) >> 1;
Harald Welteb8a18b52009-06-10 12:08:54 +0800609
610 return 0;
611}
612
613/* decode 'called party BCD number' */
Harald Welte03740842009-06-10 23:11:52 +0800614static int decode_called(struct gsm_mncc_number *called,
615 const u_int8_t *lv)
Harald Welteb8a18b52009-06-10 12:08:54 +0800616{
617 u_int8_t in_len = lv[0];
618
619 if (in_len < 1)
620 return -EINVAL;
621
622 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800623 called->plan = lv[1] & 0x0f;
624 called->type = (lv[1] & 0x70) >> 4;
Harald Welteb8a18b52009-06-10 12:08:54 +0800625
626 /* octet 4..N */
Harald Welte03740842009-06-10 23:11:52 +0800627 decode_bcd_number(called->number, sizeof(called->number), lv, 1);
Harald Welteb8a18b52009-06-10 12:08:54 +0800628
629 return 0;
630}
631
632/* encode 'called party BCD number' */
Harald Welte03740842009-06-10 23:11:52 +0800633static int encode_called(struct msgb *msg,
634 const struct gsm_mncc_number *called)
Harald Welteb8a18b52009-06-10 12:08:54 +0800635{
636 u_int8_t lv[18];
637 int ret;
638
639 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800640 lv[1] = called->plan;
641 lv[1] |= called->type << 4;
Harald Welteb8a18b52009-06-10 12:08:54 +0800642
643 /* octet 4..N, octet 2 */
Harald Welte03740842009-06-10 23:11:52 +0800644 ret = encode_bcd_number(lv, sizeof(lv), 1, called->number);
Harald Welteb8a18b52009-06-10 12:08:54 +0800645 if (ret < 0)
646 return ret;
647
648 msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1);
649
650 return 0;
651}
652
653/* encode callerid of various IEs */
Harald Welte03740842009-06-10 23:11:52 +0800654static int encode_callerid(struct msgb *msg, int ie,
655 const struct gsm_mncc_number *callerid)
Harald Welteb8a18b52009-06-10 12:08:54 +0800656{
657 u_int8_t lv[13];
658 int h_len = 1;
659 int ret;
660
661 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800662 lv[1] = callerid->plan;
663 lv[1] |= callerid->type << 4;
Harald Welteb8a18b52009-06-10 12:08:54 +0800664
Harald Welte03740842009-06-10 23:11:52 +0800665 if (callerid->present || callerid->screen) {
Harald Welteb8a18b52009-06-10 12:08:54 +0800666 /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800667 lv[2] = callerid->screen;
668 lv[2] |= callerid->present << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800669 lv[2] |= 0x80;
670 h_len++;
671 } else
672 lv[1] |= 0x80;
673
674 /* octet 4..N, octet 2 */
Harald Welte03740842009-06-10 23:11:52 +0800675 ret = encode_bcd_number(lv, sizeof(lv), h_len, callerid->number);
Harald Welteb8a18b52009-06-10 12:08:54 +0800676 if (ret < 0)
677 return ret;
678
679 msgb_tlv_put(msg, ie, lv[0], lv+1);
680
681 return 0;
682}
683
684/* decode 'cause' */
Harald Welte03740842009-06-10 23:11:52 +0800685static int decode_cause(struct gsm_mncc_cause *cause,
Harald Welteb8a18b52009-06-10 12:08:54 +0800686 const u_int8_t *lv)
687{
688 u_int8_t in_len = lv[0];
689 int i;
690
691 if (in_len < 2)
692 return -EINVAL;
693
Harald Welte03740842009-06-10 23:11:52 +0800694 cause->diag_len = 0;
Harald Welteb8a18b52009-06-10 12:08:54 +0800695
696 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800697 cause->location = lv[1] & 0x0f;
698 cause->coding = (lv[1] & 0x60) >> 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800699
700 i = 1;
701 if (!(lv[i] & 0x80)) {
702 i++; /* octet 3a */
703 if (in_len < i+1)
704 return 0;
Harald Welte03740842009-06-10 23:11:52 +0800705 cause->rec = 1;
706 cause->rec_val = lv[i] & 0x7f;
Harald Welteb8a18b52009-06-10 12:08:54 +0800707
708 }
709 i++;
710
711 /* octet 4 */
Harald Welte03740842009-06-10 23:11:52 +0800712 cause->value = lv[i] & 0x7f;
Harald Welteb8a18b52009-06-10 12:08:54 +0800713 i++;
714
715 if (in_len < i) /* no diag */
716 return 0;
717
718 if (in_len - (i-1) > 32) /* maximum 32 octets */
719 return 0;
720
721 /* octet 5-N */
Harald Welte03740842009-06-10 23:11:52 +0800722 memcpy(cause->diag, lv + i, in_len - (i-1));
723 cause->diag_len = in_len - (i-1);
Harald Welteb8a18b52009-06-10 12:08:54 +0800724
725 return 0;
726}
727
728/* encode 'cause' */
Harald Welte03740842009-06-10 23:11:52 +0800729static int encode_cause(struct msgb *msg, int lv_only,
730 const struct gsm_mncc_cause *cause)
Harald Welteb8a18b52009-06-10 12:08:54 +0800731{
732 u_int8_t lv[32+4];
733 int i;
734
Harald Welte03740842009-06-10 23:11:52 +0800735 if (cause->diag_len > 32)
Harald Welteb8a18b52009-06-10 12:08:54 +0800736 return -EINVAL;
737
738 /* octet 3 */
Harald Welte03740842009-06-10 23:11:52 +0800739 lv[1] = cause->location;
740 lv[1] |= cause->coding << 5;
Harald Welteb8a18b52009-06-10 12:08:54 +0800741
742 i = 1;
Harald Welte03740842009-06-10 23:11:52 +0800743 if (cause->rec) {
Harald Welteb8a18b52009-06-10 12:08:54 +0800744 i++; /* octet 3a */
Harald Welte03740842009-06-10 23:11:52 +0800745 lv[i] = cause->rec_val;
Harald Welteb8a18b52009-06-10 12:08:54 +0800746 }
747 lv[i] |= 0x80; /* end of octet 3 */
748
749 /* octet 4 */
750 i++;
Harald Welte03740842009-06-10 23:11:52 +0800751 lv[i] = 0x80 | cause->value;
Harald Welteb8a18b52009-06-10 12:08:54 +0800752
753 /* octet 5-N */
Harald Welte03740842009-06-10 23:11:52 +0800754 if (cause->diag_len) {
755 memcpy(lv + i, cause->diag, cause->diag_len);
756 i += cause->diag_len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800757 }
758
759 lv[0] = i;
760 if (lv_only)
761 msgb_lv_put(msg, lv[0], lv+1);
762 else
763 msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1);
764
765 return 0;
766}
767
768/* encode 'calling number' */
Harald Welte03740842009-06-10 23:11:52 +0800769static int encode_calling(struct msgb *msg,
770 const struct gsm_mncc_number *calling)
Harald Welteb8a18b52009-06-10 12:08:54 +0800771{
Harald Welte03740842009-06-10 23:11:52 +0800772 return encode_callerid(msg, GSM48_IE_CALLING_BCD, calling);
Harald Welteb8a18b52009-06-10 12:08:54 +0800773}
774
775/* encode 'connected number' */
Harald Welte03740842009-06-10 23:11:52 +0800776static int encode_connected(struct msgb *msg,
777 const struct gsm_mncc_number *connected)
Harald Welteb8a18b52009-06-10 12:08:54 +0800778{
Harald Welte03740842009-06-10 23:11:52 +0800779 return encode_callerid(msg, GSM48_IE_CONN_BCD, connected);
Harald Welteb8a18b52009-06-10 12:08:54 +0800780}
781
782/* encode 'redirecting number' */
Harald Welte03740842009-06-10 23:11:52 +0800783static int encode_redirecting(struct msgb *msg,
784 const struct gsm_mncc_number *redirecting)
Harald Welteb8a18b52009-06-10 12:08:54 +0800785{
Harald Welte03740842009-06-10 23:11:52 +0800786 return encode_callerid(msg, GSM48_IE_REDIR_BCD, redirecting);
Harald Welteb8a18b52009-06-10 12:08:54 +0800787}
788
789/* decode 'facility' */
Harald Welte03740842009-06-10 23:11:52 +0800790static int decode_facility(struct gsm_mncc_facility *facility,
Harald Welteb8a18b52009-06-10 12:08:54 +0800791 const u_int8_t *lv)
792{
793 u_int8_t in_len = lv[0];
794
795 if (in_len < 1)
796 return -EINVAL;
797
Harald Welte03740842009-06-10 23:11:52 +0800798 if (in_len > sizeof(facility->info))
Harald Welteb8a18b52009-06-10 12:08:54 +0800799 return -EINVAL;
800
Harald Welte03740842009-06-10 23:11:52 +0800801 memcpy(facility->info, lv+1, in_len);
802 facility->len = in_len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800803
804 return 0;
805}
806
807/* encode 'facility' */
Harald Welte03740842009-06-10 23:11:52 +0800808static int encode_facility(struct msgb *msg, int lv_only,
809 const struct gsm_mncc_facility *facility)
Harald Welteb8a18b52009-06-10 12:08:54 +0800810{
811 u_int8_t lv[GSM_MAX_FACILITY + 1];
812
Harald Welte03740842009-06-10 23:11:52 +0800813 if (facility->len < 1 || facility->len > GSM_MAX_FACILITY)
Harald Welteb8a18b52009-06-10 12:08:54 +0800814 return -EINVAL;
815
Harald Welte03740842009-06-10 23:11:52 +0800816 memcpy(lv+1, facility->info, facility->len);
817 lv[0] = facility->len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800818 if (lv_only)
819 msgb_lv_put(msg, lv[0], lv+1);
820 else
821 msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1);
822
823 return 0;
824}
825
826/* decode 'notify' */
827static int decode_notify(int *notify, const u_int8_t *v)
828{
829 *notify = v[0] & 0x7f;
830
831 return 0;
832}
833
834/* encode 'notify' */
835static int encode_notify(struct msgb *msg, int notify)
836{
837 msgb_v_put(msg, notify | 0x80);
838
839 return 0;
840}
841
842/* encode 'signal' */
843static int encode_signal(struct msgb *msg, int signal)
844{
845 msgb_tv_put(msg, GSM48_IE_SIGNAL, signal);
846
847 return 0;
848}
849
850/* decode 'keypad' */
851static int decode_keypad(int *keypad, const u_int8_t *lv)
852{
853 u_int8_t in_len = lv[0];
854
855 if (in_len < 1)
856 return -EINVAL;
857
858 *keypad = lv[1] & 0x7f;
859
860 return 0;
861}
862
863/* encode 'keypad' */
864static int encode_keypad(struct msgb *msg, int keypad)
865{
866 msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad);
867
868 return 0;
869}
870
871/* decode 'progress' */
Harald Welte03740842009-06-10 23:11:52 +0800872static int decode_progress(struct gsm_mncc_progress *progress,
Harald Welteb8a18b52009-06-10 12:08:54 +0800873 const u_int8_t *lv)
874{
875 u_int8_t in_len = lv[0];
876
877 if (in_len < 2)
878 return -EINVAL;
879
Harald Welte03740842009-06-10 23:11:52 +0800880 progress->coding = (lv[1] & 0x60) >> 5;
881 progress->location = lv[1] & 0x0f;
882 progress->descr = lv[2] & 0x7f;
Harald Welteb8a18b52009-06-10 12:08:54 +0800883
884 return 0;
885}
886
887/* encode 'progress' */
Harald Welte03740842009-06-10 23:11:52 +0800888static int encode_progress(struct msgb *msg, int lv_only,
889 const struct gsm_mncc_progress *p)
Harald Welteb8a18b52009-06-10 12:08:54 +0800890{
891 u_int8_t lv[3];
892
893 lv[0] = 2;
Harald Welte03740842009-06-10 23:11:52 +0800894 lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf);
895 lv[2] = 0x80 | (p->descr & 0x7f);
Harald Welteb8a18b52009-06-10 12:08:54 +0800896 if (lv_only)
897 msgb_lv_put(msg, lv[0], lv+1);
898 else
899 msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1);
900
901 return 0;
902}
903
904/* decode 'user-user' */
Harald Welte03740842009-06-10 23:11:52 +0800905static int decode_useruser(struct gsm_mncc_useruser *uu,
Harald Welteb8a18b52009-06-10 12:08:54 +0800906 const u_int8_t *lv)
907{
908 u_int8_t in_len = lv[0];
Harald Welte03740842009-06-10 23:11:52 +0800909 char *info = uu->info;
910 int info_len = sizeof(uu->info);
Harald Welteb8a18b52009-06-10 12:08:54 +0800911 int i;
912
913 if (in_len < 1)
914 return -EINVAL;
915
Harald Welte03740842009-06-10 23:11:52 +0800916 uu->proto = lv[1];
Harald Welteb8a18b52009-06-10 12:08:54 +0800917
918 for (i = 2; i <= in_len; i++) {
919 info_len--;
920 if (info_len <= 1)
921 break;
922 *info++ = lv[i];
923 }
924 if (info_len >= 1)
925 *info++ = '\0';
926
927 return 0;
928}
929
930/* encode 'useruser' */
Harald Welte03740842009-06-10 23:11:52 +0800931static int encode_useruser(struct msgb *msg, int lv_only,
932 const struct gsm_mncc_useruser *uu)
Harald Welteb8a18b52009-06-10 12:08:54 +0800933{
934 u_int8_t lv[GSM_MAX_USERUSER + 2];
935
Harald Welte03740842009-06-10 23:11:52 +0800936 if (strlen(uu->info) > GSM_MAX_USERUSER)
Harald Welteb8a18b52009-06-10 12:08:54 +0800937 return -EINVAL;
938
Harald Welte03740842009-06-10 23:11:52 +0800939 lv[0] = 1 + strlen(uu->info);
940 lv[1] = uu->proto;
941 memcpy(lv + 2, uu->info, strlen(uu->info));
Harald Welteb8a18b52009-06-10 12:08:54 +0800942 if (lv_only)
943 msgb_lv_put(msg, lv[0], lv+1);
944 else
945 msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1);
946
947 return 0;
948}
949
950/* decode 'ss version' */
Harald Welte03740842009-06-10 23:11:52 +0800951static int decode_ssversion(struct gsm_mncc_ssversion *ssv,
Harald Welteb8a18b52009-06-10 12:08:54 +0800952 const u_int8_t *lv)
953{
954 u_int8_t in_len = lv[0];
955
Harald Welte03740842009-06-10 23:11:52 +0800956 if (in_len < 1 || in_len < sizeof(ssv->info))
Harald Welteb8a18b52009-06-10 12:08:54 +0800957 return -EINVAL;
958
Harald Welte03740842009-06-10 23:11:52 +0800959 memcpy(ssv->info, lv + 1, in_len);
960 ssv->len = in_len;
Harald Welteb8a18b52009-06-10 12:08:54 +0800961
962 return 0;
963}
964
965/* encode 'more data' */
966static int encode_more(struct msgb *msg)
967{
968 u_int8_t *ie;
969
970 ie = msgb_put(msg, 1);
971 ie[0] = GSM48_IE_MORE_DATA;
972
973 return 0;
974}
975
Harald Welte59b04682009-06-10 05:40:52 +0800976struct msgb *gsm48_msgb_alloc(void)
977{
978 return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM);
979}
980
981int gsm48_sendmsg(struct msgb *msg)
982{
Harald Welte59b04682009-06-10 05:40:52 +0800983 if (msg->lchan) {
Harald Welte03740842009-06-10 23:11:52 +0800984 struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data;
Harald Welte59b04682009-06-10 05:40:52 +0800985 msg->trx = msg->lchan->ts->trx;
986
Harald Welte03740842009-06-10 23:11:52 +0800987 if ((gh->proto_discr & GSM48_PDISC_MASK) == GSM48_PDISC_CC)
988 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x) "
989 "Sending '%s' to MS.\n", msg->trx->bts->nr,
990 msg->trx->nr, msg->lchan->ts->nr,
991 gh->proto_discr & 0xf0,
992 cc_msg_names[gh->msg_type & 0x3f]);
993 else
994 DEBUGP(DCC, "(bts %d trx %d ts %d pd %02x) "
995 "Sending 0x%02x to MS.\n", msg->trx->bts->nr,
996 msg->trx->nr, msg->lchan->ts->nr,
997 gh->proto_discr, gh->msg_type);
Harald Welte59b04682009-06-10 05:40:52 +0800998 }
999
1000 msg->l3h = msg->data;
1001
1002 return rsl_data_request(msg, 0);
1003}
1004
Harald Welte59b04682009-06-10 05:40:52 +08001005/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
1006int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
1007{
1008 struct msgb *msg = gsm48_msgb_alloc();
1009 struct gsm48_hdr *gh;
1010
1011 msg->lchan = lchan;
1012
1013 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
1014 gh->proto_discr = GSM48_PDISC_MM;
1015 gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT;
1016 gh->data[0] = cause;
1017
1018 DEBUGP(DMM, "-> LOCATION UPDATING REJECT on channel: %d\n", lchan->nr);
1019
1020 return gsm48_sendmsg(msg);
1021}
1022
1023/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
1024int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
1025{
1026 struct gsm_bts *bts = lchan->ts->trx->bts;
1027 struct msgb *msg = gsm48_msgb_alloc();
1028 struct gsm48_hdr *gh;
1029 struct gsm48_loc_area_id *lai;
1030 u_int8_t *mid;
1031 int ret;
1032
1033 msg->lchan = lchan;
1034
1035 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1036 gh->proto_discr = GSM48_PDISC_MM;
1037 gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT;
1038
1039 lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
1040 gsm0408_generate_lai(lai, bts->network->country_code,
1041 bts->network->network_code, bts->location_area_code);
1042
1043 mid = msgb_put(msg, MID_TMSI_LEN);
1044 generate_mid_from_tmsi(mid, tmsi);
1045
1046 DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
1047
1048 ret = gsm48_sendmsg(msg);
1049
1050 ret = gsm48_tx_mm_info(lchan);
1051
1052 return ret;
1053}
1054
1055static char bcd2char(u_int8_t bcd)
1056{
1057 if (bcd < 0xa)
1058 return '0' + bcd;
1059 else
1060 return 'A' + (bcd - 0xa);
1061}
1062
1063/* Convert Mobile Identity (10.5.1.4) to string */
1064static int mi_to_string(char *string, int str_len, u_int8_t *mi, int mi_len)
1065{
1066 int i;
1067 u_int8_t mi_type;
1068 char *str_cur = string;
1069 u_int32_t tmsi;
1070
1071 mi_type = mi[0] & GSM_MI_TYPE_MASK;
1072
1073 switch (mi_type) {
1074 case GSM_MI_TYPE_NONE:
1075 break;
1076 case GSM_MI_TYPE_TMSI:
1077 /* Table 10.5.4.3, reverse generate_mid_from_tmsi */
1078 if (mi_len == TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {
1079 memcpy(&tmsi, &mi[1], 4);
1080 tmsi = ntohl(tmsi);
1081 return snprintf(string, str_len, "%u", tmsi);
1082 }
1083 break;
1084 case GSM_MI_TYPE_IMSI:
1085 case GSM_MI_TYPE_IMEI:
1086 case GSM_MI_TYPE_IMEISV:
1087 *str_cur++ = bcd2char(mi[0] >> 4);
1088
1089 for (i = 1; i < mi_len; i++) {
1090 if (str_cur + 2 >= string + str_len)
1091 return str_cur - string;
1092 *str_cur++ = bcd2char(mi[i] & 0xf);
1093 /* skip last nibble in last input byte when GSM_EVEN */
1094 if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
1095 *str_cur++ = bcd2char(mi[i] >> 4);
1096 }
1097 break;
1098 default:
1099 break;
1100 }
1101 *str_cur++ = '\0';
1102
1103 return str_cur - string;
1104}
1105
1106/* Transmit Chapter 9.2.10 Identity Request */
1107static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type)
1108{
1109 struct msgb *msg = gsm48_msgb_alloc();
1110 struct gsm48_hdr *gh;
1111
1112 msg->lchan = lchan;
1113
1114 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
1115 gh->proto_discr = GSM48_PDISC_MM;
1116 gh->msg_type = GSM48_MT_MM_ID_REQ;
1117 gh->data[0] = id_type;
1118
1119 return gsm48_sendmsg(msg);
1120}
1121
1122#define MI_SIZE 32
1123
1124/* Parse Chapter 9.2.11 Identity Response */
1125static int mm_rx_id_resp(struct msgb *msg)
1126{
1127 struct gsm48_hdr *gh = msgb_l3(msg);
1128 struct gsm_lchan *lchan = msg->lchan;
1129 u_int8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
1130 char mi_string[MI_SIZE];
1131
1132 mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
1133 DEBUGP(DMM, "IDENTITY RESPONSE: mi_type=0x%02x MI(%s)\n",
1134 mi_type, mi_string);
1135
Harald Welte59b04682009-06-10 05:40:52 +08001136 switch (mi_type) {
1137 case GSM_MI_TYPE_IMSI:
1138 if (!lchan->subscr)
1139 lchan->subscr = db_create_subscriber(mi_string);
1140 if (lchan->loc_operation)
1141 lchan->loc_operation->waiting_for_imsi = 0;
1142 break;
1143 case GSM_MI_TYPE_IMEI:
1144 case GSM_MI_TYPE_IMEISV:
1145 /* update subscribe <-> IMEI mapping */
1146 if (lchan->subscr)
1147 db_subscriber_assoc_imei(lchan->subscr, mi_string);
1148 if (lchan->loc_operation)
1149 lchan->loc_operation->waiting_for_imei = 0;
1150 break;
1151 }
1152
1153 /* Check if we can let the mobile station enter */
1154 return gsm0408_authorize(lchan, msg);
1155}
1156
1157
1158static void loc_upd_rej_cb(void *data)
1159{
1160 struct gsm_lchan *lchan = data;
1161
1162 release_loc_updating_req(lchan);
1163 gsm0408_loc_upd_rej(lchan, reject_cause);
1164 lchan_auto_release(lchan);
1165}
1166
1167static void schedule_reject(struct gsm_lchan *lchan)
1168{
1169 lchan->loc_operation->updating_timer.cb = loc_upd_rej_cb;
1170 lchan->loc_operation->updating_timer.data = lchan;
1171 bsc_schedule_timer(&lchan->loc_operation->updating_timer, 5, 0);
1172}
1173
1174static const char *lupd_name(u_int8_t type)
1175{
1176 switch (type) {
1177 case GSM48_LUPD_NORMAL:
1178 return "NORMAL";
1179 case GSM48_LUPD_PERIODIC:
1180 return "PEROIDOC";
1181 case GSM48_LUPD_IMSI_ATT:
1182 return "IMSI ATTACH";
1183 default:
1184 return "UNKNOWN";
1185 }
1186}
1187
1188#define MI_SIZE 32
1189/* Chapter 9.2.15: Receive Location Updating Request */
1190static int mm_rx_loc_upd_req(struct msgb *msg)
1191{
1192 struct gsm48_hdr *gh = msgb_l3(msg);
1193 struct gsm48_loc_upd_req *lu;
Harald Welte03740842009-06-10 23:11:52 +08001194 struct gsm_subscriber *subscr = NULL;
Harald Welte59b04682009-06-10 05:40:52 +08001195 struct gsm_lchan *lchan = msg->lchan;
1196 u_int8_t mi_type;
1197 char mi_string[MI_SIZE];
1198 int rc;
1199
1200 lu = (struct gsm48_loc_upd_req *) gh->data;
1201
1202 mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
1203
1204 mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
1205
1206 DEBUGP(DMM, "LUPDREQ: mi_type=0x%02x MI(%s) type=%s\n", mi_type, mi_string,
1207 lupd_name(lu->type));
1208
1209 /*
1210 * Pseudo Spoof detection: Just drop a second/concurrent
1211 * location updating request.
1212 */
1213 if (lchan->loc_operation) {
1214 DEBUGP(DMM, "LUPDREQ: ignoring request due an existing one: %p.\n",
1215 lchan->loc_operation);
1216 gsm0408_loc_upd_rej(lchan, GSM48_REJECT_PROTOCOL_ERROR);
1217 return 0;
1218 }
1219
1220 allocate_loc_updating_req(lchan);
1221
1222 switch (mi_type) {
1223 case GSM_MI_TYPE_IMSI:
Harald Welte03740842009-06-10 23:11:52 +08001224 DEBUGP(DMM, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001225 /* we always want the IMEI, too */
Harald Welte59b04682009-06-10 05:40:52 +08001226 rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEI);
1227 lchan->loc_operation->waiting_for_imei = 1;
1228
1229 /* look up subscriber based on IMSI */
1230 subscr = db_create_subscriber(mi_string);
1231 break;
1232 case GSM_MI_TYPE_TMSI:
Harald Welte03740842009-06-10 23:11:52 +08001233 DEBUGP(DMM, "\n");
Harald Welte59b04682009-06-10 05:40:52 +08001234 /* we always want the IMEI, too */
Harald Welte59b04682009-06-10 05:40:52 +08001235 rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEI);
1236 lchan->loc_operation->waiting_for_imei = 1;
1237
1238 /* look up the subscriber based on TMSI, request IMSI if it fails */
1239 subscr = subscr_get_by_tmsi(mi_string);
1240 if (!subscr) {
1241 /* send IDENTITY REQUEST message to get IMSI */
Harald Welte59b04682009-06-10 05:40:52 +08001242 rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI);
1243 lchan->loc_operation->waiting_for_imsi = 1;
1244 }
1245 break;
1246 case GSM_MI_TYPE_IMEI:
1247 case GSM_MI_TYPE_IMEISV:
1248 /* no sim card... FIXME: what to do ? */
1249 DEBUGP(DMM, "unimplemented mobile identity type\n");
1250 break;
1251 default:
1252 DEBUGP(DMM, "unknown mobile identity type\n");
1253 break;
1254 }
1255
Harald Welte03740842009-06-10 23:11:52 +08001256 if (!subscr) {
1257 DEBUGP(DRR, "<- Can't find any subscriber for this ID\n");
1258 /* FIXME: request id? close channel? */
1259 return -EINVAL;
1260 }
1261
Harald Welte59b04682009-06-10 05:40:52 +08001262 lchan->subscr = subscr;
1263
1264 /*
1265 * Schedule the reject timer and check if we can let the
1266 * subscriber into our network immediately or if we need to wait
1267 * for identity responses.
1268 */
1269 schedule_reject(lchan);
1270 return gsm0408_authorize(lchan, msg);
1271}
1272
1273/* 9.1.5 Channel mode modify */
1274int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode)
1275{
1276 struct msgb *msg = gsm48_msgb_alloc();
1277 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1278 struct gsm48_chan_mode_modify *cmm =
1279 (struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm));
1280 u_int16_t arfcn = lchan->ts->trx->arfcn & 0x3ff;
1281
1282 DEBUGP(DRR, "-> CHANNEL MODE MODIFY mode=0x%02x\n", mode);
1283
1284 lchan->tch_mode = mode;
1285 msg->lchan = lchan;
1286 gh->proto_discr = GSM48_PDISC_RR;
1287 gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF;
1288
1289 /* fill the channel information element, this code
1290 * should probably be shared with rsl_rx_chan_rqd() */
1291 cmm->chan_desc.chan_nr = lchan2chan_nr(lchan);
1292 cmm->chan_desc.h0.tsc = lchan->ts->trx->bts->tsc;
1293 cmm->chan_desc.h0.h = 0;
1294 cmm->chan_desc.h0.arfcn_high = arfcn >> 8;
1295 cmm->chan_desc.h0.arfcn_low = arfcn & 0xff;
1296 cmm->mode = mode;
1297
1298 return gsm48_sendmsg(msg);
1299}
1300
Harald Welte03740842009-06-10 23:11:52 +08001301#if 0
1302static u_int8_t to_bcd8(u_int8_t val)
1303{
1304 return ((val / 10) << 4) | (val % 10);
1305}
1306#endif
1307
Harald Welte59b04682009-06-10 05:40:52 +08001308/* Section 9.2.15a */
1309int gsm48_tx_mm_info(struct gsm_lchan *lchan)
1310{
1311 struct msgb *msg = gsm48_msgb_alloc();
1312 struct gsm48_hdr *gh;
1313 struct gsm_network *net = lchan->ts->trx->bts->network;
1314 u_int8_t *ptr8;
1315 u_int16_t *ptr16;
1316 int name_len;
1317 int i;
Harald Welte03740842009-06-10 23:11:52 +08001318#if 0
1319 time_t cur_t;
1320 struct tm* cur_time;
1321 int tz15min;
1322#endif
Harald Welte59b04682009-06-10 05:40:52 +08001323
1324 msg->lchan = lchan;
1325
1326 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1327 gh->proto_discr = GSM48_PDISC_MM;
1328 gh->msg_type = GSM48_MT_MM_INFO;
1329
1330 if (net->name_long) {
1331 name_len = strlen(net->name_long);
1332 /* 10.5.3.5a */
1333 ptr8 = msgb_put(msg, 3);
1334 ptr8[0] = GSM48_IE_NAME_LONG;
1335 ptr8[1] = name_len*2 +1;
1336 ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
1337
1338 ptr16 = (u_int16_t *) msgb_put(msg, name_len*2);
1339 for (i = 0; i < name_len; i++)
1340 ptr16[i] = htons(net->name_long[i]);
1341
1342 /* FIXME: Use Cell Broadcast, not UCS-2, since
1343 * UCS-2 is only supported by later revisions of the spec */
1344 }
1345
1346 if (net->name_short) {
1347 name_len = strlen(net->name_short);
1348 /* 10.5.3.5a */
1349 ptr8 = (u_int8_t *) msgb_put(msg, 3);
1350 ptr8[0] = GSM48_IE_NAME_LONG;
1351 ptr8[1] = name_len*2 + 1;
1352 ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
1353
1354 ptr16 = (u_int16_t *) msgb_put(msg, name_len*2);
1355 for (i = 0; i < name_len; i++)
1356 ptr16[i] = htons(net->name_short[i]);
1357 }
1358
1359#if 0
Harald Welte59b04682009-06-10 05:40:52 +08001360 /* Section 10.5.3.9 */
1361 cur_t = time(NULL);
Harald Welte03740842009-06-10 23:11:52 +08001362 cur_time = gmtime(&cur_t);
Harald Welte59b04682009-06-10 05:40:52 +08001363 ptr8 = msgb_put(msg, 8);
1364 ptr8[0] = GSM48_IE_NET_TIME_TZ;
1365 ptr8[1] = to_bcd8(cur_time->tm_year % 100);
1366 ptr8[2] = to_bcd8(cur_time->tm_mon);
1367 ptr8[3] = to_bcd8(cur_time->tm_mday);
1368 ptr8[4] = to_bcd8(cur_time->tm_hour);
1369 ptr8[5] = to_bcd8(cur_time->tm_min);
1370 ptr8[6] = to_bcd8(cur_time->tm_sec);
1371 /* 02.42: coded as BCD encoded signed value in units of 15 minutes */
1372 tz15min = (cur_time->tm_gmtoff)/(60*15);
Harald Welte03740842009-06-10 23:11:52 +08001373 ptr8[7] = to_bcd8(tz15min);
Harald Welte59b04682009-06-10 05:40:52 +08001374 if (tz15min < 0)
Harald Welte03740842009-06-10 23:11:52 +08001375 ptr8[7] |= 0x80;
Harald Welte59b04682009-06-10 05:40:52 +08001376#endif
1377
1378 return gsm48_sendmsg(msg);
1379}
1380
1381static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
1382{
1383 DEBUGP(DMM, "-> CM SERVICE ACK\n");
1384 return gsm48_tx_simple(lchan, GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_ACC);
1385}
1386
1387/* 9.2.6 CM service reject */
1388static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan,
1389 enum gsm48_reject_value value)
1390{
1391 struct msgb *msg = gsm48_msgb_alloc();
1392 struct gsm48_hdr *gh;
1393
1394 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
1395
1396 msg->lchan = lchan;
1397 use_lchan(lchan);
1398
1399 gh->proto_discr = GSM48_PDISC_MM;
1400 gh->msg_type = GSM48_MT_MM_CM_SERV_REJ;
1401 gh->data[0] = value;
1402 DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);
1403
1404 return gsm48_sendmsg(msg);
1405}
1406
1407
1408/*
1409 * Handle CM Service Requests
1410 * a) Verify that the packet is long enough to contain the information
1411 * we require otherwsie reject with INCORRECT_MESSAGE
1412 * b) Try to parse the TMSI. If we do not have one reject
1413 * c) Check that we know the subscriber with the TMSI otherwise reject
1414 * with a HLR cause
1415 * d) Set the subscriber on the gsm_lchan and accept
1416 */
1417static int gsm48_rx_mm_serv_req(struct msgb *msg)
1418{
1419 u_int8_t mi_type;
1420 char mi_string[MI_SIZE];
1421
1422 struct gsm_subscriber *subscr;
1423 struct gsm48_hdr *gh = msgb_l3(msg);
1424 struct gsm48_service_request *req =
1425 (struct gsm48_service_request *)gh->data;
1426 /* unfortunately in Phase1 the classmar2 length is variable */
1427 u_int8_t classmark2_len = gh->data[1];
1428 u_int8_t *classmark2 = gh->data+2;
1429 u_int8_t mi_len = *(classmark2 + classmark2_len);
1430 u_int8_t *mi = (classmark2 + classmark2_len + 1);
1431
1432 DEBUGP(DMM, "<- CM SERVICE REQUEST ");
1433 if (msg->data_len < sizeof(struct gsm48_service_request*)) {
1434 DEBUGPC(DMM, "wrong sized message\n");
1435 return gsm48_tx_mm_serv_rej(msg->lchan,
1436 GSM48_REJECT_INCORRECT_MESSAGE);
1437 }
1438
1439 if (msg->data_len < req->mi_len + 6) {
1440 DEBUGPC(DMM, "does not fit in packet\n");
1441 return gsm48_tx_mm_serv_rej(msg->lchan,
1442 GSM48_REJECT_INCORRECT_MESSAGE);
1443 }
1444
1445 mi_type = mi[0] & GSM_MI_TYPE_MASK;
1446 if (mi_type != GSM_MI_TYPE_TMSI) {
1447 DEBUGPC(DMM, "mi_type is not TMSI: %d\n", mi_type);
1448 return gsm48_tx_mm_serv_rej(msg->lchan,
1449 GSM48_REJECT_INCORRECT_MESSAGE);
1450 }
1451
1452 mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
1453 DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
1454 req->cm_service_type, mi_type, mi_string);
1455
1456 subscr = subscr_get_by_tmsi(mi_string);
1457
1458 /* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
1459 if (!subscr)
1460 return gsm48_tx_mm_serv_rej(msg->lchan,
1461 GSM48_REJECT_IMSI_UNKNOWN_IN_HLR);
1462
1463 if (!msg->lchan->subscr)
1464 msg->lchan->subscr = subscr;
1465 else if (msg->lchan->subscr != subscr) {
1466 DEBUGP(DMM, "<- CM Channel already owned by someone else?\n");
1467 subscr_put(subscr);
1468 }
1469
1470 subscr->classmark2_len = classmark2_len;
1471 memcpy(subscr->classmark2, classmark2, classmark2_len);
1472
1473 return gsm48_tx_mm_serv_ack(msg->lchan);
1474}
1475
1476static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg)
1477{
1478 struct gsm48_hdr *gh = msgb_l3(msg);
1479 struct gsm48_imsi_detach_ind *idi =
1480 (struct gsm48_imsi_detach_ind *) gh->data;
1481 u_int8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK;
1482 char mi_string[MI_SIZE];
Harald Welte03740842009-06-10 23:11:52 +08001483 struct gsm_subscriber *subscr = NULL;
Harald Welte59b04682009-06-10 05:40:52 +08001484
1485 mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len);
1486 DEBUGP(DMM, "IMSI DETACH INDICATION: mi_type=0x%02x MI(%s): ",
1487 mi_type, mi_string);
1488
1489 switch (mi_type) {
1490 case GSM_MI_TYPE_TMSI:
1491 subscr = subscr_get_by_tmsi(mi_string);
1492 break;
1493 case GSM_MI_TYPE_IMSI:
1494 subscr = subscr_get_by_imsi(mi_string);
1495 break;
1496 case GSM_MI_TYPE_IMEI:
1497 case GSM_MI_TYPE_IMEISV:
1498 /* no sim card... FIXME: what to do ? */
1499 DEBUGPC(DMM, "unimplemented mobile identity type\n");
1500 break;
1501 default:
1502 DEBUGPC(DMM, "unknown mobile identity type\n");
1503 break;
1504 }
1505
1506 if (subscr) {
1507 subscr_update(subscr, msg->trx->bts,
1508 GSM_SUBSCRIBER_UPDATE_DETACHED);
1509 DEBUGP(DMM, "Subscriber: %s\n",
1510 subscr->name ? subscr->name : subscr->imsi);
1511 subscr_put(subscr);
1512 } else
1513 DEBUGP(DMM, "Unknown Subscriber ?!?\n");
1514
Harald Welte59b04682009-06-10 05:40:52 +08001515 return 0;
1516}
1517
1518static int gsm48_rx_mm_status(struct msgb *msg)
1519{
1520 struct gsm48_hdr *gh = msgb_l3(msg);
1521
1522 DEBUGP(DMM, "MM STATUS (reject cause 0x%02x)\n", gh->data[0]);
1523
1524 return 0;
1525}
1526
1527/* Receive a GSM 04.08 Mobility Management (MM) message */
1528static int gsm0408_rcv_mm(struct msgb *msg)
1529{
1530 struct gsm48_hdr *gh = msgb_l3(msg);
Harald Welte03740842009-06-10 23:11:52 +08001531 int rc = 0;
Harald Welte59b04682009-06-10 05:40:52 +08001532
1533 switch (gh->msg_type & 0xbf) {
1534 case GSM48_MT_MM_LOC_UPD_REQUEST:
1535 DEBUGP(DMM, "LOCATION UPDATING REQUEST\n");
1536 rc = mm_rx_loc_upd_req(msg);
1537 break;
1538 case GSM48_MT_MM_ID_RESP:
1539 rc = mm_rx_id_resp(msg);
1540 break;
1541 case GSM48_MT_MM_CM_SERV_REQ:
1542 rc = gsm48_rx_mm_serv_req(msg);
1543 break;
1544 case GSM48_MT_MM_STATUS:
1545 rc = gsm48_rx_mm_status(msg);
1546 break;
1547 case GSM48_MT_MM_TMSI_REALL_COMPL:
1548 DEBUGP(DMM, "TMSI Reallocation Completed. Subscriber: %s\n",
1549 msg->lchan->subscr ?
1550 msg->lchan->subscr->imsi :
1551 "unknown subscriber");
1552 break;
1553 case GSM48_MT_MM_IMSI_DETACH_IND:
1554 rc = gsm48_rx_mm_imsi_detach_ind(msg);
1555 break;
1556 case GSM48_MT_MM_CM_REEST_REQ:
1557 DEBUGP(DMM, "CM REESTABLISH REQUEST: Not implemented\n");
1558 break;
1559 case GSM48_MT_MM_AUTH_RESP:
1560 DEBUGP(DMM, "AUTHENTICATION RESPONSE: Not implemented\n");
1561 break;
1562 default:
1563 fprintf(stderr, "Unknown GSM 04.08 MM msg type 0x%02x\n",
1564 gh->msg_type);
1565 break;
1566 }
1567
1568 return rc;
1569}
1570
1571/* Receive a PAGING RESPONSE message from the MS */
1572static int gsm48_rr_rx_pag_resp(struct msgb *msg)
1573{
1574 struct gsm48_hdr *gh = msgb_l3(msg);
1575 u_int8_t *classmark2_lv = gh->data + 1;
1576 u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv;
1577 u_int8_t mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
1578 char mi_string[MI_SIZE];
Harald Welte03740842009-06-10 23:11:52 +08001579 struct gsm_subscriber *subscr = NULL;
Harald Welte59b04682009-06-10 05:40:52 +08001580 struct paging_signal_data sig_data;
1581 int rc = 0;
1582
1583 mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, *mi_lv);
1584 DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
1585 mi_type, mi_string);
1586 switch (mi_type) {
1587 case GSM_MI_TYPE_TMSI:
1588 subscr = subscr_get_by_tmsi(mi_string);
1589 break;
1590 case GSM_MI_TYPE_IMSI:
1591 subscr = subscr_get_by_imsi(mi_string);
1592 break;
1593 }
1594
1595 if (!subscr) {
1596 DEBUGP(DRR, "<- Can't find any subscriber for this ID\n");
1597 /* FIXME: request id? close channel? */
1598 return -EINVAL;
1599 }
1600 DEBUGP(DRR, "<- Channel was requested by %s\n",
1601 subscr->name ? subscr->name : subscr->imsi);
1602
1603 subscr->classmark2_len = *classmark2_lv;
1604 memcpy(subscr->classmark2, classmark2_lv+1, *classmark2_lv);
1605
1606 if (!msg->lchan->subscr) {
1607 msg->lchan->subscr = subscr;
1608 } else if (msg->lchan->subscr != subscr) {
1609 DEBUGP(DRR, "<- Channel already owned by someone else?\n");
1610 subscr_put(subscr);
1611 return -EINVAL;
1612 } else {
1613 DEBUGP(DRR, "<- Channel already owned by us\n");
1614 subscr_put(subscr);
1615 subscr = msg->lchan->subscr;
1616 }
1617
1618 sig_data.subscr = subscr;
1619 sig_data.bts = msg->lchan->ts->trx->bts;
1620 sig_data.lchan = msg->lchan;
1621
1622 dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
Harald Welte876312f2009-06-10 11:21:55 +08001623
1624 /* Stop paging on the bts we received the paging response */
Harald Welte59b04682009-06-10 05:40:52 +08001625 paging_request_stop(msg->trx->bts, subscr, msg->lchan);
1626
1627 /* FIXME: somehow signal the completion of the PAGING to
1628 * the entity that requested the paging */
1629
1630 return rc;
1631}
1632
1633static int gsm48_rx_rr_classmark(struct msgb *msg)
1634{
1635 struct gsm48_hdr *gh = msgb_l3(msg);
1636 struct gsm_subscriber *subscr = msg->lchan->subscr;
1637 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1638 u_int8_t cm2_len, cm3_len = 0;
1639 u_int8_t *cm2, *cm3 = NULL;
1640
1641 DEBUGP(DRR, "CLASSMARK CHANGE ");
1642
1643 /* classmark 2 */
1644 cm2_len = gh->data[0];
1645 cm2 = &gh->data[1];
1646 DEBUGPC(DRR, "CM2(len=%u) ", cm2_len);
1647
1648 if (payload_len > cm2_len + 1) {
1649 /* we must have a classmark3 */
1650 if (gh->data[cm2_len+1] != 0x20) {
1651 DEBUGPC(DRR, "ERR CM3 TAG\n");
1652 return -EINVAL;
1653 }
1654 if (cm2_len > 3) {
1655 DEBUGPC(DRR, "CM2 too long!\n");
1656 return -EINVAL;
1657 }
1658
1659 cm3_len = gh->data[cm2_len+2];
1660 cm3 = &gh->data[cm2_len+3];
1661 if (cm3_len > 14) {
1662 DEBUGPC(DRR, "CM3 len %u too long!\n", cm3_len);
1663 return -EINVAL;
1664 }
1665 DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len);
1666 }
1667 if (subscr) {
1668 subscr->classmark2_len = cm2_len;
1669 memcpy(subscr->classmark2, cm2, cm2_len);
1670 if (cm3) {
1671 subscr->classmark3_len = cm3_len;
1672 memcpy(subscr->classmark3, cm3, cm3_len);
1673 }
1674 }
1675
1676 /* FIXME: store the classmark2/3 values with the equipment register */
1677
1678 return 0;
1679}
1680
1681static int gsm48_rx_rr_status(struct msgb *msg)
1682{
1683 struct gsm48_hdr *gh = msgb_l3(msg);
1684
1685 DEBUGP(DRR, "STATUS rr_cause = %s\n",
1686 rr_cause_name(gh->data[0]));
1687
1688 return 0;
1689}
1690
1691static int gsm48_rx_rr_meas_rep(struct msgb *msg)
1692{
1693 struct gsm48_hdr *gh = msgb_l3(msg);
1694 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1695 static struct gsm_meas_rep meas_rep;
1696
1697 DEBUGP(DRR, "MEASUREMENT REPORT ");
1698 parse_meas_rep(&meas_rep, gh->data, payload_len);
1699 if (meas_rep.flags & MEAS_REP_F_DTX)
1700 DEBUGPC(DRR, "DTX ");
1701 if (meas_rep.flags & MEAS_REP_F_BA1)
1702 DEBUGPC(DRR, "BA1 ");
1703 if (!(meas_rep.flags & MEAS_REP_F_VALID))
1704 DEBUGPC(DRR, "NOT VALID ");
1705 else
1706 DEBUGPC(DRR, "FULL(lev=%u, qual=%u) SUB(lev=%u, qual=%u) ",
1707 meas_rep.rxlev_full, meas_rep.rxqual_full, meas_rep.rxlev_sub,
1708 meas_rep.rxqual_sub);
1709
1710 DEBUGPC(DRR, "NUM_NEIGH=%u\n", meas_rep.num_cell);
1711
1712 /* FIXME: put the results somwhere */
1713
1714 return 0;
1715}
1716
1717/* Receive a GSM 04.08 Radio Resource (RR) message */
1718static int gsm0408_rcv_rr(struct msgb *msg)
1719{
1720 struct gsm48_hdr *gh = msgb_l3(msg);
1721 int rc = 0;
1722
1723 switch (gh->msg_type) {
1724 case GSM48_MT_RR_CLSM_CHG:
1725 rc = gsm48_rx_rr_classmark(msg);
1726 break;
1727 case GSM48_MT_RR_GPRS_SUSP_REQ:
1728 DEBUGP(DRR, "GRPS SUSPEND REQUEST\n");
1729 break;
1730 case GSM48_MT_RR_PAG_RESP:
1731 rc = gsm48_rr_rx_pag_resp(msg);
1732 break;
1733 case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
1734 DEBUGP(DRR, "CHANNEL MODE MODIFY ACK\n");
1735 rc = rsl_chan_mode_modify_req(msg->lchan);
1736 break;
1737 case GSM48_MT_RR_STATUS:
1738 rc = gsm48_rx_rr_status(msg);
1739 break;
1740 case GSM48_MT_RR_MEAS_REP:
1741 rc = gsm48_rx_rr_meas_rep(msg);
1742 break;
1743 default:
1744 fprintf(stderr, "Unimplemented GSM 04.08 RR msg type 0x%02x\n",
1745 gh->msg_type);
1746 break;
1747 }
1748
1749 return rc;
1750}
1751
1752/* 7.1.7 and 9.1.7 Channel release*/
1753int gsm48_send_rr_release(struct gsm_lchan *lchan)
1754{
1755 struct msgb *msg = gsm48_msgb_alloc();
1756 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1757 u_int8_t *cause;
1758
1759 msg->lchan = lchan;
1760 gh->proto_discr = GSM48_PDISC_RR;
1761 gh->msg_type = GSM48_MT_RR_CHAN_REL;
1762
1763 cause = msgb_put(msg, 1);
1764 cause[0] = GSM48_RR_CAUSE_NORMAL;
1765
1766 DEBUGP(DRR, "Sending Channel Release: Chan: Number: %d Type: %d\n",
1767 lchan->nr, lchan->type);
1768
1769 return gsm48_sendmsg(msg);
1770}
1771
1772/* Call Control */
1773
1774/* The entire call control code is written in accordance with Figure 7.10c
1775 * for 'very early assignment', i.e. we allocate a TCH/F during IMMEDIATE
1776 * ASSIGN, then first use that TCH/F for signalling and later MODE MODIFY
1777 * it for voice */
1778
Harald Welte03740842009-06-10 23:11:52 +08001779static void new_cc_state(struct gsm_trans *trans, int state)
1780{
1781 if (state > 31 || state < 0)
1782 return;
1783
1784 DEBUGP(DCC, "new state %s -> %s\n",
1785 cc_state_names[trans->state], cc_state_names[state]);
1786
1787 trans->state = state;
1788}
1789
1790static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg)
Harald Welte59b04682009-06-10 05:40:52 +08001791{
1792 struct msgb *msg = gsm48_msgb_alloc();
1793 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1794 u_int8_t *cause, *call_state;
1795
Harald Welte03740842009-06-10 23:11:52 +08001796 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
1797 msg->lchan = trans->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08001798 gh->msg_type = GSM48_MT_CC_STATUS;
1799
1800 cause = msgb_put(msg, 3);
1801 cause[0] = 2;
1802 cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
1803 cause[2] = 0x80 | 30; /* response to status inquiry */
1804
1805 call_state = msgb_put(msg, 1);
1806 call_state[0] = 0xc0 | 0x00;
1807
1808 return gsm48_sendmsg(msg);
1809}
1810
1811static int gsm48_tx_simple(struct gsm_lchan *lchan,
1812 u_int8_t pdisc, u_int8_t msg_type)
1813{
1814 struct msgb *msg = gsm48_msgb_alloc();
1815 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1816
1817 msg->lchan = lchan;
1818
1819 gh->proto_discr = pdisc;
1820 gh->msg_type = msg_type;
1821
1822 return gsm48_sendmsg(msg);
1823}
1824
Harald Welte03740842009-06-10 23:11:52 +08001825static void gsm48_stop_cc_timer(struct gsm_trans *trans)
1826{
1827 if (bsc_timer_pending(&trans->cc_timer)) {
1828 DEBUGP(DCC, "stopping pending timer T%x\n", trans->Tcurrent);
1829 bsc_del_timer(&trans->cc_timer);
1830 trans->Tcurrent = 0;
1831 }
1832}
1833
1834static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
1835 int msg_type, struct gsm_mncc *mncc)
1836{
1837 struct msgb *msg;
1838
1839 if (trans)
1840 if (trans->lchan)
1841 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
1842 "Sending '%s' to MNCC.\n",
1843 trans->lchan->ts->trx->bts->nr,
1844 trans->lchan->ts->trx->nr,
1845 trans->lchan->ts->nr, trans->transaction_id,
1846 (trans->subscr)?(trans->subscr->extension):"-",
1847 get_mncc_name(msg_type));
1848 else
1849 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
1850 "Sending '%s' to MNCC.\n",
1851 (trans->subscr)?(trans->subscr->extension):"-",
1852 get_mncc_name(msg_type));
1853 else
1854 DEBUGP(DCC, "(bts - trx - ts - ti -- sub -) "
1855 "Sending '%s' to MNCC.\n", get_mncc_name(msg_type));
1856
1857 mncc->msg_type = msg_type;
1858
1859 msg = msgb_alloc(sizeof(struct gsm_mncc));
1860 if (!msg)
1861 return -ENOMEM;
1862 memcpy(msg->data, mncc, sizeof(struct gsm_mncc));
1863 msgb_enqueue(&net->upqueue, msg);
1864
1865 return 0;
1866}
1867
1868int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans,
1869 u_int32_t callref, int location, int value)
1870{
1871 struct gsm_mncc rel;
1872
Harald Weltecb0595f2009-06-12 01:54:08 +08001873 memset(&rel, 0, sizeof(rel));
Harald Welte03740842009-06-10 23:11:52 +08001874 rel.callref = callref;
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08001875 mncc_set_cause(&rel, location, value);
Harald Welte03740842009-06-10 23:11:52 +08001876 return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
1877}
1878
1879void free_trans(struct gsm_trans *trans)
1880{
1881 struct gsm_bts *bts;
1882
1883 gsm48_stop_cc_timer(trans);
1884
1885 /* send release to L4, if callref still exists */
1886 if (trans->callref) {
1887 /* Ressource unavailable */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08001888 mncc_release_ind(trans->network, trans, trans->callref,
1889 GSM48_CAUSE_LOC_PRN_S_LU,
1890 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08001891 if (trans->state != GSM_CSTATE_NULL)
1892 new_cc_state(trans, GSM_CSTATE_NULL);
1893 }
1894
1895 if (!trans->lchan && trans->subscr && trans->subscr->net) {
1896 /* Stop paging on all bts' */
1897 bts = NULL;
1898 do {
1899 bts = gsm_bts_by_lac(trans->subscr->net,
1900 trans->subscr->lac, bts);
1901 if (!bts)
1902 break;
1903 /* Stop paging */
1904 paging_request_stop(bts, trans->subscr, NULL);
1905 } while (1);
1906 }
1907
1908 if (trans->lchan) {
1909 trau_mux_unmap(&trans->lchan->ts->e1_link, trans->callref);
1910 put_lchan(trans->lchan);
1911 }
1912
1913 if (trans->subscr)
1914 subscr_put(trans->subscr);
1915
1916 if (trans->state != GSM_CSTATE_NULL)
1917 new_cc_state(trans, GSM_CSTATE_NULL);
1918
1919 llist_del(&trans->entry);
1920
Harald Weltea8379772009-06-20 22:36:41 +02001921 talloc_free(trans);
Harald Welte03740842009-06-10 23:11:52 +08001922}
1923
1924static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
1925
Harald Welte59b04682009-06-10 05:40:52 +08001926/* call-back from paging the B-end of the connection */
1927static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
1928 struct msgb *msg, void *_lchan, void *param)
1929{
1930 struct gsm_lchan *lchan = _lchan;
Harald Welte03740842009-06-10 23:11:52 +08001931 struct gsm_subscriber *subscr = param;
1932 struct gsm_trans *transt, *tmp;
1933 struct gsm_network *net;
1934
Harald Welte59b04682009-06-10 05:40:52 +08001935 if (hooknum != GSM_HOOK_RR_PAGING)
1936 return -EINVAL;
Harald Welte03740842009-06-10 23:11:52 +08001937
1938 if (!subscr)
1939 return -EINVAL;
1940 net = subscr->net;
1941 if (!net) {
1942 DEBUGP(DCC, "Error Network not set!\n");
1943 return -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08001944 }
1945
Harald Welte03740842009-06-10 23:11:52 +08001946 /* check all tranactions (without lchan) for subscriber */
1947 llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) {
1948 if (transt->subscr != subscr || transt->lchan)
1949 continue;
1950 switch (event) {
1951 case GSM_PAGING_SUCCEEDED:
1952 if (!lchan) // paranoid
1953 break;
1954 DEBUGP(DCC, "Paging subscr %s succeeded!\n",
1955 subscr->extension);
1956 /* Assign lchan */
1957 if (!transt->lchan) {
1958 transt->lchan = lchan;
1959 use_lchan(lchan);
1960 }
1961 /* send SETUP request to called party */
1962 gsm48_cc_tx_setup(transt, &transt->cc_msg);
1963 if (is_ipaccess_bts(lchan->ts->trx->bts))
1964 rsl_ipacc_bind(lchan);
1965 break;
1966 case GSM_PAGING_EXPIRED:
1967 DEBUGP(DCC, "Paging subscr %s expired!\n",
1968 subscr->extension);
1969 /* Temporarily out of order */
1970 mncc_release_ind(transt->network, transt, transt->callref,
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08001971 GSM48_CAUSE_LOC_PRN_S_LU,
1972 GSM48_CC_CAUSE_DEST_OOO);
Harald Welte03740842009-06-10 23:11:52 +08001973 transt->callref = 0;
1974 free_trans(transt);
1975 break;
1976 }
1977 }
Harald Welte59b04682009-06-10 05:40:52 +08001978 return 0;
1979}
1980
Harald Welte59b04682009-06-10 05:40:52 +08001981/* map two ipaccess RTP streams onto each other */
1982static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
1983{
1984 struct gsm_bts *bts = lchan->ts->trx->bts;
1985 struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts;
1986 struct gsm_bts_trx_ts *ts;
1987
1988 DEBUGP(DCC, "Setting up TCH map between (bts=%u,trx=%u,ts=%u) and (bts=%u,trx=%u,ts=%u)\n",
1989 bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1990 remote_bts->nr, remote_lchan->ts->trx->nr, remote_lchan->ts->nr);
1991
1992 if (bts->type != remote_bts->type) {
1993 DEBUGP(DCC, "Cannot switch calls between different BTS types yet\n");
1994 return -EINVAL;
1995 }
1996
1997 switch (bts->type) {
1998 case GSM_BTS_TYPE_NANOBTS_900:
1999 case GSM_BTS_TYPE_NANOBTS_1800:
2000 ts = remote_lchan->ts;
2001 rsl_ipacc_connect(lchan, ts->abis_ip.bound_ip, ts->abis_ip.bound_port,
2002 lchan->ts->abis_ip.attr_f8, ts->abis_ip.attr_fc);
2003
2004 ts = lchan->ts;
2005 rsl_ipacc_connect(remote_lchan, ts->abis_ip.bound_ip, ts->abis_ip.bound_port,
2006 remote_lchan->ts->abis_ip.attr_f8, ts->abis_ip.attr_fc);
2007 break;
2008 case GSM_BTS_TYPE_BS11:
2009 trau_mux_map_lchan(lchan, remote_lchan);
2010 break;
2011 default:
2012 DEBUGP(DCC, "Unknown BTS type %u\n", bts->type);
2013 break;
2014 }
2015
2016 return 0;
2017}
2018
Harald Welte03740842009-06-10 23:11:52 +08002019static struct gsm_trans *get_trans_ref(struct gsm_network *net, u_int32_t callref)
Harald Welte59b04682009-06-10 05:40:52 +08002020{
Harald Welte03740842009-06-10 23:11:52 +08002021 struct gsm_trans *trans;
2022 llist_for_each_entry(trans, &net->trans_list, entry) {
2023 if (trans->callref == callref)
2024 return trans;
2025 }
2026 return NULL;
Harald Welte59b04682009-06-10 05:40:52 +08002027}
2028
Harald Welte03740842009-06-10 23:11:52 +08002029/* bridge channels of two transactions */
2030static int tch_bridge(struct gsm_network *net, u_int32_t *refs)
Harald Welte59b04682009-06-10 05:40:52 +08002031{
Harald Welte03740842009-06-10 23:11:52 +08002032 struct gsm_trans *trans1 = get_trans_ref(net, refs[0]);
2033 struct gsm_trans *trans2 = get_trans_ref(net, refs[1]);
Harald Welte59b04682009-06-10 05:40:52 +08002034
Harald Welte03740842009-06-10 23:11:52 +08002035 if (!trans1 || !trans2)
Harald Welte59b04682009-06-10 05:40:52 +08002036 return -EIO;
2037
Harald Welte03740842009-06-10 23:11:52 +08002038 if (!trans1->lchan || !trans2->lchan)
2039 return -EIO;
2040
2041 /* through-connect channel */
2042 return tch_map(trans1->lchan, trans2->lchan);
Harald Welte59b04682009-06-10 05:40:52 +08002043}
2044
Harald Welte03740842009-06-10 23:11:52 +08002045/* enable receive of channels to upqueue */
2046static int tch_recv(struct gsm_network *net, struct gsm_mncc *data, int enable)
2047{
2048 struct gsm_trans *trans;
Harald Welte59b04682009-06-10 05:40:52 +08002049
Harald Welte03740842009-06-10 23:11:52 +08002050 /* Find callref */
2051 trans = get_trans_ref(net, data->callref);
2052 if (!trans)
2053 return -EIO;
2054 if (!trans->lchan)
2055 return 0;
2056
2057 // todo IPACCESS
2058 if (enable)
2059 return trau_recv_lchan(trans->lchan, data->callref);
2060 return trau_mux_unmap(NULL, data->callref);
2061}
2062
2063/* send a frame to channel */
2064static int tch_frame(struct gsm_network *net, struct gsm_trau_frame *frame)
2065{
2066 struct gsm_trans *trans;
2067
2068 /* Find callref */
2069 trans = get_trans_ref(net, frame->callref);
2070 if (!trans)
2071 return -EIO;
2072 if (!trans->lchan)
2073 return 0;
2074 if (trans->lchan->type != GSM_LCHAN_TCH_F &&
2075 trans->lchan->type != GSM_LCHAN_TCH_H)
2076 return 0;
2077
2078 // todo IPACCESS
2079 return trau_send_lchan(trans->lchan,
2080 (struct decoded_trau_frame *)frame->data);
2081}
2082
2083
2084static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
2085{
2086 DEBUGP(DCC, "-> STATUS ENQ\n");
2087 return gsm48_cc_tx_status(trans, msg);
2088}
2089
2090static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
2091static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);
2092
2093static void gsm48_cc_timeout(void *arg)
2094{
2095 struct gsm_trans *trans = arg;
2096 int disconnect = 0, release = 0;
Harald Weltebbc636a2009-06-11 14:23:20 +08002097 int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
2098 int mo_location = GSM48_CAUSE_LOC_USER;
2099 int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
2100 int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
Harald Welte03740842009-06-10 23:11:52 +08002101 struct gsm_mncc mo_rel, l4_rel;
2102
2103 memset(&mo_rel, 0, sizeof(struct gsm_mncc));
2104 mo_rel.callref = trans->callref;
2105 memset(&l4_rel, 0, sizeof(struct gsm_mncc));
2106 l4_rel.callref = trans->callref;
2107
2108 switch(trans->Tcurrent) {
2109 case 0x303:
2110 release = 1;
Harald Weltebbc636a2009-06-11 14:23:20 +08002111 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
Harald Welte03740842009-06-10 23:11:52 +08002112 break;
2113 case 0x310:
2114 disconnect = 1;
Harald Weltebbc636a2009-06-11 14:23:20 +08002115 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
Harald Welte03740842009-06-10 23:11:52 +08002116 break;
2117 case 0x313:
2118 disconnect = 1;
2119 /* unknown, did not find it in the specs */
2120 break;
2121 case 0x301:
2122 disconnect = 1;
Harald Weltebbc636a2009-06-11 14:23:20 +08002123 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
Harald Welte03740842009-06-10 23:11:52 +08002124 break;
2125 case 0x308:
2126 if (!trans->T308_second) {
2127 /* restart T308 a second time */
2128 gsm48_cc_tx_release(trans, &trans->cc_msg);
2129 trans->T308_second = 1;
2130 break; /* stay in release state */
2131 }
2132 free_trans(trans);
2133 return;
2134// release = 1;
2135// l4_cause = 14;
2136// break;
2137 case 0x306:
2138 release = 1;
2139 mo_cause = trans->cc_msg.cause.value;
2140 mo_location = trans->cc_msg.cause.location;
2141 break;
2142 case 0x323:
2143 disconnect = 1;
2144 break;
2145 default:
2146 release = 1;
2147 }
2148
2149 if (release && trans->callref) {
2150 /* process release towards layer 4 */
2151 mncc_release_ind(trans->network, trans, trans->callref,
2152 l4_location, l4_cause);
2153 trans->callref = 0;
2154 }
2155
2156 if (disconnect && trans->callref) {
2157 /* process disconnect towards layer 4 */
2158 mncc_set_cause(&l4_rel, l4_location, l4_cause);
2159 mncc_recvmsg(trans->network, trans, MNCC_DISC_IND, &l4_rel);
2160 }
2161
2162 /* process disconnect towards mobile station */
2163 if (disconnect || release) {
2164 mncc_set_cause(&mo_rel, mo_location, mo_cause);
2165 mo_rel.cause.diag[0] = ((trans->Tcurrent & 0xf00) >> 8) + '0';
2166 mo_rel.cause.diag[1] = ((trans->Tcurrent & 0x0f0) >> 4) + '0';
2167 mo_rel.cause.diag[2] = (trans->Tcurrent & 0x00f) + '0';
2168 mo_rel.cause.diag_len = 3;
2169
2170 if (disconnect)
2171 gsm48_cc_tx_disconnect(trans, &mo_rel);
2172 if (release)
2173 gsm48_cc_tx_release(trans, &mo_rel);
2174 }
2175
2176}
2177
2178static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
2179 int sec, int micro)
2180{
2181 DEBUGP(DCC, "starting timer T%x with %d seconds\n", current, sec);
2182 trans->cc_timer.cb = gsm48_cc_timeout;
2183 trans->cc_timer.data = trans;
2184 bsc_schedule_timer(&trans->cc_timer, sec, micro);
2185 trans->Tcurrent = current;
2186}
2187
2188static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
2189{
2190 struct gsm48_hdr *gh = msgb_l3(msg);
2191 u_int8_t msg_type = gh->msg_type & 0xbf;
2192 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2193 struct tlv_parsed tp;
2194 struct gsm_mncc setup;
2195
2196 memset(&setup, 0, sizeof(struct gsm_mncc));
2197 setup.callref = trans->callref;
2198 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2199 /* emergency setup is identified by msg_type */
2200 if (msg_type == GSM48_MT_CC_EMERG_SETUP)
2201 setup.emergency = 1;
2202
2203 /* use subscriber as calling party number */
2204 if (trans->subscr) {
2205 setup.fields |= MNCC_F_CALLING;
2206 strncpy(setup.calling.number, trans->subscr->extension,
2207 sizeof(setup.calling.number)-1);
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02002208 strncpy(setup.imsi, trans->subscr->imsi,
2209 sizeof(setup.imsi)-1);
Harald Welte03740842009-06-10 23:11:52 +08002210 }
2211 /* bearer capability */
2212 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
2213 setup.fields |= MNCC_F_BEARER_CAP;
2214 decode_bearer_cap(&setup.bearer_cap,
2215 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
2216 }
2217 /* facility */
2218 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2219 setup.fields |= MNCC_F_FACILITY;
2220 decode_facility(&setup.facility,
2221 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2222 }
2223 /* called party bcd number */
2224 if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
2225 setup.fields |= MNCC_F_CALLED;
2226 decode_called(&setup.called,
2227 TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
2228 }
2229 /* user-user */
2230 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2231 setup.fields |= MNCC_F_USERUSER;
2232 decode_useruser(&setup.useruser,
2233 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2234 }
2235 /* ss-version */
2236 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2237 setup.fields |= MNCC_F_SSVERSION;
2238 decode_ssversion(&setup.ssversion,
2239 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2240 }
2241 /* CLIR suppression */
2242 if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_SUPP))
2243 setup.clir.sup = 1;
2244 /* CLIR invocation */
2245 if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_INVOC))
2246 setup.clir.inv = 1;
2247 /* cc cap */
2248 if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
2249 setup.fields |= MNCC_F_CCCAP;
2250 decode_cccap(&setup.cccap,
2251 TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
2252 }
2253
2254 if (is_ipaccess_bts(msg->trx->bts))
2255 rsl_ipacc_bind(msg->lchan);
2256
2257 new_cc_state(trans, GSM_CSTATE_INITIATED);
2258
2259 /* indicate setup to MNCC */
2260 mncc_recvmsg(trans->network, trans, MNCC_SETUP_IND, &setup);
2261
2262 return 0;
2263}
2264
2265static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
Harald Welte59b04682009-06-10 05:40:52 +08002266{
2267 struct msgb *msg = gsm48_msgb_alloc();
2268 struct gsm48_hdr *gh;
Harald Welte03740842009-06-10 23:11:52 +08002269 struct gsm_mncc *setup = arg;
2270 struct gsm_trans *transt;
2271 u_int16_t trans_id_mask = 0;
2272 int rc, i;
Harald Welte59b04682009-06-10 05:40:52 +08002273
2274 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2275
Harald Welte03740842009-06-10 23:11:52 +08002276 /* transaction id must not be assigned */
2277 if (trans->transaction_id != 0xff) { /* unasssigned */
2278 DEBUGP(DCC, "TX Setup with assigned transaction. "
2279 "This is not allowed!\n");
2280 /* Temporarily out of order */
2281 rc = mncc_release_ind(trans->network, trans, trans->callref,
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08002282 GSM48_CAUSE_LOC_PRN_S_LU,
2283 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08002284 trans->callref = 0;
2285 free_trans(trans);
2286 return rc;
2287 }
2288
2289 /* Get free transaction_id */
2290 llist_for_each_entry(transt, &trans->network->trans_list, entry) {
2291 /* Transaction of our lchan? */
2292 if (transt->lchan == trans->lchan &&
2293 transt->transaction_id != 0xff)
2294 trans_id_mask |= (1 << (transt->transaction_id >> 4));
2295 }
2296 /* Assign free transaction ID */
2297 if ((trans_id_mask & 0x007f) == 0x7f) {
2298 /* no free transaction ID */
2299 rc = mncc_release_ind(trans->network, trans, trans->callref,
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08002300 GSM48_CAUSE_LOC_PRN_S_LU,
2301 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08002302 trans->callref = 0;
2303 free_trans(trans);
2304 return rc;
2305 }
2306 for (i = 0; i < 7; i++) {
2307 if ((trans_id_mask & (1 << i)) == 0) {
2308 trans->transaction_id = i << 4; /* flag = 0 */
2309 break;
2310 }
2311 }
Harald Welte59b04682009-06-10 05:40:52 +08002312
Harald Welte03740842009-06-10 23:11:52 +08002313 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2314 msg->lchan = trans->lchan;
Harald Welte59b04682009-06-10 05:40:52 +08002315 gh->msg_type = GSM48_MT_CC_SETUP;
2316
Harald Welte03740842009-06-10 23:11:52 +08002317 gsm48_start_cc_timer(trans, 0x303, GSM48_T303);
Harald Welte59b04682009-06-10 05:40:52 +08002318
Harald Welte03740842009-06-10 23:11:52 +08002319 /* bearer capability */
2320 if (setup->fields & MNCC_F_BEARER_CAP)
2321 encode_bearer_cap(msg, 0, &setup->bearer_cap);
2322 /* facility */
2323 if (setup->fields & MNCC_F_FACILITY)
2324 encode_facility(msg, 0, &setup->facility);
2325 /* progress */
2326 if (setup->fields & MNCC_F_PROGRESS)
2327 encode_progress(msg, 0, &setup->progress);
2328 /* calling party BCD number */
2329 if (setup->fields & MNCC_F_CALLING)
2330 encode_calling(msg, &setup->calling);
2331 /* called party BCD number */
2332 if (setup->fields & MNCC_F_CALLED)
2333 encode_called(msg, &setup->called);
2334 /* user-user */
2335 if (setup->fields & MNCC_F_USERUSER)
2336 encode_useruser(msg, 0, &setup->useruser);
2337 /* redirecting party BCD number */
2338 if (setup->fields & MNCC_F_REDIRECTING)
2339 encode_redirecting(msg, &setup->redirecting);
2340 /* signal */
2341 if (setup->fields & MNCC_F_SIGNAL)
2342 encode_signal(msg, setup->signal);
2343
2344 new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);
Harald Welte59b04682009-06-10 05:40:52 +08002345
2346 return gsm48_sendmsg(msg);
2347}
2348
Harald Welte03740842009-06-10 23:11:52 +08002349static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
2350{
2351 struct gsm48_hdr *gh = msgb_l3(msg);
2352 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2353 struct tlv_parsed tp;
2354 struct gsm_mncc call_conf;
2355
2356 gsm48_stop_cc_timer(trans);
2357 gsm48_start_cc_timer(trans, 0x310, GSM48_T310);
2358
2359 memset(&call_conf, 0, sizeof(struct gsm_mncc));
2360 call_conf.callref = trans->callref;
2361 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2362#if 0
2363 /* repeat */
2364 if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR))
2365 call_conf.repeat = 1;
2366 if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ))
2367 call_conf.repeat = 2;
2368#endif
2369 /* bearer capability */
2370 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
2371 call_conf.fields |= MNCC_F_BEARER_CAP;
2372 decode_bearer_cap(&call_conf.bearer_cap,
2373 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
2374 }
2375 /* cause */
2376 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2377 call_conf.fields |= MNCC_F_CAUSE;
2378 decode_cause(&call_conf.cause,
2379 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2380 }
2381 /* cc cap */
2382 if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
2383 call_conf.fields |= MNCC_F_CCCAP;
2384 decode_cccap(&call_conf.cccap,
2385 TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
2386 }
2387
2388 new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
2389
2390 return mncc_recvmsg(trans->network, trans, MNCC_CALL_CONF_IND, &call_conf);
2391}
2392
2393static int gsm48_cc_tx_call_proc(struct gsm_trans *trans, void *arg)
2394{
2395 struct gsm_mncc *proceeding = arg;
2396 struct msgb *msg = gsm48_msgb_alloc();
2397 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2398
2399 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2400 msg->lchan = trans->lchan;
2401 gh->msg_type = GSM48_MT_CC_CALL_PROC;
2402
2403 new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC);
2404
2405 /* bearer capability */
2406 if (proceeding->fields & MNCC_F_BEARER_CAP)
2407 encode_bearer_cap(msg, 0, &proceeding->bearer_cap);
2408 /* facility */
2409 if (proceeding->fields & MNCC_F_FACILITY)
2410 encode_facility(msg, 0, &proceeding->facility);
2411 /* progress */
2412 if (proceeding->fields & MNCC_F_PROGRESS)
2413 encode_progress(msg, 0, &proceeding->progress);
2414
2415 return gsm48_sendmsg(msg);
2416}
2417
2418static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
2419{
2420 struct gsm48_hdr *gh = msgb_l3(msg);
2421 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2422 struct tlv_parsed tp;
2423 struct gsm_mncc alerting;
2424
2425 gsm48_stop_cc_timer(trans);
2426 gsm48_start_cc_timer(trans, 0x301, GSM48_T301);
2427
2428 memset(&alerting, 0, sizeof(struct gsm_mncc));
2429 alerting.callref = trans->callref;
2430 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2431 /* facility */
2432 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2433 alerting.fields |= MNCC_F_FACILITY;
2434 decode_facility(&alerting.facility,
2435 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2436 }
2437
2438 /* progress */
2439 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
2440 alerting.fields |= MNCC_F_PROGRESS;
2441 decode_progress(&alerting.progress,
2442 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
2443 }
2444 /* ss-version */
2445 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2446 alerting.fields |= MNCC_F_SSVERSION;
2447 decode_ssversion(&alerting.ssversion,
2448 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2449 }
2450
2451 new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
2452
2453 return mncc_recvmsg(trans->network, trans, MNCC_ALERT_IND, &alerting);
2454}
2455
2456static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
2457{
2458 struct gsm_mncc *alerting = arg;
2459 struct msgb *msg = gsm48_msgb_alloc();
2460 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2461
2462 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2463 msg->lchan = trans->lchan;
2464 gh->msg_type = GSM48_MT_CC_ALERTING;
2465
2466 /* facility */
2467 if (alerting->fields & MNCC_F_FACILITY)
2468 encode_facility(msg, 0, &alerting->facility);
2469 /* progress */
2470 if (alerting->fields & MNCC_F_PROGRESS)
2471 encode_progress(msg, 0, &alerting->progress);
2472 /* user-user */
2473 if (alerting->fields & MNCC_F_USERUSER)
2474 encode_useruser(msg, 0, &alerting->useruser);
2475
2476 new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);
2477
2478 return gsm48_sendmsg(msg);
2479}
2480
2481static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg)
2482{
2483 struct gsm_mncc *progress = arg;
2484 struct msgb *msg = gsm48_msgb_alloc();
2485 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2486
2487 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2488 msg->lchan = trans->lchan;
2489 gh->msg_type = GSM48_MT_CC_PROGRESS;
2490
2491 /* progress */
2492 encode_progress(msg, 1, &progress->progress);
2493 /* user-user */
2494 if (progress->fields & MNCC_F_USERUSER)
2495 encode_useruser(msg, 0, &progress->useruser);
2496
2497 return gsm48_sendmsg(msg);
2498}
2499
2500static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
2501{
2502 struct gsm_mncc *connect = arg;
2503 struct msgb *msg = gsm48_msgb_alloc();
2504 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2505
2506 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2507 msg->lchan = trans->lchan;
2508 gh->msg_type = GSM48_MT_CC_CONNECT;
2509
2510 gsm48_stop_cc_timer(trans);
2511 gsm48_start_cc_timer(trans, 0x313, GSM48_T313);
2512
2513 /* facility */
2514 if (connect->fields & MNCC_F_FACILITY)
2515 encode_facility(msg, 0, &connect->facility);
2516 /* progress */
2517 if (connect->fields & MNCC_F_PROGRESS)
2518 encode_progress(msg, 0, &connect->progress);
2519 /* connected number */
2520 if (connect->fields & MNCC_F_CONNECTED)
2521 encode_connected(msg, &connect->connected);
2522 /* user-user */
2523 if (connect->fields & MNCC_F_USERUSER)
2524 encode_useruser(msg, 0, &connect->useruser);
2525
2526 new_cc_state(trans, GSM_CSTATE_CONNECT_IND);
2527
2528 return gsm48_sendmsg(msg);
2529}
2530
2531static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
2532{
2533 struct gsm48_hdr *gh = msgb_l3(msg);
2534 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2535 struct tlv_parsed tp;
2536 struct gsm_mncc connect;
2537
2538 gsm48_stop_cc_timer(trans);
2539
2540 memset(&connect, 0, sizeof(struct gsm_mncc));
2541 connect.callref = trans->callref;
2542 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2543 /* use subscriber as connected party number */
2544 if (trans->subscr) {
2545 connect.fields |= MNCC_F_CONNECTED;
2546 strncpy(connect.connected.number, trans->subscr->extension,
2547 sizeof(connect.connected.number)-1);
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02002548 strncpy(connect.imsi, trans->subscr->imsi,
2549 sizeof(connect.imsi)-1);
Harald Welte03740842009-06-10 23:11:52 +08002550 }
2551 /* facility */
2552 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2553 connect.fields |= MNCC_F_FACILITY;
2554 decode_facility(&connect.facility,
2555 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2556 }
2557 /* user-user */
2558 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2559 connect.fields |= MNCC_F_USERUSER;
2560 decode_useruser(&connect.useruser,
2561 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2562 }
2563 /* ss-version */
2564 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2565 connect.fields |= MNCC_F_SSVERSION;
2566 decode_ssversion(&connect.ssversion,
2567 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2568 }
2569
2570 new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
2571
2572 return mncc_recvmsg(trans->network, trans, MNCC_SETUP_CNF, &connect);
2573}
2574
2575
2576static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
2577{
2578 struct gsm_mncc connect_ack;
2579
2580 gsm48_stop_cc_timer(trans);
2581
2582 new_cc_state(trans, GSM_CSTATE_ACTIVE);
2583
2584 memset(&connect_ack, 0, sizeof(struct gsm_mncc));
2585 connect_ack.callref = trans->callref;
2586 return mncc_recvmsg(trans->network, trans, MNCC_SETUP_COMPL_IND,
2587 &connect_ack);
2588}
2589
2590static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg)
2591{
2592 struct msgb *msg = gsm48_msgb_alloc();
2593 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2594
2595 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2596 msg->lchan = trans->lchan;
2597 gh->msg_type = GSM48_MT_CC_CONNECT_ACK;
2598
2599 new_cc_state(trans, GSM_CSTATE_ACTIVE);
2600
2601 return gsm48_sendmsg(msg);
2602}
2603
2604static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
2605{
2606 struct gsm48_hdr *gh = msgb_l3(msg);
2607 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2608 struct tlv_parsed tp;
2609 struct gsm_mncc disc;
2610
2611 gsm48_stop_cc_timer(trans);
2612
2613 new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ);
2614
2615 memset(&disc, 0, sizeof(struct gsm_mncc));
2616 disc.callref = trans->callref;
2617 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_CAUSE, 0);
2618 /* cause */
2619 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2620 disc.fields |= MNCC_F_CAUSE;
2621 decode_cause(&disc.cause,
2622 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2623 }
2624 /* facility */
2625 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2626 disc.fields |= MNCC_F_FACILITY;
2627 decode_facility(&disc.facility,
2628 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2629 }
2630 /* user-user */
2631 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2632 disc.fields |= MNCC_F_USERUSER;
2633 decode_useruser(&disc.useruser,
2634 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2635 }
2636 /* ss-version */
2637 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2638 disc.fields |= MNCC_F_SSVERSION;
2639 decode_ssversion(&disc.ssversion,
2640 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2641 }
2642
2643 return mncc_recvmsg(trans->network, trans, MNCC_DISC_IND, &disc);
2644
2645}
2646
Harald Weltebbc636a2009-06-11 14:23:20 +08002647static struct gsm_mncc_cause default_cause = {
2648 .location = GSM48_CAUSE_LOC_PRN_S_LU,
2649 .coding = 0,
2650 .rec = 0,
2651 .rec_val = 0,
2652 .value = GSM48_CC_CAUSE_NORMAL_UNSPEC,
2653 .diag_len = 0,
2654 .diag = { 0 },
2655};
Harald Welte03740842009-06-10 23:11:52 +08002656
2657static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
2658{
2659 struct gsm_mncc *disc = arg;
2660 struct msgb *msg = gsm48_msgb_alloc();
2661 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2662
2663 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2664 msg->lchan = trans->lchan;
2665 gh->msg_type = GSM48_MT_CC_DISCONNECT;
2666
2667 gsm48_stop_cc_timer(trans);
2668 gsm48_start_cc_timer(trans, 0x306, GSM48_T306);
2669
2670 /* cause */
2671 if (disc->fields & MNCC_F_CAUSE)
2672 encode_cause(msg, 1, &disc->cause);
2673 else
2674 encode_cause(msg, 1, &default_cause);
2675
2676 /* facility */
2677 if (disc->fields & MNCC_F_FACILITY)
2678 encode_facility(msg, 0, &disc->facility);
2679 /* progress */
2680 if (disc->fields & MNCC_F_PROGRESS)
2681 encode_progress(msg, 0, &disc->progress);
2682 /* user-user */
2683 if (disc->fields & MNCC_F_USERUSER)
2684 encode_useruser(msg, 0, &disc->useruser);
2685
2686 /* store disconnect cause for T306 expiry */
2687 memcpy(&trans->cc_msg, disc, sizeof(struct gsm_mncc));
2688
2689 new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND);
2690
2691 return gsm48_sendmsg(msg);
2692}
2693
2694static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
2695{
2696 struct gsm48_hdr *gh = msgb_l3(msg);
2697 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2698 struct tlv_parsed tp;
2699 struct gsm_mncc rel;
2700 int rc;
2701
2702 gsm48_stop_cc_timer(trans);
2703
2704 memset(&rel, 0, sizeof(struct gsm_mncc));
2705 rel.callref = trans->callref;
2706 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2707 /* cause */
2708 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2709 rel.fields |= MNCC_F_CAUSE;
2710 decode_cause(&rel.cause,
2711 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2712 }
2713 /* facility */
2714 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2715 rel.fields |= MNCC_F_FACILITY;
2716 decode_facility(&rel.facility,
2717 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2718 }
2719 /* user-user */
2720 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2721 rel.fields |= MNCC_F_USERUSER;
2722 decode_useruser(&rel.useruser,
2723 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2724 }
2725 /* ss-version */
2726 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2727 rel.fields |= MNCC_F_SSVERSION;
2728 decode_ssversion(&rel.ssversion,
2729 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2730 }
2731
2732 if (trans->state == GSM_CSTATE_RELEASE_REQ) {
2733 /* release collision 5.4.5 */
2734 rc = mncc_recvmsg(trans->network, trans, MNCC_REL_CNF, &rel);
2735 } else {
2736 rc = gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC | trans->transaction_id,
2737 GSM48_MT_CC_RELEASE_COMPL);
2738 rc = mncc_recvmsg(trans->network, trans, MNCC_REL_IND, &rel);
2739 }
2740
2741 new_cc_state(trans, GSM_CSTATE_NULL);
2742
2743 trans->callref = 0;
2744 free_trans(trans);
2745
2746 return rc;
2747}
2748
2749static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg)
2750{
2751 struct gsm_mncc *rel = arg;
2752 struct msgb *msg = gsm48_msgb_alloc();
2753 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2754
2755 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2756 msg->lchan = trans->lchan;
2757 gh->msg_type = GSM48_MT_CC_RELEASE;
2758
2759 trans->callref = 0;
2760
2761 gsm48_stop_cc_timer(trans);
2762 gsm48_start_cc_timer(trans, 0x308, GSM48_T308);
2763
2764 /* cause */
2765 if (rel->fields & MNCC_F_CAUSE)
2766 encode_cause(msg, 0, &rel->cause);
2767 /* facility */
2768 if (rel->fields & MNCC_F_FACILITY)
2769 encode_facility(msg, 0, &rel->facility);
2770 /* user-user */
2771 if (rel->fields & MNCC_F_USERUSER)
2772 encode_useruser(msg, 0, &rel->useruser);
2773
2774 trans->T308_second = 0;
2775 memcpy(&trans->cc_msg, rel, sizeof(struct gsm_mncc));
2776
2777 if (trans->state != GSM_CSTATE_RELEASE_REQ)
2778 new_cc_state(trans, GSM_CSTATE_RELEASE_REQ);
2779
2780 return gsm48_sendmsg(msg);
2781}
2782
2783static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
2784{
2785 struct gsm48_hdr *gh = msgb_l3(msg);
2786 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2787 struct tlv_parsed tp;
2788 struct gsm_mncc rel;
2789 int rc = 0;
2790
2791 gsm48_stop_cc_timer(trans);
2792
2793 memset(&rel, 0, sizeof(struct gsm_mncc));
2794 rel.callref = trans->callref;
2795 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
2796 /* cause */
2797 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
2798 rel.fields |= MNCC_F_CAUSE;
2799 decode_cause(&rel.cause,
2800 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
2801 }
2802 /* facility */
2803 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2804 rel.fields |= MNCC_F_FACILITY;
2805 decode_facility(&rel.facility,
2806 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2807 }
2808 /* user-user */
2809 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
2810 rel.fields |= MNCC_F_USERUSER;
2811 decode_useruser(&rel.useruser,
2812 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
2813 }
2814 /* ss-version */
2815 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2816 rel.fields |= MNCC_F_SSVERSION;
2817 decode_ssversion(&rel.ssversion,
2818 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2819 }
2820
2821 if (trans->callref) {
2822 switch (trans->state) {
2823 case GSM_CSTATE_CALL_PRESENT:
2824 rc = mncc_recvmsg(trans->network, trans,
2825 MNCC_REJ_IND, &rel);
2826 break;
2827 case GSM_CSTATE_RELEASE_REQ:
2828 rc = mncc_recvmsg(trans->network, trans,
2829 MNCC_REL_CNF, &rel);
2830 break;
2831 default:
2832 rc = mncc_recvmsg(trans->network, trans,
2833 MNCC_REL_IND, &rel);
2834 }
2835 }
2836
2837 trans->callref = 0;
2838 free_trans(trans);
2839
2840 return rc;
2841}
2842
2843static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg)
2844{
2845 struct gsm_mncc *rel = arg;
2846 struct msgb *msg = gsm48_msgb_alloc();
2847 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2848
2849 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2850 msg->lchan = trans->lchan;
2851 gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
2852
2853 trans->callref = 0;
2854
2855 gsm48_stop_cc_timer(trans);
2856
2857 /* cause */
2858 if (rel->fields & MNCC_F_CAUSE)
2859 encode_cause(msg, 0, &rel->cause);
2860 /* facility */
2861 if (rel->fields & MNCC_F_FACILITY)
2862 encode_facility(msg, 0, &rel->facility);
2863 /* user-user */
2864 if (rel->fields & MNCC_F_USERUSER)
2865 encode_useruser(msg, 0, &rel->useruser);
2866
2867 free_trans(trans);
2868
2869 return gsm48_sendmsg(msg);
2870}
2871
2872static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg)
2873{
2874 struct gsm48_hdr *gh = msgb_l3(msg);
2875 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2876 struct tlv_parsed tp;
2877 struct gsm_mncc fac;
2878
2879 memset(&fac, 0, sizeof(struct gsm_mncc));
2880 fac.callref = trans->callref;
2881 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_FACILITY, 0);
2882 /* facility */
2883 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
2884 fac.fields |= MNCC_F_FACILITY;
2885 decode_facility(&fac.facility,
2886 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
2887 }
2888 /* ss-version */
2889 if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
2890 fac.fields |= MNCC_F_SSVERSION;
2891 decode_ssversion(&fac.ssversion,
2892 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
2893 }
2894
2895 return mncc_recvmsg(trans->network, trans, MNCC_FACILITY_IND, &fac);
2896}
2897
2898static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg)
2899{
2900 struct gsm_mncc *fac = arg;
2901 struct msgb *msg = gsm48_msgb_alloc();
2902 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2903
2904 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2905 msg->lchan = trans->lchan;
2906 gh->msg_type = GSM48_MT_CC_FACILITY;
2907
2908 /* facility */
2909 encode_facility(msg, 1, &fac->facility);
2910
2911 return gsm48_sendmsg(msg);
2912}
2913
2914static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg)
2915{
2916 struct gsm_mncc hold;
2917
2918 memset(&hold, 0, sizeof(struct gsm_mncc));
2919 hold.callref = trans->callref;
2920 return mncc_recvmsg(trans->network, trans, MNCC_HOLD_IND, &hold);
2921}
2922
2923static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg)
2924{
2925 struct msgb *msg = gsm48_msgb_alloc();
2926 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2927
2928 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2929 msg->lchan = trans->lchan;
2930 gh->msg_type = GSM48_MT_CC_HOLD_ACK;
2931
2932 return gsm48_sendmsg(msg);
2933}
2934
2935static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg)
2936{
2937 struct gsm_mncc *hold_rej = arg;
2938 struct msgb *msg = gsm48_msgb_alloc();
2939 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2940
2941 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2942 msg->lchan = trans->lchan;
2943 gh->msg_type = GSM48_MT_CC_HOLD_REJ;
2944
2945 /* cause */
2946 if (hold_rej->fields & MNCC_F_CAUSE)
2947 encode_cause(msg, 1, &hold_rej->cause);
2948 else
2949 encode_cause(msg, 1, &default_cause);
2950
2951 return gsm48_sendmsg(msg);
2952}
2953
2954static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg)
2955{
2956 struct gsm_mncc retrieve;
2957
2958 memset(&retrieve, 0, sizeof(struct gsm_mncc));
2959 retrieve.callref = trans->callref;
2960 return mncc_recvmsg(trans->network, trans, MNCC_RETRIEVE_IND, &retrieve);
2961}
2962
2963static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg)
2964{
2965 struct msgb *msg = gsm48_msgb_alloc();
2966 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2967
2968 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2969 msg->lchan = trans->lchan;
2970 gh->msg_type = GSM48_MT_CC_RETR_ACK;
2971
2972 return gsm48_sendmsg(msg);
2973}
2974
2975static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg)
2976{
2977 struct gsm_mncc *retrieve_rej = arg;
2978 struct msgb *msg = gsm48_msgb_alloc();
2979 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2980
2981 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
2982 msg->lchan = trans->lchan;
2983 gh->msg_type = GSM48_MT_CC_RETR_REJ;
2984
2985 /* cause */
2986 if (retrieve_rej->fields & MNCC_F_CAUSE)
2987 encode_cause(msg, 1, &retrieve_rej->cause);
2988 else
2989 encode_cause(msg, 1, &default_cause);
2990
2991 return gsm48_sendmsg(msg);
2992}
2993
2994static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg)
2995{
2996 struct gsm48_hdr *gh = msgb_l3(msg);
2997 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2998 struct tlv_parsed tp;
2999 struct gsm_mncc dtmf;
3000
3001 memset(&dtmf, 0, sizeof(struct gsm_mncc));
3002 dtmf.callref = trans->callref;
3003 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
3004 /* keypad facility */
3005 if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) {
3006 dtmf.fields |= MNCC_F_KEYPAD;
3007 decode_keypad(&dtmf.keypad,
3008 TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1);
3009 }
3010
3011 return mncc_recvmsg(trans->network, trans, MNCC_START_DTMF_IND, &dtmf);
3012}
3013
3014static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg)
3015{
3016 struct gsm_mncc *dtmf = arg;
3017 struct msgb *msg = gsm48_msgb_alloc();
3018 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3019
3020 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3021 msg->lchan = trans->lchan;
3022 gh->msg_type = GSM48_MT_CC_START_DTMF_ACK;
3023
3024 /* keypad */
3025 if (dtmf->fields & MNCC_F_KEYPAD)
3026 encode_keypad(msg, dtmf->keypad);
3027
3028 return gsm48_sendmsg(msg);
3029}
3030
3031static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg)
3032{
3033 struct gsm_mncc *dtmf = arg;
3034 struct msgb *msg = gsm48_msgb_alloc();
3035 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3036
3037 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3038 msg->lchan = trans->lchan;
3039 gh->msg_type = GSM48_MT_CC_START_DTMF_REJ;
3040
3041 /* cause */
3042 if (dtmf->fields & MNCC_F_CAUSE)
3043 encode_cause(msg, 1, &dtmf->cause);
3044 else
3045 encode_cause(msg, 1, &default_cause);
3046
3047 return gsm48_sendmsg(msg);
3048}
3049
3050static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg)
3051{
3052 struct msgb *msg = gsm48_msgb_alloc();
3053 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3054
3055 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3056 msg->lchan = trans->lchan;
3057 gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK;
3058
3059 return gsm48_sendmsg(msg);
3060}
3061
3062static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg)
3063{
3064 struct gsm_mncc dtmf;
3065
3066 memset(&dtmf, 0, sizeof(struct gsm_mncc));
3067 dtmf.callref = trans->callref;
3068
3069 return mncc_recvmsg(trans->network, trans, MNCC_STOP_DTMF_IND, &dtmf);
3070}
3071
3072static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
3073{
3074 struct gsm48_hdr *gh = msgb_l3(msg);
3075 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3076 struct tlv_parsed tp;
3077 struct gsm_mncc modify;
3078
3079 memset(&modify, 0, sizeof(struct gsm_mncc));
3080 modify.callref = trans->callref;
3081 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
3082 /* bearer capability */
3083 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
3084 modify.fields |= MNCC_F_BEARER_CAP;
3085 decode_bearer_cap(&modify.bearer_cap,
3086 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
3087 }
3088
3089 new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
3090
3091 return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_IND, &modify);
3092}
3093
3094static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg)
3095{
3096 struct gsm_mncc *modify = arg;
3097 struct msgb *msg = gsm48_msgb_alloc();
3098 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3099
3100 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3101 msg->lchan = trans->lchan;
3102 gh->msg_type = GSM48_MT_CC_MODIFY;
3103
3104 gsm48_start_cc_timer(trans, 0x323, GSM48_T323);
3105
3106 /* bearer capability */
3107 encode_bearer_cap(msg, 1, &modify->bearer_cap);
3108
3109 new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY);
3110
3111 return gsm48_sendmsg(msg);
3112}
3113
3114static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg)
3115{
3116 struct gsm48_hdr *gh = msgb_l3(msg);
3117 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3118 struct tlv_parsed tp;
3119 struct gsm_mncc modify;
3120
3121 gsm48_stop_cc_timer(trans);
3122
3123 memset(&modify, 0, sizeof(struct gsm_mncc));
3124 modify.callref = trans->callref;
3125 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
3126 /* bearer capability */
3127 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
3128 modify.fields |= MNCC_F_BEARER_CAP;
3129 decode_bearer_cap(&modify.bearer_cap,
3130 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
3131 }
3132
3133 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3134
3135 return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_CNF, &modify);
3136}
3137
3138static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg)
3139{
3140 struct gsm_mncc *modify = arg;
3141 struct msgb *msg = gsm48_msgb_alloc();
3142 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3143
3144 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3145 msg->lchan = trans->lchan;
3146 gh->msg_type = GSM48_MT_CC_MODIFY_COMPL;
3147
3148 /* bearer capability */
3149 encode_bearer_cap(msg, 1, &modify->bearer_cap);
3150
3151 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3152
3153 return gsm48_sendmsg(msg);
3154}
3155
3156static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
3157{
3158 struct gsm48_hdr *gh = msgb_l3(msg);
3159 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3160 struct tlv_parsed tp;
3161 struct gsm_mncc modify;
3162
3163 gsm48_stop_cc_timer(trans);
3164
3165 memset(&modify, 0, sizeof(struct gsm_mncc));
3166 modify.callref = trans->callref;
3167 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE);
3168 /* bearer capability */
3169 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
3170 modify.fields |= GSM48_IE_BEARER_CAP;
3171 decode_bearer_cap(&modify.bearer_cap,
3172 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
3173 }
3174 /* cause */
3175 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
3176 modify.fields |= MNCC_F_CAUSE;
3177 decode_cause(&modify.cause,
3178 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
3179 }
3180
3181 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3182
3183 return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_REJ, &modify);
3184}
3185
3186static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg)
3187{
3188 struct gsm_mncc *modify = arg;
3189 struct msgb *msg = gsm48_msgb_alloc();
3190 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3191
3192 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3193 msg->lchan = trans->lchan;
3194 gh->msg_type = GSM48_MT_CC_MODIFY_REJECT;
3195
3196 /* bearer capability */
3197 encode_bearer_cap(msg, 1, &modify->bearer_cap);
3198 /* cause */
3199 encode_cause(msg, 1, &modify->cause);
3200
3201 new_cc_state(trans, GSM_CSTATE_ACTIVE);
3202
3203 return gsm48_sendmsg(msg);
3204}
3205
3206static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg)
3207{
3208 struct gsm_mncc *notify = arg;
3209 struct msgb *msg = gsm48_msgb_alloc();
3210 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3211
3212 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3213 msg->lchan = trans->lchan;
3214 gh->msg_type = GSM48_MT_CC_NOTIFY;
3215
3216 /* notify */
3217 encode_notify(msg, notify->notify);
3218
3219 return gsm48_sendmsg(msg);
3220}
3221
3222static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg)
3223{
3224 struct gsm48_hdr *gh = msgb_l3(msg);
3225 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3226// struct tlv_parsed tp;
3227 struct gsm_mncc notify;
3228
3229 memset(&notify, 0, sizeof(struct gsm_mncc));
3230 notify.callref = trans->callref;
3231// tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len);
3232 if (payload_len >= 1)
3233 decode_notify(&notify.notify, gh->data);
3234
3235 return mncc_recvmsg(trans->network, trans, MNCC_NOTIFY_IND, &notify);
3236}
3237
3238static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg)
3239{
3240 struct gsm_mncc *user = arg;
3241 struct msgb *msg = gsm48_msgb_alloc();
3242 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
3243
3244 gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id;
3245 msg->lchan = trans->lchan;
3246 gh->msg_type = GSM48_MT_CC_USER_INFO;
3247
3248 /* user-user */
3249 if (user->fields & MNCC_F_USERUSER)
3250 encode_useruser(msg, 1, &user->useruser);
3251 /* more data */
3252 if (user->more)
3253 encode_more(msg);
3254
3255 return gsm48_sendmsg(msg);
3256}
3257
3258static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
3259{
3260 struct gsm48_hdr *gh = msgb_l3(msg);
3261 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
3262 struct tlv_parsed tp;
3263 struct gsm_mncc user;
3264
3265 memset(&user, 0, sizeof(struct gsm_mncc));
3266 user.callref = trans->callref;
3267 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_USER_USER, 0);
3268 /* user-user */
3269 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
3270 user.fields |= MNCC_F_USERUSER;
3271 decode_useruser(&user.useruser,
3272 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
3273 }
3274 /* more data */
3275 if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA))
3276 user.more = 1;
3277
3278 return mncc_recvmsg(trans->network, trans, MNCC_USERINFO_IND, &user);
3279}
3280
3281static int gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
3282{
3283 struct gsm_mncc *mode = arg;
3284
3285 return gsm48_tx_chan_mode_modify(trans->lchan, mode->lchan_mode);
3286}
3287
3288static struct downstate {
3289 u_int32_t states;
3290 int type;
3291 int (*rout) (struct gsm_trans *trans, void *arg);
3292} downstatelist[] = {
3293 /* mobile originating call establishment */
3294 {SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.2 */
3295 MNCC_CALL_PROC_REQ, gsm48_cc_tx_call_proc},
3296 {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.2 | 5.2.1.5 */
3297 MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
3298 {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 */
3299 MNCC_SETUP_RSP, gsm48_cc_tx_connect},
3300 {SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.4.2 */
3301 MNCC_PROGRESS_REQ, gsm48_cc_tx_progress},
3302 /* mobile terminating call establishment */
3303 {SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
3304 MNCC_SETUP_REQ, gsm48_cc_tx_setup},
3305 {SBIT(GSM_CSTATE_CONNECT_REQUEST),
3306 MNCC_SETUP_COMPL_REQ, gsm48_cc_tx_connect_ack},
3307 /* signalling during call */
3308 {SBIT(GSM_CSTATE_ACTIVE),
3309 MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
3310 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
3311 MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
3312 {ALL_STATES,
3313 MNCC_START_DTMF_RSP, gsm48_cc_tx_start_dtmf_ack},
3314 {ALL_STATES,
3315 MNCC_START_DTMF_REJ, gsm48_cc_tx_start_dtmf_rej},
3316 {ALL_STATES,
3317 MNCC_STOP_DTMF_RSP, gsm48_cc_tx_stop_dtmf_ack},
3318 {SBIT(GSM_CSTATE_ACTIVE),
3319 MNCC_HOLD_CNF, gsm48_cc_tx_hold_ack},
3320 {SBIT(GSM_CSTATE_ACTIVE),
3321 MNCC_HOLD_REJ, gsm48_cc_tx_hold_rej},
3322 {SBIT(GSM_CSTATE_ACTIVE),
3323 MNCC_RETRIEVE_CNF, gsm48_cc_tx_retrieve_ack},
3324 {SBIT(GSM_CSTATE_ACTIVE),
3325 MNCC_RETRIEVE_REJ, gsm48_cc_tx_retrieve_rej},
3326 {SBIT(GSM_CSTATE_ACTIVE),
3327 MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
3328 {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
3329 MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
3330 {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
3331 MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
3332 {SBIT(GSM_CSTATE_ACTIVE),
3333 MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
3334 /* clearing */
3335 {SBIT(GSM_CSTATE_INITIATED),
3336 MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
3337 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) - SBIT(GSM_CSTATE_RELEASE_REQ) - SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.4 */
3338 MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
3339 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
3340 MNCC_REL_REQ, gsm48_cc_tx_release},
3341 /* special */
3342 {ALL_STATES,
3343 MNCC_LCHAN_MODIFY, gsm48_lchan_modify},
3344};
3345
3346#define DOWNSLLEN \
3347 (sizeof(downstatelist) / sizeof(struct downstate))
3348
3349
3350int mncc_send(struct gsm_network *net, int msg_type, void *arg)
3351{
3352 int i, j, k, l, rc = 0;
3353 struct gsm_trans *trans = NULL, *transt;
3354 struct gsm_subscriber *subscr;
3355 struct gsm_lchan *lchan = NULL, *lchant;
3356 struct gsm_bts *bts = NULL;
3357 struct gsm_bts_trx *trx;
3358 struct gsm_bts_trx_ts *ts;
3359 struct gsm_mncc *data = arg, rel;
3360
3361 /* handle special messages */
3362 switch(msg_type) {
3363 case MNCC_BRIDGE:
3364 return tch_bridge(net, arg);
3365 case MNCC_FRAME_DROP:
3366 return tch_recv(net, arg, 0);
3367 case MNCC_FRAME_RECV:
3368 return tch_recv(net, arg, 1);
3369 case GSM_TRAU_FRAME:
3370 return tch_frame(net, arg);
3371 }
3372
3373 memset(&rel, 0, sizeof(struct gsm_mncc));
3374 rel.callref = data->callref;
3375
3376 /* Find callref */
3377 trans = get_trans_ref(net, data->callref);
3378
3379 /* Callref unknown */
3380 if (!trans) {
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02003381 if (msg_type != MNCC_SETUP_REQ ||
3382 (!data->called.number[0] && !data->imsi[0])) {
Harald Welte03740842009-06-10 23:11:52 +08003383 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3384 "Received '%s' from MNCC with "
3385 "unknown callref %d\n", data->called.number,
3386 get_mncc_name(msg_type), data->callref);
3387 /* Invalid call reference */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003388 return mncc_release_ind(net, NULL, data->callref,
3389 GSM48_CAUSE_LOC_PRN_S_LU,
3390 GSM48_CC_CAUSE_INVAL_TRANS_ID);
Harald Welte03740842009-06-10 23:11:52 +08003391 }
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02003392 if (!data->called.number[0] && !data->imsi[0]) {
3393 DEBUGP(DCC, "(bts - trx - ts - ti) "
3394 "Received '%s' from MNCC with "
3395 "no number or IMSI\n", get_mncc_name(msg_type));
3396 /* Invalid number */
3397 return mncc_release_ind(net, NULL, data->callref,
3398 GSM48_CAUSE_LOC_PRN_S_LU,
3399 GSM48_CC_CAUSE_INV_NR_FORMAT);
3400 }
Harald Welte03740842009-06-10 23:11:52 +08003401 /* New transaction due to setup, find subscriber */
Andreas Eversberg9eaa5da2009-06-15 23:22:09 +02003402 if (data->called.number[0])
3403 subscr = subscr_get_by_extension(data->called.number);
3404 else
3405 subscr = subscr_get_by_imsi(data->imsi);
Harald Welte03740842009-06-10 23:11:52 +08003406 /* If subscriber is not found */
3407 if (!subscr) {
3408 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3409 "Received '%s' from MNCC with "
3410 "unknown subscriber %s\n", data->called.number,
3411 get_mncc_name(msg_type), data->called.number);
3412 /* Unknown subscriber */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003413 return mncc_release_ind(net, NULL, data->callref,
3414 GSM48_CAUSE_LOC_PRN_S_LU,
3415 GSM48_CC_CAUSE_UNASSIGNED_NR);
Harald Welte03740842009-06-10 23:11:52 +08003416 }
3417 /* If subscriber is not "attached" */
3418 if (!subscr->lac) {
3419 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3420 "Received '%s' from MNCC with "
3421 "detached subscriber %s\n", data->called.number,
3422 get_mncc_name(msg_type), data->called.number);
3423 subscr_put(subscr);
3424 /* Temporarily out of order */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003425 return mncc_release_ind(net, NULL, data->callref,
3426 GSM48_CAUSE_LOC_PRN_S_LU,
3427 GSM48_CC_CAUSE_DEST_OOO);
Harald Welte03740842009-06-10 23:11:52 +08003428 }
3429 /* Create transaction */
Harald Weltea8379772009-06-20 22:36:41 +02003430 if (!(trans = talloc(tall_trans_ctx, struct gsm_trans))) {
Harald Welte03740842009-06-10 23:11:52 +08003431 DEBUGP(DCC, "No memory for trans.\n");
3432 subscr_put(subscr);
3433 /* Ressource unavailable */
Andreas Eversbergb992a8a2009-06-14 22:14:12 +08003434 mncc_release_ind(net, NULL, data->callref,
3435 GSM48_CAUSE_LOC_PRN_S_LU,
3436 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
Harald Welte03740842009-06-10 23:11:52 +08003437 return -ENOMEM;
3438 }
3439 trans->callref = data->callref;
3440 trans->network = net;
3441 trans->transaction_id = 0xff; /* unassigned */
3442 llist_add_tail(&trans->entry, &net->trans_list);
3443 /* Assign subscriber to transaction */
3444 trans->subscr = subscr;
3445 /* Find lchan */
3446 for (i = 0; i < net->num_bts; i++) {
3447 bts = &net->bts[i];
3448 for (j = 0; j < bts->num_trx; j++) {
3449 trx = &bts->trx[j];
3450 for (k = 0; k < TRX_NR_TS; k++) {
3451 ts = &trx->ts[k];
3452 for (l = 0; l < TS_MAX_LCHAN; l++) {
3453 lchant = &ts->lchan[l];
3454 if (lchant->subscr == subscr) {
3455 lchan = lchant;
3456 break;
3457 }
3458 }
3459 }
3460 }
3461 }
3462
3463 /* If subscriber has no lchan */
3464 if (!lchan) {
3465 /* find transaction with this subscriber already paging */
3466 llist_for_each_entry(transt, &net->trans_list, entry) {
3467 /* Transaction of our lchan? */
3468 if (transt == trans ||
3469 transt->subscr != subscr)
3470 continue;
3471 DEBUGP(DCC, "(bts %d trx - ts - ti -- sub %s) "
3472 "Received '%s' from MNCC with "
3473 "unallocated channel, paging already "
3474 "started.\n", bts->nr,
3475 data->called.number,
3476 get_mncc_name(msg_type));
3477 return 0;
3478 }
3479 /* store setup informations until paging was successfull */
3480 memcpy(&trans->cc_msg, data, sizeof(struct gsm_mncc));
3481 /* start paging subscriber on all BTS with her location */
3482 subscr->net = net;
3483 bts = NULL;
3484 do {
3485 bts = gsm_bts_by_lac(net, subscr->lac, bts);
3486 if (!bts)
3487 break;
3488 DEBUGP(DCC, "(bts %d trx - ts - ti -- sub %s) "
3489 "Received '%s' from MNCC with "
3490 "unallocated channel, paging.\n",
3491 bts->nr, data->called.number,
3492 get_mncc_name(msg_type));
3493 /* Trigger paging */
Harald Weltecb0595f2009-06-12 01:54:08 +08003494 paging_request(net, subscr, RSL_CHANNEED_TCH_F,
Harald Welte03740842009-06-10 23:11:52 +08003495 setup_trig_pag_evt, subscr);
3496 } while (1);
3497 return 0;
3498 }
3499 /* Assign lchan */
3500 trans->lchan = lchan;
3501 use_lchan(lchan);
3502 }
3503 lchan = trans->lchan;
3504
3505 /* if paging did not respond yet */
3506 if (!lchan) {
3507 DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
3508 "Received '%s' from MNCC in paging state\n",
3509 (trans->subscr)?(trans->subscr->extension):"-",
3510 get_mncc_name(msg_type));
Harald Weltebbc636a2009-06-11 14:23:20 +08003511 mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
3512 GSM48_CC_CAUSE_NORM_CALL_CLEAR);
Harald Welte03740842009-06-10 23:11:52 +08003513 if (msg_type == MNCC_REL_REQ)
3514 rc = mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
3515 else
3516 rc = mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
3517 trans->callref = 0;
3518 free_trans(trans);
3519 return rc;
3520 }
3521
3522 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
3523 "Received '%s' from MNCC in state %d (%s)\n",
3524 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
3525 trans->transaction_id,
3526 (lchan->subscr)?(lchan->subscr->extension):"-",
3527 get_mncc_name(msg_type), trans->state,
3528 cc_state_names[trans->state]);
3529
3530 /* Find function for current state and message */
3531 for (i = 0; i < DOWNSLLEN; i++)
3532 if ((msg_type == downstatelist[i].type)
3533 && ((1 << trans->state) & downstatelist[i].states))
3534 break;
3535 if (i == DOWNSLLEN) {
3536 DEBUGP(DCC, "Message unhandled at this state.\n");
3537 return 0;
3538 }
3539
3540 rc = downstatelist[i].rout(trans, arg);
3541
3542 return rc;
3543}
3544
3545
3546static struct datastate {
3547 u_int32_t states;
3548 int type;
3549 int (*rout) (struct gsm_trans *trans, struct msgb *msg);
3550} datastatelist[] = {
3551 /* mobile originating call establishment */
3552 {SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
3553 GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
3554 {SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
3555 GSM48_MT_CC_EMERG_SETUP, gsm48_cc_rx_setup},
3556 {SBIT(GSM_CSTATE_CONNECT_IND), /* 5.2.1.2 */
3557 GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
3558 /* mobile terminating call establishment */
3559 {SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.2 */
3560 GSM48_MT_CC_CALL_CONF, gsm48_cc_rx_call_conf},
3561 {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* ???? | 5.2.2.3.2 */
3562 GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
3563 {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 */
3564 GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
3565 /* signalling during call */
3566 {ALL_STATES - SBIT(GSM_CSTATE_NULL),
3567 GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
3568 {SBIT(GSM_CSTATE_ACTIVE),
3569 GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
3570 {ALL_STATES,
3571 GSM48_MT_CC_START_DTMF, gsm48_cc_rx_start_dtmf},
3572 {ALL_STATES,
3573 GSM48_MT_CC_STOP_DTMF, gsm48_cc_rx_stop_dtmf},
3574 {ALL_STATES,
3575 GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
3576 {SBIT(GSM_CSTATE_ACTIVE),
3577 GSM48_MT_CC_HOLD, gsm48_cc_rx_hold},
3578 {SBIT(GSM_CSTATE_ACTIVE),
3579 GSM48_MT_CC_RETR, gsm48_cc_rx_retrieve},
3580 {SBIT(GSM_CSTATE_ACTIVE),
3581 GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
3582 {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
3583 GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
3584 {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
3585 GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
3586 {SBIT(GSM_CSTATE_ACTIVE),
3587 GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
3588 /* clearing */
3589 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
3590 GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
3591 {ALL_STATES - SBIT(GSM_CSTATE_NULL), /* 5.4.4.1.2.2 */
3592 GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
3593 {ALL_STATES, /* 5.4.3.4 */
3594 GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
3595};
3596
3597#define DATASLLEN \
3598 (sizeof(datastatelist) / sizeof(struct datastate))
3599
Harald Welte59b04682009-06-10 05:40:52 +08003600static int gsm0408_rcv_cc(struct msgb *msg)
3601{
3602 struct gsm48_hdr *gh = msgb_l3(msg);
3603 u_int8_t msg_type = gh->msg_type & 0xbf;
Harald Welte03740842009-06-10 23:11:52 +08003604 u_int8_t transaction_id = (gh->proto_discr & 0xf0) ^ 0x80; /* flip */
3605 struct gsm_lchan *lchan = msg->lchan;
3606 struct gsm_trans *trans = NULL, *transt;
3607 struct gsm_network *net = lchan->ts->trx->bts->network;
3608 int i, rc = 0;
Harald Welte59b04682009-06-10 05:40:52 +08003609
Harald Welte03740842009-06-10 23:11:52 +08003610 if (msg_type & 0x80) {
3611 DEBUGP(DCC, "MSG 0x%2x not defined for PD error\n", msg_type);
3612 return -EINVAL;
Harald Welte59b04682009-06-10 05:40:52 +08003613 }
Harald Welte03740842009-06-10 23:11:52 +08003614
3615 /* Find transaction */
3616 llist_for_each_entry(transt, &net->trans_list, entry) {
3617 /* Transaction of our lchan? */
3618 if (transt->lchan == lchan
3619 && transt->transaction_id == transaction_id) {
3620 trans = transt;
3621 }
3622 }
3623
3624 DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
3625 "Received '%s' from MS in state %d (%s)\n",
3626 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
3627 transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-",
3628 cc_msg_names[msg_type], trans?(trans->state):0,
3629 cc_state_names[trans?(trans->state):0]);
3630
3631 /* Create transaction */
3632 if (!trans) {
3633 DEBUGP(DCC, "Unknown transaction ID %02x, "
3634 "creating new trans.\n", transaction_id);
3635 /* Create transaction */
Harald Weltea8379772009-06-20 22:36:41 +02003636 if (!(trans = talloc(tall_trans_ctx, struct gsm_trans))) {
Harald Welte03740842009-06-10 23:11:52 +08003637 DEBUGP(DCC, "No memory for trans.\n");
3638 rc = gsm48_tx_simple(msg->lchan,
3639 GSM48_PDISC_CC | transaction_id,
3640 GSM48_MT_CC_RELEASE_COMPL);
3641 return -ENOMEM;
3642 }
3643 llist_add_tail(&trans->entry, &net->trans_list);
3644 /* Assign transaction */
3645 trans->callref = new_callref++;
3646 trans->network = net;
3647 trans->transaction_id = transaction_id;
3648 trans->lchan = lchan;
3649 use_lchan(lchan);
3650 if (lchan->subscr) {
3651 trans->subscr = lchan->subscr;
3652 subscr_get(trans->subscr);
3653 }
3654 }
3655
3656 /* find function for current state and message */
3657 for (i = 0; i < DATASLLEN; i++)
3658 if ((msg_type == datastatelist[i].type)
3659 && ((1 << trans->state) & datastatelist[i].states))
3660 break;
3661 if (i == DATASLLEN) {
3662 DEBUGP(DCC, "Message unhandled at this state.\n");
3663 return 0;
3664 }
3665
3666 rc = datastatelist[i].rout(trans, msg);
Harald Welte59b04682009-06-10 05:40:52 +08003667
3668 return rc;
3669}
3670
3671/* here we pass in a msgb from the RSL->RLL. We expect the l3 pointer to be set */
3672int gsm0408_rcvmsg(struct msgb *msg)
3673{
3674 struct gsm48_hdr *gh = msgb_l3(msg);
3675 u_int8_t pdisc = gh->proto_discr & 0x0f;
3676 int rc = 0;
3677
3678 switch (pdisc) {
3679 case GSM48_PDISC_CC:
3680 rc = gsm0408_rcv_cc(msg);
3681 break;
3682 case GSM48_PDISC_MM:
3683 rc = gsm0408_rcv_mm(msg);
3684 break;
3685 case GSM48_PDISC_RR:
3686 rc = gsm0408_rcv_rr(msg);
3687 break;
3688 case GSM48_PDISC_SMS:
3689 rc = gsm0411_rcv_sms(msg);
3690 break;
3691 case GSM48_PDISC_MM_GPRS:
3692 case GSM48_PDISC_SM_GPRS:
3693 fprintf(stderr, "Unimplemented GSM 04.08 discriminator 0x%02d\n",
3694 pdisc);
3695 break;
3696 default:
3697 fprintf(stderr, "Unknown GSM 04.08 discriminator 0x%02d\n",
3698 pdisc);
3699 break;
3700 }
3701
3702 return rc;
3703}
3704
Harald Welte59b04682009-06-10 05:40:52 +08003705/* Section 9.1.8 / Table 9.9 */
3706struct chreq {
3707 u_int8_t val;
3708 u_int8_t mask;
3709 enum chreq_type type;
3710};
3711
3712/* If SYSTEM INFORMATION TYPE 4 NECI bit == 1 */
3713static const struct chreq chreq_type_neci1[] = {
3714 { 0xa0, 0xe0, CHREQ_T_EMERG_CALL },
3715 { 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_F },
3716 { 0x68, 0xfc, CHREQ_T_CALL_REEST_TCH_H },
3717 { 0x6c, 0xfc, CHREQ_T_CALL_REEST_TCH_H_DBL },
3718 { 0xe0, 0xe0, CHREQ_T_SDCCH },
3719 { 0x40, 0xf0, CHREQ_T_VOICE_CALL_TCH_H },
3720 { 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H },
3721 { 0x00, 0xf0, CHREQ_T_LOCATION_UPD },
3722 { 0x10, 0xf0, CHREQ_T_SDCCH },
3723 { 0x80, 0xe0, CHREQ_T_PAG_R_ANY },
3724 { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F },
3725 { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH },
3726};
3727
3728/* If SYSTEM INFORMATION TYPE 4 NECI bit == 0 */
3729static const struct chreq chreq_type_neci0[] = {
3730 { 0xa0, 0xe0, CHREQ_T_EMERG_CALL },
3731 { 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_H },
3732 { 0xe0, 0xe0, CHREQ_T_TCH_F },
3733 { 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H },
3734 { 0x00, 0xe0, CHREQ_T_LOCATION_UPD },
3735 { 0x80, 0xe0, CHREQ_T_PAG_R_ANY },
3736 { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F },
3737 { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH },
3738};
3739
3740static const enum gsm_chan_t ctype_by_chreq[] = {
3741 [CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_F,
3742 [CHREQ_T_CALL_REEST_TCH_F] = GSM_LCHAN_TCH_F,
3743 [CHREQ_T_CALL_REEST_TCH_H] = GSM_LCHAN_TCH_H,
3744 [CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_LCHAN_TCH_H,
3745 [CHREQ_T_SDCCH] = GSM_LCHAN_SDCCH,
3746 [CHREQ_T_TCH_F] = GSM_LCHAN_TCH_F,
3747 [CHREQ_T_VOICE_CALL_TCH_H] = GSM_LCHAN_TCH_H,
3748 [CHREQ_T_DATA_CALL_TCH_H] = GSM_LCHAN_TCH_H,
3749 [CHREQ_T_LOCATION_UPD] = GSM_LCHAN_SDCCH,
3750 [CHREQ_T_PAG_R_ANY] = GSM_LCHAN_SDCCH,
3751 [CHREQ_T_PAG_R_TCH_F] = GSM_LCHAN_TCH_F,
3752 [CHREQ_T_PAG_R_TCH_FH] = GSM_LCHAN_TCH_F,
3753};
3754
3755static const enum gsm_chreq_reason_t reason_by_chreq[] = {
3756 [CHREQ_T_EMERG_CALL] = GSM_CHREQ_REASON_EMERG,
3757 [CHREQ_T_CALL_REEST_TCH_F] = GSM_CHREQ_REASON_CALL,
3758 [CHREQ_T_CALL_REEST_TCH_H] = GSM_CHREQ_REASON_CALL,
3759 [CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_CHREQ_REASON_CALL,
3760 [CHREQ_T_SDCCH] = GSM_CHREQ_REASON_OTHER,
3761 [CHREQ_T_TCH_F] = GSM_CHREQ_REASON_OTHER,
3762 [CHREQ_T_VOICE_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER,
3763 [CHREQ_T_DATA_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER,
3764 [CHREQ_T_LOCATION_UPD] = GSM_CHREQ_REASON_LOCATION_UPD,
3765 [CHREQ_T_PAG_R_ANY] = GSM_CHREQ_REASON_PAG,
3766 [CHREQ_T_PAG_R_TCH_F] = GSM_CHREQ_REASON_PAG,
3767 [CHREQ_T_PAG_R_TCH_FH] = GSM_CHREQ_REASON_PAG,
3768};
3769
3770enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra)
3771{
3772 int i;
3773 /* FIXME: determine if we set NECI = 0 in the BTS SI4 */
3774
3775 for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) {
3776 const struct chreq *chr = &chreq_type_neci0[i];
3777 if ((ra & chr->mask) == chr->val)
3778 return ctype_by_chreq[chr->type];
3779 }
3780 fprintf(stderr, "Unknown CHANNEL REQUEST RQD 0x%02x\n", ra);
3781 return GSM_LCHAN_SDCCH;
3782}
3783
3784enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra)
3785{
3786 int i;
3787 /* FIXME: determine if we set NECI = 0 in the BTS SI4 */
3788
3789 for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) {
3790 const struct chreq *chr = &chreq_type_neci0[i];
3791 if ((ra & chr->mask) == chr->val)
3792 return reason_by_chreq[chr->type];
3793 }
3794 fprintf(stderr, "Unknown CHANNEL REQUEST REASON 0x%02x\n", ra);
3795 return GSM_CHREQ_REASON_OTHER;
3796}
Harald Welte03740842009-06-10 23:11:52 +08003797
3798/* dequeue messages to layer 4 */
3799int bsc_upqueue(struct gsm_network *net)
3800{
3801 struct gsm_mncc *mncc;
3802 struct msgb *msg;
3803 int work = 0;
3804
3805 if (net)
3806 while ((msg = msgb_dequeue(&net->upqueue))) {
3807 mncc = (struct gsm_mncc *)msg->data;
3808 if (net->mncc_recv)
3809 net->mncc_recv(net, mncc->msg_type, mncc);
3810 work = 1; /* work done */
3811 }
3812
3813 return work;
3814}