Neels Hofmeyr | 7dde1f4 | 2020-05-11 19:43:20 +0200 | [diff] [blame] | 1 | /*! \file gsm23236.h |
| 2 | * API to handle Network Resource Indicator (NRI) values and ranges for MSC pooling, as in 3GPP TS 23.236. |
| 3 | */ |
| 4 | |
| 5 | #pragma once |
| 6 | |
| 7 | #include <stdint.h> |
| 8 | #include <stdbool.h> |
| 9 | |
| 10 | #include <osmocom/core/linuxlist.h> |
| 11 | |
| 12 | #define OSMO_NRI_BITLEN_MIN 1 |
| 13 | #define OSMO_NRI_BITLEN_MAX 15 |
| 14 | #define OSMO_NRI_BITLEN_DEFAULT 10 |
| 15 | |
| 16 | /*! One range of NRI values. An NRI is a Network Resource Indicator, a number of a configured bit length (typically 10 |
| 17 | * bit). In an MSC pool for load balancing, it is used to indicate which MSC has issued a TMSI: the NRI is located with |
| 18 | * its most significant bit located on the TMSI's second octet's most significant bit. See 3GPP TS 23.236. */ |
| 19 | struct osmo_nri_range { |
| 20 | struct llist_head entry; |
| 21 | |
| 22 | /*! First value of the NRI range, i.e. inclusive. */ |
| 23 | int16_t first; |
| 24 | /*! Last value of the NRI range, i.e. inclusive. */ |
| 25 | int16_t last; |
| 26 | }; |
| 27 | |
| 28 | /*! A list of struct osmo_nri_range. Use osmo_nri_ranges_alloc() to create, and osmo_nri_ranges_free() (or talloc_free() |
| 29 | * on the parent context) to destroy. Always use osmo_nri_ranges_add() to insert entries, to ensure that the list |
| 30 | * remains sorted by 'first' values, which some of the osmo_nri_ranges API assumes to always be true. |
| 31 | * |
| 32 | * This struct serves as talloc context for the osmo_nri_range entries in the list, simplifying function signatures. It |
| 33 | * also makes the API future proof, to easily accomodate possible future additions. |
| 34 | */ |
| 35 | struct osmo_nri_ranges { |
| 36 | /* List of struct osmo_nri_range entries, talloc allocated from the parent struct osmo_nri_ranges. */ |
| 37 | struct llist_head entries; |
| 38 | }; |
| 39 | |
| 40 | int osmo_nri_v_validate(int16_t nri_v, uint8_t nri_bitlen); |
| 41 | bool osmo_nri_v_matches_ranges(int16_t nri_v, const struct osmo_nri_ranges *nri_ranges); |
| 42 | int osmo_nri_v_limit_by_ranges(int16_t *nri_v, const struct osmo_nri_ranges *nri_ranges, uint32_t nri_bitlen); |
| 43 | |
| 44 | int osmo_tmsi_nri_v_get(int16_t *nri_v, uint32_t tmsi, uint8_t nri_bitlen); |
| 45 | int osmo_tmsi_nri_v_set(uint32_t *tmsi, int16_t nri_v, uint8_t nri_bitlen); |
| 46 | int osmo_tmsi_nri_v_limit_by_ranges(uint32_t *tmsi, const struct osmo_nri_ranges *nri_ranges, uint8_t nri_bitlen); |
| 47 | |
| 48 | int osmo_nri_range_validate(const struct osmo_nri_range *range, uint8_t nri_bitlen); |
| 49 | bool osmo_nri_range_overlaps_ranges(const struct osmo_nri_range *range, const struct osmo_nri_ranges *nri_ranges); |
| 50 | |
| 51 | struct osmo_nri_ranges *osmo_nri_ranges_alloc(void *ctx); |
| 52 | void osmo_nri_ranges_free(struct osmo_nri_ranges *nri_ranges); |
| 53 | int osmo_nri_ranges_add(struct osmo_nri_ranges *nri_ranges, const struct osmo_nri_range *add); |
| 54 | int osmo_nri_ranges_del(struct osmo_nri_ranges *nri_ranges, const struct osmo_nri_range *del); |
| 55 | int osmo_nri_ranges_vty_add(const char **message, struct osmo_nri_range *added_range, |
| 56 | struct osmo_nri_ranges *nri_ranges, int argc, const char **argv, uint8_t nri_bitlen); |
| 57 | int osmo_nri_ranges_vty_del(const char **message, struct osmo_nri_range *removed_range, |
| 58 | struct osmo_nri_ranges *nri_ranges, int argc, const char **argv); |
| 59 | int osmo_nri_ranges_to_str_buf(char *buf, size_t buflen, const struct osmo_nri_ranges *nri_ranges); |
| 60 | char *osmo_nri_ranges_to_str_c(void *ctx, const struct osmo_nri_ranges *nri_ranges); |