-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReadCIDTone.py
executable file
·157 lines (150 loc) · 4.4 KB
/
ReadCIDTone.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import subprocess
import sys
"""ReadCIDTone.py
a wrapper around minimodem with binary output turned on
to process demodulated CID bytes
an alternative since minimodem's callerid mdmf implementation is not working for me
on files which have more than one callerid data burst in them, or on some other occasions for some reason
but it is demodulating the bytes themselves perfectly in Bell Type 202
based on specs provided at https://hkn.eecs.berkeley.edu/~drake/callsense/callerid.html
"""
class MessageType:
MDMF = 128
SDMF = 4
class MDMFParamTypes:
DT = 1 #date/time
number = 2 #phone number
name = 7
class CIDLogger:
byteStrings = []
binaryPlacement = [1,2,4,8,16,32,64,128] #numbers are processed in the order they are defined.
#i.e, in the provided link, numbers are opposite order, reverse if this is case
startBytes = [128, #MDMF format
4] #SDMF format
messageType = None
startByteEncountered = False
pType = None
pCount = None
pTypeCounter = 1
byteStr = ''
outputStr = ''
dt = ''
number = ''
name = ''
processed = []
msgLen = None
msgCounter = 0
def __init__(self,
output):
self.byteStrings = output.splitlines()
self.ProcessData()
self.PresentData()
def BinStrToAsciiCode(self,
binStr):
curPlace = 1
num = 0
for a in binStr:
if a == '1':
num += self.binaryPlacement[curPlace - 1]
curPlace += 1
return num
def formatDT(self,
dt):
if len(dt) == 9:
hr = int(dt[5:7])
ampm = 'AM'
if hr >= 13:
hr -= 12
ampm = 'PM'
if hr <= 0:
return 'N/A'
r = '%s/%s @ Time %s' + ampm
return r % (dt[:3], dt[2:3], str(hr) + ':' + dt[7:9])
else:
return 'N/A'
def ProcessData(self):
for a in self.byteStrings:
b = self.BinStrToAsciiCode(a)
if not self.startByteEncountered:
if b in self.startBytes:
self.startByteEncountered = True
self.messageType = b
self.messageCounter = 0
elif self.messageType == MessageType.MDMF:
if self.msgLen is None:
self.msgLen = b
elif self.pType is None:
self.pType = b
elif self.pCount is None:
self.pCount = b
if self.pType == MDMFParamTypes.DT:
if self.pTypeCounter <= self.pCount:
self.dt = self.dt + unichr(b)
self.pTypeCounter += 1
else:
self.pTypeCounter = 0
self.pType = b
self.pCount = None
elif self.pType == MDMFParamTypes.number:
if self.pTypeCounter <= self.pCount:
self.number = self.number + unichr(b)
self.pTypeCounter += 1
else:
self.pTypeCounter = 0
self.pType = b
self.pCount = None
elif self.pType == MDMFParamTypes.name:
if self.pTypeCounter <= self.pCount:
self.name = self.name + unichr(b)
self.pTypeCounter += 1
if self.messageCounter == self.msgLen:
self.checkSum = b
if not self.name:
self.name = 'N/A'
if not self.number:
self.number = 'N/A'
if not self.dt:
self.dt = 'N/A'
self.processed.append([self.formatDT(self.dt),self.name,self.number])
self.pTypeCounter = 0
self.dt = ''
self.name = ''
self.number = ''
self.pType = None
self.pCount = None
self.startByteEncountered = False
self.msgLen = None
self.messageCounter = 0
self.messageCounter += 1
elif self.messageType == MessageType.SDMF:
if self.msgLen is None:
self.msgLen = b
self.pTypeCounter = 0
else:
if self.pTypeCounter <= 8:#length of SDMF date
self.dt = self.dt + unichr(b)
elif self.pTypeCounter <= self.msgLen:
self.number = self.number + unichr(b)
else:
self.processed.append([self.formatDT(self.dt), 'N/A', self.number])
self.pTypeCounter += 1
def PresentData(self):
for a in self.processed:
print 'Date:', str(a[0])
print 'name:', str(a[1])
print 'number:', str(a[2])
print '-----------------------------'
print ''
if __name__ == "__main__":
if len(sys.argv) == 2:
p = subprocess.Popen(['minimodem',
'--rx',
'--binary-output',
'1200',
'--ascii',
'-f',
sys.argv[1]],
stderr= subprocess.PIPE,
stdout = subprocess.PIPE)
out = p.communicate()[0]
CIDLogger(out)