#include "config.h" #include "ch32v30x_flash.h" #include "ch32v30x_rng.h" #include "lib/cifra/sha2.h" #include "lib/ed25519/ed_25519.h" #include "sx1262.h" #include "util/hexdump.h" #include "util/log.h" #include "FreeRTOS.h" #include "task.h" PersistentData_t persistent; LoRaSettings currentLoRaSettings; #define TAG "Config" NodeEntry *getNextNode() { uint32_t oldest_timestamp = UINT32_MAX; NodeEntry *selectedNode = &(persistent.contacts[0]); for (int i = 0; i < CONTACT_COUNT; i++) { NodeEntry *curNode = &(persistent.contacts[i]); if (curNode->flags & NODE_ENTRY_FAV_FLAG) { continue; } if (curNode->last_seen_lt == 0) { selectedNode = curNode; break; } if (curNode->last_seen_lt < oldest_timestamp) { oldest_timestamp = curNode->last_seen_lt; selectedNode = curNode; } } return selectedNode; } NodeEntry *getNode (uint8_t hash) { NodeEntry *selectedNode = NULL; for (int i = 0; i < CONTACT_COUNT; i++) { NodeEntry *curNode = &(persistent.contacts[i]); if (curNode->pubKey[0] == hash) { selectedNode = curNode; break; } } return selectedNode; } NodeEntry *getNodePrefix (const uint8_t *hash) { NodeEntry *selectedNode = NULL; for (int i = 0; i < CONTACT_COUNT; i++) { NodeEntry *curNode = &(persistent.contacts[i]); if (memcmp (curNode->pubKey, hash, 4)) { selectedNode = curNode; break; } } return selectedNode; } Channel *getChannel (uint8_t hash, uint8_t ignoreCount) { Channel *selectedChannel = NULL; Channel *finalChannel = NULL; uint8_t matchCount = 0; for (int i = 0; i < ChannelCount; i++) { Channel *curChannel = &(persistent.channels[i]); if (curChannel->hash == hash) { selectedChannel = curChannel; if (++matchCount > ignoreCount) { finalChannel = selectedChannel; break; } } } return finalChannel; } void addChannel (char *name, const uint8_t *key) { uint32_t oldest_timestamp = UINT32_MAX; Channel *selectedChannel = &(persistent.channels[0]); for (int i = 0; i < ChannelCount; i++) { Channel *curChan = &(persistent.channels[i]); if (curChan->timestamp == 0) { selectedChannel = curChan; MESH_LOGD (TAG, "Deciding on channel index %d because of timestamp 0, name is %s", i, name); break; } if (strlen (curChan->name) == 0) { selectedChannel = curChan; MESH_LOGD (TAG, "Deciding on channel index %d because of name len 0, name is %s", i, name); break; } if (curChan->timestamp < oldest_timestamp) { oldest_timestamp = curChan->timestamp; selectedChannel = curChan; } } memset (selectedChannel->name, 0, sizeof (selectedChannel->name)); strncpy (selectedChannel->name, name, sizeof (selectedChannel->name)); memcpy (selectedChannel->key, key, sizeof (selectedChannel->key)); // Buffer for the digest uint8_t hash[CF_SHA256_HASHSZ]; // Context cf_sha256_context ctx; // 1. Initialize cf_sha256_init (&ctx); // 2. Feed in your data cf_sha256_update (&ctx, selectedChannel->key, sizeof (selectedChannel->key)); // 3. Compute digest cf_sha256_digest (&ctx, hash); selectedChannel->hash = hash[0]; selectedChannel->timestamp = RTC_GetCounter(); } void printNodeDB() { printf ("Node database:\n"); for (int i = 0; i < CONTACT_COUNT; i++) { const NodeEntry *node = &(persistent.contacts[i]); if (node->last_seen_lt == 0) continue; // skip inactive nodes printf ("Node %d:\n", i); printf (" Name: %s\n", node->name); hexdump ("Pubkey", node->pubKey, sizeof (node->pubKey)); hexdump ("Secret", node->secret, sizeof (node->secret)); printf ("\n"); printf (" GPS: lat=%d, lon=%d\n", node->gps_latitude, node->gps_longitude); printf (" Path: ... (not expanded, add if needed)\n"); printf (" Flags: 0x%02X\n", node->flags); printf (" Type: 0x%02X\n", node->type); printf (" Authenticated: %s\n", node->authenticated ? "Yes" : "No"); printf (" Last Seen (remote ts): %d\n", node->last_seen_rt); printf (" Last Seen (local ts): %d\n", node->last_seen_lt); printf (" Sync timestamp: %d\n", node->sync_timestamp); printf ("--------------------------------------\n"); } } void loadConfig() { memcpy (&persistent, FLASH_USER_PAGE_ADDR, sizeof (persistent)); memcpy(¤tLoRaSettings, &(persistent.loraSettings), sizeof(currentLoRaSettings)); uint32_t crcSum = *((uint32_t *)(((uint8_t *)&persistent) + (sizeof (persistent) - 2))); memset ((((uint8_t *)&persistent) + (sizeof (persistent) - sizeof (crcSum))), 0, 4); CRC_ResetDR(); uint32_t currentSum = CRC_CalcBlockCRC ((uint32_t *)&persistent, sizeof (persistent) - 2); if (currentSum != crcSum) { memset (&persistent, 0, sizeof (persistent)); } } void saveConfig() { CRC_ResetDR(); uint32_t currentSum = CRC_CalcBlockCRC ((uint32_t *)&persistent, sizeof (persistent) - 2); memcpy ((((uint8_t *)&persistent) + (sizeof (persistent) - sizeof (currentSum))), (uint8_t *)currentSum, 4); FLASH_Unlock(); FLASH_ErasePage_Fast (1919); FLASH_ProgramPage_Fast (1919, (uint32_t *)&persistent); FLASH_Lock(); } void genSeed (uint8_t *seedOut) { RCC_AHBPeriphClockCmd (RCC_AHBPeriph_RNG, ENABLE); RNG_Cmd (ENABLE); uint32_t random; for (uint8_t i = 0; i < 8; i++) { while (RNG_GetFlagStatus (RNG_FLAG_DRDY) == RESET) { vTaskDelay (10); } random = RNG_GetRandomNumber(); memcpy (&(seedOut[i * 4]), &random, sizeof (random)); } RCC_AHBPeriphClockCmd (RCC_AHBPeriph_RNG, DISABLE); RNG_Cmd (DISABLE); } const uint8_t publicChannelPSK[16] = {0x8b, 0x33, 0x87, 0xe9, 0xc5, 0xcd, 0xea, 0x6a, 0xc9, 0xe5, 0xed, 0xba, 0xa1, 0x15, 0xcd, 0x72}; const uint8_t BRNTestChannelPSK[16] = {0x44, 0x81, 0xda, 0x0e, 0x4e, 0x03, 0xc4, 0x9e, 0x84, 0x77, 0x25, 0xd8, 0x3a, 0x93, 0xbf, 0x80}; const char *getStringRole (uint8_t role) { switch (role) { case NODE_TYPE_CHAT_NODE: return "Chat node"; case NODE_TYPE_REPEATER: return "Repeater"; case NODE_TYPE_ROOM_SERVER: return "Room server"; case NODE_TYPE_SENSOR: return "Sensor"; default: return "Unknown"; } } void populateDefaults() { uint8_t seed[32]; //memcpy(seed, "vFt0FRugSOeqnkshImMCVfgHM5vBxz4", 32); //chat node identity memcpy (seed, "vFt0FRugSOeqnkshImMCVfgHM5vBxz3", 32); // repeater identity // genSeed(seed); //random identity ed25519_create_keypair (persistent.pubkey, persistent.privkey, seed); // persistent.nodeType = NODE_TYPE_CHAT_NODE; persistent.nodeType = NODE_TYPE_REPEATER; memset (persistent.password, 0, sizeof (persistent.password)); strcpy (persistent.password, "hesielko"); strcpy (persistent.nodeName, "BRN RiscVpeater"); //strcpy (persistent.nodeName, "BRN RiscVnode"); persistent.adcMultiplier = 0; persistent.loraSettings.txPowerInDbm = 20; persistent.loraSettings.frequencyInHz = 869554000; persistent.loraSettings.spreadingFactor = 8; persistent.loraSettings.bandwidth = SX126X_LORA_BW_62_5; persistent.loraSettings.codingRate = SX126X_LORA_CR_4_8; persistent.loraSettings.preambleLength = 16; persistent.loraSettings.tcxoVoltage = 2.2; // ebyte // persistent.tcxoVoltage = 1.8; // heltec memcpy(¤tLoRaSettings, &(persistent.loraSettings), sizeof(currentLoRaSettings)); addChannel ("Public", publicChannelPSK); addChannel ("BRNTest", BRNTestChannelPSK); persistent.doRepeat = 1; persistent.allowReadOnly = 1; persistent.latitude = 48190900; persistent.longitude = 17030300; persistent.altitude = 23400; } void LoraApply() { MESH_LOGW (TAG, "LoraInit"); LoRaInit(); char useRegulatorLDO = 0; LoRaDebugPrint (0); uint16_t loraBeginStat = LoRaBegin (currentLoRaSettings.frequencyInHz, currentLoRaSettings.txPowerInDbm, currentLoRaSettings.tcxoVoltage, useRegulatorLDO); if (loraBeginStat != 0) { MESH_LOGE (TAG, "Does not recognize the module"); while (1) { vTaskDelay (pdMS_TO_TICKS (1000)); MESH_LOGE (TAG, "CRITICAL: LoRa not found, halted"); } } char crcOn = 1; char invertIrq = 0; LoRaConfig (currentLoRaSettings.spreadingFactor, currentLoRaSettings.bandwidth, currentLoRaSettings.codingRate, currentLoRaSettings.preambleLength, 0, crcOn, invertIrq); }