libosmogsm 1.9.0.196-9975
Osmocom GSM library
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_rangesosmo_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, entry, 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]dstWrite the resulting NRI value to this location.
[in]strDecimal "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_rangeTarget for parsed values.
[in]first_strDecimal or hex string, representing the first value in the range, or NULL if omitted.
[in]last_strDecimal 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]rangeNRI range to look for.
[in]nri_rangesList NRI ranges.
Returns
true iff any NRI value from 'range' appears anywhere in nri_ranges.

References osmo_nri_ranges::entries, 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_rangeNRI value range to validate.
[in]nri_bitlenValid 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_rangesList of talloc allocated struct osmo_nri_range entries to add the new range to.
[in]addNRI 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, entry, 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
ctxTalloc 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_rangesList of talloc allocated struct osmo_nri_range entries to remove values from.
[in]delNRI 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, entry, 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_rangesThe 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]bufTarget buffer.
[in]buflensizeof(buf).
[in]nri_rangesList 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, entry, 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]ctxTalloc context.
[in]nri_rangesList 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]messageReturned string constant to alert the user with, or NULL if all is well.
[out]added_rangeIf not NULL, write the range parsing result to this location.
[in]nri_rangesList NRI ranges to add to.
[in]argcArgument count.
[in]argvArgument list.
[in]nri_bitlenValid 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]messageReturned string constant to alert the user with, or NULL if all is well.
[out]removed_rangeIf not NULL, write the range parsing result to this location.
[in]nri_rangesList of NRI ranges to remove from.
[in]argcArgument count.
[in]argvArgument 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_vThe NRI value to limit, e.g. random bits or an increment counter value.
[in]nri_rangesList 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, 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_vNRI value to look for.
[in]nri_rangesList NRI ranges.
Returns
true iff nri_v appears anywhere in nri_ranges.

References osmo_nri_ranges::entries, 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_vNRI value to validate.
[in]nri_bitlenValid 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_vWrite 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]tmsiTMSI value containing NRI bits.
[in]nri_bitlenLength 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]tmsiTMSI value of which to modify the NRI bits, e.g. fresh randomized bits.
[in]nri_rangesList 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_bitlenValid 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]tmsiA base TMSI or p-TMSI to replace the NRI value in, result is written back to this location.
[in]nri_vThe NRI value to place in the tmsi.
[in]nri_bitlenLength 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().