diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-01-19 08:27:34 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-01-26 08:41:52 +0100 |
commit | 79af67d7c02a25e36146369b60f7f25c9655c862 (patch) | |
tree | 468c21be4858535fa99bad0714b05feae2475490 /openbsc/src | |
parent | 37184900e7f4f8566fbd71914f55b3cc8c0196e9 (diff) |
gprs: Add GPRS timer conversion functions
Currently, all GPRS timer values are hard-coded. To make these values
configurable in seconds and to show them, conversion functions from
and to seconds are needed.
This patch adds gprs_tmr_to_secs and gprs_secs_to_tmr_floor. Due to
the limited number of bits used to encode GPRS timer values, only a
few durations can be represented. gprs_secs_to_tmr_floor therefore
always returns the timer value that represents either the exact
number (if an exact representation exists) or the next lower number
for that an exact representation exists.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/gprs/gprs_utils.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/openbsc/src/gprs/gprs_utils.c b/openbsc/src/gprs/gprs_utils.c index 55bc629e8..2293f0254 100644 --- a/openbsc/src/gprs/gprs_utils.c +++ b/openbsc/src/gprs/gprs_utils.c @@ -20,6 +20,7 @@ * */ #include <openbsc/gprs_utils.h> +#include <openbsc/gsm_04_08_gprs.h> #include <osmocom/core/msgb.h> #include <osmocom/gprs/gprs_ns.h> @@ -172,6 +173,50 @@ int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str) return len; } +/* GSM 04.08, 10.5.7.3 GPRS Timer */ +int gprs_tmr_to_secs(uint8_t tmr) +{ + switch (tmr & GPRS_TMR_UNIT_MASK) { + case GPRS_TMR_2SECONDS: + return 2 * (tmr & GPRS_TMR_FACT_MASK); + default: + case GPRS_TMR_MINUTE: + return 60 * (tmr & GPRS_TMR_FACT_MASK); + case GPRS_TMR_6MINUTE: + return 360 * (tmr & GPRS_TMR_FACT_MASK); + case GPRS_TMR_DEACTIVATED: + return -1; + } +} + +/* This functions returns a tmr value such that + * - f is monotonic + * - f(s) <= s + * - f(s) == s if a tmr exists with s = gprs_tmr_to_secs(tmr) + * - the best possible resolution is used + * where + * f(s) = gprs_tmr_to_secs(gprs_secs_to_tmr_floor(s)) + */ +uint8_t gprs_secs_to_tmr_floor(int secs) +{ + if (secs < 0) + return GPRS_TMR_DEACTIVATED; + if (secs < 2 * 32) + return GPRS_TMR_2SECONDS | (secs / 2); + if (secs < 60 * 2) + /* Ensure monotonicity */ + return GPRS_TMR_2SECONDS | GPRS_TMR_FACT_MASK; + if (secs < 60 * 32) + return GPRS_TMR_MINUTE | (secs / 60); + if (secs < 360 * 6) + /* Ensure monotonicity */ + return GPRS_TMR_MINUTE | GPRS_TMR_FACT_MASK; + if (secs < 360 * 32) + return GPRS_TMR_6MINUTE | (secs / 360); + + return GPRS_TMR_6MINUTE | GPRS_TMR_FACT_MASK; +} + /* GSM 04.08, 10.5.1.4 */ int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len) { |