From Arran Cudbard-bell a.cudbardb@freeradius.org:
Arran Cudbard-bell has uploaded a new change for review.
Change subject: Add selector for ANSI or ITU variant ......................................................................
Add selector for ANSI or ITU variant
Change-Id: Ia17eef8c9b7d8e1092c587f469b4a68aa9702651 --- M include/sccp/sccp.h M include/sccp/sccp_types.h M src/sccp.c 3 files changed, 124 insertions(+), 46 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/73/1
diff --git a/include/sccp/sccp.h b/include/sccp/sccp.h index 36b424f..665422e 100644 --- a/include/sccp/sccp.h +++ b/include/sccp/sccp.h @@ -46,11 +46,24 @@ SCCP_CONNECTION_STATE_SETUP_ERROR, };
+struct sccp_variant { + uint8_t ai_nb; /* National or reserved bit */ + uint8_t ai_gti; /* GTI mask */ + uint8_t ai_pc_ind; /* Point code indicator mask */ + uint8_t ai_ssn_ind; /* SSN indicator mask */ + uint8_t ai_route; /* Route type mask */ + uint8_t pc_len; /* Point code length */ + uint8_t pc_first; /* whether the pointcode comes before the SSN */ +}; + struct sockaddr_sccp { - sa_family_t sccp_family; /* AF_SCCP in the future??? */ + sa_family_t sccp_family; /* AF_SCCP in the future??? */ + + int use_ssn; uint8_t sccp_ssn; /* subssystem number for routing */
- /* TODO fill in address indicator... if that is ever needed */ + int nb; /* National bit (8) */ + int route_on_ssn; /* Force routing on SSN instead of GTI */
/* optional gti information */ uint8_t *gti; @@ -60,7 +73,7 @@ uint8_t gti_ind;
int use_poi; - uint8_t poi[2]; + uint8_t poi[3]; /* Allows ITU 14bit and ANSI 24bit */
/* not sure about these */ /* uint8_t sccp_class; */ @@ -70,9 +83,8 @@ * parsed structure of an address */ struct sccp_address { - struct sccp_called_party_address address; uint8_t ssn; - uint8_t poi[2]; + uint8_t poi[3]; /* Allows ITU 14bit and ANSI 24bit */
uint8_t *gti_data; int gti_len; @@ -103,6 +115,8 @@ int incoming; };
+extern struct sccp_variant sccp_variant[]; + /** * system functionality to implement on top of any other transport layer: * call sccp_system_incoming for incoming data (from the network) @@ -122,7 +136,7 @@ int sccp_connection_free(struct sccp_connection *connection);
/** - * internal.. + * internal.. */ int sccp_connection_force_free(struct sccp_connection *conn);
@@ -157,6 +171,7 @@ int sccp_set_read(const struct sockaddr_sccp *sock, int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data), void *user_data); +void sccp_set_variant(int variant);
/* generic sock addresses */ extern const struct sockaddr_sccp sccp_ssn_bssap; diff --git a/include/sccp/sccp_types.h b/include/sccp/sccp_types.h index 986de0d..cd60c25 100644 --- a/include/sccp/sccp_types.h +++ b/include/sccp/sccp_types.h @@ -26,6 +26,12 @@
#include <osmocom/core/endian.h>
+/* Which variant of SCCP we're using */ +enum { + SCCP_VARIANT_ITU, + SCCP_VARIANT_ANSI +}; + /* Table 1/Q.713 - SCCP message types */ enum sccp_message_types { SCCP_MSG_TYPE_CR = 1, diff --git a/src/sccp.c b/src/sccp.c index e6c538d..a3cda90 100644 --- a/src/sccp.c +++ b/src/sccp.c @@ -46,16 +46,40 @@ .sccp_ssn = SCCP_SSN_BSSAP, };
+struct sccp_variant sccp_variant[] = { + [SCCP_VARIANT_ITU] = { + .ai_nb = 0x80, + .ai_gti = 0x3c, + .ai_pc_ind = 0x01, + .ai_ssn_ind = 0x02, + .ai_route = 0x40, + .pc_len = 2, + .pc_first = 1 + }, + [SCCP_VARIANT_ANSI] = { + .ai_nb = 0x80, + .ai_gti = 0x3c, + .ai_pc_ind = 0x02, + .ai_ssn_ind = 0x01, + .ai_route = 0x40, + .pc_len = 3, + .pc_first = 0, + } +}; + struct sccp_system { /* layer3 -> layer2 */ void (*write_data)(struct sccp_connection *conn, struct msgb *data, void *gctx, void *ctx); void *write_context; + + int variant; };
static struct sccp_system sccp_system = { .write_data = NULL, + .variant = SCCP_VARIANT_ITU };
struct sccp_data_callback { @@ -105,11 +129,13 @@ */ static int copy_address(struct sccp_address *addr, uint8_t offset, struct msgb *msgb) { - struct sccp_called_party_address *party; - int room = msgb_l2len(msgb) - offset; - uint8_t read = 0; + + uint8_t *data; + uint8_t read = 1; uint8_t length; + uint8_t ai; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
if (room <= 0) { LOGP(DSCCP, LOGL_ERROR, "Not enough room for an address: %u\n", room); @@ -122,36 +148,48 @@ return -1; }
+ data = msgb->l2h + offset + 1; + ai = data[0]; + data++;
- party = (struct sccp_called_party_address *)(msgb->l2h + offset + 1); - if (party->point_code_indicator) { - if (length <= read + 2) { - LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); - return -1; - } +#define PARSE_POI \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_pc_ind) { \ + if (length <= read + pc_len) { \ + LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); \ + return -1; \ + } \ + memcpy(&addr->poi, &data[read], pc_len); \ + read += pc_len; \ + } \ + } while (0)
+#define PARSE_SSN \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_ssn_ind) { \ + if (length <= read + 1) { \ + LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); \ + return -1; \ + } \ + addr->ssn = data[read]; \ + read += 1; \ + } \ + } while (0)
- memcpy(&addr->poi, &party->data[read], 2); - read += 2; - } - - if (party->ssn_indicator) { - if (length <= read + 1) { - LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); - return -1; - } - - addr->ssn = party->data[read]; - read += 1; + if (sccp_variant[sccp_system.variant].pc_first) { + PARSE_POI; + PARSE_SSN; + } else { + PARSE_SSN; + PARSE_POI; }
/* copy the GTI over */ - if (party->global_title_indicator) { - addr->gti_len = length - read - 1; - addr->gti_data = &party->data[read]; + if (ai & sccp_variant[sccp_system.variant].ai_gti) { + addr->gti_len = length - read; + addr->gti_data = &data[read]; }
- addr->address = *party; return 0; }
@@ -173,7 +211,6 @@
uint8_t length = msgb->l2h[offset + read + 1]; read += 2 + length; -
if (room <= read) { LOGP(DSCCP, LOGL_ERROR, @@ -486,28 +523,43 @@ int sccp_create_sccp_addr(struct msgb *msg, const struct sockaddr_sccp *sock) { uint8_t *len, *ai, *gti; + uint8_t *poi; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
len = msgb_put(msg, 1); ai = msgb_put(msg, 1);
+ if (sock->gti) ai[0] = (sock->gti_ind & 0x0f) << 2; + if (sock->route_on_ssn || !sock->gti) ai[0] |= sccp_variant[sccp_system.variant].ai_route;
- if (sock->gti) - ai[0] = 0 << 6 | (sock->gti_ind & 0x0f) << 2 | 1 << 1; - else - ai[0] = 1 << 6 | 1 << 1; + /* National/reserved bit */ + if (sock->nb) ai[0] |= sccp_variant[sccp_system.variant].ai_nb;
- /* store a point code */ - if (sock->use_poi) { - uint8_t *poi; + /* Pointcode ind */ + if (sock->use_poi) ai[0] |= sccp_variant[sccp_system.variant].ai_pc_ind;
- ai[0] |= 0x01; - poi = msgb_put(msg, 2); - poi[0] = sock->poi[0]; - poi[1] = sock->poi[1]; + /* SSN ind */ + ai[0] |= sccp_variant[sccp_system.variant].ai_ssn_ind; + +#define ADD_POI \ + do { \ + if (sock->use_poi) { \ + poi = msgb_put(msg, pc_len); \ + if (!poi) return -1; \ + memcpy(poi, &sock->poi[0], pc_len); \ + } \ + } while (0) + +#define ADD_SSN \ + msgb_v_put(msg, sock->sccp_ssn) + + if (sccp_variant[sccp_system.variant].pc_first) { + ADD_POI; + ADD_SSN; + } else { + ADD_SSN; + ADD_POI; } - - /* copy the SSN */ - msgb_v_put(msg, sock->sccp_ssn);
/* copy the gti if it is present */ gti = msgb_put(msg, sock->gti_len); @@ -1225,6 +1277,11 @@ return 0; }
+void sccp_set_variant(int variant) +{ + sccp_system.variant = variant; +} + /* oh my god a real SCCP packet. need to dispatch it now */ int sccp_system_incoming(struct msgb *msgb) {
From Arran Cudbard-bell a.cudbardb@freeradius.org:
Arran Cudbard-bell has posted comments on this change.
Change subject: Add selector for ANSI or ITU variant ......................................................................
Patch Set 1:
This is for initial review. Wouldn't expect this to be merged as is (needs tests for a start).
More to get feedback on whether ANSI support is desired. In the project we're doing currently it is. I have similar patches for the MTP3 layer in osmobsc, but there needs to be more discussion around that.
From Holger Freyther holger@freyther.de:
Holger Freyther has posted comments on this change.
Change subject: Add selector for ANSI or ITU variant ......................................................................
Patch Set 1:
This is for initial review. Wouldn't expect this to be merged as is (needs tests for a start).
More to get feedback on whether ANSI support is desired. In the project we're doing currently it is. I have similar patches for the MTP3 layer in osmobsc, but there needs to be more discussion around that.
Yes, ANSI (and Japan, China?) would be nice to have (for being complete). I don't know much about the differences of ANSI SCCP.
In general: * It should not break ITU support * It should not make code more ugly/slower (not saying the patch does) * ANSI code should have test cases by itself (and preferable make traces available, e.g. to the wireshark Sample Captures).
From Arran Cudbard-bell a.cudbardb@freeradius.org:
Arran Cudbard-bell has posted comments on this change.
Change subject: Add selector for ANSI or ITU variant ......................................................................
Patch Set 1:
Yes, oops. Should have run the test suite *first*. Is the general method of dealing with the variations OK? It seemed cleaner than lots of if/else if statements, and the performance hit should be minimal.
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
to look at the new patch set (#2).
Change subject: Add selector for ANSI or ITU variant ......................................................................
Add selector for ANSI or ITU variant
Change-Id: Ia17eef8c9b7d8e1092c587f469b4a68aa9702651 --- M include/sccp/sccp.h M include/sccp/sccp_types.h M src/sccp.c M tests/sccp/sccp_test.c 4 files changed, 124 insertions(+), 46 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/73/2
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
to look at the new patch set (#3).
Change subject: Add selector for ANSI or ITU variant ......................................................................
Add selector for ANSI or ITU variant
Change-Id: Ia17eef8c9b7d8e1092c587f469b4a68aa9702651 --- M include/sccp/sccp.h M include/sccp/sccp_types.h M src/sccp.c M tests/sccp/sccp_test.c 4 files changed, 126 insertions(+), 48 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/73/3
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
to look at the new patch set (#4).
Add selector for ANSI or ITU variant
Change-Id: Ia17eef8c9b7d8e1092c587f469b4a68aa9702651 --- M include/sccp/sccp.h M include/sccp/sccp_types.h M src/sccp.c M tests/sccp/sccp_test.c 4 files changed, 135 insertions(+), 59 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/73/4
diff --git a/include/sccp/sccp.h b/include/sccp/sccp.h index 36b424f..4b0bbd3 100644 --- a/include/sccp/sccp.h +++ b/include/sccp/sccp.h @@ -46,21 +46,32 @@ 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 */ +struct sccp_variant { + uint8_t ai_national; /* National or reserved bit */ + uint8_t ai_gti_ind; /* GTI mask */ + uint8_t ai_pc_ind; /* Point code indicator mask */ + uint8_t ai_ssn_ind; /* SSN indicator mask */ + uint8_t ai_route_ind; /* Route type mask */ + uint8_t pc_len; /* Point code length */ + uint8_t pc_first; /* whether the pointcode comes before the SSN */ +};
- /* TODO fill in address indicator... if that is ever needed */ +struct sockaddr_sccp { + sa_family_t sccp_family; /* AF_SCCP in the future??? */ + + uint8_t use_poi : 1, /* Include Point Code */ + use_ssn : 1, /* Include SSN */ + gti_ind : 4, /* Any of SCCP_TITLE_IND_* */ + route_ind : 1, /* Route on SSN instead of GTI */ + national : 1; /* National address format in ANSI, national usage/reserved in ITU */ + + uint8_t poi[3]; /* Allows ITU 14bit and ANSI 24bit */ + + uint8_t ssn; /* SubsSystem number for routing */
/* optional gti information */ - uint8_t *gti; + uint8_t *gti_data; 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; */ @@ -70,9 +81,8 @@ * parsed structure of an address */ struct sccp_address { - struct sccp_called_party_address address; uint8_t ssn; - uint8_t poi[2]; + uint8_t poi[3]; /* Allows ITU 14bit and ANSI 24bit */
uint8_t *gti_data; int gti_len; @@ -103,6 +113,8 @@ int incoming; };
+extern struct sccp_variant sccp_variant[]; + /** * system functionality to implement on top of any other transport layer: * call sccp_system_incoming for incoming data (from the network) @@ -122,7 +134,7 @@ int sccp_connection_free(struct sccp_connection *connection);
/** - * internal.. + * internal.. */ int sccp_connection_force_free(struct sccp_connection *conn);
@@ -157,6 +169,7 @@ int sccp_set_read(const struct sockaddr_sccp *sock, int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data), void *user_data); +void sccp_set_variant(int variant);
/* generic sock addresses */ extern const struct sockaddr_sccp sccp_ssn_bssap; diff --git a/include/sccp/sccp_types.h b/include/sccp/sccp_types.h index 986de0d..cd60c25 100644 --- a/include/sccp/sccp_types.h +++ b/include/sccp/sccp_types.h @@ -26,6 +26,12 @@
#include <osmocom/core/endian.h>
+/* Which variant of SCCP we're using */ +enum { + SCCP_VARIANT_ITU, + SCCP_VARIANT_ANSI +}; + /* Table 1/Q.713 - SCCP message types */ enum sccp_message_types { SCCP_MSG_TYPE_CR = 1, diff --git a/src/sccp.c b/src/sccp.c index e6c538d..2c52839 100644 --- a/src/sccp.c +++ b/src/sccp.c @@ -46,16 +46,40 @@ .sccp_ssn = SCCP_SSN_BSSAP, };
+struct sccp_variant sccp_variant[] = { + [SCCP_VARIANT_ITU] = { + .ai_national = 0x80, + .ai_gti_ind = 0x3c, + .ai_pc_ind = 0x01, + .ai_ssn_ind = 0x02, + .ai_route_ind = 0x40, + .pc_len = 2, + .pc_first = 1 + }, + [SCCP_VARIANT_ANSI] = { + .ai_national = 0x80, + .ai_gti_ind = 0x3c, + .ai_pc_ind = 0x02, + .ai_ssn_ind = 0x01, + .ai_route_ind = 0x40, + .pc_len = 3, + .pc_first = 0, + } +}; + struct sccp_system { /* layer3 -> layer2 */ void (*write_data)(struct sccp_connection *conn, struct msgb *data, void *gctx, void *ctx); void *write_context; + + int variant; };
static struct sccp_system sccp_system = { .write_data = NULL, + .variant = SCCP_VARIANT_ITU };
struct sccp_data_callback { @@ -105,11 +129,13 @@ */ static int copy_address(struct sccp_address *addr, uint8_t offset, struct msgb *msgb) { - struct sccp_called_party_address *party; - int room = msgb_l2len(msgb) - offset; + + uint8_t *data; uint8_t read = 0; uint8_t length; + uint8_t ai; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
if (room <= 0) { LOGP(DSCCP, LOGL_ERROR, "Not enough room for an address: %u\n", room); @@ -122,36 +148,48 @@ return -1; }
+ data = msgb->l2h + offset + 1; + ai = data[0]; + read++;
- party = (struct sccp_called_party_address *)(msgb->l2h + offset + 1); - if (party->point_code_indicator) { - if (length <= read + 2) { - LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); - return -1; - } +#define PARSE_POI \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_pc_ind) { \ + if (length < (read + pc_len)) { \ + LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); \ + return -1; \ + } \ + memcpy(&addr->poi, &data[read], pc_len); \ + read += pc_len; \ + } \ + } while (0)
+#define PARSE_SSN \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_ssn_ind) { \ + if (length < (read + 1)) { \ + LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); \ + return -1; \ + } \ + addr->ssn = data[read]; \ + read += 1; \ + } \ + } while (0)
- memcpy(&addr->poi, &party->data[read], 2); - read += 2; - } - - if (party->ssn_indicator) { - if (length <= read + 1) { - LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); - return -1; - } - - addr->ssn = party->data[read]; - read += 1; + if (sccp_variant[sccp_system.variant].pc_first) { + PARSE_POI; + PARSE_SSN; + } else { + PARSE_SSN; + PARSE_POI; }
/* copy the GTI over */ - if (party->global_title_indicator) { - addr->gti_len = length - read - 1; - addr->gti_data = &party->data[read]; + if (ai & sccp_variant[sccp_system.variant].ai_gti) { + addr->gti_len = length - read; + addr->gti_data = &data[read]; }
- addr->address = *party; return 0; }
@@ -173,7 +211,6 @@
uint8_t length = msgb->l2h[offset + read + 1]; read += 2 + length; -
if (room <= read) { LOGP(DSCCP, LOGL_ERROR, @@ -486,32 +523,47 @@ int sccp_create_sccp_addr(struct msgb *msg, const struct sockaddr_sccp *sock) { uint8_t *len, *ai, *gti; + uint8_t *poi; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
len = msgb_put(msg, 1); ai = msgb_put(msg, 1);
+ if (sock->gti_data) ai[0] = (sock->gti_ind & 0x0f) << 2; + if (sock->route_ind || !sock->gti_data) ai[0] |= sccp_variant[sccp_system.variant].ai_route_ind;
- if (sock->gti) - ai[0] = 0 << 6 | (sock->gti_ind & 0x0f) << 2 | 1 << 1; - else - ai[0] = 1 << 6 | 1 << 1; + /* National/reserved bit */ + if (sock->national) ai[0] |= sccp_variant[sccp_system.variant].ai_national;
- /* store a point code */ - if (sock->use_poi) { - uint8_t *poi; + /* Pointcode ind */ + if (sock->use_poi) ai[0] |= sccp_variant[sccp_system.variant].ai_pc_ind;
- ai[0] |= 0x01; - poi = msgb_put(msg, 2); - poi[0] = sock->poi[0]; - poi[1] = sock->poi[1]; + /* SSN ind */ + ai[0] |= sccp_variant[sccp_system.variant].ai_ssn_ind; + +#define ADD_POI \ + do { \ + if (sock->use_poi) { \ + poi = msgb_put(msg, pc_len); \ + if (!poi) return -1; \ + memcpy(poi, &sock->poi[0], pc_len); \ + } \ + } while (0) + +#define ADD_SSN \ + msgb_v_put(msg, sock->ssn) + + if (sccp_variant[sccp_system.variant].pc_first) { + ADD_POI; + ADD_SSN; + } else { + ADD_SSN; + ADD_POI; } - - /* copy the SSN */ - msgb_v_put(msg, sock->sccp_ssn);
/* copy the gti if it is present */ gti = msgb_put(msg, sock->gti_len); - memcpy(gti, sock->gti, sock->gti_len); + memcpy(gti, sock->gti_data, sock->gti_len);
/* update the length now */ len[0] = msg->tail - len - 1; @@ -1225,6 +1277,11 @@ return 0; }
+void sccp_set_variant(int variant) +{ + sccp_system.variant = variant; +} + /* oh my god a real SCCP packet. need to dispatch it now */ int sccp_system_incoming(struct msgb *msgb) { @@ -1355,7 +1412,7 @@ if (!sock) return -2;
- cb = _find_ssn(sock->sccp_ssn); + cb = _find_ssn(sock->ssn); if (!cb) return -1;
@@ -1378,7 +1435,7 @@ if (!sock) return -2;
- cb = _find_ssn(sock->sccp_ssn); + cb = _find_ssn(sock->ssn); if (!cb) return -1;
diff --git a/tests/sccp/sccp_test.c b/tests/sccp/sccp_test.c index 6043cff..f3155d3 100644 --- a/tests/sccp/sccp_test.c +++ b/tests/sccp/sccp_test.c @@ -873,15 +873,15 @@
if (parse_result[current_test].dst_ssn != -1 && parse_result[current_test].dst_ssn != result.called.ssn) { - FAIL("Called SSN is wrong..\n"); + FAIL("Called SSN is wrong...\n"); }
if (parse_result[current_test].src_gti_len != result.calling.gti_len) { - FAIL("GTI length is wrong: %d\n", result.calling.gti_len); + FAIL("GTI length is wrong: Expected %d, got %d\n", parse_result[current_test].src_gti_len, result.calling.gti_len); }
if (parse_result[current_test].dst_gti_len != result.called.gti_len) { - FAIL("GTI length is wrong: %d\n", result.called.gti_len); + FAIL("GTI length is wrong: Expected %d, got %d\n", parse_result[current_test].dst_gti_len, result.called.gti_len); }
if (memcmp(&parse_result[current_test].dst_gti_data[0],
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
to look at the new patch set (#5).
Add selector for ANSI or ITU variant
Change-Id: Ia17eef8c9b7d8e1092c587f469b4a68aa9702651 --- M include/sccp/sccp.h M include/sccp/sccp_types.h M src/sccp.c M tests/sccp/sccp_test.c 4 files changed, 147 insertions(+), 76 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/73/5
diff --git a/include/sccp/sccp.h b/include/sccp/sccp.h index 36b424f..37a3b61 100644 --- a/include/sccp/sccp.h +++ b/include/sccp/sccp.h @@ -46,36 +46,35 @@ 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 */ +struct sccp_variant { + uint8_t ai_national; /* National or reserved bit */ + uint8_t ai_gti_ind; /* GTI mask */ + uint8_t ai_pc_ind; /* Point code indicator mask */ + uint8_t ai_ssn_ind; /* SSN indicator mask */ + uint8_t ai_route_ind; /* Route type mask */ + uint8_t pc_len; /* Point code length */ + uint8_t pc_first; /* whether the pointcode comes before the SSN */ +};
- /* TODO fill in address indicator... if that is ever needed */ +struct sockaddr_sccp { + sa_family_t sccp_family; /* AF_SCCP in the future??? */ + + uint8_t use_poi : 1, /* Include Point Code */ + use_ssn : 1, /* Include SSN */ + gti_ind : 4, /* Any of SCCP_TITLE_IND_* */ + route_ind : 1, /* Route on SSN instead of GTI */ + national : 1; /* National address format in ANSI, national usage/reserved in ITU */ + + uint8_t poi[3]; /* Allows ITU 14bit and ANSI 24bit */ + + uint8_t ssn; /* SubsSystem number for routing */
/* optional gti information */ - uint8_t *gti; + uint8_t *gti_data; 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 { @@ -103,6 +102,8 @@ int incoming; };
+extern struct sccp_variant sccp_variant[]; + /** * system functionality to implement on top of any other transport layer: * call sccp_system_incoming for incoming data (from the network) @@ -122,7 +123,7 @@ int sccp_connection_free(struct sccp_connection *connection);
/** - * internal.. + * internal.. */ int sccp_connection_force_free(struct sccp_connection *conn);
@@ -157,6 +158,7 @@ int sccp_set_read(const struct sockaddr_sccp *sock, int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data), void *user_data); +void sccp_set_variant(int variant);
/* generic sock addresses */ extern const struct sockaddr_sccp sccp_ssn_bssap; @@ -177,8 +179,8 @@ * Below this are helper functions and structs for parsing SCCP messages */ struct sccp_parse_result { - struct sccp_address called; - struct sccp_address calling; + struct sockaddr_sccp called; + struct sockaddr_sccp calling;
/* point to the msg packet */ struct sccp_source_reference *source_local_reference; diff --git a/include/sccp/sccp_types.h b/include/sccp/sccp_types.h index 986de0d..cd60c25 100644 --- a/include/sccp/sccp_types.h +++ b/include/sccp/sccp_types.h @@ -26,6 +26,12 @@
#include <osmocom/core/endian.h>
+/* Which variant of SCCP we're using */ +enum { + SCCP_VARIANT_ITU, + SCCP_VARIANT_ANSI +}; + /* Table 1/Q.713 - SCCP message types */ enum sccp_message_types { SCCP_MSG_TYPE_CR = 1, diff --git a/src/sccp.c b/src/sccp.c index e6c538d..d756b8d 100644 --- a/src/sccp.c +++ b/src/sccp.c @@ -43,7 +43,28 @@ /* global data */ const struct sockaddr_sccp sccp_ssn_bssap = { .sccp_family = 0, - .sccp_ssn = SCCP_SSN_BSSAP, + .ssn = SCCP_SSN_BSSAP, +}; + +struct sccp_variant sccp_variant[] = { + [SCCP_VARIANT_ITU] = { + .ai_national = 0x80, + .ai_gti_ind = 0x3c, + .ai_pc_ind = 0x01, + .ai_ssn_ind = 0x02, + .ai_route_ind = 0x40, + .pc_len = 2, + .pc_first = 1 + }, + [SCCP_VARIANT_ANSI] = { + .ai_national = 0x80, + .ai_gti_ind = 0x3c, + .ai_pc_ind = 0x02, + .ai_ssn_ind = 0x01, + .ai_route_ind = 0x40, + .pc_len = 3, + .pc_first = 0, + } };
struct sccp_system { @@ -51,11 +72,14 @@ void (*write_data)(struct sccp_connection *conn, struct msgb *data, void *gctx, void *ctx); void *write_context; + + int variant; };
static struct sccp_system sccp_system = { .write_data = NULL, + .variant = SCCP_VARIANT_ITU };
struct sccp_data_callback { @@ -103,13 +127,15 @@ /* * parsing routines */ -static int copy_address(struct sccp_address *addr, uint8_t offset, struct msgb *msgb) +static int copy_address(struct sockaddr_sccp *addr, uint8_t offset, struct msgb *msgb) { - struct sccp_called_party_address *party; - int room = msgb_l2len(msgb) - offset; + + uint8_t *data; uint8_t read = 0; uint8_t length; + uint8_t ai; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
if (room <= 0) { LOGP(DSCCP, LOGL_ERROR, "Not enough room for an address: %u\n", room); @@ -122,36 +148,54 @@ return -1; }
+ data = msgb->l2h + offset + 1; + ai = data[0]; + read++;
- party = (struct sccp_called_party_address *)(msgb->l2h + offset + 1); - if (party->point_code_indicator) { - if (length <= read + 2) { - LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); - return -1; - } +#define PARSE_POI \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_pc_ind) { \ + addr->use_poi = 1; \ + if (length < (read + pc_len)) { \ + LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); \ + return -1; \ + } \ + memcpy(&addr->poi, &data[read], pc_len); \ + read += pc_len; \ + } \ + } while (0)
+#define PARSE_SSN \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_ssn_ind) { \ + addr->use_ssn = 1; \ + if (length < (read + 1)) { \ + LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); \ + return -1; \ + } \ + addr->ssn = data[read]; \ + read += 1; \ + } \ + } while (0)
- memcpy(&addr->poi, &party->data[read], 2); - read += 2; + if (sccp_variant[sccp_system.variant].pc_first) { + PARSE_POI; + PARSE_SSN; + } else { + PARSE_SSN; + PARSE_POI; }
- if (party->ssn_indicator) { - if (length <= read + 1) { - LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); - return -1; - } - - addr->ssn = party->data[read]; - read += 1; - } + addr->gti_ind = ((ai & sccp_variant[sccp_system.variant].ai_gti_ind) >> 2); + addr->route_ind = ai & sccp_variant[sccp_system.variant].ai_route_ind; + addr->national = ai & sccp_variant[sccp_system.variant].ai_national;
/* copy the GTI over */ - if (party->global_title_indicator) { - addr->gti_len = length - read - 1; - addr->gti_data = &party->data[read]; + if (addr->gti_ind) { + addr->gti_len = length - read; + addr->gti_data = &data[read]; }
- addr->address = *party; return 0; }
@@ -173,7 +217,6 @@
uint8_t length = msgb->l2h[offset + read + 1]; read += 2 + length; -
if (room <= read) { LOGP(DSCCP, LOGL_ERROR, @@ -486,32 +529,47 @@ int sccp_create_sccp_addr(struct msgb *msg, const struct sockaddr_sccp *sock) { uint8_t *len, *ai, *gti; + uint8_t *poi; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
len = msgb_put(msg, 1); ai = msgb_put(msg, 1);
+ if (sock->gti_data) ai[0] = (sock->gti_ind & 0x0f) << 2; + if (sock->route_ind || !sock->gti_data) ai[0] |= sccp_variant[sccp_system.variant].ai_route_ind;
- if (sock->gti) - ai[0] = 0 << 6 | (sock->gti_ind & 0x0f) << 2 | 1 << 1; - else - ai[0] = 1 << 6 | 1 << 1; + /* National/reserved bit */ + if (sock->national) ai[0] |= sccp_variant[sccp_system.variant].ai_national;
- /* store a point code */ - if (sock->use_poi) { - uint8_t *poi; + /* Pointcode ind */ + if (sock->use_poi) ai[0] |= sccp_variant[sccp_system.variant].ai_pc_ind;
- ai[0] |= 0x01; - poi = msgb_put(msg, 2); - poi[0] = sock->poi[0]; - poi[1] = sock->poi[1]; + /* SSN ind */ + ai[0] |= sccp_variant[sccp_system.variant].ai_ssn_ind; + +#define ADD_POI \ + do { \ + if (sock->use_poi) { \ + poi = msgb_put(msg, pc_len); \ + if (!poi) return -1; \ + memcpy(poi, &sock->poi[0], pc_len); \ + } \ + } while (0) + +#define ADD_SSN \ + msgb_v_put(msg, sock->ssn) + + if (sccp_variant[sccp_system.variant].pc_first) { + ADD_POI; + ADD_SSN; + } else { + ADD_SSN; + ADD_POI; } - - /* copy the SSN */ - msgb_v_put(msg, sock->sccp_ssn);
/* copy the gti if it is present */ gti = msgb_put(msg, sock->gti_len); - memcpy(gti, sock->gti, sock->gti_len); + memcpy(gti, sock->gti_data, sock->gti_len);
/* update the length now */ len[0] = msg->tail - len - 1; @@ -1225,6 +1283,11 @@ return 0; }
+void sccp_set_variant(int variant) +{ + sccp_system.variant = variant; +} + /* oh my god a real SCCP packet. need to dispatch it now */ int sccp_system_incoming(struct msgb *msgb) { @@ -1355,7 +1418,7 @@ if (!sock) return -2;
- cb = _find_ssn(sock->sccp_ssn); + cb = _find_ssn(sock->ssn); if (!cb) return -1;
@@ -1378,7 +1441,7 @@ if (!sock) return -2;
- cb = _find_ssn(sock->sccp_ssn); + cb = _find_ssn(sock->ssn); if (!cb) return -1;
diff --git a/tests/sccp/sccp_test.c b/tests/sccp/sccp_test.c index 6043cff..8d430d9 100644 --- a/tests/sccp/sccp_test.c +++ b/tests/sccp/sccp_test.c @@ -305,7 +305,7 @@ };
static const uint8_t it_test[] = { -0x10, 0x01, 0x07, +0x10, 0x01, 0x07, 0x94, 0x01, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 };
static const uint8_t proto_err[] = { @@ -873,15 +873,15 @@
if (parse_result[current_test].dst_ssn != -1 && parse_result[current_test].dst_ssn != result.called.ssn) { - FAIL("Called SSN is wrong..\n"); + FAIL("Called SSN is wrong...\n"); }
if (parse_result[current_test].src_gti_len != result.calling.gti_len) { - FAIL("GTI length is wrong: %d\n", result.calling.gti_len); + FAIL("GTI length is wrong: Expected %d, got %d\n", parse_result[current_test].src_gti_len, result.calling.gti_len); }
if (parse_result[current_test].dst_gti_len != result.called.gti_len) { - FAIL("GTI length is wrong: %d\n", result.called.gti_len); + FAIL("GTI length is wrong: Expected %d, got %d\n", parse_result[current_test].dst_gti_len, result.called.gti_len); }
if (memcmp(&parse_result[current_test].dst_gti_data[0], @@ -919,7 +919,7 @@
const struct sockaddr_sccp sccp_poi_bssap = { .sccp_family = 0, - .sccp_ssn = SCCP_SSN_BSSAP, + .ssn = SCCP_SSN_BSSAP, .poi = {0x01, 0x00}, .use_poi = 1, }; @@ -934,10 +934,10 @@
const struct sockaddr_sccp sccp_gti_bssap = { .sccp_family = 0, - .sccp_ssn = 7, + .ssn = 7, .gti_ind = 4, .gti_len = ARRAY_SIZE(gti_dat), - .gti = gti_dat, + .gti_data = gti_dat, };
static uint8_t gti_out[] = {
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
to look at the new patch set (#6).
Add selector for ANSI or ITU variant
Change-Id: Ia17eef8c9b7d8e1092c587f469b4a68aa9702651 --- M include/sccp/sccp.h M include/sccp/sccp_types.h M src/sccp.c M tests/sccp/sccp_test.c 4 files changed, 146 insertions(+), 75 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/73/6
diff --git a/include/sccp/sccp.h b/include/sccp/sccp.h index 36b424f..37a3b61 100644 --- a/include/sccp/sccp.h +++ b/include/sccp/sccp.h @@ -46,36 +46,35 @@ 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 */ +struct sccp_variant { + uint8_t ai_national; /* National or reserved bit */ + uint8_t ai_gti_ind; /* GTI mask */ + uint8_t ai_pc_ind; /* Point code indicator mask */ + uint8_t ai_ssn_ind; /* SSN indicator mask */ + uint8_t ai_route_ind; /* Route type mask */ + uint8_t pc_len; /* Point code length */ + uint8_t pc_first; /* whether the pointcode comes before the SSN */ +};
- /* TODO fill in address indicator... if that is ever needed */ +struct sockaddr_sccp { + sa_family_t sccp_family; /* AF_SCCP in the future??? */ + + uint8_t use_poi : 1, /* Include Point Code */ + use_ssn : 1, /* Include SSN */ + gti_ind : 4, /* Any of SCCP_TITLE_IND_* */ + route_ind : 1, /* Route on SSN instead of GTI */ + national : 1; /* National address format in ANSI, national usage/reserved in ITU */ + + uint8_t poi[3]; /* Allows ITU 14bit and ANSI 24bit */ + + uint8_t ssn; /* SubsSystem number for routing */
/* optional gti information */ - uint8_t *gti; + uint8_t *gti_data; 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 { @@ -103,6 +102,8 @@ int incoming; };
+extern struct sccp_variant sccp_variant[]; + /** * system functionality to implement on top of any other transport layer: * call sccp_system_incoming for incoming data (from the network) @@ -122,7 +123,7 @@ int sccp_connection_free(struct sccp_connection *connection);
/** - * internal.. + * internal.. */ int sccp_connection_force_free(struct sccp_connection *conn);
@@ -157,6 +158,7 @@ int sccp_set_read(const struct sockaddr_sccp *sock, int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data), void *user_data); +void sccp_set_variant(int variant);
/* generic sock addresses */ extern const struct sockaddr_sccp sccp_ssn_bssap; @@ -177,8 +179,8 @@ * Below this are helper functions and structs for parsing SCCP messages */ struct sccp_parse_result { - struct sccp_address called; - struct sccp_address calling; + struct sockaddr_sccp called; + struct sockaddr_sccp calling;
/* point to the msg packet */ struct sccp_source_reference *source_local_reference; diff --git a/include/sccp/sccp_types.h b/include/sccp/sccp_types.h index 986de0d..cd60c25 100644 --- a/include/sccp/sccp_types.h +++ b/include/sccp/sccp_types.h @@ -26,6 +26,12 @@
#include <osmocom/core/endian.h>
+/* Which variant of SCCP we're using */ +enum { + SCCP_VARIANT_ITU, + SCCP_VARIANT_ANSI +}; + /* Table 1/Q.713 - SCCP message types */ enum sccp_message_types { SCCP_MSG_TYPE_CR = 1, diff --git a/src/sccp.c b/src/sccp.c index e6c538d..d756b8d 100644 --- a/src/sccp.c +++ b/src/sccp.c @@ -43,7 +43,28 @@ /* global data */ const struct sockaddr_sccp sccp_ssn_bssap = { .sccp_family = 0, - .sccp_ssn = SCCP_SSN_BSSAP, + .ssn = SCCP_SSN_BSSAP, +}; + +struct sccp_variant sccp_variant[] = { + [SCCP_VARIANT_ITU] = { + .ai_national = 0x80, + .ai_gti_ind = 0x3c, + .ai_pc_ind = 0x01, + .ai_ssn_ind = 0x02, + .ai_route_ind = 0x40, + .pc_len = 2, + .pc_first = 1 + }, + [SCCP_VARIANT_ANSI] = { + .ai_national = 0x80, + .ai_gti_ind = 0x3c, + .ai_pc_ind = 0x02, + .ai_ssn_ind = 0x01, + .ai_route_ind = 0x40, + .pc_len = 3, + .pc_first = 0, + } };
struct sccp_system { @@ -51,11 +72,14 @@ void (*write_data)(struct sccp_connection *conn, struct msgb *data, void *gctx, void *ctx); void *write_context; + + int variant; };
static struct sccp_system sccp_system = { .write_data = NULL, + .variant = SCCP_VARIANT_ITU };
struct sccp_data_callback { @@ -103,13 +127,15 @@ /* * parsing routines */ -static int copy_address(struct sccp_address *addr, uint8_t offset, struct msgb *msgb) +static int copy_address(struct sockaddr_sccp *addr, uint8_t offset, struct msgb *msgb) { - struct sccp_called_party_address *party; - int room = msgb_l2len(msgb) - offset; + + uint8_t *data; uint8_t read = 0; uint8_t length; + uint8_t ai; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
if (room <= 0) { LOGP(DSCCP, LOGL_ERROR, "Not enough room for an address: %u\n", room); @@ -122,36 +148,54 @@ return -1; }
+ data = msgb->l2h + offset + 1; + ai = data[0]; + read++;
- party = (struct sccp_called_party_address *)(msgb->l2h + offset + 1); - if (party->point_code_indicator) { - if (length <= read + 2) { - LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); - return -1; - } +#define PARSE_POI \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_pc_ind) { \ + addr->use_poi = 1; \ + if (length < (read + pc_len)) { \ + LOGP(DSCCP, LOGL_ERROR, "POI does not fit %u\n", length); \ + return -1; \ + } \ + memcpy(&addr->poi, &data[read], pc_len); \ + read += pc_len; \ + } \ + } while (0)
+#define PARSE_SSN \ + do { \ + if (ai & sccp_variant[sccp_system.variant].ai_ssn_ind) { \ + addr->use_ssn = 1; \ + if (length < (read + 1)) { \ + LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); \ + return -1; \ + } \ + addr->ssn = data[read]; \ + read += 1; \ + } \ + } while (0)
- memcpy(&addr->poi, &party->data[read], 2); - read += 2; + if (sccp_variant[sccp_system.variant].pc_first) { + PARSE_POI; + PARSE_SSN; + } else { + PARSE_SSN; + PARSE_POI; }
- if (party->ssn_indicator) { - if (length <= read + 1) { - LOGP(DSCCP, LOGL_ERROR, "SSN does not fit %u\n", length); - return -1; - } - - addr->ssn = party->data[read]; - read += 1; - } + addr->gti_ind = ((ai & sccp_variant[sccp_system.variant].ai_gti_ind) >> 2); + addr->route_ind = ai & sccp_variant[sccp_system.variant].ai_route_ind; + addr->national = ai & sccp_variant[sccp_system.variant].ai_national;
/* copy the GTI over */ - if (party->global_title_indicator) { - addr->gti_len = length - read - 1; - addr->gti_data = &party->data[read]; + if (addr->gti_ind) { + addr->gti_len = length - read; + addr->gti_data = &data[read]; }
- addr->address = *party; return 0; }
@@ -173,7 +217,6 @@
uint8_t length = msgb->l2h[offset + read + 1]; read += 2 + length; -
if (room <= read) { LOGP(DSCCP, LOGL_ERROR, @@ -486,32 +529,47 @@ int sccp_create_sccp_addr(struct msgb *msg, const struct sockaddr_sccp *sock) { uint8_t *len, *ai, *gti; + uint8_t *poi; + uint8_t pc_len = sccp_variant[sccp_system.variant].pc_len;
len = msgb_put(msg, 1); ai = msgb_put(msg, 1);
+ if (sock->gti_data) ai[0] = (sock->gti_ind & 0x0f) << 2; + if (sock->route_ind || !sock->gti_data) ai[0] |= sccp_variant[sccp_system.variant].ai_route_ind;
- if (sock->gti) - ai[0] = 0 << 6 | (sock->gti_ind & 0x0f) << 2 | 1 << 1; - else - ai[0] = 1 << 6 | 1 << 1; + /* National/reserved bit */ + if (sock->national) ai[0] |= sccp_variant[sccp_system.variant].ai_national;
- /* store a point code */ - if (sock->use_poi) { - uint8_t *poi; + /* Pointcode ind */ + if (sock->use_poi) ai[0] |= sccp_variant[sccp_system.variant].ai_pc_ind;
- ai[0] |= 0x01; - poi = msgb_put(msg, 2); - poi[0] = sock->poi[0]; - poi[1] = sock->poi[1]; + /* SSN ind */ + ai[0] |= sccp_variant[sccp_system.variant].ai_ssn_ind; + +#define ADD_POI \ + do { \ + if (sock->use_poi) { \ + poi = msgb_put(msg, pc_len); \ + if (!poi) return -1; \ + memcpy(poi, &sock->poi[0], pc_len); \ + } \ + } while (0) + +#define ADD_SSN \ + msgb_v_put(msg, sock->ssn) + + if (sccp_variant[sccp_system.variant].pc_first) { + ADD_POI; + ADD_SSN; + } else { + ADD_SSN; + ADD_POI; } - - /* copy the SSN */ - msgb_v_put(msg, sock->sccp_ssn);
/* copy the gti if it is present */ gti = msgb_put(msg, sock->gti_len); - memcpy(gti, sock->gti, sock->gti_len); + memcpy(gti, sock->gti_data, sock->gti_len);
/* update the length now */ len[0] = msg->tail - len - 1; @@ -1225,6 +1283,11 @@ return 0; }
+void sccp_set_variant(int variant) +{ + sccp_system.variant = variant; +} + /* oh my god a real SCCP packet. need to dispatch it now */ int sccp_system_incoming(struct msgb *msgb) { @@ -1355,7 +1418,7 @@ if (!sock) return -2;
- cb = _find_ssn(sock->sccp_ssn); + cb = _find_ssn(sock->ssn); if (!cb) return -1;
@@ -1378,7 +1441,7 @@ if (!sock) return -2;
- cb = _find_ssn(sock->sccp_ssn); + cb = _find_ssn(sock->ssn); if (!cb) return -1;
diff --git a/tests/sccp/sccp_test.c b/tests/sccp/sccp_test.c index 6043cff..6ea31dd 100644 --- a/tests/sccp/sccp_test.c +++ b/tests/sccp/sccp_test.c @@ -305,7 +305,7 @@ };
static const uint8_t it_test[] = { -0x10, 0x01, 0x07, +0x10, 0x01, 0x07, 0x94, 0x01, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 };
static const uint8_t proto_err[] = { @@ -877,11 +877,11 @@ }
if (parse_result[current_test].src_gti_len != result.calling.gti_len) { - FAIL("GTI length is wrong: %d\n", result.calling.gti_len); + FAIL("GTI length is wrong: Expected %d, got %d\n", parse_result[current_test].src_gti_len, result.calling.gti_len); }
if (parse_result[current_test].dst_gti_len != result.called.gti_len) { - FAIL("GTI length is wrong: %d\n", result.called.gti_len); + FAIL("GTI length is wrong: Expected %d, got %d\n", parse_result[current_test].dst_gti_len, result.called.gti_len); }
if (memcmp(&parse_result[current_test].dst_gti_data[0], @@ -919,7 +919,7 @@
const struct sockaddr_sccp sccp_poi_bssap = { .sccp_family = 0, - .sccp_ssn = SCCP_SSN_BSSAP, + .ssn = SCCP_SSN_BSSAP, .poi = {0x01, 0x00}, .use_poi = 1, }; @@ -934,10 +934,10 @@
const struct sockaddr_sccp sccp_gti_bssap = { .sccp_family = 0, - .sccp_ssn = 7, + .ssn = 7, .gti_ind = 4, .gti_len = ARRAY_SIZE(gti_dat), - .gti = gti_dat, + .gti_data = gti_dat, };
static uint8_t gti_out[] = {