blob: 55dad380ac5a23dd699560cabc547b1d1b98afae [file] [log] [blame]
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +08001/*
2 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
3 * (C) 2010 by On-Waves
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#include <openbsc/bsc_nat.h>
23#include <openbsc/gsm_data.h>
24#include <openbsc/bssap.h>
25#include <openbsc/debug.h>
26
27#include <netinet/in.h>
28#include <arpa/inet.h>
29
30int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg)
31{
32 struct tlv_parsed tp;
33 u_int16_t cic;
34 u_int8_t timeslot;
35 u_int8_t multiplex;
36
37 if (!msg->l3h) {
38 LOGP(DNAT, LOGL_ERROR, "Assignment message should have l3h pointer.\n");
39 return -1;
40 }
41
42 if (msgb_l3len(msg) < 3) {
43 LOGP(DNAT, LOGL_ERROR, "Assignment message has not enough space for GSM0808.\n");
44 return -1;
45 }
46
47 tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 3, msgb_l3len(msg) - 3, 0, 0);
48 if (!TLVP_PRESENT(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) {
49 LOGP(DNAT, LOGL_ERROR, "Circuit identity code not found in assignment message.\n");
50 return -1;
51 }
52
53 cic = ntohs(*(u_int16_t *)TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE));
54 timeslot = cic & 0x1f;
55 multiplex = (cic & ~0x1f) >> 5;
56
57 con->msc_timeslot = (32 * multiplex) + timeslot;
58 con->bsc_timeslot = con->msc_timeslot;
59 return 0;
60}
61
62void bsc_mgcp_clear(struct sccp_connections *con)
63{
64 con->msc_timeslot = -1;
65 con->bsc_timeslot = -1;
66}