LDU decoding, more fake decoders

git-svn-id: http://op25.osmocom.org/svn/trunk@26 65a5c917-d112-43f1-993d-58c26a4786be
This commit is contained in:
mossmann 2008-04-11 14:35:00 +00:00
parent 60d58f6415
commit 0c59829ff7
1 changed files with 107 additions and 69 deletions

View File

@ -97,9 +97,10 @@ def trellis_1_2_decode(input):
#print output #print output
return output return output
# fake (63,16,23) BCH decoder, no error correction # fake (64,16,23) BCH decoder, no error correction
# spec sometimes refers to this as (63,16,23) plus a parity bit
# TODO: make less fake # TODO: make less fake
def bch_63_16_23_decode(input): def bch_64_16_23_decode(input):
return input[:8] return input[:8]
# fake (18,6,8) shortened Golay decoder, no error correction # fake (18,6,8) shortened Golay decoder, no error correction
@ -111,11 +112,6 @@ def golay_18_6_8_decode(input):
output.extend(codeword[:3]) output.extend(codeword[:3])
return output return output
# fake (36,20,17) Reed-Solomon decoder, no error correction
# TODO: make less fake
def rs_36_20_17_decode(input):
return input[:60]
# fake (24,12,8) extended Golay decoder, no error correction # fake (24,12,8) extended Golay decoder, no error correction
# TODO: make less fake # TODO: make less fake
def golay_24_12_8_decode(input): def golay_24_12_8_decode(input):
@ -125,11 +121,59 @@ def golay_24_12_8_decode(input):
output.extend(codeword[:6]) output.extend(codeword[:6])
return output return output
# fake (10,6,3) shortened Hamming decoder, no error correction
# TODO: make less fake
def hamming_10_6_3_decode(input):
output = []
for i in range(0,len(input),5):
codeword = input[i:i+5]
output.extend(codeword[:3])
return output
# fake (24,12,13) Reed-Solomon decoder, no error correction # fake (24,12,13) Reed-Solomon decoder, no error correction
# TODO: make less fake # TODO: make less fake
def rs_24_12_13_decode(input): def rs_24_12_13_decode(input):
return input[:36] return input[:36]
# fake (24,16,9) Reed-Solomon decoder, no error correction
# TODO: make less fake
def rs_24_16_9_decode(input):
return input[:48]
# fake (36,20,17) Reed-Solomon decoder, no error correction
# TODO: make less fake
def rs_36_20_17_decode(input):
return input[:60]
# fake (16_8_5) shortened cyclic decoder, no error correction
# TODO: make less fake
def cyclic_16_8_5_decode(input):
output = []
for i in range(0,len(input),8):
codeword = input[i:i+8]
output.extend(codeword[:4])
return output
# fake IMBE frame decoder
# TODO: make less fake
#
# each IMBE frame encodes 20 ms of voice in 88 bits
# words u_0, u_1, . . . u_7 may be encrypted
# 56 coding bits added for total of 144 bits
# 48 most important bits protected by (23,12,7) Golay code
# (u_0, u_1, u_2, u_3 12 bits each)
# TODO: Golay decoding
# next 33 important bits protected by (15,11,3 Hamming code
# (u_4, u_5, u_6, 11 bits each)
# TODO: Hamming decoding
# 7 least important bits unprotected
# (u_7 7 bits)
# words u_1, u_2, . . . u_6 are further xored by PN based on u_0
# TODO: de-randomization
# TODO: de-interleaving
def imbe_decode(input):
print "Raw IMBE frame: 0x%0x" % (symbols_to_integer(input))
# collect input sample statistics for normalization # collect input sample statistics for normalization
total_value = 0.0 total_value = 0.0
total_deviation = 0.0 total_deviation = 0.0
@ -225,7 +269,7 @@ print "frame sync: 0x%012x" % symbols_to_integer(symbols[0:24])
# extract Network Identifier from in between status symbols # extract Network Identifier from in between status symbols
nid_symbols = symbols[24:35] + symbols[36:57] nid_symbols = symbols[24:35] + symbols[36:57]
network_id = bch_63_16_23_decode(nid_symbols) network_id = bch_64_16_23_decode(nid_symbols)
network_access_code = symbols_to_integer(network_id[:6]) network_access_code = symbols_to_integer(network_id[:6])
data_unit_id = symbols_to_integer(network_id[6:]) data_unit_id = symbols_to_integer(network_id[6:])
@ -290,75 +334,69 @@ elif data_unit_id == 15:
golay_codewords = terminator_symbols[:144] golay_codewords = terminator_symbols[:144]
rs_codeword = golay_24_12_8_decode(golay_codewords) rs_codeword = golay_24_12_8_decode(golay_codewords)
link_control = rs_24_12_13_decode(rs_codeword) link_control = rs_24_12_13_decode(rs_codeword)
print "Link Control: 0x%09x" % (symbols_to_integer(link_control)) print "Link Control: 0x%018x" % (symbols_to_integer(link_control))
elif data_unit_id == 5: elif data_unit_id == 5:
print "found a Logical Link Data Unit 1 (LDU1)" print "found a Logical Link Data Unit 1 (LDU1)"
# contains voice frames 1 through 9 of a superframe # contains voice frames 1 through 9 of a superframe
#
# each IMBE frame encodes 20 ms of voice in 88 bits
# words u_0, u_1, . . . u_7 may be encrypted
# 56 coding bits added for total of 144 bits
# 48 most important bits protected by (23,12,7) Golay code
# (u_0, u_1, u_2, u_3 12 bits each)
# TODO: Golay decoding
# next 33 important bits protected by (15,11,3 Hamming code
# (u_4, u_5, u_6, 11 bits each)
# TODO: Hamming decoding
# 7 least important bits unprotected
# (u_7 7 bits)
# words u_1, u_2, . . . u_6 are further xored by PN based on u_0
# TODO: de-randomization
# TODO: de-interleaving
ldu_symbols = symbols[57:864] ldu_symbols = symbols[57:864]
status_symbols = extract_status_symbols(ldu_symbols) status_symbols = extract_status_symbols(ldu_symbols)
imbe1_symbols = ldu_symbols[:72] imbe_symbols = []
imbe2_symbols = ldu_symbols[72:144] imbe_symbols.append(ldu_symbols[:72])
imbe3_symbols = ldu_symbols[164:236] imbe_symbols.append(ldu_symbols[72:144])
imbe4_symbols = ldu_symbols[256:328] imbe_symbols.append(ldu_symbols[164:236])
imbe5_symbols = ldu_symbols[348:420] imbe_symbols.append(ldu_symbols[256:328])
imbe6_symbols = ldu_symbols[440:512] imbe_symbols.append(ldu_symbols[348:420])
imbe7_symbols = ldu_symbols[532:604] imbe_symbols.append(ldu_symbols[440:512])
imbe8_symbols = ldu_symbols[624:696] imbe_symbols.append(ldu_symbols[532:604])
imbe9_symbols = ldu_symbols[712:784] imbe_symbols.append(ldu_symbols[624:696])
lc_symbols = ldu_symbols[144:164] + ldu_symbols[236:256] + ldu_symbols[328:348] + ldu_symbols[420:440] + ldu_symbols[512:532] + ldu_symbols[604:624] imbe_symbols.append(ldu_symbols[712:784])
lsd_symbols = ldu_symbols[696:712] for frame in imbe_symbols:
# + Link Control Word (LC): 72 bits data, 168 bits parity imbe_decode(frame)
# variable format specified by first field: link_control_symbols = ldu_symbols[144:164] + ldu_symbols[236:256] + ldu_symbols[328:348] + ldu_symbols[420:440] + ldu_symbols[512:532] + ldu_symbols[604:624]
# Link Control Format (LCF) 8 bits low_speed_data_symbols = ldu_symbols[696:712]
# rest of frame is 64 bits of fields specified by LCF link_control_rs_codeword = hamming_10_6_3_decode(link_control_symbols)
# likeliy to include TGID, Source ID, Destination ID, Emergency indicator, MFID link_control = rs_24_12_13_decode(link_control_rs_codeword)
# 72 bits encoded with (24,12,13) Reed Solomon code and then (10,6,3) shortened Hamming code print "Link Control: 0x%018x" % (symbols_to_integer(link_control))
# total length encoded: 240 bits link_control_format = link_control[:4]
# TODO: decode print "Link Control Format: 0x%02x" % (symbols_to_integer(link_control_format))
# + Low Speed Data: 32 bits data, 32 bits parity # rest of link control frame is 64 bits of fields specified by LCF
# 32 bits encoded with (16,8,5) shortened cyclic code # likeliy to include TGID, Source ID, Destination ID, Emergency indicator, MFID
# total length encoded: 64 bits low_speed_data = cyclic_16_8_5_decode(low_speed_data_symbols)
# huh? Is the other half in LDU2? print "Low Speed Data: 0x%04x" % (symbols_to_integer(low_speed_data))
# TODO: decode # spec says Low Speed Data = 32 bits data + 32 bits parity
# huh? Is the other half in LDU2?
elif data_unit_id == 10: elif data_unit_id == 10:
print "found a Logical Link Data Unit 2 (LDU2)"
# contains voice frames (codewords) 10 through 18 of a superframe # contains voice frames (codewords) 10 through 18 of a superframe
print "found a Logical Link Data Unit 2 (LDU2)"
ldu_symbols = symbols[57:864] ldu_symbols = symbols[57:864]
status_symbols = extract_status_symbols(ldu_symbols) status_symbols = extract_status_symbols(ldu_symbols)
imbe10_symbols = ldu_symbols[:72] imbe_symbols = []
imbe11_symbols = ldu_symbols[72:144] imbe_symbols.append(ldu_symbols[:72])
imbe12_symbols = ldu_symbols[164:236] imbe_symbols.append(ldu_symbols[72:144])
imbe13_symbols = ldu_symbols[256:328] imbe_symbols.append(ldu_symbols[164:236])
imbe14_symbols = ldu_symbols[348:420] imbe_symbols.append(ldu_symbols[256:328])
imbe15_symbols = ldu_symbols[440:512] imbe_symbols.append(ldu_symbols[348:420])
imbe16_symbols = ldu_symbols[532:604] imbe_symbols.append(ldu_symbols[440:512])
imbe17_symbols = ldu_symbols[624:696] imbe_symbols.append(ldu_symbols[532:604])
imbe_symbols = ldu_symbols[712:784] imbe_symbols.append(ldu_symbols[624:696])
esd_symbols = ldu_symbols[144:164] + ldu_symbols[236:256] + ldu_symbols[328:348] + ldu_symbols[420:440] + ldu_symbols[512:532] + ldu_symbols[604:624] imbe_symbols.append(ldu_symbols[712:784])
lsd_symbols = ldu_symbols[696:712] for frame in imbe_symbols:
# TODO: decode imbe_decode(frame)
# + Encryption Sync Word encryption_sync_symbols = ldu_symbols[144:164] + ldu_symbols[236:256] + ldu_symbols[328:348] + ldu_symbols[420:440] + ldu_symbols[512:532] + ldu_symbols[604:624]
# Message Indicator (MI) 72 bits low_speed_data_symbols = ldu_symbols[696:712]
#message_indicator = encryption_sync_rs_codeword = hamming_10_6_3_decode(encryption_sync_symbols)
# Algorithm ID (ALGID) 8 bits encryption_sync = rs_24_16_9_decode(encryption_sync_rs_codeword)
#algorithm_id = print "Encryption Sync Word: 0x%024x" % (symbols_to_integer(encryption_sync))
# Key ID (KID) 16 bits # Message Indicator (MI) 72 bits
#key_id = message_indicator = encryption_sync[:36]
# 96 bits encoded with (24,16,9) Reed Solomon code and then (10,6,3) shortened Hamming code print "Message Indicator: 0x%018x" % (symbols_to_integer(message_indicator))
# Algorithm ID (ALGID) 8 bits
algorithm_id = encryption_sync[36:40]
print "Algorithm ID: 0x%02x" % (symbols_to_integer(algorithm_id))
# Key ID (KID) 16 bits
key_id = encryption_sync[40:48]
print "Key ID: 0x%04x" % (symbols_to_integer(key_id))
low_speed_data = cyclic_16_8_5_decode(low_speed_data_symbols)
print "Low Speed Data: 0x%04x" % (symbols_to_integer(low_speed_data))
else: else:
print "unknown Data Unit ID" print "unknown Data Unit ID"