aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/sgsn/gprs_sndcp_comp.h6
-rw-r--r--include/osmocom/sgsn/gprs_sndcp_xid.h36
-rw-r--r--src/gprs/gprs_sndcp.c8
-rw-r--r--src/gprs/gprs_sndcp_comp.c15
-rw-r--r--src/gprs/gprs_sndcp_dcomp.c8
-rw-r--r--src/gprs/gprs_sndcp_pcomp.c8
-rw-r--r--src/gprs/gprs_sndcp_xid.c177
-rw-r--r--tests/sndcp_xid/sndcp_xid_test.c10
8 files changed, 180 insertions, 88 deletions
diff --git a/include/osmocom/sgsn/gprs_sndcp_comp.h b/include/osmocom/sgsn/gprs_sndcp_comp.h
index c04f7d49a..e01a9d72f 100644
--- a/include/osmocom/sgsn/gprs_sndcp_comp.h
+++ b/include/osmocom/sgsn/gprs_sndcp_comp.h
@@ -41,9 +41,9 @@ struct gprs_sndcp_comp {
uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */
/* Algorithm parameters */
- int algo; /* Algorithm type (see gprs_sndcp_xid.h) */
- int compclass; /* See gprs_sndcp_xid.h/c */
- void *state; /* Algorithm status and parameters */
+ union gprs_sndcp_comp_algo algo;
+ enum gprs_sndcp_xid_param_types compclass; /* See gprs_sndcp_xid.h/c */
+ void *state; /* Algorithm status and parameters */
};
#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */
diff --git a/include/osmocom/sgsn/gprs_sndcp_xid.h b/include/osmocom/sgsn/gprs_sndcp_xid.h
index e64bc5237..0dce43e40 100644
--- a/include/osmocom/sgsn/gprs_sndcp_xid.h
+++ b/include/osmocom/sgsn/gprs_sndcp_xid.h
@@ -32,6 +32,24 @@
#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */
#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */
+/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
+enum gprs_sndcp_hdr_comp_algo {
+ RFC_1144, /* TCP/IP header compression, see also 6.5.2 */
+ RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */
+ ROHC /* Robust Header Compression, see also 6.5.4 */
+};
+
+/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
+enum gprs_sndcp_data_comp_algo {
+ V42BIS, /* V.42bis data compression, see also 6.6.2 */
+ V44 /* V44 data compression, see also: 6.6.3 */
+};
+
+union gprs_sndcp_comp_algo {
+ enum gprs_sndcp_hdr_comp_algo pcomp;
+ enum gprs_sndcp_data_comp_algo dcomp;
+};
+
/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control
* information compression field (Figure 7) and 3GPP TS 44.065,
* 6.6.1.1 Format of the data compression field (Figure 9) */
@@ -45,7 +63,7 @@ struct gprs_sndcp_comp_field {
unsigned int entity;
/* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */
- int algo;
+ union gprs_sndcp_comp_algo algo;
/* Number of contained PCOMP / DCOMP values */
uint8_t comp_len;
@@ -62,24 +80,12 @@ struct gprs_sndcp_comp_field {
struct gprs_sndcp_dcomp_v44_params *v44_params;
};
-/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
-enum gprs_sndcp_hdr_comp_algo {
- RFC_1144, /* TCP/IP header compression, see also 6.5.2 */
- RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */
- ROHC /* Robust Header Compression, see also 6.5.4 */
-};
-
-/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
-enum gprs_sndcp_data_comp_algo {
- V42BIS, /* V.42bis data compression, see also 6.6.2 */
- V44 /* V44 data compression, see also: 6.6.3 */
-};
-
/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */
enum gprs_sndcp_xid_param_types {
SNDCP_XID_VERSION_NUMBER,
SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */
SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */
+ SNDCP_XID_INVALID_COMPRESSION /* Not part of the spec; this means we found an invalid value */
};
/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */
@@ -209,7 +215,7 @@ struct llist_head *gprs_sndcp_parse_xid(int *version,
/* Find out to which compression class the specified comp-field belongs
* (header compression or data compression?) */
-int gprs_sndcp_get_compression_class(
+enum gprs_sndcp_xid_param_types gprs_sndcp_get_compression_class(
const struct gprs_sndcp_comp_field *comp_field);
/* Dump a list with SNDCP-XID fields (Debug) */
diff --git a/src/gprs/gprs_sndcp.c b/src/gprs/gprs_sndcp.c
index 52eeb75d5..f0239cb66 100644
--- a/src/gprs/gprs_sndcp.c
+++ b/src/gprs/gprs_sndcp.c
@@ -934,7 +934,7 @@ static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi)
rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01;
rfc1144_comp_field.p = 1;
rfc1144_comp_field.entity = entity;
- rfc1144_comp_field.algo = RFC_1144;
+ rfc1144_comp_field.algo.pcomp = RFC_1144;
rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1;
rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2;
rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM;
@@ -952,7 +952,7 @@ static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi)
v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2;
v42bis_comp_field.p = 1;
v42bis_comp_field.entity = entity;
- v42bis_comp_field.algo = V42BIS;
+ v42bis_comp_field.algo.dcomp = V42BIS;
v42bis_comp_field.comp[V42BIS_DCOMP1] = 1;
v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM;
v42bis_comp_field.v42bis_params = &v42bis_params;
@@ -1021,7 +1021,7 @@ static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field,
comp_field->p = 0;
/* Process proposed parameters */
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
if (sgsn->cfg.pcomp_rfc1144.passive
&& comp_field->rfc1144_params->nsapi_len > 0) {
@@ -1068,7 +1068,7 @@ static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field,
comp_field->p = 0;
/* Process proposed parameters */
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
if (sgsn->cfg.dcomp_v42bis.passive &&
comp_field->v42bis_params->nsapi_len > 0) {
diff --git a/src/gprs/gprs_sndcp_comp.c b/src/gprs/gprs_sndcp_comp.c
index 3e026032e..0b4c67cd4 100644
--- a/src/gprs/gprs_sndcp_comp.c
+++ b/src/gprs/gprs_sndcp_comp.c
@@ -55,32 +55,36 @@ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx,
memcpy(comp_entity->nsapi,
comp_field->rfc1144_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.pcomp = comp_field->algo.pcomp;
} else if (comp_field->rfc2507_params) {
comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len;
memcpy(comp_entity->nsapi,
comp_field->rfc2507_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.pcomp = comp_field->algo.pcomp;
} else if (comp_field->rohc_params) {
comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len;
memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.pcomp = comp_field->algo.pcomp;
} else if (comp_field->v42bis_params) {
comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len;
memcpy(comp_entity->nsapi,
comp_field->v42bis_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.dcomp = comp_field->algo.dcomp;
} else if (comp_field->v44_params) {
comp_entity->nsapi_len = comp_field->v44_params->nsapi_len;
memcpy(comp_entity->nsapi,
comp_field->v44_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.dcomp = comp_field->algo.dcomp;
} else {
/* The caller is expected to check carefully if the all
* data fields required for compression entity creation
* are present. Otherwise we blow an assertion here */
OSMO_ASSERT(false);
}
- comp_entity->algo = comp_field->algo;
/* Check if an NSAPI is selected, if not, it does not make sense
* to create the compression entity, since the caller should
@@ -93,17 +97,20 @@ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx,
comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field);
/* Create an algorithm specific compression context */
- if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (comp_entity->compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) {
talloc_free(comp_entity);
comp_entity = NULL;
}
- } else if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION) {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) {
talloc_free(comp_entity);
comp_entity = NULL;
}
- } else {
+ break;
+ default:
/* comp_field is somehow invalid */
OSMO_ASSERT(false);
}
diff --git a/src/gprs/gprs_sndcp_dcomp.c b/src/gprs/gprs_sndcp_dcomp.c
index 04ff491f3..00e40a7ef 100644
--- a/src/gprs/gprs_sndcp_dcomp.c
+++ b/src/gprs/gprs_sndcp_dcomp.c
@@ -83,7 +83,7 @@ int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
OSMO_ASSERT(comp_field);
if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION
- && comp_entity->algo == V42BIS) {
+ && comp_entity->algo.dcomp == V42BIS) {
OSMO_ASSERT(comp_field->v42bis_params);
comp_entity->state =
v42bis_init(ctx, NULL, comp_field->v42bis_params->p0,
@@ -114,7 +114,7 @@ void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity)
OSMO_ASSERT(comp_entity);
if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION
- && comp_entity->algo == V42BIS) {
+ && comp_entity->algo.dcomp == V42BIS) {
if (comp_entity->state) {
v42bis_free((v42bis_state_t *) comp_entity->state);
comp_entity->state = NULL;
@@ -293,7 +293,7 @@ int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp,
/* Note: Currently V42BIS is the only compression method we
* support, so the only allowed algorithm is V42BIS */
- OSMO_ASSERT(comp_entity->algo == V42BIS);
+ OSMO_ASSERT(comp_entity->algo.dcomp == V42BIS);
/* Find pcomp_index */
pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp);
@@ -339,7 +339,7 @@ int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp,
/* Note: Currently V42BIS is the only compression method we
* support, so the only allowed algorithm is V42BIS */
- OSMO_ASSERT(comp_entity->algo == V42BIS);
+ OSMO_ASSERT(comp_entity->algo.dcomp == V42BIS);
/* Run compression algo */
rc = v42bis_compress_unitdata(&pcomp_index, data, len,
diff --git a/src/gprs/gprs_sndcp_pcomp.c b/src/gprs/gprs_sndcp_pcomp.c
index 2911b5ebe..5f7f22aed 100644
--- a/src/gprs/gprs_sndcp_pcomp.c
+++ b/src/gprs/gprs_sndcp_pcomp.c
@@ -53,7 +53,7 @@ int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
OSMO_ASSERT(comp_field);
if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION
- && comp_entity->algo == RFC_1144) {
+ && comp_entity->algo.pcomp == RFC_1144) {
OSMO_ASSERT(comp_field->rfc1144_params);
comp_entity->state =
slhc_init(ctx, comp_field->rfc1144_params->s01 + 1,
@@ -79,7 +79,7 @@ void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity)
OSMO_ASSERT(comp_entity);
if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION
- && comp_entity->algo == RFC_1144) {
+ && comp_entity->algo.pcomp == RFC_1144) {
if (comp_entity->state) {
slhc_free((struct slcompress *)comp_entity->state);
comp_entity->state = NULL;
@@ -214,7 +214,7 @@ int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp,
/* Note: Currently RFC1144 is the only compression method we
* support, so the only allowed algorithm is RFC1144 */
- OSMO_ASSERT(comp_entity->algo == RFC_1144);
+ OSMO_ASSERT(comp_entity->algo.pcomp == RFC_1144);
/* Find pcomp_index */
pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp);
@@ -263,7 +263,7 @@ int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp,
/* Note: Currently RFC1144 is the only compression method we
* support, so the only allowed algorithm is RFC1144 */
- OSMO_ASSERT(comp_entity->algo == RFC_1144);
+ OSMO_ASSERT(comp_entity->algo.pcomp == RFC_1144);
/* Run compression algo */
rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state);
diff --git a/src/gprs/gprs_sndcp_xid.c b/src/gprs/gprs_sndcp_xid.c
index 09e21f594..a19f64514 100644
--- a/src/gprs/gprs_sndcp_xid.c
+++ b/src/gprs/gprs_sndcp_xid.c
@@ -42,9 +42,8 @@
* about the referenced algorithm to the parser. */
struct entity_algo_table {
unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */
- unsigned int algo; /* see also: 6.5.1.1.4 and 6.6.1.1.4 */
- unsigned int compclass; /* Can be either SNDCP_XID_DATA_COMPRESSION or
- SNDCP_XID_PROTOCOL_COMPRESSION */
+ union gprs_sndcp_comp_algo algo;
+ enum gprs_sndcp_xid_param_types compclass;
};
/* FUNCTIONS RELATED TO SNDCP-XID ENCODING */
@@ -386,6 +385,7 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
int len;
int expected_length;
int i;
+ enum gprs_sndcp_xid_param_types compclass;
uint8_t payload_bytes[256];
int payload_bytes_len = -1;
@@ -443,7 +443,17 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
OSMO_ASSERT(comp_field->entity <= 0x1f);
/* Check if the algorithm number is within bounds */
- OSMO_ASSERT(comp_field->algo >= 0 && comp_field->algo <= 0x1f);
+ compclass = gprs_sndcp_get_compression_class(comp_field);
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ OSMO_ASSERT(comp_field->algo.pcomp >= 0 && comp_field->algo.pcomp <= 0x1f);
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ OSMO_ASSERT(comp_field->algo.dcomp >= 0 && comp_field->algo.dcomp <= 0x1f);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
/* Zero out buffer */
memset(dst, 0, dst_maxlen);
@@ -459,7 +469,10 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
/* Encode algorithm number */
if (comp_field->p) {
- *dst |= comp_field->algo & 0x1F;
+ if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION)
+ *dst |= comp_field->algo.pcomp & 0x1F;
+ else
+ *dst |= comp_field->algo.dcomp & 0x1F;
dst++;
dst_counter++;
}
@@ -501,7 +514,7 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
/* Find out to which compression class the specified comp-field belongs
* (header compression or data compression?) */
-int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field
+enum gprs_sndcp_xid_param_types gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field
*comp_field)
{
OSMO_ASSERT(comp_field);
@@ -517,7 +530,7 @@ int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field
else if (comp_field->v44_params)
return SNDCP_XID_DATA_COMPRESSION;
else
- return -EINVAL;
+ return SNDCP_XID_INVALID_COMPRESSION;
}
/* Convert all compression fields to bytstreams */
@@ -1005,10 +1018,29 @@ static int decode_dcomp_v44_params(struct gprs_sndcp_dcomp_v44_params *params,
return byte_counter;
}
-/* Lookup algorithm identfier by entity ID */
-static int lookup_algorithm_identifier(int entity, const struct
- entity_algo_table
- *lt, unsigned int lt_len, int compclass)
+/* Lookup protocol compression algorithm identfier by entity ID */
+static enum gprs_sndcp_hdr_comp_algo lookup_algorithm_identifier_pcomp(int entity,
+ const struct entity_algo_table *lt,
+ unsigned int lt_len)
+{
+ int i;
+
+ if (!lt)
+ return -1;
+
+ for (i = 0; i < lt_len; i++) {
+ if ((lt[i].entity == entity)
+ && (lt[i].compclass == SNDCP_XID_PROTOCOL_COMPRESSION))
+ return lt[i].algo.pcomp;
+ }
+
+ return SNDCP_XID_INVALID_COMPRESSION;
+}
+
+/* Lookup a data compression algorithm identfier by entity ID */
+static enum gprs_sndcp_data_comp_algo lookup_algorithm_identifier_dcomp(int entity,
+ const struct entity_algo_table *lt,
+ unsigned int lt_len)
{
int i;
@@ -1017,26 +1049,27 @@ static int lookup_algorithm_identifier(int entity, const struct
for (i = 0; i < lt_len; i++) {
if ((lt[i].entity == entity)
- && (lt[i].compclass == compclass))
- return lt[i].algo;
+ && (lt[i].compclass == SNDCP_XID_DATA_COMPRESSION))
+ return lt[i].algo.dcomp;
}
- return -1;
+ return SNDCP_XID_INVALID_COMPRESSION;
}
/* Helper function for decode_comp_field(), decodes
* numeric pcomp/dcomp values */
static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field,
- const uint8_t *src, int compclass)
+ const uint8_t *src, enum gprs_sndcp_xid_param_types compclass)
{
int src_counter = 0;
int i;
if (comp_field->p) {
/* Determine the number of expected PCOMP/DCOMP values */
- if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
/* For protocol compression */
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
comp_field->comp_len = RFC1144_PCOMP_NUM;
break;
@@ -1052,9 +1085,10 @@ static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field,
default:
return -EINVAL;
}
- } else {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
/* For data compression */
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
comp_field->comp_len = V42BIS_DCOMP_NUM;
break;
@@ -1067,6 +1101,9 @@ static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field,
default:
return -EINVAL;
}
+ break;
+ default:
+ return -EINVAL;
}
for (i = 0; i < comp_field->comp_len; i++) {
@@ -1094,7 +1131,7 @@ static int decode_pcomp_params(struct gprs_sndcp_comp_field *comp_field,
{
int rc;
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
comp_field->rfc1144_params = talloc_zero(comp_field, struct
gprs_sndcp_pcomp_rfc1144_params);
@@ -1142,7 +1179,7 @@ static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field,
{
int rc;
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
comp_field->v42bis_params = talloc_zero(comp_field, struct
gprs_sndcp_dcomp_v42bis_params);
@@ -1180,7 +1217,8 @@ static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field,
static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field,
const uint8_t *src, unsigned int src_len,
const struct entity_algo_table *lt,
- unsigned int lt_len, int compclass)
+ unsigned int lt_len,
+ enum gprs_sndcp_xid_param_types compclass)
{
int src_counter = 0;
unsigned int len;
@@ -1205,15 +1243,34 @@ static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field,
/* Decode algorithm number (if present) */
if (comp_field->p) {
- comp_field->algo = (*src) & 0x1F;
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ comp_field->algo.pcomp = (*src) & 0x1F;
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ comp_field->algo.dcomp = (*src) & 0x1F;
+ break;
+ default:
+ return -EINVAL;
+ }
src_counter++;
src++;
}
/* Alternatively take the information from the lookup table */
- else
- comp_field->algo =
- lookup_algorithm_identifier(comp_field->entity, lt,
- lt_len, compclass);
+ else {
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ comp_field->algo.pcomp =
+ lookup_algorithm_identifier_pcomp(comp_field->entity, lt, lt_len);
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ comp_field->algo.dcomp =
+ lookup_algorithm_identifier_dcomp(comp_field->entity, lt, lt_len);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
/* Decode length field */
len = *src;
@@ -1368,7 +1425,7 @@ static int gprs_sndcp_fill_table(struct
{
struct gprs_sndcp_comp_field *comp_field;
int i = 0;
- int rc;
+ enum gprs_sndcp_xid_param_types compclass;
if (!comp_fields)
return -EINVAL;
@@ -1378,19 +1435,23 @@ static int gprs_sndcp_fill_table(struct
memset(lt, 0, sizeof(*lt));
llist_for_each_entry(comp_field, comp_fields, list) {
- if (comp_field->algo >= 0) {
- lt[i].entity = comp_field->entity;
- lt[i].algo = comp_field->algo;
- rc = gprs_sndcp_get_compression_class(comp_field);
-
- if (rc < 0) {
- memset(lt, 0, sizeof(*lt));
- return -EINVAL;
- }
-
- lt[i].compclass = rc;
- i++;
+ compclass = gprs_sndcp_get_compression_class(comp_field);
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ lt[i].algo.pcomp = comp_field->algo.pcomp;
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ lt[i].algo.dcomp = comp_field->algo.dcomp;
+ break;
+ case SNDCP_XID_INVALID_COMPRESSION:
+ continue;
+ default:
+ memset(lt, 0, sizeof(*lt));
+ return -EINVAL;
}
+ lt[i].compclass = compclass;
+ lt[i].entity = comp_field->entity;
+ i++;
}
return i;
@@ -1402,7 +1463,10 @@ static int complete_comp_field_params(struct gprs_sndcp_comp_field
*comp_field_dst, const struct
gprs_sndcp_comp_field *comp_field_src)
{
- if (comp_field_dst->algo < 0)
+ enum gprs_sndcp_xid_param_types compclass;
+
+ compclass = gprs_sndcp_get_compression_class(comp_field_dst);
+ if (compclass == SNDCP_XID_INVALID_COMPRESSION)
return -EINVAL;
if (comp_field_dst->rfc1144_params && comp_field_src->rfc1144_params) {
@@ -1626,7 +1690,7 @@ static void dump_pcomp_params(const struct gprs_sndcp_comp_field
{
int i;
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
if (comp_field->rfc1144_params == NULL) {
LOGP(DSNDCP, logl,
@@ -1726,7 +1790,7 @@ static void dump_dcomp_params(const struct gprs_sndcp_comp_field
{
int i;
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
if (comp_field->v42bis_params == NULL) {
LOGP(DSNDCP, logl,
@@ -1791,15 +1855,26 @@ void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields,
{
struct gprs_sndcp_comp_field *comp_field;
int i;
- int compclass;
+ enum gprs_sndcp_xid_param_types compclass;
OSMO_ASSERT(comp_fields);
llist_for_each_entry(comp_field, comp_fields, list) {
+ compclass = gprs_sndcp_get_compression_class(comp_field);
LOGP(DSNDCP, logl, "SNDCP-XID:\n");
LOGP(DSNDCP, logl, "struct gprs_sndcp_comp_field {\n");
LOGP(DSNDCP, logl, " entity=%d;\n", comp_field->entity);
- LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo);
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo.pcomp);
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo.dcomp);
+ break;
+ default:
+ LOGP(DSNDCP, logl, " algo invalid!\n");
+ break;
+ }
LOGP(DSNDCP, logl, " comp_len=%d;\n", comp_field->comp_len);
if (comp_field->comp_len == 0)
LOGP(DSNDCP, logl, " comp[] = NULL;\n");
@@ -1808,12 +1883,16 @@ void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields,
comp_field->comp[i]);
}
- compclass = gprs_sndcp_get_compression_class(comp_field);
-
- if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
dump_pcomp_params(comp_field, logl);
- } else if (compclass == SNDCP_XID_DATA_COMPRESSION) {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
dump_dcomp_params(comp_field, logl);
+ break;
+ default:
+ LOGP(DSNDCP, logl, " compression algorithm invalid!\n");
+ break;
}
LOGP(DSNDCP, logl, "}\n");
diff --git a/tests/sndcp_xid/sndcp_xid_test.c b/tests/sndcp_xid/sndcp_xid_test.c
index 5ed695c5e..56b97e336 100644
--- a/tests/sndcp_xid/sndcp_xid_test.c
+++ b/tests/sndcp_xid/sndcp_xid_test.c
@@ -106,7 +106,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup rfc1144 compression field */
rfc1144_comp_field.p = 1;
rfc1144_comp_field.entity = 0;
- rfc1144_comp_field.algo = RFC_1144;
+ rfc1144_comp_field.algo.pcomp = RFC_1144;
rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1;
rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2;
rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM;
@@ -126,7 +126,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup rfc2507 compression field */
rfc2507_comp_field.p = 1;
rfc2507_comp_field.entity = 1;
- rfc2507_comp_field.algo = RFC_2507;
+ rfc2507_comp_field.algo.pcomp = RFC_2507;
rfc2507_comp_field.comp[RFC2507_PCOMP1] = 3;
rfc2507_comp_field.comp[RFC2507_PCOMP2] = 4;
rfc2507_comp_field.comp[RFC2507_PCOMP3] = 5;
@@ -173,7 +173,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup ROHC compression field */
rohc_comp_field.p = 1;
rohc_comp_field.entity = 2;
- rohc_comp_field.algo = ROHC;
+ rohc_comp_field.algo.pcomp = ROHC;
rohc_comp_field.comp[ROHC_PCOMP1] = 8;
rohc_comp_field.comp[ROHC_PCOMP2] = 9;
rohc_comp_field.comp_len = ROHC_PCOMP_NUM;
@@ -191,7 +191,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup v42bis compression field */
v42bis_comp_field.p = 1;
v42bis_comp_field.entity = 3;
- v42bis_comp_field.algo = V42BIS;
+ v42bis_comp_field.algo.dcomp = V42BIS;
v42bis_comp_field.comp[V42BIS_DCOMP1] = 10;
v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM;
v42bis_comp_field.v42bis_params = &v42bis_params;
@@ -211,7 +211,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup v44 compression field */
v44_comp_field.p = 1;
v44_comp_field.entity = 3;
- v44_comp_field.algo = V44;
+ v44_comp_field.algo.dcomp = V44;
v44_comp_field.comp[V44_DCOMP1] = 10;
v44_comp_field.comp[V44_DCOMP2] = 11;
v44_comp_field.comp_len = V44_DCOMP_NUM;