#!/usr/bin/env python3 """Patch 3 of RX support: dispatch in the hotspot state machine, and read the payload out of the HR-C6000 when a data burst arrives off air.""" W = "/home/viktor/ogd77rel/uv_src/OpenGD77_MDUV380_DM1701_20260130/MDUV380_firmware/application" # ---------------------------------------------------------------- hotspot.c p = W + "/source/functions/hotspot.c" s = open(p).read() if "case HOTSPOT_RX_DATA_FRAME:" in s: print("hotspot.c: dispatch already present") else: a = "\t\t\t\t\t\tcase HOTSPOT_RX_STOP:\n" assert a in s, "RX_STOP case not found" case = """\t\t\t\t\t\tcase HOTSPOT_RX_DATA_FRAME: \t\t\t\t\t\t\t// Packet data burst (SMS, position report...) received off air. \t\t\t\t\t\t\t// The data type the HR-C6000 reported is stored right after the frame. \t\t\t\t\t\t\tsendDataFrameToHost(audioAndHotspotDataBuffer.hotspotBuffer[rfFrameBufReadIdx], \t\t\t\t\t\t\t\t\taudioAndHotspotDataBuffer.hotspotBuffer[rfFrameBufReadIdx][AMBE_AUDIO_LENGTH + LC_DATA_LENGTH + 1]); \t\t\t\t\t\t\tlastRxState = HOTSPOT_RX_DATA_FRAME; \t\t\t\t\t\t\trxFrameTime = ticksGetMillis(); \t\t\t\t\t\t\tbreak; """ s = s.replace(a, case + a, 1) open(p, "w").write(s) print("hotspot.c: RX_DATA_FRAME dispatch added") # ------------------------------------------------------------- HR-C6000.c p = W + "/source/hardware/HR-C6000.c" s = open(p).read() if "HOTSPOT_RX_DATA_FRAME" in s: print("HR-C6000.c: already patched") raise SystemExit(0) # Hook in right after the terminator handling, which is the existing example of # "this is a data sync burst" handling in this interrupt. a = """ if (hrc6000CrcIsValid() && (slotState != DMR_STATE_IDLE) && (hrc.skipCount > 0) && (rxSyncClass != SYNC_CLASS_DATA) && ((rxDataType & 0x07) == 0x01)) { hrc.skipCount--; } """ assert a in s, "skipCount anchor missing" block = """ // Packet data bursts (SMS, position reports, CSBK). Stock firmware reads nothing off the // chip for these, which is why data never reached the host. The HR-C6000 has already // removed the FEC, so the 96 bit payload can be read from the same register page that // carries LC data, and handed to the hotspot code to be rebuilt into a full burst. if ((settingsUsbMode == USB_MODE_HOTSPOT) && hrc6000CrcIsValid() && (rxSyncClass == SYNC_CLASS_DATA) && ((rxDataType == DT_CSBK) || (rxDataType == DT_DATA_HEADER) || (rxDataType == DT_RATE_12_DATA)) && hrc6000CheckColourCodeFilter()) { if (SPI0ReadPageRegByteArray(0x02, 0x00, (uint8_t *)DMR_frame_buffer, LC_DATA_LENGTH) == kStatus_Success) { DMR_frame_buffer[AMBE_AUDIO_LENGTH + LC_DATA_LENGTH] = HOTSPOT_RX_DATA_FRAME; DMR_frame_buffer[AMBE_AUDIO_LENGTH + LC_DATA_LENGTH + 1] = rxDataType; hrc.hotspotDMRRxFrameBufferAvailable = true; } return; } """ s = s.replace(a, block + a, 1) open(p, "w").write(s) print("HR-C6000.c: data burst capture added")