Merge pull request #66 from kamilsss655/rc19.1

Rc19.1
This commit is contained in:
Nunu 2024-01-13 21:26:07 +01:00 committed by GitHub
commit d0f97a8842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 127 additions and 203 deletions

View File

@ -18,7 +18,7 @@ ENABLE_VOICE := 0
ENABLE_VOX := 1
ENABLE_ALARM := 0
ENABLE_TX1750 := 0
ENABLE_PWRON_PASSWORD := 0
ENABLE_PWRON_PASSWORD := 1
ENABLE_DTMF_CALLING := 0
#---- DEBUG ----
@ -83,9 +83,6 @@ OBJS += external/printf/printf.o
# Drivers
OBJS += driver/adc.o
ifeq ($(ENABLE_UART),1)
OBJS += driver/aes.o
endif
OBJS += driver/backlight.o
ifeq ($(ENABLE_FMRADIO),1)
OBJS += driver/bk1080.o

View File

@ -474,6 +474,13 @@ void MENU_AcceptSetting(void)
gUpdateStatus = true;
break;
#ifdef ENABLE_PWRON_PASSWORD
case MENU_PASSWORD:
gEeprom.POWER_ON_PASSWORD = MIN(gSubMenuSelection, PASSWORD_OFF);
gUpdateStatus = true;
break;
#endif
case MENU_W_N:
gTxVfo->CHANNEL_BANDWIDTH = gSubMenuSelection;
gRequestSaveChannel = 1;
@ -903,6 +910,12 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.RX_OFFSET;
break;
#ifdef ENABLE_PWRON_PASSWORD
case MENU_PASSWORD:
gSubMenuSelection = gEeprom.POWER_ON_PASSWORD;
break;
#endif
case MENU_W_N:
gSubMenuSelection = gTxVfo->CHANNEL_BANDWIDTH;
break;
@ -916,7 +929,8 @@ void MENU_ShowCurrentSetting(void)
break;
case MENU_MEM_CH:
gSubMenuSelection = RADIO_ValidMemoryChannelsCount(false, 0);
//todo: in vfo mode select last empty channel slot
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO];
break;
case MENU_MEM_NAME:
@ -1258,6 +1272,17 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gInputBoxIndex = 0;
return;
}
#ifdef ENABLE_PWRON_PASSWORD
if (UI_MENU_GetCurrentMenuId() == MENU_PASSWORD)
{
// get 4 digits
if (gInputBoxIndex < 4) { return; }
uint32_t Password;
Password = StrToUL(INPUTBOX_GetAscii());
gSubMenuSelection = Password;
}
#endif
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
@ -1650,6 +1675,13 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gRequestDisplayScreen = DISPLAY_MENU;
return;
}
#ifdef ENABLE_PWRON_PASSWORD
if (UI_MENU_GetCurrentMenuId() == MENU_PASSWORD)
{
gSubMenuSelection = PASSWORD_OFF;
gRequestDisplayScreen = DISPLAY_MENU;
}
#endif
VFO = 0;

View File

@ -26,7 +26,6 @@
#include "board.h"
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/aes.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
@ -120,11 +119,6 @@ typedef struct {
} Data;
} REPLY_0529_t;
typedef struct {
Header_t Header;
uint32_t Response[4];
} CMD_052D_t;
typedef struct {
Header_t Header;
struct {
@ -207,25 +201,6 @@ static void SendVersion(void)
SendReply(&Reply, sizeof(Reply));
}
static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse)
{
unsigned int i;
uint32_t IV[4];
IV[0] = 0;
IV[1] = 0;
IV[2] = 0;
IV[3] = 0;
AES_Encrypt(pKey, IV, pIn, IV, true);
for (i = 0; i < 4; i++)
if (IV[i] != pResponse[i])
return true;
return false;
}
static void CMD_0514(const uint8_t *pBuffer)
{
const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer;
@ -346,47 +321,6 @@ static void CMD_0529(void)
SendReply(&Reply, sizeof(Reply));
}
static void CMD_052D(const uint8_t *pBuffer)
{
const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer;
REPLY_052D_t Reply;
bool bIsLocked;
#ifdef ENABLE_FMRADIO
gFmRadioCountdown_500ms = fm_radio_countdown_500ms;
#endif
Reply.Header.ID = 0x052E;
Reply.Header.Size = sizeof(Reply.Data);
bIsLocked = bHasCustomAesKey;
if (!bIsLocked)
bIsLocked = IsBadChallenge(gCustomAesKey, gChallenge, pCmd->Response);
if (!bIsLocked)
{
bIsLocked = IsBadChallenge(gDefaultAesKey, gChallenge, pCmd->Response);
if (bIsLocked)
gTryCount++;
}
if (gTryCount < 3)
{
if (!bIsLocked)
gTryCount = 0;
}
else
{
gTryCount = 3;
bIsLocked = true;
}
gIsLocked = bIsLocked;
Reply.Data.bIsLocked = bIsLocked;
SendReply(&Reply, sizeof(Reply));
}
static void CMD_052F(const uint8_t *pBuffer)
{
const CMD_052F_t *pCmd = (const CMD_052F_t *)pBuffer;
@ -544,10 +478,6 @@ void UART_HandleCommand(void)
CMD_0529();
break;
case 0x052D:
CMD_052D(UART_Command.Buffer);
break;
case 0x052F:
CMD_052F(UART_Command.Buffer);
break;

15
board.c
View File

@ -45,6 +45,7 @@
#include "sram-overlay.h"
#endif
#include "ui/menu.h"
#include "ARMCM0.h"
static const uint32_t gDefaultFrequencyTable[] =
{
@ -579,8 +580,10 @@ void BOARD_EEPROM_Init(void)
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE;
// 0E98..0E9F
EEPROM_ReadBuffer(0x0E98, Data, 8);
memmove(&gEeprom.POWER_ON_PASSWORD, Data, 4);
#ifdef ENABLE_PWRON_PASSWORD
EEPROM_ReadBuffer(0x0E98, Data, 8);
memmove(&gEeprom.POWER_ON_PASSWORD, Data, 4);
#endif
// 0EA0..0EA7
EEPROM_ReadBuffer(0x0EA0, Data, 8);
@ -588,6 +591,9 @@ void BOARD_EEPROM_Init(void)
gEeprom.VOX_DELAY = (Data[0] < 11) ? Data[0] : 4;
#endif
gEeprom.RX_AGC = (Data[1] < RX_AGC_LEN) ? Data[1] : RX_AGC_SLOW;
#ifdef ENABLE_PWRON_PASSWORD
gEeprom.PASSWORD_WRONG_ATTEMPTS = (Data[2] > PASSWORD_MAX_RETRIES) ? PASSWORD_MAX_RETRIES : Data[2];
#endif
// 0EA8..0EAF
EEPROM_ReadBuffer(0x0EA8, Data, 8);
@ -868,6 +874,9 @@ void BOARD_FactoryReset(bool bIsAll)
{
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
gEeprom.RX_OFFSET = 0;
gEeprom.POWER_ON_PASSWORD = PASSWORD_OFF;
gEeprom.PASSWORD_WRONG_ATTEMPTS = 0;
SETTINGS_SaveSettings();
// set the first few memory channels
for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++)
{
@ -877,5 +886,7 @@ void BOARD_FactoryReset(bool bIsAll)
gRxVfo->Band = FREQUENCY_GetBand(Frequency);
SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2);
}
// reboot device
NVIC_SystemReset();
}
}

Binary file not shown.

View File

@ -1,74 +0,0 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdbool.h>
#include "bsp/dp32g030/aes.h"
#include "driver/aes.h"
static void AES_Setup_ENC_CBC(bool IsDecrypt, const void *pKey, const void *pIv)
{
const uint32_t *pK = (const uint32_t *)pKey;
const uint32_t *pI = (const uint32_t *)pIv;
(void)IsDecrypt; // unused
AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_DISABLE;
AES_CR = AES_CR_CHMOD_BITS_CBC;
AES_KEYR3 = pK[0];
AES_KEYR2 = pK[1];
AES_KEYR1 = pK[2];
AES_KEYR0 = pK[3];
AES_IVR3 = pI[0];
AES_IVR2 = pI[1];
AES_IVR1 = pI[2];
AES_IVR0 = pI[3];
AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_ENABLE;
}
static void AES_Transform(const void *pIn, void *pOut)
{
const uint32_t *pI = (const uint32_t *)pIn;
uint32_t *pO = (uint32_t *)pOut;
AES_DINR = pI[0];
AES_DINR = pI[1];
AES_DINR = pI[2];
AES_DINR = pI[3];
while ((AES_SR & AES_SR_CCF_MASK) == AES_SR_CCF_BITS_NOT_COMPLETE) {
}
pO[0] = AES_DOUTR;
pO[1] = AES_DOUTR;
pO[2] = AES_DOUTR;
pO[3] = AES_DOUTR;
AES_CR |= AES_CR_CCFC_BITS_SET;
}
void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks)
{
const uint8_t *pI = (const uint8_t *)pIn;
uint8_t *pO = (uint8_t *)pOut;
uint8_t i;
AES_Setup_ENC_CBC(0, pKey, pIv);
for (i = 0; i < NumBlocks; i++) {
AES_Transform(pI + (i * 16), pO + (i * 16));
}
}

View File

@ -1,25 +0,0 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_AES_H
#define DRIVER_AES_H
#include <stdint.h>
void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks);
#endif

View File

@ -69,7 +69,8 @@ void BK1080_Init(uint16_t Frequency, bool bDoScan)
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201);
}
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A5F);
// Europe/USA configuration
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, (0u << 8) | (0b00 << 6) | (0b01 << 4) | (0b1111 << 0));
BK1080_SetFrequency(Frequency);
}
else
@ -78,8 +79,7 @@ void BK1080_Init(uint16_t Frequency, bool bDoScan)
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
}
// Europe/USA configuration
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, (0u << 8) | (0b00 << 6) | (0b01 << 4) | (0b1111 << 0));
}
uint16_t BK1080_ReadRegister(BK1080_Register_t Register)

4
main.c
View File

@ -174,12 +174,14 @@ void Main(void)
}
#ifdef ENABLE_PWRON_PASSWORD
if (gEeprom.POWER_ON_PASSWORD < 1000000)
if (gEeprom.POWER_ON_PASSWORD < PASSWORD_OFF)
{
bIsInLockScreen = true;
UI_DisplayLock();
bIsInLockScreen = false;
}
gEeprom.PASSWORD_WRONG_ATTEMPTS = 0;
gFlagSaveSettings = true;
#endif
BOOT_ProcessMode(BootMode);

7
misc.h
View File

@ -51,6 +51,13 @@ enum {
LAST_CHANNEL
};
#ifdef ENABLE_PWRON_PASSWORD
enum {
PASSWORD_OFF = 10000u
};
#define PASSWORD_MAX_RETRIES 3
#endif
enum {
FLASHLIGHT_OFF = 0,
FLASHLIGHT_ON,

View File

@ -98,7 +98,7 @@ void SETTINGS_SaveSettings(void)
EEPROM_ReadBuffer(0x0E98, State, 8);
#ifdef ENABLE_PWRON_PASSWORD
memcpy(&State[0], &gEeprom.POWER_ON_PASSWORD, 4);
#endif
#endif
memcpy(&State[4], &gEeprom.RX_OFFSET, 4);
EEPROM_WriteBuffer(0x0E98, State, true);
@ -107,6 +107,7 @@ void SETTINGS_SaveSettings(void)
State[0] = gEeprom.VOX_DELAY;
#endif
State[1] = gEeprom.RX_AGC;
State[2] = gEeprom.PASSWORD_WRONG_ATTEMPTS;
EEPROM_WriteBuffer(0x0EA0, State, true);
memset(State, 0xFF, sizeof(State));

View File

@ -243,7 +243,10 @@ typedef struct {
uint8_t DAC_GAIN;
VFO_Info_t VfoInfo[2];
#ifdef ENABLE_PWRON_PASSWORD
uint32_t POWER_ON_PASSWORD;
uint8_t PASSWORD_WRONG_ATTEMPTS;
#endif
uint16_t VOX1_THRESHOLD;
uint16_t VOX0_THRESHOLD;

View File

@ -28,22 +28,28 @@
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "ui/lock.h"
#include "board.h"
static void Render(void)
static void Render(bool maxAttemptsReached)
{
unsigned int i;
char String[7];
char String[5];
memset(gStatusLine, 0, sizeof(gStatusLine));
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
strcpy(String, "LOCK");
UI_PrintString(String, 0, 127, 1, 10);
for (i = 0; i < 6; i++)
String[i] = (gInputBox[i] == 10) ? '-' : '*';
String[6] = 0;
UI_PrintString(String, 0, 127, 3, 12);
if (maxAttemptsReached){
strcpy(String, "OK");
UI_PrintString(String, 0, 127, 2, 10);
}
else
{
strcpy(String, "LOCK");
UI_PrintString(String, 0, 127, 1, 10);
for (i = 0; i < 4; i++)
String[i] = (gInputBox[i] == 10) ? '-' : '*';
String[6] = 0;
UI_PrintString(String, 0, 127, 3, 12);
}
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
}
@ -51,6 +57,7 @@ static void Render(void)
void UI_DisplayLock(void)
{
KEY_Code_t Key;
KEY_Code_t gKeyReadingLocal;
BEEP_Type_t Beep;
gUpdateDisplay = true;
@ -66,8 +73,13 @@ void UI_DisplayLock(void)
gNextTimeslice = false;
Key = KEYBOARD_Poll();
if (gKeyReading0 == Key)
if (gEeprom.PASSWORD_WRONG_ATTEMPTS >= PASSWORD_MAX_RETRIES)
{
Render(true);
BOARD_FactoryReset(true);
return;
}
if (gKeyReadingLocal == Key)
{
if (++gDebounceCounter == key_debounce_10ms)
{
@ -93,7 +105,7 @@ void UI_DisplayLock(void)
case KEY_9:
INPUTBOX_Append(Key - KEY_0);
if (gInputBoxIndex < 6) // 6 frequency digits
if (gInputBoxIndex < 4) // 4 frequency digits
{
Beep = BEEP_1KHZ_60MS_OPTIONAL;
}
@ -107,8 +119,15 @@ void UI_DisplayLock(void)
if ((gEeprom.POWER_ON_PASSWORD) == Password)
{
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
gEeprom.PASSWORD_WRONG_ATTEMPTS = 0;
return;
}
else
{
gEeprom.PASSWORD_WRONG_ATTEMPTS++;
}
SETTINGS_SaveSettings();
memset(gInputBox, 10, sizeof(gInputBox));
@ -140,19 +159,12 @@ void UI_DisplayLock(void)
else
{
gDebounceCounter = 0;
gKeyReading0 = Key;
}
if (UART_IsCommandAvailable())
{
__disable_irq();
UART_HandleCommand();
__enable_irq();
gKeyReadingLocal = Key;
}
if (gUpdateDisplay)
{
Render();
Render(false);
gUpdateDisplay = false;
}
}

View File

@ -109,6 +109,9 @@ const t_menu_item MenuList[] =
#endif
{"BatVol", VOICE_ID_INVALID, MENU_VOL }, // was "VOL"
{"RxMode", VOICE_ID_DUAL_STANDBY, MENU_TDR },
#ifdef ENABLE_PWRON_PASSWORD
{"Passwd", VOICE_ID_INVALID, MENU_PASSWORD }, // power on password
#endif
{"Sql", VOICE_ID_SQUELCH, MENU_SQL },
// hidden menu items from here on
// enabled if pressing both the PTT and upper side button at power-on
@ -559,6 +562,28 @@ void UI_DisplayMenu(void)
already_printed = true;
break;
#ifdef ENABLE_PWRON_PASSWORD
case MENU_PASSWORD:
if (!gIsInSubMenu || gInputBoxIndex == 0)
{
if((unsigned int)gSubMenuSelection >= PASSWORD_OFF)
{
sprintf(String, "OFF");
}
else
{
sprintf(String, "****");
}
}
else
{
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.4s ",ascii);
}
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
already_printed = true;
break;
#endif
case MENU_W_N:
strcpy(String, bwNames[gSubMenuSelection]);

View File

@ -59,6 +59,9 @@ enum
MENU_ABR_MIN,
MENU_ABR_MAX,
MENU_TDR,
#ifdef ENABLE_PWRON_PASSWORD
MENU_PASSWORD,
#endif
MENU_BEEP,
#ifdef ENABLE_VOICE
MENU_VOICE,