tdma decoder
git-svn-id: http://op25.osmocom.org/svn/trunk@319 65a5c917-d112-43f1-993d-58c26a4786be
This commit is contained in:
parent
f84a4ff655
commit
9b7e3709ac
|
@ -0,0 +1,84 @@
|
|||
|
||||
# P25 TDMA Decoder (C) Copyright 2013 KA1RBI
|
||||
#
|
||||
# This file is part of OP25
|
||||
#
|
||||
# OP25 is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# OP25 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 General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OP25; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
import numpy as np
|
||||
|
||||
def rev_int(n,l):
|
||||
j=0
|
||||
for i in xrange(l):
|
||||
b=n&1
|
||||
n=n>>1
|
||||
j = (j << 1) | b
|
||||
return j
|
||||
|
||||
def bits_to_dibits(bits):
|
||||
d = []
|
||||
for i in xrange(len(bits)>>1):
|
||||
d.append((bits[i*2]<<1) + bits[i*2+1])
|
||||
return d
|
||||
|
||||
def dibits_to_bits(dibits):
|
||||
b = []
|
||||
for d in dibits:
|
||||
b.append((d>>1)&1)
|
||||
b.append(d&1)
|
||||
return b
|
||||
|
||||
def mk_array(n, l):
|
||||
a = []
|
||||
for i in xrange(0,l):
|
||||
a.insert(0, n & 1)
|
||||
n = n >> 1
|
||||
return np.array(a)
|
||||
|
||||
def mk_int(a):
|
||||
res= 0L
|
||||
for i in xrange(0, len(a)):
|
||||
res = res * 2
|
||||
res = res + (a[i] & 1)
|
||||
return res
|
||||
|
||||
def mk_str(a):
|
||||
return ''.join(['%s' % (x&1) for x in a])
|
||||
|
||||
def check_l(a,b):
|
||||
ans = 0
|
||||
assert len(a) == len(b)
|
||||
for i in xrange(len(a)):
|
||||
if (a[i] == b[i]):
|
||||
ans += 1
|
||||
return ans
|
||||
|
||||
def fixup(a):
|
||||
res = []
|
||||
for c in a:
|
||||
if c == 3:
|
||||
res.append(1)
|
||||
else: # -3
|
||||
res.append(3)
|
||||
|
||||
return res
|
||||
|
||||
def find_sym(pattern, symbols):
|
||||
for i in xrange(0, len(symbols)-len(pattern)):
|
||||
chunk = symbols[i : i + len(pattern)]
|
||||
if chunk == pattern:
|
||||
return i
|
||||
return -1
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
# P25 TDMA Decoder (C) Copyright 2013 KA1RBI
|
||||
#
|
||||
# This file is part of OP25
|
||||
#
|
||||
# OP25 is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# OP25 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 General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OP25; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
import numpy as np
|
||||
from bit_utils import *
|
||||
|
||||
duid_str = {}
|
||||
duid_str[0] = "4v"
|
||||
duid_str[3] = "sacch w"
|
||||
duid_str[6] = "2v"
|
||||
duid_str[9] = "facch w"
|
||||
duid_str[12] = "sacch w/o"
|
||||
duid_str[15] = "facch w/o"
|
||||
|
||||
duid_map = {}
|
||||
def mk_duid_lookup():
|
||||
g = np.array(np.mat('1 0 0 0 1 1 0 1; 0 1 0 0 1 0 1 1; 0 0 1 0 1 1 1 0; 0 0 0 1 0 1 1 1'))
|
||||
for i in xrange(16):
|
||||
codeword = mk_str(np.dot(mk_array(i, 4), g))
|
||||
duid_map[codeword] = i
|
||||
|
||||
def extract_duid(b):
|
||||
duid0 = b[10] # duid 3,2
|
||||
duid1 = b[47] # duid 1,0
|
||||
duid2 = b[132] # par 3,2
|
||||
duid3 = b[169] # par 1,0
|
||||
v = (duid0 << 6) + (duid1 << 4) + (duid2 << 2) + duid3
|
||||
va = mk_array(v, 8)
|
||||
return mk_str(va)
|
||||
|
||||
def decode_duid(burst):
|
||||
try:
|
||||
b = duid_str[duid_map[extract_duid(burst)]]
|
||||
except: # FIXME: find closest matching codeword
|
||||
b = 'unknown' + extract_duid(burst)
|
||||
return b
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
# P25 TDMA Decoder (C) Copyright 2013 KA1RBI
|
||||
#
|
||||
# This file is part of OP25
|
||||
#
|
||||
# OP25 is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# OP25 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 General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OP25; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
import numpy as np
|
||||
from bit_utils import *
|
||||
|
||||
isch_map = {}
|
||||
|
||||
def mk_isch_lookup():
|
||||
g = np.array(np.mat('1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 1 1 1; 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 0; 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 1 1 0 0 0 1 0 1 1 1 0 1 0 1 1 0 0 0; 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 1 1 0 1 0 0 0 1 1 0 0 0 1 1 1 0; 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1; 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 1 0 0 1 1 0 1 1 0 1 1 1 0 0 1 0; 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 1 1 0 1 0 0 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 0 0 0 1; 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 0 0 1 0 0 1 1 1 0; 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1 0 1 1 0 0 0 0 1 0 1 1 0 0 1 0 1 1 1'))
|
||||
c0 = 0x184229d461L
|
||||
for i in xrange(0, 2**7):
|
||||
codeword = mk_int(np.dot(mk_array(i, 9), g)) ^ c0
|
||||
isch_map['%x' % codeword] = i
|
||||
|
||||
def mk_isch(v):
|
||||
v1 = v & 3
|
||||
v = v >> 2
|
||||
v2 = v & 1
|
||||
v = v >> 1
|
||||
v3 = v & 3
|
||||
v = v >> 2
|
||||
v4 = v & 3
|
||||
v = v >> 2
|
||||
v5 = v & 3
|
||||
return v4, v3, v2, v1
|
||||
|
||||
def decode_isch(syms):
|
||||
sync0 = 0x575d57f7ff
|
||||
v = mk_int(dibits_to_bits(syms))
|
||||
vp = '%x' % v
|
||||
isch = 'unknown'
|
||||
if v == sync0:
|
||||
return -2, -2, -2, -2
|
||||
if vp in isch_map:
|
||||
chn,loc,fr,cnt = mk_isch(isch_map[vp])
|
||||
return chn, loc, fr, cnt
|
||||
# FIXME: if bit error(s), locate closest matching codeword
|
||||
return -1, -1, -1, -1
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
# P25 TDMA Decoder (C) Copyright 2013 KA1RBI
|
||||
#
|
||||
# This file is part of OP25
|
||||
#
|
||||
# OP25 is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# OP25 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 General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OP25; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
import numpy as np
|
||||
from bit_utils import *
|
||||
|
||||
def mk_xor(nac,sysid,wacn):
|
||||
xorbits = mk_xor_bits(nac,sysid,wacn)
|
||||
xorsyms = [0] * (len(xorbits)/2)
|
||||
for i in xrange(len(xorsyms)):
|
||||
xorsyms[i] = (xorbits[i*2] << 1) + xorbits[i*2+1]
|
||||
return xorsyms
|
||||
|
||||
def asm_reg(s1,s2,s3,s4,s5,s6):
|
||||
s1 = s1 & 0xfL
|
||||
s2 = s2 & 0x1fL
|
||||
s3 = s3 & 0x3fL
|
||||
s4 = s4 & 0x1fL
|
||||
s5 = s5 & 0x3fffL
|
||||
s6 = s6 & 0x3ffL
|
||||
return (s1<<40)+(s2<<35)+(s3<<29)+(s4<<24)+(s5<<10)+s6
|
||||
|
||||
def disasm_reg(r):
|
||||
s1 = (r>>40) & 0xfL
|
||||
s2 = (r>>35) & 0x1fL
|
||||
s3 = (r>>29) & 0x3fL
|
||||
s4 = (r>>24) & 0x1fL
|
||||
s5 = (r>>10) & 0x3fffL
|
||||
s6 = r & 0x3ffL
|
||||
return s1,s2,s3,s4,s5,s6
|
||||
|
||||
def cyc_reg(reg):
|
||||
s1,s2,s3,s4,s5,s6 = disasm_reg(reg)
|
||||
cy1 = (s1 >> 3) & 1L
|
||||
cy2 = (s2 >> 4) & 1L
|
||||
cy3 = (s3 >> 5) & 1L
|
||||
cy4 = (s4 >> 4) & 1L
|
||||
cy5 = (s5 >> 13) & 1L
|
||||
cy6 = (s6 >> 9) & 1L
|
||||
x1 = cy1 ^ cy2
|
||||
x2 = cy1 ^ cy3
|
||||
x3 = cy1 ^ cy4
|
||||
x4 = cy1 ^ cy5
|
||||
x5 = cy1 ^ cy6
|
||||
s1 = (s1 << 1) & 0xfL
|
||||
s2 = (s2 << 1) & 0x1fL
|
||||
s3 = (s3 << 1) & 0x3fL
|
||||
s4 = (s4 << 1) & 0x1fL
|
||||
s5 = (s5 << 1) & 0x3fffL
|
||||
s6 = (s6 << 1) & 0x3ffL
|
||||
s1 = s1 | (x1 & 1L)
|
||||
s2 = s2 | (x2 & 1L)
|
||||
s3 = s3 | (x3 & 1L)
|
||||
s4 = s4 | (x4 & 1L)
|
||||
s5 = s5 | (x5 & 1L)
|
||||
s6 = s6 | (cy1 & 1L)
|
||||
return asm_reg(s1,s2,s3,s4,s5,s6)
|
||||
|
||||
def mk_xor_bits(nac,sysid,wacn):
|
||||
reg = mk_array(16777216*wacn + 4096*sysid + nac, 44)
|
||||
|
||||
M = np.array(np.mat('1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0; 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0; 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0; 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0; 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0; 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0; 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0; 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0; 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0; 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1; 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1'))
|
||||
reg = mk_int(np.dot(reg,M))
|
||||
|
||||
s = []
|
||||
for i in xrange(4320):
|
||||
s.append((reg >> 43) & 1)
|
||||
reg = cyc_reg(reg)
|
||||
|
||||
return s
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
gly23127DecTbl = [
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 147459,
|
||||
1, 2, 2, 3, 2, 3, 3, 4268035, 2, 3, 3, 1574915, 3, 2097155, 294915, 4099,
|
||||
1, 2, 2, 3, 2, 3, 3, 147459, 2, 3, 3, 147459, 3, 147459, 147459, 147458,
|
||||
2, 3, 3, 32771, 3, 2051, 3149827, 786435, 3, 274435, 4194307, 2162691, 589827, 5275651, 10243, 147459,
|
||||
1, 2, 2, 3, 2, 3, 3, 2621443, 2, 3, 3, 8195, 3, 1118211, 294915, 4196355,
|
||||
2, 3, 3, 135171, 3, 2051, 294915, 1064963, 3, 4210691, 294915, 2162691, 294915, 663555, 294914, 294915,
|
||||
2, 3, 3, 5505027, 3, 2051, 65539, 45059, 3, 557059, 6147, 2162691, 6299651, 262147, 1572867, 147459,
|
||||
3, 2051, 548867, 2162691, 2051, 2050, 4325379, 2051, 1179651, 2162691, 2162691, 2162690, 20483, 2051, 294915, 2162691,
|
||||
1, 2, 2, 3, 2, 3, 3, 2621443, 2, 3, 3, 327683, 3, 43011, 5242883, 4099,
|
||||
2, 3, 3, 32771, 3, 1441795, 18435, 4099, 3, 4210691, 2236419, 4099, 589827, 4099, 4099, 4098,
|
||||
2, 3, 3, 32771, 3, 4198403, 270339, 1116163, 3, 3145731, 6147, 4726787, 589827, 262147, 2129923, 147459,
|
||||
3, 32771, 32771, 32770, 589827, 2121731, 4325379, 32771, 589827, 133123, 1327107, 32771, 589826, 589827, 589827, 4099,
|
||||
2, 3, 3, 2621443, 3, 2621443, 2621443, 2621442, 3, 4210691, 6147, 1212419, 131075, 262147, 90115, 2621443,
|
||||
3, 4210691, 1114115, 272387, 12291, 98307, 4325379, 2621443, 4210691, 4210690, 524291, 4210691, 3147779, 4210691, 294915, 4099,
|
||||
3, 204803, 6147, 16387, 1097731, 262147, 4325379, 2621443, 6147, 262147, 6146, 6147, 262147, 262146, 6147, 262147,
|
||||
2359299, 1576963, 4325379, 32771, 4325379, 2051, 4325378, 4325379, 40963, 4210691, 6147, 2162691, 589827, 262147, 4325379, 1056771,
|
||||
1, 2, 2, 3, 2, 3, 3, 268291, 2, 3, 3, 8195, 3, 2097155, 5242883, 622595,
|
||||
2, 3, 3, 32771, 3, 2097155, 655363, 1064963, 3, 2097155, 86019, 4587523, 2097155, 2097154, 10243, 2097155,
|
||||
2, 3, 3, 32771, 3, 1581059, 65539, 6291459, 3, 4261891, 2883587, 1052675, 36867, 262147, 10243, 147459,
|
||||
3, 32771, 32771, 32770, 4472835, 200707, 10243, 32771, 1179651, 540675, 10243, 32771, 10243, 2097155, 10242, 10243,
|
||||
2, 3, 3, 8195, 3, 4358147, 65539, 1064963, 3, 8195, 8195, 8194, 542723, 262147, 2232323, 8195,
|
||||
3, 851971, 6293507, 1064963, 12291, 1064963, 1064963, 1064962, 1179651, 38915, 524291, 8195, 4259843, 2097155, 294915, 1064963,
|
||||
3, 2117635, 65539, 657411, 65539, 262147, 65538, 65539, 1179651, 262147, 4243459, 8195, 262147, 262146, 65539, 262147,
|
||||
1179651, 4202499, 266243, 32771, 2654211, 2051, 65539, 1064963, 1179650, 1179651, 1179651, 2162691, 1179651, 262147, 10243, 4722691,
|
||||
2, 3, 3, 32771, 3, 81923, 5242883, 139267, 3, 659459, 5242883, 2115587, 5242883, 262147, 5242882, 5242883,
|
||||
3, 32771, 32771, 32770, 12291, 4720643, 2424835, 32771, 264195, 1122307, 524291, 32771, 180227, 2097155, 5242883, 4099,
|
||||
3, 32771, 32771, 32770, 2230275, 262147, 544771, 32771, 24579, 262147, 196611, 32771, 262147, 262146, 5242883, 262147,
|
||||
32771, 32770, 32770, 32769, 1048579, 32771, 32771, 32770, 6295555, 32771, 32771, 32770, 589827, 262147, 10243, 32771,
|
||||
3, 1050627, 409603, 4263939, 12291, 262147, 34819, 2621443, 2195459, 262147, 524291, 8195, 262147, 262146, 5242883, 262147,
|
||||
12291, 2228227, 524291, 32771, 12290, 12291, 12291, 1064963, 524291, 4210691, 524290, 524291, 12291, 262147, 524291, 198659,
|
||||
4718595, 262147, 3153923, 32771, 262147, 262146, 65539, 262147, 262147, 262146, 6147, 262147, 262146, 262145, 262147, 262146,
|
||||
83971, 32771, 32771, 32770, 12291, 262147, 4325379, 32771, 1179651, 262147, 524291, 32771, 262147, 262146, 2113539, 262147,
|
||||
1, 2, 2, 3, 2, 3, 3, 1081347, 2, 3, 3, 327683, 3, 2097155, 536579, 4196355,
|
||||
2, 3, 3, 135171, 3, 2097155, 18435, 786435, 3, 2097155, 4194307, 57347, 2097155, 2097154, 1245187, 2097155,
|
||||
2, 3, 3, 2107395, 3, 4198403, 65539, 786435, 3, 557059, 4194307, 1052675, 1312771, 73731, 2129923, 147459,
|
||||
3, 1130499, 4194307, 786435, 172035, 786435, 786435, 786434, 4194307, 133123, 4194306, 4194307, 20483, 2097155, 4194307, 786435,
|
||||
2, 3, 3, 135171, 3, 286723, 65539, 4196355, 3, 557059, 3162115, 4196355, 131075, 4196355, 4196355, 4196354,
|
||||
3, 135171, 135171, 135170, 5767171, 98307, 2105347, 135171, 75779, 1310723, 524291, 135171, 20483, 2097155, 294915, 4196355,
|
||||
3, 557059, 65539, 16387, 65539, 3276803, 65538, 65539, 557059, 557058, 401411, 557059, 20483, 557059, 65539, 4196355,
|
||||
2359299, 4202499, 1083395, 135171, 20483, 2051, 65539, 786435, 20483, 557059, 4194307, 2162691, 20482, 20483, 20483, 1056771,
|
||||
2, 3, 3, 327683, 3, 4198403, 18435, 139267, 3, 327683, 327683, 327682, 131075, 1589251, 2129923, 327683,
|
||||
3, 532483, 18435, 7340035, 18435, 98307, 18434, 18435, 1085443, 133123, 524291, 327683, 4464643, 2097155, 18435, 4099,
|
||||
3, 4198403, 1703939, 16387, 4198403, 4198402, 2129923, 4198403, 24579, 133123, 2129923, 327683, 2129923, 4198403, 2129922, 2129923,
|
||||
2359299, 133123, 77827, 32771, 1048579, 4198403, 18435, 786435, 133123, 133122, 4194307, 133123, 589827, 133123, 2129923, 1056771,
|
||||
3, 1050627, 4235267, 16387, 131075, 98307, 1314819, 2621443, 131075, 2109443, 524291, 327683, 131074, 131075, 131075, 4196355,
|
||||
2359299, 98307, 524291, 135171, 98307, 98306, 18435, 98307, 524291, 4210691, 524290, 524291, 131075, 98307, 524291, 1056771,
|
||||
2359299, 16387, 16387, 16386, 534531, 4198403, 65539, 16387, 5308419, 557059, 6147, 16387, 131075, 262147, 2129923, 1056771,
|
||||
2359298, 2359299, 2359299, 16387, 2359299, 98307, 4325379, 1056771, 2359299, 133123, 524291, 1056771, 20483, 1056771, 1056771, 1056770,
|
||||
2, 3, 3, 4734979, 3, 2097155, 65539, 139267, 3, 2097155, 165891, 1052675, 2097155, 2097154, 278531, 2097155,
|
||||
3, 2097155, 1318915, 67587, 2097155, 2097154, 4231171, 2097155, 2097155, 2097154, 524291, 2097155, 2097154, 2097153, 2097155, 2097154,
|
||||
3, 393219, 65539, 1052675, 65539, 51203, 65538, 65539, 24579, 1052675, 1052675, 1052674, 4849667, 2097155, 65539, 1052675,
|
||||
530435, 4202499, 2244611, 32771, 1048579, 2097155, 65539, 786435, 360451, 2097155, 4194307, 1052675, 2097155, 2097154, 10243, 2097155,
|
||||
3, 1050627, 65539, 2392067, 65539, 528387, 65538, 65539, 4460547, 212995, 524291, 8195, 1089539, 2097155, 65539, 4196355,
|
||||
49155, 4202499, 524291, 135171, 395267, 2097155, 65539, 1064963, 524291, 2097155, 524290, 524291, 2097155, 2097154, 524291, 2097155,
|
||||
65539, 4202499, 65538, 65539, 65538, 65539, 65537, 65538, 2099203, 557059, 65539, 1052675, 65539, 262147, 65538, 65539,
|
||||
4202499, 4202498, 65539, 4202499, 65539, 4202499, 65538, 65539, 1179651, 4202499, 524291, 280579, 20483, 2097155, 65539, 163843,
|
||||
3, 1050627, 2101251, 139267, 819203, 139267, 139267, 139266, 24579, 4227075, 524291, 327683, 71683, 2097155, 5242883, 139267,
|
||||
4390915, 282627, 524291, 32771, 1048579, 2097155, 18435, 139267, 524291, 2097155, 524290, 524291, 2097155, 2097154, 524291, 2097155,
|
||||
24579, 2686979, 4458499, 32771, 1048579, 4198403, 65539, 139267, 24578, 24579, 24579, 1052675, 24579, 262147, 2129923, 526339,
|
||||
1048579, 32771, 32771, 32770, 1048578, 1048579, 1048579, 32771, 24579, 133123, 524291, 32771, 1048579, 2097155, 397315, 4276227,
|
||||
1050627, 1050626, 524291, 1050627, 6307843, 1050627, 65539, 139267, 524291, 1050627, 524290, 524291, 131075, 262147, 524291, 53251,
|
||||
524291, 1050627, 524290, 524291, 12291, 98307, 524291, 4456451, 524290, 524291, 524289, 524290, 524291, 2097155, 524290, 524291,
|
||||
167939, 1050627, 65539, 16387, 65539, 262147, 65538, 65539, 24579, 262147, 524291, 6422531, 262147, 262146, 65539, 262147,
|
||||
2359299, 4202499, 524291, 32771, 1048579, 671747, 65539, 2103299, 524291, 69635, 524290, 524291, 4229123, 262147, 524291, 1056771,
|
||||
1, 2, 2, 3, 2, 3, 3, 1081347, 2, 3, 3, 8195, 3, 4980739, 2164739, 4099,
|
||||
2, 3, 3, 2375683, 3, 2051, 655363, 4099, 3, 229379, 4194307, 4099, 1073155, 4099, 4099, 4098,
|
||||
2, 3, 3, 593923, 3, 2051, 270339, 6291459, 3, 3145731, 4194307, 296963, 36867, 73731, 1572867, 147459,
|
||||
3, 2051, 4194307, 1187843, 2051, 2050, 114691, 2051, 4194307, 540675, 4194306, 4194307, 2490371, 2051, 4194307, 4099,
|
||||
2, 3, 3, 8195, 3, 2051, 4214787, 458755, 3, 8195, 8195, 8194, 131075, 2146307, 1572867, 8195,
|
||||
3, 2051, 1114115, 4751363, 2051, 2050, 2105347, 2051, 2625539, 1310723, 149507, 8195, 4259843, 2051, 294915, 4099,
|
||||
3, 2051, 2260995, 16387, 2051, 2050, 1572867, 2051, 344067, 4329475, 1572867, 8195, 1572867, 2051, 1572866, 1572867,
|
||||
2051, 2050, 266243, 2051, 2050, 2049, 2051, 2050, 40963, 2051, 4194307, 2162691, 2051, 2050, 1572867, 2051,
|
||||
2, 3, 3, 4327427, 3, 81923, 270339, 4099, 3, 3145731, 573443, 4099, 131075, 4099, 4099, 4098,
|
||||
3, 532483, 1114115, 4099, 6324227, 4099, 4099, 4098, 264195, 4099, 4099, 4098, 4099, 4098, 4098, 4097,
|
||||
3, 3145731, 270339, 16387, 270339, 688131, 270338, 270339, 3145731, 3145730, 196611, 3145731, 4212739, 3145731, 270339, 4099,
|
||||
151555, 4521987, 2623491, 32771, 1048579, 2051, 270339, 4099, 40963, 3145731, 4194307, 4099, 589827, 4099, 4099, 4098,
|
||||
3, 299011, 1114115, 16387, 131075, 5251075, 34819, 2621443, 131075, 591875, 6553603, 8195, 131074, 131075, 131075, 4099,
|
||||
1114115, 2228227, 1114114, 1114115, 802819, 2051, 1114115, 4099, 40963, 4210691, 1114115, 4099, 131075, 4099, 4099, 4098,
|
||||
4718595, 16387, 16387, 16386, 2166787, 2051, 270339, 16387, 40963, 3145731, 6147, 16387, 131075, 262147, 1572867, 4292611,
|
||||
40963, 2051, 1114115, 16387, 2051, 2050, 4325379, 2051, 40962, 40963, 40963, 917507, 40963, 2051, 2113539, 4099,
|
||||
2, 3, 3, 8195, 3, 81923, 655363, 6291459, 3, 8195, 8195, 8194, 36867, 1181699, 278531, 8195,
|
||||
3, 5246979, 655363, 67587, 655363, 303107, 655362, 655363, 264195, 540675, 3178499, 8195, 4259843, 2097155, 655363, 4099,
|
||||
3, 393219, 1067011, 6291459, 36867, 6291459, 6291459, 6291458, 36867, 540675, 196611, 8195, 36866, 36867, 36867, 6291459,
|
||||
2170883, 540675, 266243, 32771, 1048579, 2051, 655363, 6291459, 540675, 540674, 4194307, 540675, 36867, 540675, 10243, 1376259,
|
||||
3, 8195, 8195, 8194, 3407875, 528387, 34819, 8195, 8195, 8194, 8194, 8193, 4259843, 8195, 8195, 8194,
|
||||
49155, 2228227, 266243, 8195, 4259843, 2051, 655363, 1064963, 4259843, 8195, 8195, 8194, 4259842, 4259843, 4259843, 8195,
|
||||
4718595, 1146883, 266243, 8195, 155651, 2051, 65539, 6291459, 2099203, 8195, 8195, 8194, 36867, 262147, 1572867, 8195,
|
||||
266243, 2051, 266242, 266243, 2051, 2050, 266243, 2051, 1179651, 540675, 266243, 8195, 4259843, 2051, 2113539, 163843,
|
||||
3, 81923, 2101251, 1835011, 81923, 81922, 34819, 81923, 264195, 4227075, 196611, 8195, 2629635, 81923, 5242883, 4099,
|
||||
264195, 2228227, 4218883, 32771, 1048579, 81923, 655363, 4099, 264194, 264195, 264195, 4099, 264195, 4099, 4099, 4098,
|
||||
4718595, 14339, 196611, 32771, 1048579, 81923, 270339, 6291459, 196611, 3145731, 196610, 196611, 36867, 262147, 196611, 526339,
|
||||
1048579, 32771, 32771, 32770, 1048578, 1048579, 1048579, 32771, 264195, 540675, 196611, 32771, 1048579, 4333571, 2113539, 4099,
|
||||
4718595, 2228227, 34819, 8195, 34819, 81923, 34818, 34819, 1069059, 8195, 8195, 8194, 131075, 262147, 34819, 8195,
|
||||
2228227, 2228226, 1114115, 2228227, 12291, 2228227, 34819, 4456451, 264195, 2228227, 524291, 8195, 4259843, 1605635, 2113539, 4099,
|
||||
4718594, 4718595, 4718595, 16387, 4718595, 262147, 34819, 1183747, 4718595, 262147, 196611, 8195, 262147, 262146, 2113539, 262147,
|
||||
4718595, 2228227, 266243, 32771, 1048579, 2051, 2113539, 598019, 40963, 69635, 2113539, 5244931, 2113539, 262147, 2113538, 2113539,
|
||||
2, 3, 3, 1081347, 3, 1081347, 1081347, 1081346, 3, 22531, 4194307, 2752515, 131075, 73731, 278531, 1081347,
|
||||
3, 532483, 4194307, 67587, 331779, 4341763, 2105347, 1081347, 4194307, 1310723, 4194306, 4194307, 559107, 2097155, 4194307, 4099,
|
||||
3, 393219, 4194307, 16387, 2637827, 73731, 137219, 1081347, 4194307, 73731, 4194306, 4194307, 73731, 73730, 4194307, 73731,
|
||||
4194307, 2134019, 4194306, 4194307, 1048579, 2051, 4194307, 786435, 4194306, 4194307, 4194305, 4194306, 4194307, 73731, 4194306, 4194307,
|
||||
3, 6356995, 788483, 16387, 131075, 528387, 2105347, 1081347, 131075, 1310723, 102403, 8195, 131074, 131075, 131075, 4196355,
|
||||
49155, 1310723, 2105347, 135171, 2105347, 2051, 2105346, 2105347, 1310723, 1310722, 4194307, 1310723, 131075, 1310723, 2105347, 606211,
|
||||
1060867, 16387, 16387, 16386, 4489219, 2051, 65539, 16387, 2099203, 557059, 4194307, 16387, 131075, 73731, 1572867, 2363395,
|
||||
720899, 2051, 4194307, 16387, 2051, 2050, 2105347, 2051, 4194307, 1310723, 4194306, 4194307, 20483, 2051, 4194307, 163843,
|
||||
3, 532483, 2101251, 16387, 131075, 2361347, 4784131, 1081347, 131075, 4227075, 1058819, 327683, 131074, 131075, 131075, 4099,
|
||||
532483, 532482, 425987, 532483, 1048579, 532483, 18435, 4099, 2179075, 532483, 4194307, 4099, 131075, 4099, 4099, 4098,
|
||||
100355, 16387, 16387, 16386, 1048579, 4198403, 270339, 16387, 790531, 3145731, 4194307, 16387, 131075, 73731, 2129923, 526339,
|
||||
1048579, 532483, 4194307, 16387, 1048578, 1048579, 1048579, 2293763, 4194307, 133123, 4194306, 4194307, 1048579, 311299, 4194307, 4099,
|
||||
131075, 16387, 16387, 16386, 131074, 131075, 131075, 16387, 131074, 131075, 131075, 16387, 131073, 131074, 131074, 131075,
|
||||
4200451, 532483, 1114115, 16387, 131075, 98307, 2105347, 4456451, 131075, 1310723, 524291, 2131971, 131074, 131075, 131075, 4099,
|
||||
16387, 16386, 16386, 16385, 131075, 16387, 16387, 16386, 131075, 16387, 16387, 16386, 131074, 131075, 131075, 16387,
|
||||
2359299, 16387, 16387, 16386, 1048579, 2051, 561155, 16387, 40963, 69635, 4194307, 16387, 131075, 6815747, 329731, 1056771,
|
||||
3, 393219, 2101251, 67587, 4204547, 528387, 278531, 1081347, 1638403, 4227075, 278531, 8195, 278531, 2097155, 278530, 278531,
|
||||
49155, 67587, 67587, 67586, 1048579, 2097155, 655363, 67587, 143363, 2097155, 4194307, 67587, 2097155, 2097154, 278531, 2097155,
|
||||
393219, 393218, 565251, 393219, 1048579, 393219, 65539, 6291459, 2099203, 393219, 4194307, 1052675, 36867, 73731, 278531, 526339,
|
||||
1048579, 393219, 4194307, 67587, 1048578, 1048579, 1048579, 28675, 4194307, 540675, 4194306, 4194307, 1048579, 2097155, 4194307, 163843,
|
||||
49155, 528387, 5373955, 8195, 528387, 528386, 65539, 528387, 2099203, 8195, 8195, 8194, 131075, 528387, 278531, 8195,
|
||||
49154, 49155, 49155, 67587, 49155, 528387, 2105347, 4456451, 49155, 1310723, 524291, 8195, 4259843, 2097155, 1054723, 163843,
|
||||
2099203, 393219, 65539, 16387, 65539, 528387, 65538, 65539, 2099202, 2099203, 2099203, 8195, 2099203, 5259267, 65539, 163843,
|
||||
49155, 4202499, 266243, 3670019, 1048579, 2051, 65539, 163843, 2099203, 69635, 4194307, 163843, 794627, 163843, 163843, 163842,
|
||||
2101251, 4227075, 2101250, 2101251, 1048579, 81923, 2101251, 139267, 4227075, 4227074, 2101251, 4227075, 131075, 4227075, 278531, 526339,
|
||||
1048579, 532483, 2101251, 67587, 1048578, 1048579, 1048579, 4456451, 264195, 4227075, 524291, 1196035, 1048579, 2097155, 106499, 4099,
|
||||
1048579, 393219, 2101251, 16387, 1048578, 1048579, 1048579, 526339, 24579, 4227075, 196611, 526339, 1048579, 526339, 526339, 526338,
|
||||
1048578, 1048579, 1048579, 32771, 1048577, 1048578, 1048578, 1048579, 1048579, 69635, 4194307, 2367491, 1048578, 1048579, 1048579, 526339,
|
||||
335875, 1050627, 2101251, 16387, 131075, 528387, 34819, 4456451, 131075, 4227075, 524291, 8195, 131074, 131075, 131075, 3211267,
|
||||
49155, 2228227, 524291, 4456451, 1048579, 4456451, 4456451, 4456450, 524291, 69635, 524290, 524291, 131075, 26627, 524291, 4456451,
|
||||
4718595, 16387, 16387, 16386, 1048579, 2138115, 65539, 16387, 2099203, 69635, 1343491, 16387, 131075, 262147, 4206595, 526339,
|
||||
1048579, 69635, 141315, 16387, 1048578, 1048579, 1048579, 4456451, 69635, 69634, 524291, 69635, 1048579, 69635, 2113539, 163843 ]
|
||||
|
||||
def gly23127GetSyn (pattern) :
|
||||
aux = 0x400000
|
||||
|
||||
while(pattern & 0xFFFFF800) != 0 :
|
||||
while (aux & pattern) == 0:
|
||||
aux = aux >> 1
|
||||
pattern = pattern ^ (aux / 0x800 * 0xC75) #generator is C75
|
||||
|
||||
return pattern
|
||||
|
||||
def gly23127Dec (CW) :
|
||||
correction = gly23127DecTbl[gly23127GetSyn(CW)]
|
||||
CW = (CW ^ correction) >> 11
|
||||
return CW, correction
|
||||
|
||||
def gly24128Dec (n) :
|
||||
|
||||
#based on gly23127Dec
|
||||
|
||||
CW = n >> 1 ; #toss the parity bit
|
||||
correction = gly23127DecTbl[gly23127GetSyn(CW)]
|
||||
CW = (CW ^ correction) >> 11
|
||||
return CW, correction
|
|
@ -0,0 +1,114 @@
|
|||
#! /usr/bin/python
|
||||
|
||||
# P25 TDMA Decoder (C) Copyright 2013 KA1RBI
|
||||
#
|
||||
# This file is part of OP25
|
||||
#
|
||||
# OP25 is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# OP25 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 General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OP25; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
"""
|
||||
Decode a file of P25 TDMA symbols and write out all detected voice codewords
|
||||
|
||||
After FEC decoding, print the resulting "B" vectors (49 bits per CW).
|
||||
|
||||
Optionally, dump the timeslot info (type, position, type of content)
|
||||
|
||||
The input file must contain the demodulated symbols, one per character
|
||||
using the low-order two bits of each byte
|
||||
"""
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
from optparse import OptionParser
|
||||
|
||||
from bit_utils import *
|
||||
from isch import mk_isch_lookup, decode_isch
|
||||
from duid import mk_duid_lookup, decode_duid
|
||||
from lfsr import mk_xor
|
||||
from vf import process_v
|
||||
|
||||
SUPERFRAME_LEN = 2160
|
||||
|
||||
def main():
|
||||
parser = OptionParser()
|
||||
parser.add_option("-v", "--verbose", action="store_true", default=False)
|
||||
parser.add_option("-i", "--input-file", type="string", default=None, help="input file name")
|
||||
parser.add_option("-n", "--nac", type="int", default=0, help="NAC")
|
||||
parser.add_option("-s", "--sysid", type="int", default=0, help="sysid")
|
||||
parser.add_option("-w", "--wacn", type="int", default=0, help="WACN")
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 0:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
file = options.input_file
|
||||
|
||||
mk_isch_lookup()
|
||||
mk_duid_lookup()
|
||||
#print 'nac: %d' % options.nac
|
||||
xorsyms = mk_xor(options.nac, options.sysid, options.wacn)
|
||||
|
||||
d = open(file).read()
|
||||
|
||||
symbols = []
|
||||
for c in d:
|
||||
symbols.append(ord(c))
|
||||
|
||||
sync0= bits_to_dibits(mk_array(0x575d57f7ff,40))
|
||||
sync_start = find_sym(sync0, symbols)
|
||||
assert sync_start > 0 # unable to locate any sync sequence
|
||||
superframe = -1
|
||||
for i in xrange(sync_start, sync_start + (180*32), 180):
|
||||
chn, loc, fr, cnt = decode_isch ( symbols [ i : i + 20 ])
|
||||
if chn == 0 and loc == 0:
|
||||
superframe = i
|
||||
break
|
||||
assert superframe > 0 # unable to locate start of superframe
|
||||
|
||||
errors = 0
|
||||
for i in xrange(superframe,len(symbols)-SUPERFRAME_LEN,SUPERFRAME_LEN):
|
||||
syms1 = symbols[i + 10: i + SUPERFRAME_LEN + 10]
|
||||
syms2 = np.array(syms1) ^ xorsyms
|
||||
for j in xrange(12):
|
||||
if options.verbose:
|
||||
print '%s superframe %d timeslot %d %s' % ('=' * 20, i, j, '=' * 20)
|
||||
chn, loc, fr, cnt = decode_isch ( symbols [ i + (j*180) : i + (j*180) + 20 ])
|
||||
if chn == -1:
|
||||
if options.verbose:
|
||||
print 'unknown isch codeword at %d' % (i + (j*180))
|
||||
errors += 1
|
||||
elif chn == -2:
|
||||
if options.verbose:
|
||||
print 'sync isch codeword found at %d' % (i + (j*180))
|
||||
errors = 0
|
||||
else:
|
||||
if options.verbose:
|
||||
print "channel %d loc %d fr %d count %d" % (chn, loc, fr, cnt)
|
||||
errors = 0
|
||||
|
||||
burst = syms1 [ (j*180) : (j*180) + 180 ]
|
||||
burst_d= syms2 [ (j*180) : (j*180) + 180 ]
|
||||
b = decode_duid(burst)
|
||||
if options.verbose:
|
||||
print 'burst at %d type %s' % (i + (j*180), b)
|
||||
if b == '2v' or b == '4v':
|
||||
process_v(burst_d, b)
|
||||
if errors > 6:
|
||||
if options.verbose:
|
||||
print "too many successive errors, exiting at i=%d" % (i)
|
||||
break
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,153 @@
|
|||
|
||||
# P25 TDMA Decoder (C) Copyright 2013 KA1RBI
|
||||
#
|
||||
# This file is part of OP25
|
||||
#
|
||||
# OP25 is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# OP25 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 General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OP25; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
from bit_utils import *
|
||||
from rs import gly23127Dec, gly24128Dec
|
||||
|
||||
def process_vcw(vf):
|
||||
c0, c1, c2, c3 = extract_vcw(vf)
|
||||
c0 = mk_int(c0)
|
||||
c0 = rev_int(c0, 24)
|
||||
c1 = mk_int(c1)
|
||||
c1 = rev_int(c1, 23)
|
||||
c2 = mk_int(c2)
|
||||
c2 = rev_int(c2, 11)
|
||||
c3 = mk_int(c3)
|
||||
c3 = rev_int(c3, 14)
|
||||
u0, correction0 = gly24128Dec(c0)
|
||||
pr = [0] * 24
|
||||
m1 = [0] * 23
|
||||
pr[0] = 16 * u0
|
||||
for n in xrange(1,24):
|
||||
pr[n] = (173*pr[n-1] + 13849) - 65536 * int((173*pr[n-1]+13849)/65536)
|
||||
m1[n-1] = int(pr[n] / 32768) & 1
|
||||
m1 = mk_int(m1)
|
||||
|
||||
u1, correction1 = gly23127Dec(c1 ^ m1)
|
||||
u2 = c2
|
||||
u3 = c3
|
||||
b = [0] * 9
|
||||
b[0] = ((u0 >> 5) & 0x78) + ((u3 >> 9) & 0x7)
|
||||
b[1] = ((u0 >> 3) & 0x1e) + ((u3 >> 13) & 0x1)
|
||||
b[2] = ((u0 << 1) & 0x1e) + ((u3 >> 12) & 0x1)
|
||||
b[3] = ((u1 >> 3) & 0x1fe) + ((u3 >> 8) & 0x1)
|
||||
b[4] = ((u1 << 3) & 0x78) + ((u3 >> 5) & 0x7)
|
||||
b[5] = ((u2 >> 6) & 0x1e) + ((u3 >> 4) & 0x1)
|
||||
b[6] = ((u2 >> 3) & 0x0e) + ((u3 >> 3) & 0x1)
|
||||
b[7] = ( u2 & 0x0e) + ((u3 >> 2) & 0x1)
|
||||
b[8] = ((u2 << 2) & 0x04) + ( u3 & 0x3)
|
||||
s = "\t".join(['%s' % x for x in b])
|
||||
print "%s" % s
|
||||
|
||||
def process_v(f,type):
|
||||
vf = dibits_to_bits(f[11:11+36])
|
||||
process_vcw(vf)
|
||||
vf = dibits_to_bits(f[48:48+36])
|
||||
process_vcw(vf)
|
||||
if type == '2v':
|
||||
return
|
||||
vf = dibits_to_bits(f[96:96+36])
|
||||
process_vcw(vf)
|
||||
vf = dibits_to_bits(f[133:133+36])
|
||||
process_vcw(vf)
|
||||
|
||||
def extract_vcw(vf):
|
||||
c0 = [0] * 24
|
||||
c1 = [0] * 23
|
||||
c2 = [0] * 11
|
||||
c3 = [0] * 14
|
||||
|
||||
c0[23] = vf[0]
|
||||
c0[5] = vf[1]
|
||||
c1[10] = vf[2]
|
||||
c2[3] = vf[3]
|
||||
c0[22] = vf[4]
|
||||
c0[4] = vf[5]
|
||||
c1[9] = vf[6]
|
||||
c2[2] = vf[7]
|
||||
c0[21] = vf[8]
|
||||
c0[3] = vf[9]
|
||||
c1[8] = vf[10]
|
||||
c2[1] = vf[11]
|
||||
c0[20] = vf[12]
|
||||
c0[2] = vf[13]
|
||||
c1[7] = vf[14]
|
||||
c2[0] = vf[15]
|
||||
c0[19] = vf[16]
|
||||
c0[1] = vf[17]
|
||||
c1[6] = vf[18]
|
||||
c3[13] = vf[19]
|
||||
c0[18] = vf[20]
|
||||
c0[0] = vf[21]
|
||||
c1[5] = vf[22]
|
||||
c3[12] = vf[23]
|
||||
c0[17] = vf[24]
|
||||
c1[22] = vf[25]
|
||||
c1[4] = vf[26]
|
||||
c3[11] = vf[27]
|
||||
c0[16] = vf[28]
|
||||
c1[21] = vf[29]
|
||||
c1[3] = vf[30]
|
||||
c3[10] = vf[31]
|
||||
c0[15] = vf[32]
|
||||
c1[20] = vf[33]
|
||||
c1[2] = vf[34]
|
||||
c3[9] = vf[35]
|
||||
c0[14] = vf[36]
|
||||
c1[19] = vf[37]
|
||||
c1[1] = vf[38]
|
||||
c3[8] = vf[39]
|
||||
c0[13] = vf[40]
|
||||
c1[18] = vf[41]
|
||||
c1[0] = vf[42]
|
||||
c3[7] = vf[43]
|
||||
c0[12] = vf[44]
|
||||
c1[17] = vf[45]
|
||||
c2[10] = vf[46]
|
||||
c3[6] = vf[47]
|
||||
c0[11] = vf[48]
|
||||
c1[16] = vf[49]
|
||||
c2[9] = vf[50]
|
||||
c3[5] = vf[51]
|
||||
c0[10] = vf[52]
|
||||
c1[15] = vf[53]
|
||||
c2[8] = vf[54]
|
||||
c3[4] = vf[55]
|
||||
c0[9] = vf[56]
|
||||
c1[14] = vf[57]
|
||||
c2[7] = vf[58]
|
||||
c3[3] = vf[59]
|
||||
c0[8] = vf[60]
|
||||
c1[13] = vf[61]
|
||||
c2[6] = vf[62]
|
||||
c3[2] = vf[63]
|
||||
c0[7] = vf[64]
|
||||
c1[12] = vf[65]
|
||||
c2[5] = vf[66]
|
||||
c3[1] = vf[67]
|
||||
c0[6] = vf[68]
|
||||
c1[11] = vf[69]
|
||||
c2[4] = vf[70]
|
||||
c3[0] = vf[71]
|
||||
|
||||
return c0, c1, c2, c3
|
Reference in New Issue