tdma decoder

git-svn-id: http://op25.osmocom.org/svn/trunk@319 65a5c917-d112-43f1-993d-58c26a4786be
This commit is contained in:
max 2013-06-30 17:31:52 +00:00
parent f84a4ff655
commit 9b7e3709ac
7 changed files with 701 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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