An ASTM F3411 message encoding and decoding library written in C programming language.
The library provides struct definitions for all Remote ID messages. It also provides getter and setter functions for all members of the structure. You should not access the struct members directly. Instead use the provided functions which will decode and encode the data to and from the correct wire format.
This is a read only mirror of the repository. Actual developing happens elsewhere. I do monitor the bug reports, feature requests and any discussion here though.
Provides UAS identification (serial number, registration ID, or UUID) and characterizes the aircraft type.
rid_basic_id_t basic_id;
char uas_id[21];
char json[255];
rid_basic_id_init(&basic_id);
rid_basic_id_set_type(&basic_id, RID_ID_TYPE_SERIAL_NUMBER);
rid_basic_id_set_ua_type(&basic_id, RID_UA_TYPE_HELICOPTER_OR_MULTIROTOR);
rid_basic_id_set_uas_id(&basic_id, "1ABCD2345EF678XYZ");
rid_basic_id_validate(&basic_id);
rid_basic_id_type_t id_type = rid_basic_id_get_type(&basic_id);
rid_ua_type_t ua_type = rid_basic_id_get_ua_type(&basic_id);
rid_basic_id_get_uas_id(&basic_id, uas_id, sizeof(uas_id));
const char *id_type_string = rid_basic_id_type_to_string(id_type);
const char *ua_type_string = rid_ua_type_to_string(ua_type);
rid_basic_id_to_json(&basic_id, json, sizeof(json));See examples/basic_id/ for usage example.
Contains current position, altitude, speed, direction, and timestamp of the UA.
rid_location_t location;
char json[512];
rid_location_init(&location);
rid_location_set_operational_status(&location, RID_OPERATIONAL_STATUS_AIRBORNE);
rid_location_set_height_type(&location, RID_HEIGHT_TYPE_ABOVE_TAKEOFF);
rid_location_set_latitude(&location, 62.683472);
rid_location_set_longitude(&location, 21.974944);
rid_location_set_geodetic_altitude(&location, 120.5f);
rid_location_set_pressure_altitude(&location, 101.3f);
rid_location_set_height(&location, 50.0f);
rid_location_set_speed(&location, 15.5f);
rid_location_set_vertical_speed(&location, 2.0f);
rid_location_set_track_direction(&location, 45);
rid_location_set_timestamp(&location, 12345);
rid_location_set_unixtime(&location, 1234567890);
rid_location_set_horizontal_accuracy(&location, RID_HORIZONTAL_ACCURACY_10M);
rid_location_set_vertical_accuracy(&location, RID_VERTICAL_ACCURACY_10M);
rid_location_set_speed_accuracy(&location, RID_SPEED_ACCURACY_1MS);
rid_location_set_baro_altitude_accuracy(&location, RID_VERTICAL_ACCURACY_3M);
rid_location_set_timestamp_accuracy(&location, RID_TIMESTAMP_ACCURACY_0_1S);
rid_location_validate(&location);
rid_height_type_t height_type = rid_location_get_height_type(&location);
rid_operational_status_t status = rid_location_get_operational_status(&location);
uint16_t direction = rid_location_get_track_direction(&location);
float speed = rid_location_get_speed(&location);
float vspeed = rid_location_get_vertical_speed(&location);
double latitude = rid_location_get_latitude(&location);
double longitude = rid_location_get_longitude(&location);
float pressure_altitude = rid_location_get_pressure_altitude(&location);
float geodetic_altitude = rid_location_get_geodetic_altitude(&location);
float height = rid_location_get_height(&location);
rid_horizontal_accuracy_t h_accuracy = rid_location_get_horizontal_accuracy(&location);
rid_vertical_accuracy_t v_accuracy = rid_location_get_vertical_accuracy(&location);
rid_speed_accuracy_t s_accuracy = rid_location_get_speed_accuracy(&location);
rid_vertical_accuracy_t baro_accuracy = rid_location_get_baro_altitude_accuracy(&location);
uint16_t timestamp = rid_location_get_timestamp(&location);
rid_timestamp_accuracy_t ts_accuracy = rid_location_get_timestamp_accuracy(&location);
const char *height_type_string = rid_height_type_to_string(height_type);
const char *status_string = rid_operational_status_to_string(status);
const char *horizontal_accuracy_string = rid_horizontal_accuracy_to_string(h_accuracy);
const char *vertical_accuracy_string = rid_vertical_accuracy_to_string(v_accuracy);
const char *speed_accuracy_string = rid_speed_accuracy_to_string(s_accuracy);
const char *timestamp_accuracy_string = rid_timestamp_accuracy_to_string(ts_accuracy);
rid_location_to_json(&location, json, sizeof(json));See examples/location/ for usage example.
Provides authentication data for verifying the identity of the UA sending the message.
rid_auth_t auth;
uint8_t signature[64];
uint8_t retrieved[64];
char json[512];
rid_auth_init(&auth);
rid_auth_set_type(&auth, RID_AUTH_TYPE_UAS_ID_SIGNATURE);
rid_auth_set_timestamp(&auth, 3600);
rid_auth_set_unixtime(&auth, (uint32_t)time(NULL));
rid_auth_set_signature(&auth, signature, sizeof(signature));
rid_auth_validate(&auth);
rid_auth_type_t auth_type = rid_auth_get_type(&auth);
uint32_t timestamp = rid_auth_get_timestamp(&auth);
uint32_t unixtime = rid_auth_get_unixtime(&auth);
uint8_t page_count = rid_auth_get_page_count(&auth);
uint8_t length = rid_auth_get_length(&auth);
rid_auth_get_signature(&auth, retrieved, sizeof(retrieved));
const char *auth_type_string = rid_auth_type_to_string(auth_type);
rid_auth_to_json(&auth, json, sizeof(json));See examples/auth/ for usage example.
Allows operators to declare their identity or describe the purpose of a flight.
rid_self_id_t self_id;
char description[24];
char json[256];
rid_self_id_init(&self_id);
rid_self_id_set_description_type(&self_id, RID_DESCRIPTION_TYPE_TEXT);
rid_self_id_set_description(&self_id, "Drone delivery test");
rid_self_id_validate(&self_id);
rid_description_type_t description_type = rid_self_id_get_description_type(&self_id);
rid_self_id_get_description(&self_id, description, sizeof(description));
const char *description_type_string = rid_description_type_to_string(desc_type);
rid_self_id_to_json(&self_id, json, sizeof(json));See examples/self_id/ for usage example.
Contains remote pilot location, operating area details, and group aircraft information.
rid_system_t system;
char json[512];
rid_system_init(&system);
rid_system_set_operator_location_type(&system, RID_OPERATOR_LOCATION_TYPE_TAKEOFF);
rid_system_set_classification_type(&system, RID_CLASSIFICATION_TYPE_EUROPEAN_UNION);
rid_system_set_ua_classification_category(&system, RID_UA_CLASSIFICATION_CATEGORY_OPEN);
rid_system_set_ua_classification_class(&system, RID_UA_CLASSIFICATION_CLASS_1);
rid_system_set_operator_latitude(&system, 60.2870324);
rid_system_set_operator_longitude(&system, 24.5397187);
rid_system_set_operator_altitude(&system, 50.0f);
rid_system_set_area_count(&system, 1);
rid_system_set_area_radius(&system, 100);
rid_system_set_area_ceiling(&system, 120.0f);
rid_system_set_area_floor(&system, 0.0f);
rid_system_set_timestamp(&system, 3600);
rid_system_set_unixtime(&system, 1234567890);
rid_system_validate(&system);
rid_operator_location_type_t operator_location_type = rid_system_get_operator_location_type(&system);
rid_classification_type_t classification_type = rid_system_get_classification_type(&system);
rid_ua_classification_category_t ua_category = rid_system_get_ua_classification_category(&system);
rid_ua_classification_class_t ua_class = rid_system_get_ua_classification_class(&system);
double operator_latitude = rid_system_get_operator_latitude(&system);
double operator_longitude = rid_system_get_operator_longitude(&system);
float operator_altitude = rid_system_get_operator_altitude(&system);
uint16_t area_count = rid_system_get_area_count(&system);
uint16_t area_radius = rid_system_get_area_radius(&system);
float area_ceiling = rid_system_get_area_ceiling(&system);
float area_floor = rid_system_get_area_floor(&system);
uint32_t timestamp = rid_system_get_timestamp(&system);
uint32_t unixtime = rid_system_get_unixtime(&system);
const char *operator_location_type_string = rid_operator_location_type_to_string(operator_location_type);
const char *classification_type_string = rid_classification_type_to_string(classification_type);
const char *ua_category_string = rid_ua_classification_category_to_string(ua_category);
const char *ua_class_string = rid_ua_classification_class_to_string(ua_class);
rid_system_to_json(&system, json, sizeof(json));See examples/system/ for usage example.
Provides CAA-issued registration or license ID for the remote pilot or operator.
rid_operator_id_t operator_id;
char id[21];
char json[256];
rid_operator_id_init(&operator_id);
rid_operator_id_set_type(&operator_id, RID_ID_TYPE_OPERATOR_ID);
rid_operator_id_set(&operator_id, "FIN87astrdge12k8");
rid_operator_id_validate(&operator_id);
rid_operator_id_type_t id_type = rid_operator_id_get_type(&operator_id);
rid_operator_id_get(&operator_id, id, sizeof(id));
const char *id_type_string = rid_operator_id_type_to_string(id_type);
rid_operator_id_to_json(&operator_id, json, sizeof(json));See examples/operator_id/ for usage example.
Combines multiple message types into a single payload for transmission.
rid_message_pack_t pack;
rid_basic_id_t basic_id;
rid_location_t location;
char json[1024];
rid_message_pack_init(&pack);
rid_message_pack_add_message(&pack, &basic_id);
rid_message_pack_add_message(&pack, &location);
rid_message_pack_set_message_count(&pack, 2);
rid_message_pack_replace_message_at(&pack, 0, &basic_id);
rid_message_pack_delete_message_at(&pack, 1);
rid_message_pack_validate(&pack);
uint8_t count = rid_message_pack_get_message_count(&pack);
const void *message = rid_message_pack_get_message_at(&pack, 0);
rid_message_pack_to_json(&pack, json, sizeof(json));See examples/message_pack/ for usage example.
This library output is byte compatible to the Open Drone ID library which is the reference implementation. There are a couple of behavior differences though.
According to ASTM F3411-22, the ground speed in a Location message must be clamped to a maximum of 254.25 m/s. The vertical speed must be clamped to either -62 m/s or 62 m/s depending on direction.
"Ground speed of flight. This value is provided in meters per second with a minimum resolution of 0.25 m/s. Special Values: Invalid, No Value, or Unknown: 255 m/s, if speed is >= 254.25 m/s: 254.25 m/s"
"Vertical speed upward relative to the WGS-84 datum, meters per second. Special Values: Invalid, No Value, or Unknown: 63 m/s, if speed is >= 62 m/s: 62 m/s, if speed is <= -62 m/s: -62 m/s"
ODID rejects any input value outside the valid bounds. Instead of rejecting this library clamps the values.
$ mkdir build && cd build
$ cmake -DRID_BUILD_EXAMPLES=ON ..
$ make
$ mkdir build && cd build
$ cmake -DRID_BUILD_TESTS=ON ..
$ make
$ ctest
Build and install a static library.
$ mkdir build && cd build
$ cmake ..
$ make
$ sudo make install
Or install to a custom location.
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/librid ..
$ make
$ make install
Build and install a shared library.
$ cmake -DBUILD_SHARED_LIBS=ON ..
$ make
$ sudo make install
$ cd build
$ sudo make uninstall
The MIT License (MIT). Please see License File for more information.