2019-09-21 00:16:06 -03:00
|
|
|
#pragma once
|
2022-02-28 21:19:20 -04:00
|
|
|
#include <AP_HAL/AP_HAL_Boards.h>
|
|
|
|
#include <AP_HAL/Semaphores.h>
|
2019-09-21 00:16:06 -03:00
|
|
|
|
2023-04-08 01:09:10 -03:00
|
|
|
#if HAL_ENABLE_DRONECAN_DRIVERS
|
2019-09-21 00:16:06 -03:00
|
|
|
#include <AP_Common/Bitmask.h>
|
|
|
|
#include <StorageManager/StorageManager.h>
|
2020-05-31 09:47:45 -03:00
|
|
|
#include <AP_CANManager/AP_CANManager.h>
|
2023-01-04 21:09:23 -04:00
|
|
|
#include <canard/publisher.h>
|
|
|
|
#include <canard/subscriber.h>
|
|
|
|
#include <canard/service_client.h>
|
|
|
|
#include "AP_Canard_iface.h"
|
|
|
|
#include <dronecan_msgs.h>
|
2019-09-21 00:16:06 -03:00
|
|
|
|
2023-04-06 21:18:01 -03:00
|
|
|
class AP_DroneCAN;
|
2023-01-04 21:09:23 -04:00
|
|
|
//Forward declaring classes
|
2023-04-06 21:18:01 -03:00
|
|
|
class AP_DroneCAN_DNA_Server
|
2019-09-21 00:16:06 -03:00
|
|
|
{
|
|
|
|
StorageAccess storage;
|
|
|
|
|
2024-08-17 14:24:17 -03:00
|
|
|
struct NodeRecord {
|
|
|
|
uint8_t uid_hash[6];
|
2019-09-21 00:16:06 -03:00
|
|
|
uint8_t crc;
|
|
|
|
};
|
|
|
|
|
2024-08-17 15:58:34 -03:00
|
|
|
/*
|
|
|
|
* For each node ID (1 through MAX_NODE_ID), the database can have one
|
2024-08-17 14:24:17 -03:00
|
|
|
* registration for it. Each registration consists of a NodeRecord which
|
2024-08-17 15:58:34 -03:00
|
|
|
* contains the (hash of the) unique ID reported by that node ID. Other
|
|
|
|
* info could be added to the registration in the future.
|
|
|
|
*
|
|
|
|
* Physically, the database is stored as a header and format version,
|
2024-08-17 14:24:17 -03:00
|
|
|
* followed by an array of NodeRecords indexed by node ID. If a particular
|
|
|
|
* NodeRecord has an all-zero unique ID hash or an invalid CRC, then that
|
2024-08-17 15:58:34 -03:00
|
|
|
* node ID isn't considerd to have a registration.
|
|
|
|
*
|
|
|
|
* The database has public methods which handle the server behavior for the
|
|
|
|
* relevant message. The methods can be used by multiple servers in
|
|
|
|
* different threads, so each holds a lock for its duration.
|
|
|
|
*/
|
2024-08-05 12:31:01 -03:00
|
|
|
class Database {
|
|
|
|
public:
|
|
|
|
Database() {};
|
|
|
|
|
|
|
|
// initialize database (storage accessor is always replaced with the one supplied)
|
|
|
|
void init(StorageAccess *storage_);
|
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// remove all registrations from the database
|
2024-08-05 12:31:01 -03:00
|
|
|
void reset();
|
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// return true if the given node ID is registered
|
2024-08-17 14:51:24 -03:00
|
|
|
bool is_registered(uint8_t node_id) {
|
|
|
|
return node_registered.get(node_id);
|
2024-08-05 12:39:37 -03:00
|
|
|
}
|
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// handle initializing the server with its own node ID and unique ID
|
2024-09-08 21:09:16 -03:00
|
|
|
void init_server(uint8_t own_node_id, const uint8_t own_unique_id[], uint8_t own_unique_id_len);
|
2024-08-05 12:43:53 -03:00
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// handle processing the node info message. returns true if from a duplicate node
|
2024-08-17 14:51:24 -03:00
|
|
|
bool handle_node_info(uint8_t source_node_id, const uint8_t unique_id[]);
|
2024-08-05 12:50:55 -03:00
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// handle the allocation message. returns the allocated node ID, or 0 if allocation failed
|
2024-09-13 23:12:48 -03:00
|
|
|
uint8_t handle_allocation(const uint8_t unique_id[]);
|
2024-08-05 12:57:38 -03:00
|
|
|
|
2024-08-05 13:04:32 -03:00
|
|
|
private:
|
2024-08-17 15:17:42 -03:00
|
|
|
// retrieve node ID that matches the given unique ID. returns 0 if not found
|
2024-08-17 14:51:24 -03:00
|
|
|
uint8_t find_node_id(const uint8_t unique_id[], uint8_t size);
|
2024-08-05 12:39:37 -03:00
|
|
|
|
2024-08-17 16:49:32 -03:00
|
|
|
// fill the given record with the hash of the given unique ID
|
|
|
|
void compute_uid_hash(NodeRecord &record, const uint8_t unique_id[], uint8_t size) const;
|
|
|
|
|
2024-09-08 21:09:16 -03:00
|
|
|
// register a given unique ID to a given node ID, deleting any existing registration for the unique ID
|
|
|
|
void register_uid(uint8_t node_id, const uint8_t unique_id[], uint8_t size);
|
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// create the registration for the given node ID and set its record's unique ID
|
2024-08-17 14:51:24 -03:00
|
|
|
void create_registration(uint8_t node_id, const uint8_t unique_id[], uint8_t size);
|
2024-08-05 12:39:37 -03:00
|
|
|
|
2024-08-17 16:49:32 -03:00
|
|
|
// delete the given node ID's registration
|
|
|
|
void delete_registration(uint8_t node_id);
|
2024-08-05 12:39:37 -03:00
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// return true if the given node ID has a registration
|
2024-08-17 14:51:24 -03:00
|
|
|
bool check_registration(uint8_t node_id);
|
2024-08-05 12:31:01 -03:00
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// read the given node ID's registration's record
|
2024-08-17 14:51:24 -03:00
|
|
|
void read_record(NodeRecord &record, uint8_t node_id);
|
2024-08-05 12:31:01 -03:00
|
|
|
|
2024-08-17 15:17:42 -03:00
|
|
|
// write the given node ID's registration's record
|
2024-08-17 14:51:24 -03:00
|
|
|
void write_record(const NodeRecord &record, uint8_t node_id);
|
2024-08-05 12:31:01 -03:00
|
|
|
|
|
|
|
// bitmasks containing a status for each possible node ID (except 0 and > MAX_NODE_ID)
|
2024-08-17 14:51:24 -03:00
|
|
|
Bitmask<128> node_registered; // have a registration for this node ID
|
2024-08-05 12:31:01 -03:00
|
|
|
|
|
|
|
StorageAccess *storage;
|
|
|
|
HAL_Semaphore sem;
|
|
|
|
};
|
|
|
|
|
|
|
|
static Database db;
|
|
|
|
|
2019-09-21 00:16:06 -03:00
|
|
|
enum ServerState {
|
2022-04-29 08:47:51 -03:00
|
|
|
NODE_STATUS_UNHEALTHY = -5,
|
2019-09-21 00:16:06 -03:00
|
|
|
DUPLICATE_NODES = -2,
|
|
|
|
HEALTHY = 0
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t last_verification_request;
|
|
|
|
uint8_t curr_verifying_node;
|
2023-01-04 21:09:23 -04:00
|
|
|
uint8_t self_node_id;
|
2019-09-21 00:16:06 -03:00
|
|
|
bool nodeInfo_resp_rcvd;
|
|
|
|
|
2024-07-13 16:59:20 -03:00
|
|
|
// bitmasks containing a status for each possible node ID (except 0 and > MAX_NODE_ID)
|
|
|
|
Bitmask<128> node_verified; // node seen and unique ID matches stored
|
|
|
|
Bitmask<128> node_seen; // received NodeStatus
|
|
|
|
Bitmask<128> node_logged; // written to log fle
|
|
|
|
Bitmask<128> node_healthy; // reports healthy
|
2020-12-31 17:04:08 -04:00
|
|
|
|
|
|
|
uint8_t last_logging_count;
|
2019-09-21 00:16:06 -03:00
|
|
|
|
|
|
|
//Error State
|
|
|
|
enum ServerState server_state;
|
|
|
|
uint8_t fault_node_id;
|
|
|
|
char fault_node_name[15];
|
|
|
|
|
|
|
|
|
2024-09-08 23:37:41 -03:00
|
|
|
// dynamic node ID allocation state variables
|
2019-09-21 00:16:06 -03:00
|
|
|
uint8_t rcvd_unique_id[16];
|
|
|
|
uint8_t rcvd_unique_id_offset;
|
2020-05-31 09:47:45 -03:00
|
|
|
uint32_t last_alloc_msg_ms;
|
2019-09-21 00:16:06 -03:00
|
|
|
|
2023-04-06 21:18:01 -03:00
|
|
|
AP_DroneCAN &_ap_dronecan;
|
2023-01-04 21:09:23 -04:00
|
|
|
CanardInterface &_canard_iface;
|
2022-04-04 07:33:33 -03:00
|
|
|
|
2023-01-04 21:09:23 -04:00
|
|
|
Canard::Publisher<uavcan_protocol_dynamic_node_id_Allocation> allocation_pub{_canard_iface};
|
2022-04-04 07:33:33 -03:00
|
|
|
|
2024-09-08 23:37:41 -03:00
|
|
|
Canard::ObjCallback<AP_DroneCAN_DNA_Server, uavcan_protocol_dynamic_node_id_Allocation> allocation_cb{this, &AP_DroneCAN_DNA_Server::handle_allocation};
|
2023-01-04 21:09:23 -04:00
|
|
|
Canard::Subscriber<uavcan_protocol_dynamic_node_id_Allocation> allocation_sub;
|
|
|
|
|
2023-04-06 21:18:01 -03:00
|
|
|
Canard::ObjCallback<AP_DroneCAN_DNA_Server, uavcan_protocol_NodeStatus> node_status_cb{this, &AP_DroneCAN_DNA_Server::handleNodeStatus};
|
2023-01-04 21:09:23 -04:00
|
|
|
Canard::Subscriber<uavcan_protocol_NodeStatus> node_status_sub;
|
|
|
|
|
2023-04-06 21:18:01 -03:00
|
|
|
Canard::ObjCallback<AP_DroneCAN_DNA_Server, uavcan_protocol_GetNodeInfoResponse> node_info_cb{this, &AP_DroneCAN_DNA_Server::handleNodeInfo};
|
2023-01-04 21:09:23 -04:00
|
|
|
Canard::Client<uavcan_protocol_GetNodeInfoResponse> node_info_client;
|
2020-01-15 19:49:41 -04:00
|
|
|
|
2019-09-21 00:16:06 -03:00
|
|
|
public:
|
2023-07-28 00:25:04 -03:00
|
|
|
AP_DroneCAN_DNA_Server(AP_DroneCAN &ap_dronecan, CanardInterface &canard_iface, uint8_t driver_index);
|
2022-04-04 07:33:33 -03:00
|
|
|
|
2019-09-21 00:16:06 -03:00
|
|
|
|
|
|
|
// Do not allow copies
|
2023-04-06 21:18:01 -03:00
|
|
|
CLASS_NO_COPY(AP_DroneCAN_DNA_Server);
|
2019-09-21 00:16:06 -03:00
|
|
|
|
|
|
|
//Initialises publisher and Server Record for specified uavcan driver
|
2023-01-04 21:09:23 -04:00
|
|
|
bool init(uint8_t own_unique_id[], uint8_t own_unique_id_len, uint8_t node_id);
|
2019-09-21 00:16:06 -03:00
|
|
|
|
|
|
|
//report the server state, along with failure message if any
|
|
|
|
bool prearm_check(char* fail_msg, uint8_t fail_msg_len) const;
|
|
|
|
|
2024-09-08 23:37:41 -03:00
|
|
|
// canard message handler callbacks
|
|
|
|
void handle_allocation(const CanardRxTransfer& transfer, const uavcan_protocol_dynamic_node_id_Allocation& msg);
|
2023-01-04 21:09:23 -04:00
|
|
|
void handleNodeStatus(const CanardRxTransfer& transfer, const uavcan_protocol_NodeStatus& msg);
|
|
|
|
void handleNodeInfo(const CanardRxTransfer& transfer, const uavcan_protocol_GetNodeInfoResponse& rsp);
|
2019-09-21 00:16:06 -03:00
|
|
|
|
|
|
|
//Run through the list of seen node ids for verification
|
2022-04-04 07:33:33 -03:00
|
|
|
void verify_nodes();
|
2019-09-21 00:16:06 -03:00
|
|
|
};
|
|
|
|
|
2019-10-25 00:03:16 -03:00
|
|
|
#endif
|