blob: 502fa6e713f007a182de3617e682b190597cac8c [file] [log] [blame]
Oliver Smithe53a34a2019-11-20 12:48:12 +01001#!/usr/bin/env python3
2"""
3SPDX-License-Identifier: MIT
4Copyright 2019 sysmocom s.f.m.c GmbH <info@sysmocom.de>
5
6This is a freeswitch dialplan implementation, see:
7https://freeswitch.org/confluence/display/FREESWITCH/mod_python
8
9Find the right SIP server with mslookup (depending on the destination number)
10and bridge calls accordingly.
11"""
12import json
13import subprocess
14
15
16def query_mslookup(service_type, id, id_type='msisdn'):
17 query_str = '%s.%s.%s' % (service_type, id, id_type)
18 print('[dialplan-dgsm] mslookup: ' + query_str)
19
20 result_line = subprocess.check_output([
21 'osmo-mslookup-client', query_str, '-f', 'json'])
22 if isinstance(result_line, bytes):
23 result_line = result_line.decode('ascii')
24
25 print('[dialplan-dgsm] mslookup result: ' + result_line)
26 return json.loads(result_line)
27
28
29def handler(session, args):
30 """ Handle calls: bridge to the SIP server found with mslookup. """
31 print('[dialplan-dgsm] call handler')
32 msisdn = session.getVariable('destination_number')
33
34 # Run osmo-mslookup-client binary. We have also tried to directly call the
35 # C functions with ctypes but this has lead to hard-to-debug segfaults.
36 try:
37 result = query_mslookup("sip.voice", msisdn)
38
39 # This example only makes use of IPv4
40 if not result['v4']:
41 print('[dialplan-dgsm] no IPv4 result from mslookup')
42 session.hangup('UNALLOCATED_NUMBER')
43 return
44
45 sip_ip, sip_port = result['v4']
46 dial_str = 'sofia/internal/sip:{}@{}:{}'.format(
47 msisdn, sip_ip, sip_port)
48 print('[dialplan-dgsm] dial_str: ' + str(dial_str))
49
50 session.execute('bridge', dial_str)
51 except:
52 print('[dialplan-dgsm]: exception during call handler')
53 session.hangup('UNALLOCATED_NUMBER')
54
55
56def fsapi(session, stream, env, args):
57 """ Freeswitch refuses to load the module without this. """
58 stream.write(env.serialize())
59
60
61def main():
62 import argparse
63
64 parser = argparse.ArgumentParser()
65 parser.add_argument('id', type=int)
66 parser.add_argument('-i', '--id-type', default='msisdn',
67 help='default: "msisdn"')
68 parser.add_argument('-s', '--service', default='sip.voice',
69 help='default: "sip.voice"')
70 args = parser.parse_args()
71
72 result = query_mslookup(args.service, args.id, args.id_type)
73 print(json.dumps(result))
74
75
76if __name__ == '__main__':
77 main()