diff options
| author | Max <msuraev@sysmocom.de> | 2017-01-02 14:10:30 +0100 | 
|---|---|---|
| committer | Max <msuraev@sysmocom.de> | 2017-01-06 10:21:11 +0000 | 
| commit | dbd3a92f70325b7a02d0a637929732f297fb2612 (patch) | |
| tree | b89e89d4bf066323a010a7ee5415ca6cc25e74ef /src | |
| parent | 0bee65c0d89f81a4b90aa3d484016d9ba680dd46 (diff) | |
Add parsed TLV helpers from OsmoBTS
Add functions to copy and merge parsed TLV structures from OsmoBTS.
Change-Id: Ieaaaed19da9c069fe451faa53d24c5b84d7d5615
Diffstat (limited to 'src')
| -rw-r--r-- | src/gsm/libosmogsm.map | 2 | ||||
| -rw-r--r-- | src/gsm/tlv_parser.c | 60 | 
2 files changed, 62 insertions, 0 deletions
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 199d05af..b84f859f 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -324,6 +324,8 @@ tlv_parse_one;  tvlv_att_def;  vtvlv_gan_att_def; +osmo_tlvp_copy; +osmo_tlvp_merge;  osmo_shift_v_fixed;  osmo_match_shift_tv_fixed;  osmo_shift_tlv; diff --git a/src/gsm/tlv_parser.c b/src/gsm/tlv_parser.c index e84edd97..4cc43f67 100644 --- a/src/gsm/tlv_parser.c +++ b/src/gsm/tlv_parser.c @@ -19,6 +19,7 @@  #include <stdio.h>  #include <stdint.h> +#include <errno.h>  #include <osmocom/core/utils.h>  #include <osmocom/gsm/tlv.h> @@ -43,6 +44,65 @@ int tlv_dump(struct tlv_parsed *dec)  	return 0;  } +/*! \brief Copy \ref tlv_parsed using given talloc context + *  \param[in] tp_orig Parsed TLV structure + *  \param[in] ctx Talloc context for allocations + *  \returns NULL on errors, \ref tlv_parsed pointer otherwise + */ +struct tlv_parsed *osmo_tlvp_copy(const struct tlv_parsed *tp_orig, void *ctx) +{ +	struct tlv_parsed *tp_out; +	size_t i, len; + +	tp_out = talloc_zero(ctx, struct tlv_parsed); +	if (!tp_out) +		return NULL; + +	/* if the original is NULL, return empty tlvp */ +	if (!tp_orig) +		return tp_out; + +	for (i = 0; i < ARRAY_SIZE(tp_orig->lv); i++) { +		len = tp_orig->lv[i].len; +		tp_out->lv[i].len = len; +		if (len && tp_out->lv[i].val) { +			tp_out->lv[i].val = talloc_zero_size(tp_out, len); +			if (!tp_out->lv[i].val) { +				talloc_free(tp_out); +				return NULL; +			} +			memcpy((uint8_t *)tp_out->lv[i].val, tp_orig->lv[i].val, +			       len); +		} +	} + +	return tp_out; +} + +/*! \brief Merge all \ref tlv_parsed attributes of 'src' into 'dst' + *  \param[in] dst Parsed TLV structure to merge into + *  \param[in] src Parsed TLV structure to merge from + *  \returns 0 on success, negative on error + */ +int osmo_tlvp_merge(struct tlv_parsed *dst, const struct tlv_parsed *src) +{ +	size_t i, len; +	for (i = 0; i < ARRAY_SIZE(dst->lv); i++) { +		len = src->lv[i].len; +		if (len == 0 || src->lv[i].val == NULL) +			continue; +		if (dst->lv[i].val) { +			talloc_free((uint8_t *) dst->lv[i].val); +			dst->lv[i].len = 0; +		} +		dst->lv[i].val = talloc_zero_size(dst, len); +		if (!dst->lv[i].val) +			return -ENOMEM; +		memcpy((uint8_t *) dst->lv[i].val, src->lv[i].val, len); +	} +	return 0; +} +  /*! \brief Parse a single TLV encoded IE   *  \param[out] o_tag the tag of the IE that was found   *  \param[out] o_len length of the IE that was found  | 
