aboutsummaryrefslogtreecommitdiffstats
path: root/op25/gr-op25_repeater/apps/tdma
diff options
context:
space:
mode:
authorroot <root@op25.osmocom.org>2013-12-10 01:47:21 +0100
committerroot <root@op25.osmocom.org>2013-12-10 01:47:21 +0100
commite9aa1ab5fe03026957b2a11a6a48b5b83f275f08 (patch)
tree5f402d240c5f5b9d923eb4ad44aaa0ea0e6e5f03 /op25/gr-op25_repeater/apps/tdma
Initial check-in.
Diffstat (limited to 'op25/gr-op25_repeater/apps/tdma')
-rw-r--r--op25/gr-op25_repeater/apps/tdma/bit_utils.py84
-rw-r--r--op25/gr-op25_repeater/apps/tdma/duid.py53
-rw-r--r--op25/gr-op25_repeater/apps/tdma/isch.py56
-rw-r--r--op25/gr-op25_repeater/apps/tdma/lfsr.py87
-rw-r--r--op25/gr-op25_repeater/apps/tdma/rs.py154
-rwxr-xr-xop25/gr-op25_repeater/apps/tdma/tdma-decode.py114
-rw-r--r--op25/gr-op25_repeater/apps/tdma/vf.py153
7 files changed, 701 insertions, 0 deletions
diff --git a/op25/gr-op25_repeater/apps/tdma/bit_utils.py b/op25/gr-op25_repeater/apps/tdma/bit_utils.py
new file mode 100644
index 0000000..df667dd
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/bit_utils.py
@@ -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
diff --git a/op25/gr-op25_repeater/apps/tdma/duid.py b/op25/gr-op25_repeater/apps/tdma/duid.py
new file mode 100644
index 0000000..0468e1c
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/duid.py
@@ -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
diff --git a/op25/gr-op25_repeater/apps/tdma/isch.py b/op25/gr-op25_repeater/apps/tdma/isch.py
new file mode 100644
index 0000000..6a6a4c0
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/isch.py
@@ -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
diff --git a/op25/gr-op25_repeater/apps/tdma/lfsr.py b/op25/gr-op25_repeater/apps/tdma/lfsr.py
new file mode 100644
index 0000000..c9b06f6
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/lfsr.py
@@ -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
diff --git a/op25/gr-op25_repeater/apps/tdma/rs.py b/op25/gr-op25_repeater/apps/tdma/rs.py
new file mode 100644
index 0000000..55438d1
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/rs.py
@@ -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
diff --git a/op25/gr-op25_repeater/apps/tdma/tdma-decode.py b/op25/gr-op25_repeater/apps/tdma/tdma-decode.py
new file mode 100755
index 0000000..7d04f9b
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/tdma-decode.py
@@ -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()
diff --git a/op25/gr-op25_repeater/apps/tdma/vf.py b/op25/gr-op25_repeater/apps/tdma/vf.py
new file mode 100644
index 0000000..96dbeaa
--- /dev/null
+++ b/op25/gr-op25_repeater/apps/tdma/vf.py
@@ -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