summaryrefslogtreecommitdiffstats
path: root/include/sccp/sccp.h
blob: d19a977be2ddd593ebfe57125b19c01e71b81c05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
 * SCCP management code
 *
 * (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef SCCP_H
#define SCCP_H

#include <stdlib.h>

#include <sys/socket.h>
#include <sys/types.h>

#include "sccp_types.h"

struct msgb;
struct sccp_system;

enum {
	SCCP_CONNECTION_STATE_NONE,
	SCCP_CONNECTION_STATE_REQUEST,
	SCCP_CONNECTION_STATE_CONFIRM,
	SCCP_CONNECTION_STATE_ESTABLISHED,
	SCCP_CONNECTION_STATE_RELEASE,
	SCCP_CONNECTION_STATE_RELEASE_COMPLETE,
	SCCP_CONNECTION_STATE_REFUSED,
	SCCP_CONNECTION_STATE_SETUP_ERROR,
};

struct sockaddr_sccp {
	sa_family_t	sccp_family;		/* AF_SCCP in the future??? */
	uint8_t	sccp_ssn;		/* subssystem number for routing */

	/* TODO fill in address indicator... if that is ever needed */

	/* optional gti information */
	uint8_t *gti;
	int gti_len;

	/* any of SCCP_TITLE_IND_* */
	uint8_t gti_ind;

	int use_poi;
	uint8_t poi[2];

	/* not sure about these */
	/* uint8_t    sccp_class; */
};

/*
 * parsed structure of an address
 */
struct sccp_address {
	struct sccp_called_party_address    address;
	uint8_t			    ssn;
	uint8_t			    poi[2];

	uint8_t			    *gti_data;
	int			    gti_len;
};

struct sccp_optional_data {
	uint8_t			    data_len;
	uint8_t			    data_start;
};

struct sccp_connection {
	/* public */
	void *data_ctx;
	void (*data_cb)(struct sccp_connection *conn, struct msgb *msg, unsigned int len);

	void *state_ctx;
	void (*state_cb)(struct sccp_connection *, int old_state);

	struct sccp_source_reference source_local_reference;
	struct sccp_source_reference destination_local_reference;

	int connection_state;

	/* private */
	/* list of active connections */
	struct llist_head list;
	struct sccp_system *system;
	int incoming;
};

/**
 * system functionality to implement on top of any other transport layer:
 *   call sccp_system_incoming for incoming data (from the network)
 *   sccp will call outgoing whenever outgoing data exists
 */
int sccp_system_init(void (*outgoing)(struct msgb *data, void *ctx), void *context);
int sccp_system_incoming(struct msgb *data);

/**
 * Send data on an existing connection
 */
int sccp_connection_write(struct sccp_connection *connection, struct msgb *data);
int sccp_connection_send_it(struct sccp_connection *connection);
int sccp_connection_close(struct sccp_connection *connection, int cause);
int sccp_connection_free(struct sccp_connection *connection);

/**
 * internal.. 
 */
int sccp_connection_force_free(struct sccp_connection *conn);

/**
 * Create a new socket. Set your callbacks and then call bind to open
 * the connection.
 */
struct sccp_connection *sccp_connection_socket(void);

/**
 * Open the connection and send additional data
 */
int sccp_connection_connect(struct sccp_connection *conn,
			    const struct sockaddr_sccp *sccp_called,
			    struct msgb *data);

/**
 * mostly for testing purposes only. Set the accept callback.
 * TODO: add true routing information... in analogy to socket, bind, accept
 */
int sccp_connection_set_incoming(const struct sockaddr_sccp *sock,
				 int (*accept_cb)(struct sccp_connection *connection, void *data),
				 void *user_data);

/**
 * Send data in terms of unit data. A fixed address indicator will be used.
 */
int sccp_write(struct msgb *data,
	       const struct sockaddr_sccp *sock_sender,
	       const struct sockaddr_sccp *sock_target, int class);
int sccp_set_read(const struct sockaddr_sccp *sock,
		  int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data),
		  void *user_data);

/* generic sock addresses */
extern const struct sockaddr_sccp sccp_ssn_bssap;

/* helpers */
uint32_t sccp_src_ref_to_int(struct sccp_source_reference *ref);
struct sccp_source_reference sccp_src_ref_from_int(uint32_t);

struct msgb *sccp_create_refuse(struct sccp_source_reference *src_ref, int cause, uint8_t *data, int length);
struct msgb *sccp_create_cc(struct sccp_source_reference *src_ref, struct sccp_source_reference *dst_ref);
struct msgb *sccp_create_rlsd(struct sccp_source_reference *src_ref, struct sccp_source_reference *dst_ref, int cause);
struct msgb *sccp_create_dt1(struct sccp_source_reference *dst_ref, uint8_t *data, uint8_t len);
struct msgb *sccp_create_udt(int _class, const struct sockaddr_sccp *sock_sender,
			     const struct sockaddr_sccp *sock_target, struct msgb *msg);

/**
 * Below this are helper functions and structs for parsing SCCP messages
 */
struct sccp_parse_result {
	struct sccp_address called;
	struct sccp_address calling;

	/* point to the msg packet */
	struct sccp_source_reference *source_local_reference;
	struct sccp_source_reference *destination_local_reference;

	/* data pointer */
	int data_len;
};

/*
 * helper functions for the nat code
 */
int sccp_determine_msg_type(struct msgb *msg);
int sccp_parse_header(struct msgb *msg, struct sccp_parse_result *result);

/*
 * osmocore logging features
 */
void sccp_set_log_area(int log_area);

#endif