librnode/src/librnode.h

523 lines
11 KiB
C

/* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef LIBRNODE_H
#define LIBRNODE_H
#include <stdint.h>
#include <stdbool.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#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