Skip to content

Commit

Permalink
Fix aircopy bypassing TX restrictions & refactor
Browse files Browse the repository at this point in the history
And scrapes together a few more bytes.
  • Loading branch information
JuantAldea authored and egzumer committed Dec 9, 2023
1 parent eb6a3d0 commit 2e69acb
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 163 deletions.
280 changes: 146 additions & 134 deletions app/aircopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,40 @@
#include "ui/inputbox.h"
#include "ui/ui.h"

static const uint16_t Obfuscation[8] = {0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9};
static const uint16_t Obfuscation[8] = { 0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9 };

AIRCOPY_State_t gAircopyState;
uint16_t gAirCopyBlockNumber;
uint16_t gErrorsDuringAirCopy;
uint8_t gAirCopyIsSendMode;
uint16_t gAirCopyBlockNumber;
uint16_t gErrorsDuringAirCopy;
uint8_t gAirCopyIsSendMode;

uint16_t g_FSK_Buffer[36];
uint16_t g_FSK_Buffer[36];

void AIRCOPY_SendMessage(void)
bool AIRCOPY_SendMessage(void)
{
unsigned int i;
static uint8_t gAircopySendCountdown = 1;

if (gAircopyState != AIRCOPY_TRANSFER) {
return 1;
}

if (--gAircopySendCountdown) {
return 1;
}

g_FSK_Buffer[1] = (gAirCopyBlockNumber & 0x3FF) << 6;

EEPROM_ReadBuffer(g_FSK_Buffer[1], &g_FSK_Buffer[2], 64);

g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);

for (i = 0; i < 34; i++)
for (unsigned int i = 0; i < 34; i++) {
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
}

if (++gAirCopyBlockNumber >= 0x78)
if (++gAirCopyBlockNumber >= 0x78) {
gAircopyState = AIRCOPY_COMPLETE;
}

RADIO_SetTxParameters();

Expand All @@ -60,170 +70,172 @@ void AIRCOPY_SendMessage(void)
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);

gAircopySendCountdown = 30;

return 0;
}

void AIRCOPY_StorePacket(void)
{
uint16_t Status;

if (gFSKWriteIndex < 36)
if (gFSKWriteIndex < 36) {
return;
}

gFSKWriteIndex = 0;
gUpdateDisplay = true;
Status = BK4819_ReadRegister(BK4819_REG_0B);
uint16_t Status = BK4819_ReadRegister(BK4819_REG_0B);
BK4819_PrepareFSKReceive();

// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL.

if ((Status & 0x0010U) == 0 && g_FSK_Buffer[0] == 0xABCD && g_FSK_Buffer[35] == 0xDCBA)
{
uint16_t CRC;
unsigned int i;

for (i = 0; i < 34; i++)
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];

CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
if (g_FSK_Buffer[34] == CRC)
{
const uint16_t *pData;
uint16_t Offset;

Offset = g_FSK_Buffer[1];
if (Offset < 0x1E00)
{
pData = &g_FSK_Buffer[2];
for (i = 0; i < 8; i++)
{
EEPROM_WriteBuffer(Offset, pData);
pData += 4;
Offset += 8;
}

if (Offset == 0x1E00)
gAircopyState = AIRCOPY_COMPLETE;

gAirCopyBlockNumber++;

return;
}
}
if ((Status & 0x0010U) != 0 || g_FSK_Buffer[0] != 0xABCD || g_FSK_Buffer[35] != 0xDCBA) {
gErrorsDuringAirCopy++;
return;
}

for (unsigned int i = 0; i < 34; i++) {
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
}
gErrorsDuringAirCopy++;

uint16_t CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
if (g_FSK_Buffer[34] != CRC) {
gErrorsDuringAirCopy++;
return;
}

uint16_t Offset = g_FSK_Buffer[1];

if (Offset >= 0x1E00) {
gErrorsDuringAirCopy++;
return;
}

const uint16_t *pData = &g_FSK_Buffer[2];
for (unsigned int i = 0; i < 8; i++) {
EEPROM_WriteBuffer(Offset, pData);
pData += 4;
Offset += 8;
}

if (Offset == 0x1E00) {
gAircopyState = AIRCOPY_COMPLETE;
}

gAirCopyBlockNumber++;
}

static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
uint32_t Frequency;
unsigned int i;

INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_AIRCOPY;
if (gInputBoxIndex < 6)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
if (bKeyHeld || !bKeyPressed) {
return;
}

INPUTBOX_Append(Key);

gRequestDisplayScreen = DISPLAY_AIRCOPY;

if (gInputBoxIndex < 6) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}

gInputBoxIndex = 0;
uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;

for (unsigned int i = 0; i < BAND_N_ELEM; i++) {
if (Frequency < frequencyBandTable[i].lower || Frequency >= frequencyBandTable[i].upper) {
continue;
}

gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;

for (i = 0; i < BAND_N_ELEM; i++)
{
if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRxVfo->Band = i;
Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency);
gRxVfo->freq_config_RX.Frequency = Frequency;
gRxVfo->freq_config_TX.Frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
gCurrentVfo = gRxVfo;
RADIO_SetupRegisters(true);
BK4819_SetupAircopy();
BK4819_ResetFSK();
return;
}
if (TX_freq_check(Frequency)) {
continue;
}

gRequestDisplayScreen = DISPLAY_AIRCOPY;
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif

Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency);
gRxVfo->Band = i;
gRxVfo->freq_config_RX.Frequency = Frequency;
gRxVfo->freq_config_TX.Frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
gCurrentVfo = gRxVfo;
RADIO_SetupRegisters(true);
BK4819_SetupAircopy();
BK4819_ResetFSK();
return;
}

gRequestDisplayScreen = DISPLAY_AIRCOPY;
}

static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (gInputBoxIndex == 0)
{
gFSKWriteIndex = 0;
gAirCopyBlockNumber = 0;
gErrorsDuringAirCopy = 0;
gInputBoxIndex = 0;
gAirCopyIsSendMode = 0;

BK4819_PrepareFSKReceive();

gAircopyState = AIRCOPY_TRANSFER;
}
else
gInputBox[--gInputBoxIndex] = 10;
if (bKeyHeld || !bKeyPressed) {
return;
}

if (gInputBoxIndex == 0) {
gFSKWriteIndex = 0;
gAirCopyBlockNumber = 0;
gInputBoxIndex = 0;
gErrorsDuringAirCopy = 0;
gAirCopyIsSendMode = 0;

BK4819_PrepareFSKReceive();

gRequestDisplayScreen = DISPLAY_AIRCOPY;
gAircopyState = AIRCOPY_TRANSFER;
} else {
gInputBox[--gInputBoxIndex] = 10;
}

gRequestDisplayScreen = DISPLAY_AIRCOPY;
}

static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
gFSKWriteIndex = 0;
gAirCopyBlockNumber = 0;
gInputBoxIndex = 0;
gAirCopyIsSendMode = 1;
g_FSK_Buffer[0] = 0xABCD;
g_FSK_Buffer[1] = 0;
g_FSK_Buffer[35] = 0xDCBA;
if (bKeyHeld || !bKeyPressed) {
return;
}

AIRCOPY_SendMessage();
gFSKWriteIndex = 0;
gAirCopyBlockNumber = 0;
gInputBoxIndex = 0;
gAirCopyIsSendMode = 1;
g_FSK_Buffer[0] = 0xABCD;
g_FSK_Buffer[1] = 0;
g_FSK_Buffer[35] = 0xDCBA;

GUI_DisplayScreen();
GUI_DisplayScreen();

gAircopyState = AIRCOPY_TRANSFER;
}
gAircopyState = AIRCOPY_TRANSFER;
}

void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:
AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld);
break;
case KEY_EXIT:
AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld);
break;
default:
break;
switch (Key) {
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:
AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld);
break;
case KEY_EXIT:
AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld);
break;
default:
break;
}
}

Expand Down
3 changes: 1 addition & 2 deletions app/aircopy.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ extern uint8_t gAirCopyIsSendMode;

extern uint16_t g_FSK_Buffer[36];

void AIRCOPY_SendMessage(void);
bool AIRCOPY_SendMessage(void);
void AIRCOPY_StorePacket(void);
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);

#endif

#endif

Loading

0 comments on commit 2e69acb

Please sign in to comment.