sms: Proper decoding and storage of SMS validity period.
diff mbox

Message ID CABmJbFUtMyDshvv8g2XMiwy9aPMAmepXXMB8xocJEZjxUwqVtQ@mail.gmail.com
State Superseded
Headers show

Commit Message

Alexander Chemeris March 11, 2014, 9:44 p.m. UTC
I've updated the patch to rename gsm340_validity_period() to
gsm340_validity_period_2() and keep gsm340_validity_period() as a
deprecated broken implementation. This way we keep compatibility with
older OpenBSC versions without updating to a new libosmocore library.

Branch achemeris/sms-validity is updated accordingly.

Comments

Daniel Willmann March 12, 2014, 2:59 p.m. UTC | #1
Hello Alexander,

On Wed, 2014-03-12 at 01:44, Alexander Chemeris wrote:
> I've updated the patch to rename gsm340_validity_period() to
> gsm340_validity_period_2() and keep gsm340_validity_period() as a
> deprecated broken implementation. This way we keep compatibility with
> older OpenBSC versions without updating to a new libosmocore library.

looks all fine except for the function name. Something more expressive
would be nice - how about gsm340_validity_period_as_ts()?

Regards,
Daniel
Alexander Chemeris March 12, 2014, 3:53 p.m. UTC | #2
On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann <dwillmann@sysmocom.de> wrote:
> Hello Alexander,
>
> On Wed, 2014-03-12 at 01:44, Alexander Chemeris wrote:
>> I've updated the patch to rename gsm340_validity_period() to
>> gsm340_validity_period_2() and keep gsm340_validity_period() as a
>> deprecated broken implementation. This way we keep compatibility with
>> older OpenBSC versions without updating to a new libosmocore library.
>
> looks all fine except for the function name. Something more expressive
> would be nice - how about gsm340_validity_period_as_ts()?

I'm not sure "as_ts" is really more expressive,
gsm340_validity_period_unix_time() would be more expressive, but it's
also painfully long. I would suggest:
 - gsm340_validity_time()
 - gsm340_validity_period_decode()
 - leave as is
Alexander Chemeris March 12, 2014, 3:55 p.m. UTC | #3
On Wed, Mar 12, 2014 at 7:53 PM, Alexander Chemeris
<alexander.chemeris@gmail.com> wrote:
> On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann <dwillmann@sysmocom.de> wrote:
>> Hello Alexander,
>>
>> On Wed, 2014-03-12 at 01:44, Alexander Chemeris wrote:
>>> I've updated the patch to rename gsm340_validity_period() to
>>> gsm340_validity_period_2() and keep gsm340_validity_period() as a
>>> deprecated broken implementation. This way we keep compatibility with
>>> older OpenBSC versions without updating to a new libosmocore library.
>>
>> looks all fine except for the function name. Something more expressive
>> would be nice - how about gsm340_validity_period_as_ts()?
>
> I'm not sure "as_ts" is really more expressive,
> gsm340_validity_period_unix_time() would be more expressive, but it's
> also painfully long. I would suggest:
>  - gsm340_validity_time()
>  - gsm340_validity_period_decode()
>  - leave as is

 - gsm340_valid_until()
Daniel Willmann March 12, 2014, 4:02 p.m. UTC | #4
On Wed, 2014-03-12 at 19:53, Alexander Chemeris wrote:
> On Wed, Mar 12, 2014 at 6:59 PM, Daniel Willmann <dwillmann@sysmocom.de> wrote:
> > looks all fine except for the function name. Something more expressive
> > would be nice - how about gsm340_validity_period_as_ts()?
> 
> I'm not sure "as_ts" is really more expressive,

> gsm340_validity_period_unix_time() would be more expressive, but it's
> also painfully long. I would suggest:
>  - gsm340_validity_time()

I like that one.


Regards,

Patch
diff mbox

From c484e39073a239a3aaa806803dbe7b812c07bee3 Mon Sep 17 00:00:00 2001
From: Alexander Chemeris <Alexander.Chemeris@gmail.com>
Date: Tue, 26 Nov 2013 16:43:10 -0600
Subject: [PATCH 1/6] sms: Proper decoding and storage of SMS validity period.

- Use time_t instead of abstract minutes to store validity time to make sure we support all possible values.
- Return UNIX time from it to support both relative and absolute expire times.
- Pass a current time to gsm340_validity_period() to compute the absolute expire time if a relative time is specified. What time is "current" is to be decided by callers.
- We also introduce SMS_DEFAULT_VALIDITY_PERIOD macros to reduce number of magic values.
---
 include/osmocom/gsm/gsm0411_utils.h |   11 ++++-
 src/gsm/gsm0411_utils.c             |   91 +++++++++++++++++------------------
 src/gsm/libosmogsm.map              |    1 +
 3 files changed, 54 insertions(+), 49 deletions(-)

diff --git a/include/osmocom/gsm/gsm0411_utils.h b/include/osmocom/gsm/gsm0411_utils.h
index ad368e6..7506148 100644
--- a/include/osmocom/gsm/gsm0411_utils.h
+++ b/include/osmocom/gsm/gsm0411_utils.h
@@ -2,6 +2,10 @@ 
 #define _GSM0411_UTILS_H
 
 #include <time.h>
+#include <osmocom/core/defs.h>
+
+/* Default SMS validity period is 2 days */
+#define SMS_DEFAULT_VALIDITY_PERIOD	(2 * 24 * 60 * 60)
 
 /* Turn int into semi-octet representation: 98 => 0x89 */
 uint8_t gsm411_bcdify(uint8_t value);
@@ -17,8 +21,11 @@  void gsm340_gen_scts(uint8_t *scts, time_t time);
 /* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */
 time_t gsm340_scts(uint8_t *scts);
 
-/* decode validity period. return minutes */
-unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp);
+/* decode validity period. return absolute time */
+time_t gsm340_validity_period_2(time_t now, uint8_t sms_vpf, uint8_t *sms_vp);
+/* decode validity period. return relative minutes */
+unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp)
+	OSMO_DEPRECATED("Use gsm340_validity_period_2() instead.");
 
 /* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
 enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs);
diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c
index a8ba810..70779de 100644
--- a/src/gsm/gsm0411_utils.c
+++ b/src/gsm/gsm0411_utils.c
@@ -7,6 +7,7 @@ 
  * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
  * (C) 2010 by On-Waves
  * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2014 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
  *
  * All Rights Reserved
  *
@@ -34,6 +35,7 @@ 
 
 #include <osmocom/gsm/gsm48.h>
 #include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/gsm0411_utils.h>
 #include <osmocom/gsm/protocol/gsm_03_40.h>
 #include <osmocom/gsm/protocol/gsm_04_11.h>
 
@@ -120,21 +122,13 @@  time_t gsm340_scts(uint8_t *scts)
 	return mktime(&tm) - ofs;
 }
 
-/* Return the default validity period in minutes */
-static unsigned long gsm340_vp_default(void)
-{
-	unsigned long minutes;
-	/* Default validity: two days */
-	minutes = 24 * 60 * 2;
-	return minutes;
-}
-
-/* Decode validity period format 'relative' */
-static unsigned long gsm340_vp_relative(uint8_t *sms_vp)
+/* Decode validity period format 'relative'.
+ * Returns number of seconds relative to a current time. */
+static time_t gsm340_vp_relative(uint8_t *sms_vp)
 {
 	/* Chapter 9.2.3.12.1 */
 	uint8_t vp;
-	unsigned long minutes;
+	time_t minutes;
 
 	vp = *(sms_vp);
 	if (vp <= 143)
@@ -145,58 +139,53 @@  static unsigned long gsm340_vp_relative(uint8_t *sms_vp)
 		minutes = vp-166 * 60 * 24;
 	else
 		minutes = vp-192 * 60 * 24 * 7;
-	return minutes;
+
+	/* Convert to seconds */
+	return minutes * 60;
 }
 
-/* Decode validity period format 'absolute' */
-static unsigned long gsm340_vp_absolute(uint8_t *sms_vp)
+/* Decode validity period format 'absolute'.
+ * Returns UNIX time. */
+static time_t gsm340_vp_absolute(uint8_t *sms_vp)
 {
 	/* Chapter 9.2.3.12.2 */
-	time_t expires, now;
-	unsigned long minutes;
-
-	expires = gsm340_scts(sms_vp);
-	now = time(NULL);
-	if (expires <= now)
-		minutes = 0;
-	else
-		minutes = (expires-now)/60;
-	return minutes;
+	return gsm340_scts(sms_vp);
 }
 
-/* Decode validity period format 'relative in integer representation' */
-static unsigned long gsm340_vp_relative_integer(uint8_t *sms_vp)
+/* Decode validity period format 'relative in integer representation'.
+ * Returns number of seconds relative to a current time. */
+static time_t gsm340_vp_relative_integer(uint8_t *sms_vp)
 {
 	uint8_t vp;
-	unsigned long minutes;
 	vp = *(sms_vp);
 	if (vp == 0) {
 		LOGP(DLSMS, LOGL_ERROR,
 		     "reserved relative_integer validity period\n");
-		return gsm340_vp_default();
+#warning We should return an RP-Error here.
+		return SMS_DEFAULT_VALIDITY_PERIOD;
 	}
-	minutes = vp/60;
-	return minutes;
+	return vp;
 }
 
-/* Decode validity period format 'relative in semi-octet representation' */
-static unsigned long gsm340_vp_relative_semioctet(uint8_t *sms_vp)
+/* Decode validity period format 'relative in semi-octet representation'.
+ * Returns number of seconds relative to a current time. */
+static time_t gsm340_vp_relative_semioctet(uint8_t *sms_vp)
 {
-	unsigned long minutes;
-	minutes = gsm411_unbcdify(*sms_vp++)*60;  /* hours */
-	minutes += gsm411_unbcdify(*sms_vp++);    /* minutes */
-	minutes += gsm411_unbcdify(*sms_vp++)/60; /* seconds */
-	return minutes;
+	time_t hours, minutes, seconds;
+	hours   = gsm411_unbcdify(*sms_vp++); /* hours */
+	minutes = gsm411_unbcdify(*sms_vp++); /* minutes */
+	seconds = gsm411_unbcdify(*sms_vp++); /* seconds */
+	return hours*60*60 + minutes*60 + seconds;
 }
 
-/* decode validity period. return minutes */
-unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp)
+/* Decode validity period. Returns absolute UNIX time. */
+time_t gsm340_validity_period_2(time_t now, uint8_t sms_vpf, uint8_t *sms_vp)
 {
 	uint8_t fi; /* functionality indicator */
 
 	switch (sms_vpf) {
 	case GSM340_TP_VPF_RELATIVE:
-		return gsm340_vp_relative(sms_vp);
+		return now + gsm340_vp_relative(sms_vp);
 	case GSM340_TP_VPF_ABSOLUTE:
 		return gsm340_vp_absolute(sms_vp);
 	case GSM340_TP_VPF_ENHANCED:
@@ -207,26 +196,34 @@  unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp)
 		/* read validity period format */
 		switch (fi & 0x7) {
 		case 0x0:
-			return gsm340_vp_default(); /* no vpf specified */
+			return now + SMS_DEFAULT_VALIDITY_PERIOD; /* no vpf specified */
 		case 0x1:
-			return gsm340_vp_relative(sms_vp);
+			return now + gsm340_vp_relative(sms_vp);
 		case 0x2:
-			return gsm340_vp_relative_integer(sms_vp);
+			return now + gsm340_vp_relative_integer(sms_vp);
 		case 0x3:
-			return gsm340_vp_relative_semioctet(sms_vp);
+			return now + gsm340_vp_relative_semioctet(sms_vp);
 		default:
 			/* The GSM spec says that the SC should reject any
 			   unsupported and/or undefined values. FIXME */
 			LOGP(DLSMS, LOGL_ERROR,
 			     "Reserved enhanced validity period format\n");
-			return gsm340_vp_default();
+			return now + SMS_DEFAULT_VALIDITY_PERIOD;
 		}
 	case GSM340_TP_VPF_NONE:
 	default:
-		return gsm340_vp_default();
+		return now + SMS_DEFAULT_VALIDITY_PERIOD;
 	}
 }
 
+/* Decode validity period. return relative minutes.
+ * This behaviour is broken, but we're mimicing to it for compatibility. */
+unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp)
+{
+	time_t now = time(NULL);
+	return (gsm340_validity_period_2(now, sms_vpf, sms_vp) - now) / 60;
+}
+
 /* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
 enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs)
 {
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 9d15d66..25ee727 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -66,6 +66,7 @@  gsm340_gen_oa;
 gsm340_gen_scts;
 gsm340_scts;
 gsm340_validity_period;
+gsm340_validity_period_2;
 
 gsm411_bcdify;
 gsm411_msgb_alloc;
-- 
1.7.9.5