/* Copyright (c) 2025 - Jacob Eva (Liberated Embedded Systems) * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef LIBRNODE_H #define LIBRNODE_H #include #include #include #include #define MIN_FW_VER 1.66 // PLATFORMS #define PLATFORM_ESP32 0x80 #define PLATFORM_NRF52 0x70 // #define SERIAL_SIZE 4 #define MADE_SIZE 4 #define CHECKSUM_SIZE 16 #define SIGNATURE_SIZE 128 #define FW_HASH_SIZE 256 / 8 #define RESP_BUF_SIZE 512 #define EEPROM_SIZE 296 #define MAX_INTERFACES 256 #define FILE_MAX_SIZE 4 * 1024 * 1024 // 4MB max file size for single fw binary // BLUETOOTH VALUES #define BT_OFF 0 #define BT_ON 1 #define BT_PAIRING 2 // struct RNode { char* port; int fd; uint32_t baud; uint8_t platform; uint8_t mcu; // EEPROM below here! uint8_t product; uint8_t model; uint8_t hw_rev; uint8_t serial[4]; uint8_t made[4]; uint8_t checksum[16]; uint8_t signature[128]; uint8_t lock_byte; // All these have their own getter functions as they can change on runtime; the cached EEPROM values may not reflect the true status of the radio uint8_t sf; uint8_t cr; uint8_t txp; uint32_t bw; uint32_t freq; uint8_t cfg_ok; bool bt; bool disp_set; uint8_t disp_int; uint8_t disp_addr; // This is where the EEPROM read directly from the RNode is stored uint8_t r_eeprom[EEPROM_SIZE]; // END EEPROM float st_alock; float lt_alock; uint32_t bt_pairing_pin; // ESP32 only! uint32_t boot_app0_addr; uint32_t bootloader_addr; uint32_t bin_addr; uint32_t partitions_addr; uint32_t console_image_addr; // float fw_ver; bool connected; // Multiple modems uint8_t sel_int; uint8_t interfaces[MAX_INTERFACES]; uint8_t int_state[MAX_INTERFACES]; // void (*prog_cb)(uint8_t); }; /* Establishes communication with an RNode * Params: port (e.g. /dev/ttyACM0), baud rate (e.g. 115200), detect (attempt * to communicate with RNode), force_detect (fail if cannot communicate with * RNode) * Scope: public * Returns: * 0 - success * -1 - generic error */ int rnode_init(struct RNode* rn, char* path, uint32_t baud, bool detect, bool force_detect); /* Resets an RNode * Scope: public * Returns: * 0 - success * -1 - generic error */ int rnode_reset(struct RNode* rn); /* Sets an RNode's platform attribute manually * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_platform(struct RNode* rn, uint8_t platform); /* Enable / disable Bluetooth on an RNode * Scope: public * Returns * > 0 - bluetooth pairing pin value * 0 - success * -1 - generic error * -4 - rnode did not respond */ int rnode_set_bt(struct RNode* rn, uint8_t val); /* Attempt to retrieve the BT pairing code of an RNode. Blocking function, * should be run in a separate thread. * Params: timeout (in ms, minimum value 200) * Scope: public * Returns * > 0 - bluetooth pairing code * 0 - success * -1 - generic error * -4 - rnode did not respond */ int rnode_get_bt_pin(struct RNode* rn, uint32_t timeout); /* Display related functions */ /* Set display intensity on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_disp_int(struct RNode* rn, uint8_t disp_int); /* Set display timeout on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_disp_timeout(struct RNode* rn, uint8_t timeout); /* Set display address on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_disp_addr(struct RNode* rn, uint8_t addr); #define DISPLAY_PORTRAIT 0 #define DISPLAY_LANDSCAPE 1 #define DISPLAY_PORTRAIT_INV 2 #define DISPLAY_LANDSCAPE_INV 3 /* Set display rotation on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_disp_rot(struct RNode* rn, uint8_t rot); /* Start display reconditioning on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_start_disp_recon(struct RNode* rn); /* Set neopixel intensity on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_np_int(struct RNode* rn, uint8_t np_int); /* Get available interfaces on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_interfaces(struct RNode* rn); /* Select interface on an RNode (in preparation for running rnode_set_freq, etc) * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_select_interface(struct RNode* rn, uint8_t modem); /* Set frequency on an RNode (in preparation for TNC mode) * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_freq(struct RNode* rn, uint32_t freq); /* Get frequency on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_freq(struct RNode* rn); /* Set bandwidth on an RNode (in preparation for TNC mode) * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_bw(struct RNode* rn, uint32_t bw); /* Get bandwidth on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_bw(struct RNode* rn); /* Set transmission power on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_txp(struct RNode* rn, uint8_t txp); /* Get transmission power on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_txp(struct RNode* rn); /* Set spreading factor on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_sf(struct RNode* rn, uint8_t sf); /* Get spreading factor on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_sf(struct RNode* rn); /* Set coding rate on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_cr(struct RNode* rn, uint8_t cr); /* Get coding rate on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_cr(struct RNode* rn); /* Set short term airtime limit on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ float rnode_set_st_alock(struct RNode* rn, float at_l); /* Set long term airtime limit on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ float rnode_set_lt_alock(struct RNode* rn, float at_l); /* Start or stop selected interface on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_interface_state(struct RNode* rn, bool state); /* Get selected interface state on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_interface_state(struct RNode* rn); /* Mode selection functions */ /* Enable the host-controlled (normal) mode of operation on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_normal_mode(struct RNode* rn); /* Enable the serial TNC mode of operation on an RNode * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_tnc_mode(struct RNode* rn); /* EEPROM related functions */ /* Sets the firmware hash on an RNode. * Scope: public * Returns: * 0 - success * -1 - generic error */ int rnode_set_fw_hash(struct RNode* rn, uint8_t* hash); /* Sets an RNode's product in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_product(struct RNode* rn, uint8_t product); /* Sets an RNode's model in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_model(struct RNode* rn, uint8_t model); /* Sets an RNode's hardware revision in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_hw_rev(struct RNode* rn, uint8_t hw_rev); /* Sets an RNode's serial in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_serial(struct RNode* rn, uint8_t* serial); /* Sets an RNode's manufacture time in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_made_time(struct RNode* rn, uint32_t time); /* Calculates an RNode's checksum for its EEPROM. Must ONLY be called AFTER * rnode_set_product, rnode_set_model, rnode_set_hw_rev, rnode_set_serial and * rnode_set_made_time are all called. OR alternatively, after rnode_get_eeprom. * Scope: public * Returns * 0 - success * -1 - generic error * -3 - provided array was too small */ int rnode_calculate_checksum(struct RNode* rn, uint8_t* checksum); /* Sets an RNode's checksum in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_checksum(struct RNode* rn, uint8_t* checksum); /* Generate's an RNode's EEPROM signature from the checksum * Scope: public * Returns * 0 - success * -1 - generic error */ void* rnode_generate_signature(struct RNode* rn, EVP_PKEY *signing_key); /* Sets an RNode's signature in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_signature(struct RNode* rn, uint8_t* data); /* Sets an RNode's lock byte in its EEPROM * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_set_lock(struct RNode* rn); /* Retrieve an RNode's EEPROM values into its struct * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_get_eeprom(struct RNode* rn); /* Dump an RNode's entire EEPROM to r_eeprom * Note: This will populate r_eeprom but not the cached EEPROM values. If you * want to update the cached values, call rnode_get_eeprom instead. * Scope: public * Returns * 0 - success * -1 - generic error */ int rnode_dump_eeprom(struct RNode* rn); /* Verify an RNode's EEPROM matches the expected values * Scope: public * Returns * 0 - success * value > 0 or value < 0 - EEPROM invalid */ int rnode_verify_eeprom(struct RNode* rn); /* Wipes an RNode's EEPROM. * Scope: public * Returns: * 0 - success * -1 - generic error * -2 - rnode not supported (firmware too old, please update) */ int rnode_wipe_eeprom(struct RNode* rn); /* Flashes an RNode. * Scope: public * Returns: * 0 - success * -1 - generic error * -9 - ESP32 image invalid, SHA256 digest incorrect */ int rnode_flash(struct RNode* rn, char* zip_path, bool update, uint8_t* serial, EVP_PKEY* priv_key, bool touch); int rnode_cleanup(struct RNode* rn); #endif