diff options
| author | Harald Welte <laforge@gnumonks.org> | 2019-05-03 21:01:13 +0200 | 
|---|---|---|
| committer | Harald Welte <laforge@gnumonks.org> | 2019-06-04 11:05:20 +0200 | 
| commit | ef7be49a3217827fd48e3a90899bfa475b1185ff (patch) | |
| tree | f1599b4a07cc45c4fd6c540cb4906ed487ed6d7f | |
| parent | 171ef826e1489031bc48745f29fa2d4657bf165f (diff) | |
gsm0808_utils: Add gsm0808_decode_cell_id_u()
This function parses a single Cell ID list element into a
'union gsm0808_cell_id_u'.  This function is going to be used
by the upcoming CBSP support.
Related: OS#3537
Change-Id: I08b33881667aa32f01e53ccb70d44d5b79c7c986
| -rw-r--r-- | include/osmocom/gsm/gsm0808_utils.h | 1 | ||||
| -rw-r--r-- | src/gsm/gsm0808_utils.c | 69 | ||||
| -rw-r--r-- | src/gsm/libosmogsm.map | 1 | 
3 files changed, 60 insertions, 11 deletions
| diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 9cfaea68..76db2b6d 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -94,6 +94,7 @@ void gsm0808_cell_id_from_cgi(struct gsm0808_cell_id *cid, enum CELL_IDENT id_di  			      const struct osmo_cell_global_id *cgi);  int gsm0808_cell_id_to_cgi(struct osmo_cell_global_id *cgi, const struct gsm0808_cell_id *cid);  void gsm0808_msgb_put_cell_id_u(struct msgb *msg, enum CELL_IDENT id_discr, const union gsm0808_cell_id_u *u); +int gsm0808_decode_cell_id_u(union gsm0808_cell_id_u *out, enum CELL_IDENT discr, const uint8_t *buf, unsigned int len);  uint8_t gsm0808_enc_cause(struct msgb *msg, uint16_t cause);  uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 70eed15e..afff59aa 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -193,6 +193,17 @@ int gsm0808_dec_osmux_cid(uint8_t *cid, const uint8_t *elem, uint8_t len)  #endif /* HAVE_SYS_SOCKET_H */ +/* Decode 5-byte LAI list element data (see TS 08.08 3.2.2.27) into MCC/MNC/LAC. */ +static void decode_lai(const uint8_t *data, struct osmo_location_area_id *decoded) +{ +	struct gsm48_loc_area_id lai; + +	/* Copy data to stack to prevent unaligned access in gsm48_decode_lai2(). */ +	memcpy(&lai, data, sizeof(lai)); /* don't byte swap yet */ + +	gsm48_decode_lai2(&lai, decoded); +} +  /* Helper function for gsm0808_enc_speech_codec()   * and gsm0808_enc_speech_codec_list() */  static uint8_t enc_speech_codec(struct msgb *msg, @@ -756,6 +767,53 @@ int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei,  	return (int)(elem - old_elem);  } +/*! Decode a single GSM 08.08 Cell ID list element payload + *  \param[out] out caller-provided output union + *  \param[in] discr Cell ID discriminator describing type to be decoded + *  \param[in] buf User-provided input buffer containing binary Cell ID list element + *  \param[in] len Length of buf + *  \returns 0 on success; negative on error */ +int gsm0808_decode_cell_id_u(union gsm0808_cell_id_u *out, enum CELL_IDENT discr, const uint8_t *buf, unsigned int len) +{ +	switch (discr) { +	case CELL_IDENT_WHOLE_GLOBAL: +		if (len < 7) +			return -EINVAL; +		decode_lai(buf, &out->global.lai); +		out->global.cell_identity = osmo_load16be(buf + sizeof(struct gsm48_loc_area_id)); +		break; +	case CELL_IDENT_LAC_AND_CI: +		if (len < 4) +			return -EINVAL; +		out->lac_and_ci.lac = osmo_load16be(buf); +		out->lac_and_ci.ci = osmo_load16be(buf + sizeof(uint16_t)); +		break; +	case CELL_IDENT_CI: +		if (len < 2) +			return -EINVAL; +		out->ci = osmo_load16be(buf); +		break; +	case CELL_IDENT_LAI_AND_LAC: +		if (len < 5) +			return -EINVAL; +		decode_lai(buf, &out->lai_and_lac); +		break; +	case CELL_IDENT_LAC: +		if (len < 2) +			return -EINVAL; +		out->lac = osmo_load16be(buf); +		break; +	case CELL_IDENT_BSS: +	case CELL_IDENT_NO_CELL: +		/* Does not have any list items */ +		break; +	default: +		/* Remaining cell identification types are not implemented. */ +		return -EINVAL; +	} +	return 0; +} +  void gsm0808_msgb_put_cell_id_u(struct msgb *msg, enum CELL_IDENT id_discr, const union gsm0808_cell_id_u *u)  {  	switch (id_discr) { @@ -865,17 +923,6 @@ uint8_t gsm0808_enc_cell_id_list(struct msgb *msg,  	return *tlv_len + 2;  } -/* Decode 5-byte LAI list element data (see TS 08.08 3.2.2.27) into MCC/MNC/LAC. */ -static void decode_lai(const uint8_t *data, struct osmo_location_area_id *decoded) -{ -	struct gsm48_loc_area_id lai; - -	/* Copy data to stack to prevent unaligned access in gsm48_decode_lai2(). */ -	memcpy(&lai, data, sizeof(lai)); /* don't byte swap yet */ - -	gsm48_decode_lai2(&lai, decoded); -} -  static int parse_cell_id_global_list(struct gsm0808_cell_id_list2 *cil, const uint8_t *data, size_t remain,  				     size_t *consumed)  { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index d49401d8..9aa9683a 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -244,6 +244,7 @@ gsm0808_lcls_status_names;  gsm0808_enc_lcls;  gsm0808_dec_lcls;  gsm0808_msgb_put_cell_id_u; +gsm0808_decode_cell_id_u;  gsm29118_msgb_alloc;  gsm29118_create_alert_req; | 
