Holger Hans Peter Freyther | 3a434f8 | 2016-04-16 15:53:58 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python2.7 |
| 2 | |
| 3 | """ |
| 4 | AGPLv3+ 2016 Copyright Holger Hans Peter Freyther |
| 5 | |
| 6 | Example of how to connect to the USSD side-channel and how to respond |
| 7 | with a fixed message. |
| 8 | """ |
| 9 | |
| 10 | import socket |
| 11 | import struct |
| 12 | |
| 13 | ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 14 | ussdSocket.connect(('127.0.0.1', 5001)) |
| 15 | |
| 16 | def send_dt1(dstref, data): |
| 17 | dlen = struct.pack('B', len(data)).encode('hex') |
| 18 | hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex') |
| 19 | pdata = hex.decode('hex') |
| 20 | out = struct.pack('>HB', len(pdata), 0xfd) + pdata |
| 21 | ussdSocket.send(out) |
| 22 | |
| 23 | def send_rel(srcref, dstref): |
| 24 | hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100' |
| 25 | pdata = hex.decode('hex') |
| 26 | out = struct.pack('>HB', len(pdata), 0xfd) + pdata |
| 27 | ussdSocket.send(out) |
| 28 | |
| 29 | def recv_one(): |
| 30 | plen = ussdSocket.recv(3) |
| 31 | (plen,ptype) = struct.unpack(">HB", plen) |
| 32 | data = ussdSocket.recv(plen) |
| 33 | |
| 34 | return ptype, data |
| 35 | |
| 36 | # Assume this is the ID request |
| 37 | data = ussdSocket.recv(4) |
| 38 | ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd") |
| 39 | # ^len ^len of tag ... and ignore |
| 40 | |
| 41 | # Expect a fake message. see struct ipac_msgt_sccp_state |
| 42 | ptype, data = recv_one() |
| 43 | print("%d %s" % (ptype, data.encode('hex'))) |
| 44 | (srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9]) |
| 45 | print("New transID %d invoke %d" % (transid, invokeid)) |
| 46 | |
| 47 | # Expect a the invocation.. todo.. extract invoke id |
| 48 | ptype, data = recv_one() |
| 49 | print("%d %s" % (ptype, data.encode('hex'))) |
| 50 | |
| 51 | # Reply with BSSAP + GSM 04.08 + MAP portion |
| 52 | # 00 == invoke id 0f == DCS |
| 53 | res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713" |
| 54 | send_dt1(dstref, res.decode('hex')) |
| 55 | |
| 56 | clear = "000420040109" |
| 57 | send_dt1(dstref, clear.decode('hex')) |
| 58 | |
| 59 | # should be the clear complete |
| 60 | send_rel(srcref, dstref) |
| 61 | |
| 62 | # Give it some time to handle connection shutdown properly |
| 63 | print("Gracefully sleeping") |
| 64 | import time |
| 65 | time.sleep(3) |