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
diff --git a/openbsc/include/openbsc/gprs_utils.h b/openbsc/include/openbsc/gprs_utils.h
index 60b55a1..6880e05 100644
--- a/openbsc/include/openbsc/gprs_utils.h
+++ b/openbsc/include/openbsc/gprs_utils.h
@@ -31,6 +31,11 @@
 			    size_t old_size, size_t new_size);
 char *gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars);
 int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str);
+
+/* GSM 04.08, 10.5.7.3 GPRS Timer */
+int gprs_tmr_to_secs(uint8_t tmr);
+uint8_t gprs_secs_to_tmr_floor(int secs);
+
 int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len);
 int gprs_is_mi_imsi(const uint8_t *value, size_t value_len);
 int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi);
diff --git a/openbsc/include/openbsc/gsm_04_08_gprs.h b/openbsc/include/openbsc/gsm_04_08_gprs.h
index fb30dff..3eec983 100644
--- a/openbsc/include/openbsc/gsm_04_08_gprs.h
+++ b/openbsc/include/openbsc/gsm_04_08_gprs.h
@@ -116,9 +116,12 @@
 	GPRS_TMR_2SECONDS	= 0 << 5,
 	GPRS_TMR_MINUTE		= 1 << 5,
 	GPRS_TMR_6MINUTE	= 2 << 5,
-	GPRS_TMR_DEACTIVATED	= 3 << 5,
+	GPRS_TMR_DEACTIVATED	= 7 << 5,
 };
 
+#define GPRS_TMR_UNIT_MASK (7 << 5)
+#define GPRS_TMR_FACT_MASK ((1 << 5)-1)
+
 /* Chapter 9.4.2 / Table 9.4.2 */
 struct gsm48_attach_ack {
 	uint8_t att_result:4,	/* 10.5.5.7 */