aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2013-04-10 10:11:27 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-04-10 16:17:14 +0200
commitb01178898f32f3ee4844cbc7cb7eefea2a9751ac (patch)
tree0507aaf559a9da282c61ab410ba35d923d534238
parent736c66066bd5c03a50551f9c3c2d8e846faebf50 (diff)
sccp: Create sccp_create_cr and use it in the connection creation
The data is optional in the in the CR msg so we have to check if the msgb is NULL or not.
-rw-r--r--include/sccp/sccp.h4
-rw-r--r--src/sccp.c62
2 files changed, 41 insertions, 25 deletions
diff --git a/include/sccp/sccp.h b/include/sccp/sccp.h
index 3c30a73..9a616c7 100644
--- a/include/sccp/sccp.h
+++ b/include/sccp/sccp.h
@@ -1,7 +1,8 @@
/*
* SCCP management code
*
- * (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009, 2010, 2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009, 2010, 2013 by On-Waves
*
* All Rights Reserved
*
@@ -163,6 +164,7 @@ extern const struct sockaddr_sccp sccp_ssn_bssap;
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_cr(const struct sccp_source_reference *src_ref, const struct sockaddr_sccp *called, const uint8_t *data, size_t length);
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);
diff --git a/src/sccp.c b/src/sccp.c
index ecec9b3..217cec7 100644
--- a/src/sccp.c
+++ b/src/sccp.c
@@ -1,8 +1,8 @@
/*
* SCCP management code
*
- * (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009, 2010 by On-Waves
+ * (C) 2009, 2010, 2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009, 2010, 2013 by On-Waves
*
* All Rights Reserved
*
@@ -750,8 +750,9 @@ static int _sccp_send_connection_confirm(struct sccp_connection *connection)
return 0;
}
-static int _sccp_send_connection_request(struct sccp_connection *connection,
- const struct sockaddr_sccp *called, struct msgb *msg)
+struct msgb *sccp_create_cr(const struct sccp_source_reference *src_ref,
+ const struct sockaddr_sccp *called,
+ const uint8_t *l3_data, size_t l3_length)
{
struct msgb *request;
struct sccp_connection_request *req;
@@ -759,30 +760,20 @@ static int _sccp_send_connection_request(struct sccp_connection *connection,
uint8_t extra_size = 3 + 1;
int called_len;
-
- if (msg && (msgb_l3len(msg) < 3 || msgb_l3len(msg) > 130)) {
- LOGP(DSCCP, LOGL_ERROR, "Invalid amount of data... %d\n", msgb_l3len(msg));
- return -1;
- }
-
- /* try to find a id */
- if (assign_source_local_reference(connection) != 0) {
- LOGP(DSCCP, LOGL_ERROR, "Assigning a local reference failed.\n");
- _sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_SETUP_ERROR);
- return -1;
+ if (l3_data && (l3_length < 3 || l3_length > 130)) {
+ LOGP(DSCCP, LOGL_ERROR, "Invalid amount of data... %zu\n", l3_length);
+ return NULL;
}
-
- if (msg)
- extra_size += 2 + msgb_l3len(msg);
+ if (l3_data)
+ extra_size += 2 + l3_length;
request = msgb_alloc_headroom(SCCP_MSG_SIZE,
SCCP_MSG_HEADROOM, "sccp connection request");
request->l2h = &request->data[0];
req = (struct sccp_connection_request *) msgb_put(request, sizeof(*req));
req->type = SCCP_MSG_TYPE_CR;
- memcpy(&req->source_local_reference, &connection->source_local_reference,
- sizeof(connection->source_local_reference));
+ memcpy(&req->source_local_reference, src_ref, sizeof(*src_ref));
req->proto_class = 2;
/* write the called party address */
@@ -793,16 +784,39 @@ static int _sccp_send_connection_request(struct sccp_connection *connection,
req->optional_start = 1 + called_len;
/* write the payload */
- if (msg) {
- data = msgb_put(request, 2 + msgb_l3len(msg));
+ if (l3_data) {
+ data = msgb_put(request, 2 + l3_length);
data[0] = SCCP_PNC_DATA;
- data[1] = msgb_l3len(msg);
- memcpy(&data[2], msg->l3h, msgb_l3len(msg));
+ data[1] = l3_length;
+ memcpy(&data[2], l3_data, l3_length);
}
data = msgb_put(request, 1);
data[0] = SCCP_PNC_END_OF_OPTIONAL;
+ return request;
+}
+
+static int _sccp_send_connection_request(struct sccp_connection *connection,
+ const struct sockaddr_sccp *called, struct msgb *msg)
+{
+ struct msgb *request;
+
+ /* try to find an id */
+ if (assign_source_local_reference(connection) != 0) {
+ LOGP(DSCCP, LOGL_ERROR, "Assigning a local reference failed.\n");
+ _sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_SETUP_ERROR);
+ return -1;
+ }
+
+ request = sccp_create_cr(&connection->source_local_reference, called,
+ msg ? msg->l3h : NULL,
+ msg ? msgb_l3len(msg) : 0);
+ if (!request) {
+ _sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_SETUP_ERROR);
+ return -1;
+ }
+
llist_add_tail(&connection->list, &sccp_connections);
_sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_REQUEST);