Add support for SMPP testing

As defined in [1], the different related actors are implemented in this
commit: ESME and SMSC.

SMSC: In Osmocom, the SMSC is currently implemented inside the NITB or
the MSC. A new Smsc abstract class is created to shared code between the
NITB and the MSC, and also makes it easier for later when the SMSC is
splitted. ESMEs can be dynamically added to its configuration in a
similar way to how the BTSs are added.

ESME: A new class Esme is created which can be used by tests to control
an ESME to interact with the SMSC. The ESME functionalities are
implemented using python-smpplib. Required version of this library is at
least 43cc6f819ec76b2c0a9d36d1d439308634716227, which contains support
for python 3 and some required features to poll the socket.

This commit already contains a few tests which checks different
features and tests the API. Extending tested features or scenarios can be
later done quite easily.

The tests are not enabled by default right now, because there are several
of them in a suite and the ip_address resources are not freed after every
tests which ends up in the suite failing due to missing reserved
resources. All the tests run alone work though. When the issue is fixed
they can then be added to the default list of tests to be run.

[1] http://opensmpp.org/specs/SMPP_v3_4_Issue1_2.pdf

Change-Id: I14ca3cb009d6d646a449ca99b0200da12085c0da
diff --git a/selftest/template_test.ok b/selftest/template_test.ok
index 1267dac..688361f 100644
--- a/selftest/template_test.ok
+++ b/selftest/template_test.ok
@@ -136,10 +136,13 @@
     phys_chan_config val_phys_chan_config_3
 smpp
  local-tcp-ip val_ip_address 2775
- system-id test
- policy closed
- esme test
-  password test
+ system-id test-nitb
+ policy val_smsc_policy
+ esme val_system_id_esme0
+  password val_password_esme0
+  default-route
+ esme val_system_id_esme1
+  no password
   default-route
 ctrl
  bind val_ip_address
diff --git a/selftest/template_test.py b/selftest/template_test.py
index 45347b6..f8c32a5 100755
--- a/selftest/template_test.py
+++ b/selftest/template_test.py
@@ -35,6 +35,11 @@
             )
 }
 
+mock_esme = {
+    'system_id': 'val_system_id',
+    'password': 'val_password'
+}
+
 def clone_mod(d, val_ext):
     c = dict(d)
     for name in c.keys():
@@ -47,6 +52,10 @@
 mock_bts0 = clone_mod(mock_bts, '_bts0')
 mock_bts1 = clone_mod(mock_bts, '_bts1')
 
+mock_esme0 = clone_mod(mock_esme, '_esme0')
+mock_esme1 = clone_mod(mock_esme, '_esme1')
+mock_esme1['password'] = ''
+
 vals = dict(nitb=dict(
                     net=dict(
                         mcc='val_mcc',
@@ -59,6 +68,10 @@
                     ),
                     ip_address=dict(addr='val_ip_address'),
             ),
+            smsc=dict(
+                policy='val_smsc_policy',
+                esme_list=(mock_esme0, mock_esme1)
+            ),
        )
 
 print(template.render('osmo-nitb.cfg', vals))
diff --git a/selftest/template_test/osmo-nitb.cfg.tmpl b/selftest/template_test/osmo-nitb.cfg.tmpl
index 3404b7f..7a76878 100644
--- a/selftest/template_test/osmo-nitb.cfg.tmpl
+++ b/selftest/template_test/osmo-nitb.cfg.tmpl
@@ -47,12 +47,18 @@
  timer t3119 0
  timer t3141 0
 smpp
- local-tcp-ip ${smpp_bind_ip} 2775
- system-id test
- policy closed
- esme test
-  password test
-  default-route
+ local-tcp-ip ${nitb.ip_address.addr} 2775
+ system-id test-nitb
+ policy ${smsc.policy}
+ %for esme in esme_list:
+  esme ${esme.system_id}
+ % if esme.password == '':
+   no password
+ % else:
+   password ${esme.password}
+ % endif
+   default-route
+ %endfor
 ctrl
  bind ${ctrl_bind_ip}
 %for bts in bts_list: