blob: b1d128b4041d900289ac5f1cd5b4c263b99173ec [file] [log] [blame]
Holger Hans Peter Freyther689e3cc2010-11-03 16:40:03 +01001/* Interaction with the SCCP subsystem */
2/*
3 * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * (C) 2009-2010 by On-Waves
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <openbsc/gsm_data.h>
Holger Hans Peter Freytherb93e35d2010-11-06 18:08:43 +010024#include <openbsc/osmo_bsc.h>
25#include <openbsc/osmo_bsc_grace.h>
Holger Hans Peter Freyther689e3cc2010-11-03 16:40:03 +010026#include <openbsc/osmo_msc_data.h>
27#include <openbsc/debug.h>
28
29#include <osmocore/gsm0808.h>
Holger Hans Peter Freyther9c61b2a2010-11-05 19:48:47 +010030#include <osmocore/talloc.h>
Holger Hans Peter Freyther689e3cc2010-11-03 16:40:03 +010031#include <osmocore/protocol/gsm_08_08.h>
32
33#include <osmocom/sccp/sccp.h>
34
Holger Hans Peter Freytherb93e35d2010-11-06 18:08:43 +010035static LLIST_HEAD(active_connections);
36
37static void msc_outgoing_sccp_data(struct sccp_connection *conn,
38 struct msgb *msg, unsigned int len)
39{
40}
41
42static void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
43{
44}
45
Holger Hans Peter Freyther689e3cc2010-11-03 16:40:03 +010046static void msc_sccp_write_ipa(struct sccp_connection *conn, struct msgb *msg, void *data)
47{
48 LOGP(DMSC, LOGL_ERROR, "Writing is not implemented.\n");
49 msgb_free(msg);
50}
51
52static int msc_sccp_accept(struct sccp_connection *connection, void *data)
53{
54 LOGP(DMSC, LOGL_DEBUG, "Rejecting incoming SCCP connection.\n");
55 return -1;
56}
57
58static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
59{
60 struct bssmap_header *bs;
61
62 LOGP(DMSC, LOGL_DEBUG, "Incoming SCCP message ftom MSC: %s\n",
63 hexdump(msgb->l3h, length));
64
65 if (length < sizeof(*bs)) {
66 LOGP(DMSC, LOGL_ERROR, "The header is too short.\n");
67 return -1;
68 }
69
70 bs = (struct bssmap_header *) msgb->l3h;
71 if (bs->length < length - sizeof(*bs))
72 return -1;
73
74 switch (bs->type) {
75 case BSSAP_MSG_BSS_MANAGEMENT:
Holger Hans Peter Freythere0f3bb52010-11-03 18:46:52 +010076 LOGP(DMSC, LOGL_ERROR, "BSS management not implemented.\n");
Holger Hans Peter Freyther689e3cc2010-11-03 16:40:03 +010077 break;
78 default:
79 LOGP(DMSC, LOGL_ERROR, "Unimplemented msg type: %d\n", bs->type);
80 }
81
82 return 0;
83}
84
Holger Hans Peter Freyther13cde942010-11-04 11:48:49 +010085int bsc_queue_for_msc(struct gsm_subscriber_connection *conn, struct msgb *msg)
86{
87 LOGP(DMSC, LOGL_ERROR, "Sending SCCP messages is not yet implemented.\n");
88 msgb_free(msg);
89 return 0;
90}
91
Holger Hans Peter Freyther9c61b2a2010-11-05 19:48:47 +010092int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
Holger Hans Peter Freyther1b8e90a2010-11-05 11:10:46 +010093{
Holger Hans Peter Freytherb93e35d2010-11-06 18:08:43 +010094 struct gsm_network *net;
95 struct osmo_bsc_sccp_con *bsc_con;
96 struct sccp_connection *sccp;
97
98 net = conn->bts->network;
99 if (!net->msc_data->msc_con->is_authenticated) {
100 LOGP(DMSC, LOGL_ERROR, "Not connected to a MSC. Not forwarding data.\n");
101 return -1;
102 }
103
104 if (!bsc_grace_allow_new_connection(net)) {
105 LOGP(DMSC, LOGL_NOTICE, "BSC in grace period. No new connections.\n");
106 return -1;
107 }
108
109 sccp = sccp_connection_socket();
110 if (!sccp) {
111 LOGP(DMSC, LOGL_ERROR, "Failed to allocate memory.\n");
112 return -ENOMEM;
113 }
114
115 bsc_con = talloc_zero(conn->bts, struct osmo_bsc_sccp_con);
116 if (!bsc_con) {
117 LOGP(DMSC, LOGL_ERROR, "Failed to allocate.\n");
118 sccp_connection_free(sccp);
119 return -1;
120 }
121
122 /* callbacks */
123 sccp->state_cb = msc_outgoing_sccp_state;
124 sccp->data_cb = msc_outgoing_sccp_data;
125 sccp->data_ctx = bsc_con;
126
127 bsc_con->sccp = sccp;
128 bsc_con->msc_con = net->msc_data->msc_con;
Holger Hans Peter Freyther288b80a2010-11-06 20:15:17 +0100129 bsc_con->conn = conn;
Holger Hans Peter Freytherb93e35d2010-11-06 18:08:43 +0100130 llist_add(&bsc_con->entry, &active_connections);
131 conn->sccp_con = bsc_con;
132 return 0;
Holger Hans Peter Freyther1b8e90a2010-11-05 11:10:46 +0100133}
134
Holger Hans Peter Freyther288b80a2010-11-06 20:15:17 +0100135int bsc_open_connection(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
Holger Hans Peter Freyther9c61b2a2010-11-05 19:48:47 +0100136{
137 LOGP(DMSC, LOGL_ERROR, "Not implemented yet.\n");
138 return -1;
139}
140
Holger Hans Peter Freyther288b80a2010-11-06 20:15:17 +0100141int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp)
Holger Hans Peter Freyther9c61b2a2010-11-05 19:48:47 +0100142{
Holger Hans Peter Freytherb93e35d2010-11-06 18:08:43 +0100143 if (!sccp)
Holger Hans Peter Freyther9c61b2a2010-11-05 19:48:47 +0100144 return 0;
145
Holger Hans Peter Freyther288b80a2010-11-06 20:15:17 +0100146 if (sccp->conn)
147 LOGP(DMSC, LOGL_ERROR, "Should have been cleared.\n");
148
Holger Hans Peter Freytherb93e35d2010-11-06 18:08:43 +0100149 llist_del(&sccp->entry);
150 bsc_del_timer(&sccp->sccp_it_timeout);
151 bsc_del_timer(&sccp->sccp_cc_timeout);
152 talloc_free(sccp);
Holger Hans Peter Freyther9c61b2a2010-11-05 19:48:47 +0100153 return 0;
154}
155
Holger Hans Peter Freyther689e3cc2010-11-03 16:40:03 +0100156int osmo_bsc_sccp_init(struct gsm_network *gsmnet)
157{
158 sccp_set_log_area(DSCCP);
159 sccp_system_init(msc_sccp_write_ipa, gsmnet);
160 sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
161 sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL);
162
163 return 0;
164}