blob: 95c0e50eccebf5fd38fa08f1793cdca317c14883 [file] [log] [blame]
Neels Hofmeyre25018b2017-11-27 21:29:33 +01001#pragma once
2
3#include <stdbool.h>
4
5struct vty;
6
7/* handover_cfg is an opaque struct to manage several levels of configuration. There is an overall handover
8 * config on 'network' level and a per-'bts' specific handover config. If the 'bts' level sets no values,
9 * the defaults from 'network' level are used implicitly, and changes take effect immediately. */
10struct handover_cfg;
11
12struct handover_cfg *ho_cfg_init(void *ctx, struct handover_cfg *higher_level_cfg);
13
14#define HO_CFG_STR_HANDOVER "Handover options\n"
15#define HO_CFG_STR_WIN HO_CFG_STR_HANDOVER "Measurement averaging settings\n"
16#define HO_CFG_STR_WIN_RXLEV HO_CFG_STR_WIN "Received-Level averaging\n"
17#define HO_CFG_STR_WIN_RXQUAL HO_CFG_STR_WIN "Received-Quality averaging\n"
18#define HO_CFG_STR_POWER_BUDGET HO_CFG_STR_HANDOVER "Neighbor cell power triggering\n" "Neighbor cell power triggering\n"
19#define HO_CFG_STR_AVG_COUNT "Number of values to average over\n"
20
21#define as_is(x) (x)
22
23static inline bool a2bool(const char *arg)
24{
25 return (bool)(atoi(arg));
26}
27
28static inline int bool2i(bool arg)
29{
30 return arg? 1 : 0;
31}
32
33
34/* The HO_CFG_ONE_MEMBER macro gets redefined, depending on whether to define struct members,
35 * function declarations or definitions... It is of the format
36 * HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL,
37 * VTY_CMD, VTY_CMD_ARG, VTY_ARG_EVAL,
38 * VTY_WRITE_FMT, VTY_WRITE_CONV,
39 * VTY_DOC)
40 * Then using HO_CFG_ALL_MEMBERS can save a lot of code dup in defining API declaration, API
41 * definitions, VTY commands and VTY write code. Of course this doesn't prevent us from adding manual
42 * members as well, in case future additions don't fit in this scheme.
43 *
44 * TYPE: a type name like int.
45 * NAME: a variable name suitable for a struct member.
46 * DEFAULT_VAL: default value, as passed to the VTY, e.g. '0' or 'foo', without quotes.
47 * VTY_CMD: a command string for VTY without any arguments.
48 * VTY_CMD_ARG: VTY value range like '<0-23>' or 'foo|bar', will become '(VTY_CMD_ARG|default)'.
49 * VTY_ARG_EVAL: function name for parsing the VTY arg[0], e.g. 'atoi'.
50 * VTY_WRITE_FMT: printf-like string format for vty_out().
51 * VTY_WRITE_CONV: function name to convert struct value to VTY_WRITE_FMT, e.g. 'as_is'.
52 * VTY_DOC: VTY documentation strings to match VTY_CMD and VTY_CMD_ARGs.
53 */
54#define HO_CFG_ALL_MEMBERS \
55 \
56 HO_CFG_ONE_MEMBER(bool, ho_active, 0, \
57 "handover", "0|1", a2bool, "%d", bool2i, \
58 HO_CFG_STR_HANDOVER \
59 "Disable in-call handover\n" \
60 "Enable in-call handover\n" \
61 "Enable/disable handover: ") \
62 \
63 HO_CFG_ONE_MEMBER(unsigned int, rxlev_avg_win, 10, \
64 "handover window rxlev averaging", "<1-10>", atoi, "%u", as_is, \
65 HO_CFG_STR_WIN_RXLEV \
66 "How many RxLev measurements are used for averaging\n" \
67 "RxLev averaging: " HO_CFG_STR_AVG_COUNT) \
68 \
69 HO_CFG_ONE_MEMBER(unsigned int, rxqual_avg_win, 1, \
70 "handover window rxqual averaging", "<1-10>", atoi, "%u", as_is, \
71 HO_CFG_STR_WIN_RXQUAL \
72 "How many RxQual measurements are used for averaging\n" \
73 "RxQual averaging: " HO_CFG_STR_AVG_COUNT) \
74 \
75 HO_CFG_ONE_MEMBER(unsigned int, rxlev_neigh_avg_win, 10, \
76 "handover window rxlev neighbor averaging", "<1-10>", atoi, "%u", as_is, \
77 HO_CFG_STR_WIN_RXLEV \
78 "How many Neighbor RxLev measurements are used for averaging\n" \
79 "How many Neighbor RxLev measurements are used for averaging\n" \
80 "Neighbor RxLev averaging: " HO_CFG_STR_AVG_COUNT) \
81 \
82 HO_CFG_ONE_MEMBER(unsigned int, pwr_interval, 6, \
83 "handover power budget interval", "<1-99>", atoi, "%u", as_is, \
84 HO_CFG_STR_POWER_BUDGET \
85 "How often to check for a better cell (SACCH frames)\n" \
86 "Check for stronger neighbor every N number of SACCH frames\n") \
87 \
88 HO_CFG_ONE_MEMBER(unsigned int, pwr_hysteresis, 3, \
89 "handover power budget hysteresis", "<0-999>", atoi, "%u", as_is, \
90 HO_CFG_STR_POWER_BUDGET \
91 "How many dBm stronger must a neighbor be to become a HO candidate\n" \
92 "Neighbor's strength difference in dBm\n") \
93 \
94 HO_CFG_ONE_MEMBER(unsigned int, max_distance, 9999, \
95 "handover maximum distance" , "<0-9999>", atoi, "%u", as_is, \
96 HO_CFG_STR_HANDOVER \
97 "Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \
98 "Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \
99 "Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n") \
100
101
102/* Declare public API for handover cfg parameters... */
103
104#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, VTY1, VTY2, VTY3, VTY4, VTY5, VTY6) \
105 TYPE ho_get_##NAME(struct handover_cfg *ho); \
106 void ho_set_##NAME(struct handover_cfg *ho, TYPE val); \
107 bool ho_isset_##NAME(struct handover_cfg *ho); \
108 void ho_clear_##NAME(struct handover_cfg *ho); \
109 bool ho_isset_on_parent_##NAME(struct handover_cfg *ho);
110
111HO_CFG_ALL_MEMBERS
112#undef HO_CFG_ONE_MEMBER