smpp: Move the coding/mode detection into a utils file

Make sure to not ever have issues with this code again, move the
utility code to a new file and create a basic testcase. The method
currently has 100% line and branch coverage. My initial patched
missed the smpp_utils.c file and I re-did the copying (and verifying
the branch coverage)
This commit is contained in:
Holger Hans Peter Freyther 2013-07-13 17:09:56 +02:00
parent 5ecbc93656
commit a7328a5642
13 changed files with 174 additions and 37 deletions

1
openbsc/.gitignore vendored
View File

@ -61,6 +61,7 @@ tests/timer/timer_test
tests/gprs/gprs_test
tests/abis/abis_test
tests/si/si_test
tests/smpp/smpp_test
tests/atconfig
tests/atlocal

View File

@ -44,12 +44,13 @@ AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
# Enable/disable smpp support in the nitb?
AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
[osmo_ac_build_smpp="$enableval"])
[osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"])
if test "$osmo_ac_build_smpp" = "yes" ; then
PKG_CHECK_MODULES(LIBSMPP34, libsmpp34 >= 1.10)
AC_DEFINE(BUILD_SMPP, 1, [Define if we want to build SMPP])
fi
AM_CONDITIONAL(BUILD_SMPP, test "x$osmo_ac_build_smpp" = "xyes")
AC_SUBST(osmo_ac_build_smpp)
found_libgtp=yes
@ -160,6 +161,7 @@ AC_OUTPUT(
tests/gprs/Makefile
tests/si/Makefile
tests/abis/Makefile
tests/smpp/Makefile
doc/Makefile
doc/examples/Makefile
Makefile)

View File

@ -19,5 +19,5 @@ libmsc_a_SOURCES = auth.c \
osmo_msc.c
if BUILD_SMPP
libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c
libmsc_a_SOURCES += smpp_smsc.c smpp_openbsc.c smpp_vty.c smpp_utils.c
endif

View File

@ -79,9 +79,6 @@ static struct tlv_t *find_tlv(struct tlv_t *head, uint16_t tag)
return NULL;
}
#define MODE_7BIT 7
#define MODE_8BIT 8
/*! \brief convert from submit_sm_t to gsm_sms */
static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
const struct submit_sm_t *submit)
@ -469,39 +466,8 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
/* Figure out SMPP DCS from TP-DCS */
dcs = sms->data_coding_scheme;
if ((dcs & 0xF0) == 0xF0) {
if (dcs & 0x04) {
/* bit 2 == 1: 8bit data */
deliver.data_coding = 0x02;
mode = MODE_8BIT;
} else {
/* bit 2 == 0: default alphabet */
deliver.data_coding = 0x01;
mode = MODE_7BIT;
}
} else if ((dcs & 0xE0) == 0) {
switch (dcs & 0xC) {
case 0:
deliver.data_coding = 0x01;
mode = MODE_7BIT;
break;
case 4:
deliver.data_coding = 0x02;
mode = MODE_8BIT;
break;
case 8:
deliver.data_coding = 0x08; /* UCS-2 */
mode = MODE_8BIT;
break;
default:
goto unknown_mo;
}
} else {
unknown_mo:
LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n",
dcs);
if (smpp_determine_scheme(dcs, &deliver.data_coding, &mode) == -1)
return -1;
}
/* Transparently pass on DCS via SMPP if requested */
if (esme->acl && esme->acl->dcs_transparent)

View File

@ -15,6 +15,9 @@
#define SMPP_SYS_ID_LEN 16
#define SMPP_PASSWD_LEN 16
#define MODE_7BIT 7
#define MODE_8BIT 8
enum esme_read_state {
READ_ST_IN_LEN = 0,
READ_ST_IN_MSG = 1,
@ -126,4 +129,6 @@ int smpp_route_pfx_del(struct osmo_smpp_acl *acl,
const struct osmo_smpp_addr *pfx);
int smpp_vty_init(void);
int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode);
#endif

View File

@ -0,0 +1,62 @@
/* (C) 2012-2013 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "smpp_smsc.h"
#include <openbsc/debug.h>
int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode)
{
if ((dcs & 0xF0) == 0xF0) {
if (dcs & 0x04) {
/* bit 2 == 1: 8bit data */
*data_coding = 0x02;
*mode = MODE_8BIT;
} else {
/* bit 2 == 0: default alphabet */
*data_coding = 0x01;
*mode = MODE_7BIT;
}
} else if ((dcs & 0xE0) == 0) {
switch (dcs & 0xC) {
case 0:
*data_coding = 0x01;
*mode = MODE_7BIT;
break;
case 4:
*data_coding = 0x02;
*mode = MODE_8BIT;
break;
case 8:
*data_coding = 0x08; /* UCS-2 */
*mode = MODE_8BIT;
break;
default:
goto unknown_mo;
}
} else {
unknown_mo:
LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", dcs);
return -1;
}
return 0;
}

View File

@ -4,6 +4,10 @@ if BUILD_NAT
SUBDIRS += bsc-nat
endif
if BUILD_SMPP
SUBDIRS += smpp
endif
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac

View File

@ -1 +1,2 @@
enable_nat_test='@osmo_ac_build_nat@'
enable_smpp_test='@osmo_ac_build_smpp@'

View File

@ -0,0 +1,12 @@
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/libmsc
AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS)
AM_LDFLAGS = $(COVERAGE_LDFLAGS)
EXTRA_DIST = smpp_test.ok smpp_test.err
noinst_PROGRAMS = smpp_test
smpp_test_SOURCES = smpp_test.c \
$(top_srcdir)/src/libmsc/smpp_utils.c
smpp_test_LDADD = $(LIBOSMOCORE_LIBS) \
$(top_srcdir)/src/libcommon/libcommon.a

View File

@ -0,0 +1,73 @@
/*
* (C) 2013 by Holger Hans Peter Freyther
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <openbsc/debug.h>
#include <osmocom/core/application.h>
#include <osmocom/core/backtrace.h>
#include "smpp_smsc.h"
struct coding_test {
uint8_t dcs;
uint8_t coding;
int mode;
int res;
};
static struct coding_test codecs[] = {
{ .dcs = 0xf6 , .coding = 0x02, .mode = MODE_8BIT, .res = 0 },
{ .dcs = 0xf2 , .coding = 0x01, .mode = MODE_7BIT, .res = 0 },
{ .dcs = 0x02 , .coding = 0x01, .mode = MODE_7BIT, .res = 0 },
{ .dcs = 0x06 , .coding = 0x02, .mode = MODE_8BIT, .res = 0 },
{ .dcs = 0x0A , .coding = 0x08, .mode = MODE_8BIT, .res = 0 },
{ .dcs = 0x0E , .coding = 0xFF, .mode = 0xFF, .res = -1 },
{ .dcs = 0xE0 , .coding = 0xFF, .mode = 0xFF, .res = -1 },
};
static void test_coding_scheme(void)
{
int i;
printf("Testing coding scheme support\n");
for (i = 0; i < ARRAY_SIZE(codecs); ++i) {
uint8_t coding;
int mode, res;
res = smpp_determine_scheme(codecs[i].dcs, &coding, &mode);
OSMO_ASSERT(res == codecs[i].res);
if (res != -1) {
OSMO_ASSERT(mode == codecs[i].mode);
OSMO_ASSERT(coding == codecs[i].coding);
}
}
}
int main(int argc, char **argv)
{
osmo_init_logging(&log_info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
test_coding_scheme();
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,2 @@
SMPP MO Unknown Data Coding 0x0e
SMPP MO Unknown Data Coding 0xe0

View File

@ -0,0 +1 @@
Testing coding scheme support

View File

@ -40,6 +40,14 @@ cat $abs_srcdir/bsc-nat/bsc_nat_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/bsc-nat/bsc_nat_test], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([smpp])
AT_KEYWORDS([smpp])
AT_CHECK([test "$enable_smpp_test" != no || exit 77])
cat $abs_srcdir/smpp/smpp_test.ok > expout
cat $abs_srcdir/smpp/smpp_test.err > experr
AT_CHECK([$abs_top_builddir/tests/smpp/smpp_test], [], [expout], [experr])
AT_CLEANUP
AT_SETUP([si])
AT_KEYWORDS([si])
cat $abs_srcdir/si/si_test.ok > expout