diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2013-04-10 10:11:27 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2013-04-10 16:17:14 +0200 |
commit | b01178898f32f3ee4844cbc7cb7eefea2a9751ac (patch) | |
tree | 0507aaf559a9da282c61ab410ba35d923d534238 | |
parent | 736c66066bd5c03a50551f9c3c2d8e846faebf50 (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.h | 4 | ||||
-rw-r--r-- | src/sccp.c | 62 |
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); @@ -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); |