gsm23236.c File Reference

Utility function implementations related to 3GPP TS 23.236. More...

`#include <errno.h>`
`#include <stdlib.h>`
`#include <osmocom/core/utils.h>`
`#include <osmocom/gsm/gsm23236.h>`

## Functions

int | osmo_nri_v_validate (int16_t nri_v, uint8_t nri_bitlen)
| Validate that the given NRI is valid for a given nri_bitlen range. More...
static bool | nri_v_matches_range (const struct osmo_nri_range *range, int16_t nri_v)
| Match NRI value against a list NRI ranges. More...
static bool | nri_range_overlaps_range (const struct osmo_nri_range *a, const struct osmo_nri_range *b)
| Return true if the ranges overlap, i.e. More...
static bool | nri_range_touches (const struct osmo_nri_range *a, const struct osmo_nri_range *b)
| Return true if the ranges overlap or are directly adjacent to each other. More...
static void | nri_range_extend (struct osmo_nri_range *target, const struct osmo_nri_range *add)
| Grow target range to also span range 'add'. More...
bool | osmo_nri_v_matches_ranges (int16_t nri_v, const struct osmo_nri_ranges *nri_ranges)
| Return true when the given NRI value appears in the list of NRI ranges. More...
int | osmo_nri_v_limit_by_ranges (int16_t *nri_v, const struct osmo_nri_ranges *nri_ranges, uint32_t nri_bitlen)
| Modulo and shift the given NRI value so that it becomes a value present in a list of NRI ranges. More...
int | osmo_tmsi_nri_v_get (int16_t *nri_v, uint32_t tmsi, uint8_t nri_bitlen)
| Retrieve the Network Resource Indicator bits from a TMSI or p-TMSI. More...
int | osmo_tmsi_nri_v_set (uint32_t *tmsi, int16_t nri_v, uint8_t nri_bitlen)
| Write Network Resource Indicator bits into a TMSI or p-TMSI. More...
int | osmo_tmsi_nri_v_limit_by_ranges (uint32_t *tmsi, const struct osmo_nri_ranges *nri_ranges, uint8_t nri_bitlen)
| Apply osmo_nri_v_limit_by_ranges() in-place on the NRI value included in a TMSI. More...
int | osmo_nri_range_validate (const struct osmo_nri_range *range, uint8_t nri_bitlen)
| Validate that the given NRI range is valid for a given nri_bitlen range. More...
bool | osmo_nri_range_overlaps_ranges (const struct osmo_nri_range *range, const struct osmo_nri_ranges *nri_ranges)
| Return true when the given NRI range has at least one NRI value that appears in a list of other NRI ranges. More...
struct osmo_nri_ranges * | osmo_nri_ranges_alloc (void *ctx)
| Allocate an empty struct osmo_nri_ranges (list of struct osmo_nri_range). More...
void | osmo_nri_ranges_free (struct osmo_nri_ranges *nri_ranges)
| Free a struct osmo_nri_ranges. More...
static void | nri_ranges_add_entry_sorted (struct osmo_nri_ranges *nri_ranges, struct osmo_nri_range *add)
| Insert a new struct osmo_nri_range in an osmo_nri_ranges list, so that it remains sorted by 'first' values. More...
int | osmo_nri_ranges_add (struct osmo_nri_ranges *nri_ranges, const struct osmo_nri_range *add)
| Add a range of NRI values to a list of nri_range structs. More...
int | osmo_nri_ranges_del (struct osmo_nri_ranges *nri_ranges, const struct osmo_nri_range *del)
| Remove a range of NRI values from a list of nri_range structs. More...
int | osmo_nri_ranges_to_str_buf (char *buf, size_t buflen, const struct osmo_nri_ranges *nri_ranges)
| Compose a human readable representation of a list of NRI ranges in a buffer, like "23..42,123..142". More...
char * | osmo_nri_ranges_to_str_c (void *ctx, const struct osmo_nri_ranges *nri_ranges)
| Compose a human readable representation of a list of NRI ranges in a talloc buffer, like "23..42,123..142". More...
static int | osmo_nri_parse (int16_t *dst, const char *str)
| Parse a string to an NRI value, allowing both decimal and hexadecimal formats; useful for VTY config implementations. More...
static int | osmo_nri_parse_range (struct osmo_nri_range *nri_range, const char *first_str, const char *last_str)
| Parse string arguments to a struct osmo_nri_range; useful for VTY config implementations. More...
int | osmo_nri_ranges_vty_add (const char **message, struct osmo_nri_range *added_range, struct osmo_nri_ranges *nri_ranges, int argc, const char **argv, uint8_t nri_bitlen)
| VTY implementation for adding an NRI range to a list of ranges. More...
int | osmo_nri_ranges_vty_del (const char **message, struct osmo_nri_range *removed_range, struct osmo_nri_ranges *nri_ranges, int argc, const char **argv)
| VTY implementation for removing an NRI range from a list of ranges. More...

## Detailed Description

Utility function implementations related to 3GPP TS 23.236.

## Function Documentation

## nri_range_extend()

static void nri_range_extend | ( | struct osmo_nri_range * | target,
|  | const struct osmo_nri_range * | add
| ) |  |

static

Grow target range to also span range 'add'.

Only useful for touching ranges, since all values between the two ranges are also included.

References osmo_nri_range::first, osmo_nri_range::last, OSMO_MAX, and OSMO_MIN.

Referenced by osmo_nri_ranges_add().

## nri_range_overlaps_range()

static bool nri_range_overlaps_range | ( | const struct osmo_nri_range * | a,
|  | const struct osmo_nri_range * | b
| ) |  |

static

Return true if the ranges overlap, i.e.

one or more NRI values appear in both ranges.

References osmo_nri_range::first, osmo_nri_range::last, and nri_v_matches_range().

Referenced by nri_range_touches(), osmo_nri_range_overlaps_ranges(), and osmo_nri_ranges_del().

## nri_range_touches()

static bool nri_range_touches | ( | const struct osmo_nri_range * | a,
|  | const struct osmo_nri_range * | b
| ) |  |

static

Return true if the ranges overlap or are directly adjacent to each other.

References osmo_nri_range::first, osmo_nri_range::last, and nri_range_overlaps_range().

Referenced by osmo_nri_ranges_add().

## nri_ranges_add_entry_sorted()

static void nri_ranges_add_entry_sorted | ( | struct osmo_nri_ranges * | nri_ranges,
|  | struct osmo_nri_range * | add
| ) |  |

static

Insert a new struct osmo_nri_range in an osmo_nri_ranges list, so that it remains sorted by 'first' values.

References osmo_nri_ranges::entries, osmo_nri_range::entry, osmo_nri_range::first, llist_add(), llist_for_each_entry, OSMO_ASSERT, and llist_head::prev.

Referenced by osmo_nri_ranges_add().

## nri_v_matches_range()

static bool nri_v_matches_range | ( | const struct osmo_nri_range * | range,
|  | int16_t | nri_v
| ) |  |

static

Match NRI value against a list NRI ranges.

References osmo_nri_range::first, and osmo_nri_range::last.

Referenced by nri_range_overlaps_range(), osmo_nri_ranges_del(), and osmo_nri_v_matches_ranges().

## osmo_nri_parse()

static int osmo_nri_parse | ( | int16_t * | dst,
|  | const char * | str
| ) |  |

static

Parse a string to an NRI value, allowing both decimal and hexadecimal formats; useful for VTY config implementations.

Parameters

  [out] | dst | Write the resulting NRI value to this location.
  [in] | str | Decimal "511" or hex "0x1ff" string to parse.

Returns
  0 on success, negative on error.

References osmo_str_startswith(), and osmo_str_to_int().

Referenced by osmo_nri_parse_range().

## osmo_nri_parse_range()

static int osmo_nri_parse_range | ( | struct osmo_nri_range * | nri_range,
|  | const char * | first_str,
|  | const char * | last_str
| ) |  |

static

Parse string arguments to a struct osmo_nri_range; useful for VTY config implementations.

Validate and parse 'first' and optional 'last' string arguments into struct osmo_nri_range values. The strings may be in decimal format ("511") or hexadecimal with leading "0x" ("0x1ff"). If only one of 'first'/'last' is provided, the resulting range will have only that value (first == last).

Parameters

  [out] | nri_range | Target for parsed values.
  [in] | first_str | Decimal or hex string, representing the first value in the range, or NULL if omitted.
  [in] | last_str | Decimal or hex string, representing the last value in the range, or NULL if omitted.

Returns
  0 on success, negative on error.

References osmo_nri_range::first, osmo_nri_range::last, and osmo_nri_parse().

Referenced by osmo_nri_ranges_vty_add(), and osmo_nri_ranges_vty_del().

## osmo_nri_range_overlaps_ranges()

bool osmo_nri_range_overlaps_ranges | ( | const struct osmo_nri_range * | range,
|  | const struct osmo_nri_ranges * | nri_ranges
| ) |  |

Return true when the given NRI range has at least one NRI value that appears in a list of other NRI ranges.

Parameters

  [in] | range | NRI range to look for.
  [in] | nri_ranges | List NRI ranges.

Returns
  true iff any NRI value from 'range' appears anywhere in nri_ranges.

References osmo_nri_ranges::entries, osmo_nri_range::entry, llist_for_each_entry, and nri_range_overlaps_range().

## osmo_nri_range_validate()

int osmo_nri_range_validate | ( | const struct osmo_nri_range * | range,
|  | uint8_t | nri_bitlen
| ) |  |

Validate that the given NRI range is valid for a given nri_bitlen range.

Parameters

  [in] | nri_range | NRI value range to validate.
  [in] | nri_bitlen | Valid NRI range in nr of bits used. If nri_bitlen > OSMO_NRI_BITLEN_MAX, the NRI range is only validated to be first <= last and non-negative, not checked to fit a bit length range,

Returns
  0 if valid, -1 or 1 if range->first is invalid, -2 or 2 if range->last is invalid, -3 if first > last.

References osmo_nri_range::first, osmo_nri_range::last, and osmo_nri_v_validate().

Referenced by osmo_nri_ranges_add(), osmo_nri_ranges_del(), osmo_nri_ranges_vty_add(), and osmo_nri_v_limit_by_ranges().

## osmo_nri_ranges_add()

int osmo_nri_ranges_add | ( | struct osmo_nri_ranges * | nri_ranges,
|  | const struct osmo_nri_range * | add
| ) |  |

Add a range of NRI values to a list of nri_range structs.

Intelligently add and/or combine the entries in a list of NRI ranges to also include the NRI range given in 'add'. The list remains sorted by 'first' values.

Parameters

  [in,out] | nri_ranges | List of talloc allocated struct osmo_nri_range entries to add the new range to.
  [in] | add | NRI range to add to 'nri_ranges'.

Returns
  0 on success, negative on error (if the range in 'add' is invalid).

References osmo_nri_ranges::entries, osmo_nri_range::entry, llist_del(), llist_for_each_entry, llist_for_each_entry_safe, nri_range_extend(), nri_range_touches(), nri_ranges_add_entry_sorted(), OSMO_ASSERT, and osmo_nri_range_validate().

Referenced by osmo_nri_ranges_vty_add().

## osmo_nri_ranges_alloc()

struct osmo_nri_ranges* osmo_nri_ranges_alloc | ( | void * | ctx | ) |

Allocate an empty struct osmo_nri_ranges (list of struct osmo_nri_range).

Parameters

  ctx | Talloc context to allocate from.

Returns
  allocated empty list.

References osmo_nri_ranges::entries, INIT_LLIST_HEAD, and OSMO_ASSERT.

## osmo_nri_ranges_del()

int osmo_nri_ranges_del | ( | struct osmo_nri_ranges * | nri_ranges,
|  | const struct osmo_nri_range * | del
| ) |  |

Remove a range of NRI values from a list of nri_range structs.

Intelligently drop and/or cut or split the entries in a list of NRI ranges to no longer include the NRI range given in 'del'. Note that after this, the list may have more entries than before, if a range was split into two smaller ranges.

Parameters

  [in,out] | nri_ranges | List of talloc allocated struct osmo_nri_range entries to remove values from.
  [in] | del | NRI range to remove from 'nri_ranges'.

Returns
  0 on success, negative on error (if the range in 'del' is invalid).

References osmo_nri_ranges::entries, osmo_nri_range::entry, osmo_nri_range::first, osmo_nri_range::last, llist_add(), llist_del(), llist_for_each_entry_safe, nri_range_overlaps_range(), nri_v_matches_range(), OSMO_ASSERT, and osmo_nri_range_validate().

Referenced by osmo_nri_ranges_vty_del().

## osmo_nri_ranges_free()

void osmo_nri_ranges_free | ( | struct osmo_nri_ranges * | nri_ranges | ) |

Free a struct osmo_nri_ranges.

Parameters

  nri_ranges | The list to discard.

## osmo_nri_ranges_to_str_buf()

int osmo_nri_ranges_to_str_buf | ( | char * | buf,
|  | size_t | buflen,
|  | const struct osmo_nri_ranges * | nri_ranges
| ) |  |

Compose a human readable representation of a list of NRI ranges in a buffer, like "23..42,123..142".

Parameters

  [out] | buf | Target buffer.
  [in] | buflen | sizeof(buf).
  [in] | nri_ranges | List NRI ranges.

Returns
  strlen() of string that would be written if the buffer is large enough, like snprintf().

References osmo_strbuf::buf, osmo_strbuf::chars_needed, osmo_nri_ranges::entries, osmo_nri_range::first, osmo_nri_range::last, llist_empty(), llist_for_each_entry, and OSMO_STRBUF_PRINTF.

Referenced by osmo_nri_ranges_to_str_c().

## osmo_nri_ranges_to_str_c()

char* osmo_nri_ranges_to_str_c | ( | void * | ctx,
|  | const struct osmo_nri_ranges * | nri_ranges
| ) |  |

Compose a human readable representation of a list of NRI ranges in a talloc buffer, like "23..42,123..142".

Parameters

  [in] | ctx | Talloc context.
  [in] | nri_ranges | List of NRI ranges.

Returns
  a talloc allocated string.

References OSMO_NAME_C_IMPL, and osmo_nri_ranges_to_str_buf().

## osmo_nri_ranges_vty_add()

int osmo_nri_ranges_vty_add | ( | const char ** | message,
|  | struct osmo_nri_range * | added_range,
|  | struct osmo_nri_ranges * | nri_ranges,
|  | int | argc,
|  | const char ** | argv,
|  | uint8_t | nri_bitlen
| ) |  |

VTY implementation for adding an NRI range to a list of ranges.

Parse one or, if present, two argv arguments, which must be numbers representing the first and last value to add to the list of NRI ranges, in decimal format ("511") or hexadecimal with leading "0x" ("0x1ff"). If the range values surpass the nri_bitlen, return a warning in 'message', but still add the values to the list.

Parameters

  [out] | message | Returned string constant to alert the user with, or NULL if all is well.
  [out] | added_range | If not NULL, write the range parsing result to this location.
  [in] | nri_ranges | List NRI ranges to add to.
  [in] | argc | Argument count.
  [in] | argv | Argument list.
  [in] | nri_bitlen | Valid NRI range in nr of bits used.

Returns
  0 on success, -1 on error, 1 for a warning (if adding was successful but the added range surpasses nri_bitlen).

References argc, argv, OSMO_NRI_BITLEN_MAX, osmo_nri_parse_range(), osmo_nri_range_validate(), and osmo_nri_ranges_add().

## osmo_nri_ranges_vty_del()

int osmo_nri_ranges_vty_del | ( | const char ** | message,
|  | struct osmo_nri_range * | removed_range,
|  | struct osmo_nri_ranges * | nri_ranges,
|  | int | argc,
|  | const char ** | argv
| ) |  |

VTY implementation for removing an NRI range from a list of ranges.

Parse one or, if present, two argv arguments, which must be numbers representing the first and last value to remove from the list of NRI ranges, in decimal format ("511") or hexadecimal with leading "0x" ("0x1ff").

Parameters

  [out] | message | Returned string constant to alert the user with, or NULL if all is well.
  [out] | removed_range | If not NULL, write the range parsing result to this location.
  [in] | nri_ranges | List of NRI ranges to remove from.
  [in] | argc | Argument count.
  [in] | argv | Argument list.

Returns
  0 on success, -1 on error, 1 for a warning.

References argc, argv, osmo_nri_parse_range(), and osmo_nri_ranges_del().

## osmo_nri_v_limit_by_ranges()

int osmo_nri_v_limit_by_ranges | ( | int16_t * | nri_v,
|  | const struct osmo_nri_ranges * | nri_ranges,
|  | uint32_t | nri_bitlen
| ) |  |

Modulo and shift the given NRI value so that it becomes a value present in a list of NRI ranges.

Only range values within nri_bitlen are used.

Parameters

  [in,out] | nri_v | The NRI value to limit, e.g. random bits or an increment counter value.
  [in] | nri_ranges | List of NRI ranges indicating valid NRI values, where no entries may overlap in range values, and all entries must be valid (first <= last).

Returns
  0 on success, negative on error.

References osmo_nri_ranges::entries, osmo_nri_range::entry, osmo_nri_range::first, osmo_nri_range::last, len, llist_for_each_entry, OSMO_MIN, and osmo_nri_range_validate().

Referenced by osmo_tmsi_nri_v_limit_by_ranges().

## osmo_nri_v_matches_ranges()

bool osmo_nri_v_matches_ranges | ( | int16_t | nri_v,
|  | const struct osmo_nri_ranges * | nri_ranges
| ) |  |

Return true when the given NRI value appears in the list of NRI ranges.

Parameters

  [in] | nri_v | NRI value to look for.
  [in] | nri_ranges | List NRI ranges.

Returns
  true iff nri_v appears anywhere in nri_ranges.

References osmo_nri_ranges::entries, osmo_nri_range::entry, llist_for_each_entry, and nri_v_matches_range().

## osmo_nri_v_validate()

int osmo_nri_v_validate | ( | int16_t | nri_v,
|  | uint8_t | nri_bitlen
| ) |  |

Validate that the given NRI is valid for a given nri_bitlen range.

Parameters

  [in] | nri_v | NRI value to validate.
  [in] | nri_bitlen | Valid NRI range in nr of bits used; if nri_bitlen > OSMO_NRI_BITLEN_MAX, nri_v is only checked to not be marked invalid.

Returns
  0 if valid, <0 if the NRI is <0, >0 if the NRI surpasses the range.

References OSMO_NRI_BITLEN_MAX, and OSMO_NRI_BITLEN_MIN.

Referenced by osmo_nri_range_validate().

## osmo_tmsi_nri_v_get()

int osmo_tmsi_nri_v_get | ( | int16_t * | nri_v,
|  | uint32_t | tmsi,
|  | uint8_t | nri_bitlen
| ) |  |

Retrieve the Network Resource Indicator bits from a TMSI or p-TMSI.

Useful for MSC pooling as described by 3GPP TS 23.236.

Parameters

  [out] | nri_v | Write the extracted NRI value to this location (if non-NULL). If 0 is returned, it is guaranteed that nri_v >= 0. On non-zero return code, nri_v == -1.
  [in] | tmsi | TMSI value containing NRI bits.
  [in] | nri_bitlen | Length of the NRI value in number of bits, OSMO_NRI_BITLEN_MIN <= nri_bitlen <= * OSMO_NRI_BITLEN_MAX.

Returns
  0 on success, negative on error (i.e. if nri_bitlen is not in the valid range).

References OSMO_NRI_BITLEN_MAX.

Referenced by osmo_tmsi_nri_v_limit_by_ranges().

## osmo_tmsi_nri_v_limit_by_ranges()

int osmo_tmsi_nri_v_limit_by_ranges | ( | uint32_t * | tmsi,
|  | const struct osmo_nri_ranges * | nri_ranges,
|  | uint8_t | nri_bitlen
| ) |  |

Apply osmo_nri_v_limit_by_ranges() in-place on the NRI value included in a TMSI.

Extract the NRI value from the TMSI, limit that to be part of the ranges given in 'nri_ranges', and place the resulting NRI value back in the TMSI.

Parameters

  [in,out] | tmsi | TMSI value of which to modify the NRI bits, e.g. fresh randomized bits.
  [in] | nri_ranges | List of NRI ranges indicating valid NRI values, where no entries may overlap in range values, and all entries must be valid (first <= last).
  [in] | nri_bitlen | Valid NRI range in nr of bits used.

Returns
  0 on success, negative on error.

References osmo_nri_v_limit_by_ranges(), osmo_tmsi_nri_v_get(), and osmo_tmsi_nri_v_set().

## osmo_tmsi_nri_v_set()

int osmo_tmsi_nri_v_set | ( | uint32_t * | tmsi,
|  | int16_t | nri_v,
|  | uint8_t | nri_bitlen
| ) |  |

Write Network Resource Indicator bits into a TMSI or p-TMSI.

Overwrite the NRI bits with a given NRI value in a TMSI or p-TMSI. Useful for MSC pooling as described by 3GPP TS 23.236.

Parameters

  [in,out] | tmsi | A base TMSI or p-TMSI to replace the NRI value in, result is written back to this location.
  [in] | nri_v | The NRI value to place in the tmsi.
  [in] | nri_bitlen | Length of the NRI value in number of bits, OSMO_NRI_BITLEN_MIN <= nri_bitlen <= * OSMO_NRI_BITLEN_MAX.

Returns
  0 on success, negative on error (i.e. if nri_bitlen is not in the valid range or if tmsi is NULL).

References OSMO_NRI_BITLEN_MAX.

Referenced by osmo_tmsi_nri_v_limit_by_ranges().