OK-DMR / ok-dmrlib

DMR PDUs, elements, FEC and CRC library, including proprietary DMR protocols of Hytera and Motorola
GNU Affero General Public License v3.0
31 stars 7 forks source link

Help with embedded outbound Reverse Channel information #8

Open kantooon opened 5 months ago

kantooon commented 5 months ago

Hi, I'm trying to implement in MMDVMHost the DMR tier III reverse channel commands for MS de-key and MS power control. I use ok-dmrlib to generate the 32 bit PDUs, but the radios do not respond to the commands so there seems to be some issue with my code. I figured out by myself that in VBPTC3211 I have to invert the parity bits row to odd in the set_parity() method and changed it accordingly. I'm not so sure about CRC7 configuration. I wonder if you could help me troubleshoot my ok-dmrlib code below. Otherwise, the EMB fields are set with LCSS 0, PI 1 and correct colour code. The PDU is only transmitted in voice burst F so that seems fine as well.

 ba = bitarray('0100')
 CRC7_conf = BitCrcConfiguration(
        width_bits=7,
        polynomial=0x27,
        init_value=0x00,
        final_xor_value=0x7A,
        reverse_input_bytes=False,
        reverse_output_bytes=False,
    )
    crc7_calc = BitCrcCalculator(CRC7_conf, True)
    crc7_nm = crc7_calc.calculate_checksum(ba)
    print(crc7_nm)
    ba = ba + crc7_nm
    out = VBPTC3211.encode(ba)
    print(out)
    pad = bitarray('0000')
    padl = bitarray('0000')
    pad.extend(out)
    pad.extend(padl)
    all_bytes = bits_to_bytes(pad)
    readable = all_bytes.hex(',').split(',')
    x = str()
    for i in readable:
        x += "0x" + i + ', '
    print(x)
smarek commented 5 months ago

Hey @kantooon

1) for formatting, put ``` (three backticks) on empty line before and after your code, docs: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks

  my formatted code

2) Can you let me know if you have RC Info payload with valid CRC7 ? I can add the CRC7 with tests here

3) From "ETSI TS 102 361-1 V2.5.1 (2017-10)" section B.3.13 (7-bit CRC calculation) I'd guess this is correct config

https://github.com/OK-DMR/ok-dmrlib/blob/master/okdmr/dmrlib/etsi/crc/crc.py#L291

    BitCrcConfiguration(
        width_bits=7,
        polynomial=0x27,
        init_value=0x00,
        final_xor_value=0x00,
        reverse_input_bytes=False,
        reverse_output_bytes=False,
    )

Not sure why you have final_xor_value=0x7A

kantooon commented 5 months ago

Hi, thanks for responding, answers below:

2. Can you let me know if you have RC Info payload with valid CRC7 ? I can add the CRC7 with tests here

Unfortunately I don't. I'm writing this blind, and the only way of testing it is with my radios (Hytera HP785, manual says it supports transmit interrupt and power control).

Not sure why you have final_xor_value=0x7A

ETSI TS 102 361-1, section B.3.12 Data Type CRC Mask, table B.21, reverse channel has a CRC mask of 0x7A. Isn't that the purpose of final_xor_value?

Also, if you can, is it possible to add odd parity option to VBTC3211 as in B.2.2.2 Reverse Channel Single Burst BPTC?

smarek commented 5 months ago

Ok, data type mask, i handle those differently since the CRC impl is typically not data-type-specific, indeed I think that's where your problem might be

If you take a look for example in CRC9 https://github.com/OK-DMR/ok-dmrlib/blob/fdb3fa7037a40cd397101e3e13e618c2c9ecbd0a/okdmr/dmrlib/etsi/crc/crc9.py#L51

I apply the mask to calculated and two-complement value of CRC, you can try similar flow, coding the crc's was the most tricky part for me as well :))

And last, how did you figure your payload is not taking effect because of invalid CRC ? Working with Hytera radios sometimes the reason is codeplug settings or licensing or just straight firmware bug. If you're able to capture full traffic with your MS as PCAP, we could maybe see more? I guess you're already aware of pcap tooling we have

kantooon commented 5 months ago

Ok, data type mask, i handle those differently since the CRC impl is typically not data-type-specific, indeed I think that's where your problem might be

If you take a look for example in CRC9

https://github.com/OK-DMR/ok-dmrlib/blob/fdb3fa7037a40cd397101e3e13e618c2c9ecbd0a/okdmr/dmrlib/etsi/crc/crc9.py#L51

I apply the mask to calculated and two-complement value of CRC, you can try similar flow, coding the crc's was the most tricky part for me as well :))

Thanks for the advice, I'll try this method as well, but for CRC9 the standard specifies an inversion polynomial, whereas for CRC7 it explicitly says there's no inversion polynomial.

And last, how did you figure your payload is not taking effect because of invalid CRC ? Working with Hytera radios sometimes the reason is codeplug settings or licensing or just straight firmware bug. If you're able to capture full traffic with your MS as PCAP, we could maybe see more? I guess you're already aware of pcap tooling we have

I guess I will need to double check the codeplug, power control is explicitly enabled, but there's no setting for receiving TX interrupt, only for transmitting. As far as licenses, I'm covered, the tier III license has everything. I'll need to check what I can do with pcap since I don't see how to get the data from MMDVM to pcap...

smarek commented 5 months ago

Regarding the network, suffices to capture network traffic between mmdvmhost (i assume you have some rpi hotspot or similar) and your computer (hblink maybe?), pcap can then be filtered and data extracted using dmrlib-pcap-tool, usually simply running "dmrlib-pcap-tool PATH_TO_YOUR_CAPTURE.pcapng" shows you data and stats, then you can fiddle with cli switches, see help

> dmrlib-pcap-tool --help
usage: dmrlib-pcap-tool [-h] [--ports WHITELIST_PORTS [WHITELIST_PORTS ...]] [--filter BLACKLIST_PORTS [BLACKLIST_PORTS ...]] [--no-statistics]
                        [--print-raw] [--extract-embedded-lc] [--observe-transmissions] [--debug-vocoder-bytes] [--verbose] [--ipsc]
                        [--filter-ip FILTER_IP [FILTER_IP ...]]
                        files [files ...]

Read and debug UDP packets in PCAP/PCAPNG file

positional arguments:
  files                 PCAP or PCAPNG file to be read

options:
  -h, --help            show this help message and exit
  --ports WHITELIST_PORTS [WHITELIST_PORTS ...], -p WHITELIST_PORTS [WHITELIST_PORTS ...]
                        Whitelist UDP ports to inspect (source or destination or both) (default: [])
  --filter BLACKLIST_PORTS [BLACKLIST_PORTS ...], -f BLACKLIST_PORTS [BLACKLIST_PORTS ...]
                        Blacklist UDP ports to exclude from inspection (source or destination or both) (default: [67, 68, 53, 161, 162, 123, 137, 138, 443,
                        80, 1900, 5353, 5355, 30052, 30061])
  --no-statistics, -q   Suppress statistics at the end of output (default: False)
  --print-raw, -r       Print raw UDP Data before parsing the payload (default: False)
  --extract-embedded-lc, -e
                        Extract only Embedded LinkControl data and print these (default: False)
  --observe-transmissions, -o
                        Feed bursts to Transmission and debug the data and how the state of terminals changed (default: False)
  --debug-vocoder-bytes
                        Effective only with --observe-transmissions, will print voice bytes in format ready for vocoder decode (default: False)
  --verbose, -v         Verbose logging (default: False)
  --ipsc                Analyze IPSC traffic (map between slot-type, frame-type and data-type) (default: False)
  --filter-ip FILTER_IP [FILTER_IP ...]
                        Filter traffic by "ORIGIN" IP address(es) (default: [])
kantooon commented 5 months ago

Oh I see what you meant with pcap. The RC PDU is only trnsmitted via RF currently, but I can also add it to the network transmisssion so I can wireshark it. I don't have a classic hotspot, my setup is all SDR-based and running on x86_64 Linux.

If you're curious, my test tier III system consists of a LimeSDR family device, qradiolink as lower PHY with 7 RF channels multiplexed in GNU radio flowgraphs, and some custom forks of MMDVM and MMDVMHost called MMDVM-SDR and MMDVMHost-SDR. The setup is partly described here: https://qradiolink.org/multicarrier-transceiver-DMR-YSF-M17-with-MMDVM-and-LimeSDR.html but there's like zero docs for tier III since it's WIP.

The RC PDU transmit is initiated from the trunking controller (dmrtc) and sent on the alternate logical channel (it only works with aligned timing and not offset timing).

smarek commented 5 months ago

very impressive, i've yet to work more with downlink and Tier-III PDUs, and the reason is i don't have them captured (i have SDR but it wasn't my priority so far to get it), if you could supply me with the on-air data, i would add a support for all these PDUs and routines to handle them.

Regarding form of the data, you can take inspiration from our and lwvmobile's last-years adventure with dsd-fme "DSP structured output" https://github.com/lwvmobile/dsd-fme/issues/94#issuecomment-1399266023

And last I guess your note about aligned/offset timing is just the current state of implementation, not actual AI protocol limitation?

kantooon commented 5 months ago

Yes sure, I use dsd-fme as well to test PDUs. Let me know what PDU captures you need, I already asked lwvmobile for a few changes in the DMR decoder and supplied him with some captures off the air.

The aligned timing limitation is specified in the standard at 5.1.1 Channel timing relationship. Reverse channel only works in this mode, basically the MS transmits its own timeslot, then switches to RX for the duration of the other timeslot and hears its own transmission repeated back (maybe with RC signalling). In offset timing, on the other hand it supports full duplex calls instead since the MS receives the other logical channel during that time.

kantooon commented 5 months ago

I'm going to close this now, as I haven't been able to find the solution yet, but I'm busy with other stuff. I'll come back to this later with a fresh perspective and if I find the right solution I'll also let you know. Thanks for your informative answers and your help in this topic!

smarek commented 5 months ago

Keep it open, its bookmark for my brain as well, thanks and good luck 🤞