aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-01-19 08:27:34 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-01-26 08:41:52 +0100
commit79af67d7c02a25e36146369b60f7f25c9655c862 (patch)
tree468c21be4858535fa99bad0714b05feae2475490 /openbsc/src
parent37184900e7f4f8566fbd71914f55b3cc8c0196e9 (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.c45
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)
{