mirror of https://gerrit.osmocom.org/libosmocore
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.
This commit is contained in:
parent
e47523874d
commit
e6475447bf
|
@ -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_time(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_time() instead.");
|
||||
|
||||
/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
|
||||
enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs);
|
||||
|
|
|
@ -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_time(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_time(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)
|
||||
{
|
||||
|
|
|
@ -66,6 +66,7 @@ gsm340_gen_oa;
|
|||
gsm340_gen_scts;
|
||||
gsm340_scts;
|
||||
gsm340_validity_period;
|
||||
gsm340_validity_time;
|
||||
|
||||
gsm411_bcdify;
|
||||
gsm411_msgb_alloc;
|
||||
|
|
Loading…
Reference in New Issue