opendroneid / opendroneid-core-c Goto Github PK
View Code? Open in Web Editor NEWOpen Drone ID Core C Library
License: Apache License 2.0
Open Drone ID Core C Library
License: Apache License 2.0
F3411-22a Table 6:
Location/Vector Message Timestamp:
Time of applicability expressed in 1/10ths of seconds since the last hour relative to UTC time.
0-36000: 16 Bit UInt (LE)
opendroneid.h line 94:
#define MAX_TIMESTAMP (60 * 60)
I believe this should be:
#define MAX_TIMESTAMP (60 * 60 * 10)
Hello,
ESP01 is ultra compact and dispose wifi 2.4ghz and one serial port (that can be connected to mavlink), it can be perfect for test OPENDRONEID Wifi only version.
Does anybody can help me to compile opendrone id for esp01 ?
I found esp01 firmware that enable to output wifi raw packets:
wifi_set_channel(5);
uint8_t packetH[36]={
0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Receiver Address= Destination Address
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Transmitter Address= Source Address
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID
0x00, 0x00, //Sequence control
0x01, 0x02, 0x02, 0x03,0x03,0x03,0x04,0x04, //Body
0x05, 0x03, 0x02, 0x01 //FCS
};
wifi_send_pkt_freedom(packetH,sizeof(packetH),0);
esp-open-sdk
https://projetsdiy.fr/esp-01-esp8266-flasher-firmware-origine/
https://github.com/pulkin/esp8266-injection-example
Also:
https://github.com/spacehuhn/esp8266_beaconSpam/blob/master/README.md
https://github.com/spacehuhn/esp8266_beaconSpam/blob/master/esp8266_beaconSpam/esp8266_beaconSpam.ino
https://github.com/tabarra/ESP8266-ABS/blob/master/esp8266_abs/esp8266_abs.ino
http://arduino.esp8266.com/Arduino/versions/2.3.0/
https://github.com/spacehuhn/esp8266_beaconSpam/blob/master/esp8266_beaconSpam/esp8266_beaconSpam.ino
https://github.com/tabarra/ESP8266-ABS/blob/master/esp8266_abs/esp8266_abs.ino
All
The question I am asking came up in some personal conversations with a co-worker of mine while writing the following appendix section [1] for the DRIP Authentication draft.
We wondered if sending the same message twice, in a given duty cycle, would stay within the spirit of the RID rule and be something implementations actually perform as a computation save?
For example say we are sending at a message set rate of 2 Hz (double the required rate). A message set is defined as the set of messages consisting of Basic ID, Location, System and optionally Operator ID (depending on jurisdiction) to met the CAA requirements. Would it be in the spirit of the rule to send generate and broadcast the set in the first 1/2 second and just re-broadcast immediately, without any modifications, in the last 1/2 second?
Of course the same logic could be applied to any transport that uses Message Pack as well.
[1] https://www.ietf.org/archive/id/draft-ietf-drip-auth-30.html#name-methodology
int encodeBasicIDMessage(ODID_BasicID_encoded *outEncoded, ODID_BasicID_data *inData)
{
if (!outEncoded || !inData ||
!intInRange(inData->IDType, 0, 15) ||
!intInRange(inData->UAType, 0, 15))
return ODID_FAIL;
outEncoded->MessageType = ODID_MESSAGETYPE_BASIC_ID;
outEncoded->ProtoVersion = ODID_PROTOCOL_VERSION;
outEncoded->IDType = inData->IDType;
outEncoded->UAType = inData->UAType;
strncpy(outEncoded->UASID, inData->UASID, sizeof(outEncoded->UASID));
memset(outEncoded->Reserved, 0, sizeof(outEncoded->Reserved));
return ODID_SUCCESS;
}
Per F3411-22a the encoding and format of the UAS ID's are as follows:
<ICAO Nationality MarkA >.<CAA Assigned ID>
Due to the behavior of strncpy
[1] as currently written any Type 3 and Type 4 UAS IDs with a byte of value 0x00
will be truncated at that byte. For example a Type 4 of the value 0x0120010030112233058899AABBCCDDEEFF000000
will be encoded and displayed over air as 0x0120010000000000000000000000000000000000
as the 0x00
in byte position 4 will be treated as a null terminator by strncpy
.
Either the strncpy
should be swapped for memcpy
to be agnostic to the null terminator (0x00
) or have a clause based on the ID Type and use strncpy
for Type 1 and Type 2, and memcpy
for Type 3, Type 4 or other currently undefined ID Types.
I suspect that the decode side also treats the UAS ID as ASCII at all times but have yet to check and confirm this. I suspect a simple memcpy
replacement there as well would suffice but have not analyzed any side-effects of such a change.
What are you using to develop this?
libopendroneid used to compile on my Raspberry Pi, but I am getting errors with the latest code.
error: dereferencing pointer to incomplete type ‘struct ieee80211_vendor_specific’
cc1: warning: unrecognized command line option ‘-Wno-address-of-packed-member’
gcc 8.3.0
Based on what I have read in the final rule on remote id released by the faa, he maximum timestamp should be 36000 not 3600 as is currently the case.
I copied the regulation straight from the ruling: Timestamp Time of applicability expressed in 1/10ths of seconds since the last hour 0–36000: 16 Bit UInt (LE)
Unless I am completely misinterpreting this ruling. I came across this issue when trying to represent larger time values. For example, if the timestamp value taken from a flight controller is 34 minutes, 35 seconds, 6 tenths of a second, it would be written as 20756, this is larger than the max timestamp value and thus can not be transmitted. In my code, I changed the MAX_TIMESTAMP value from (60*60) to 36000 and ran into no issues.
I found a public version of what I believe to be the Japanese rule for remote ID.
I found a way to auto-translate the document to English but the translation was far from clear in all places. I tried to generate a summary of the main changes compared to the US and EU rules/standards and I also updated the comparison table.
@ToshihiroMakuuchi: Would it be possible for you to read through the Japanese version of the rule document and correct any mistakes I have made?
encodeSystemMessage() has a limit of MAX_AREA_RADIUS, which is only 2250 meters. Why such a small limit? Is there something in the FAA rules or ASTM MOC that mandates this?
I noticed this as my test setup set a 8000m radius and odid_message_build_pack() silently discarded my System message in UAS_Data. Took a while to work out what was wrong. Flights to over 2250 meters are quite common under EVLOS or BVLOS rules.
It seems there is a rounding issue in encodeDirection() function.
When the function receives the value from 359.5 to 359.9 it rounds the Direction in degree value to 360 which in turn create an issue by producing the wrong value 180 but the encode value should be between 0-179.
static uint8_t encodeDirection(float Direction, uint8_t *EWDirection) { unsigned int direction_int = (unsigned int) roundf(Direction);
Example:
Input Direction in degree : 359.5
unsigned int direction_int = (unsigned int) roundf(Direction); // direction_int =360 if (direction_int < 180) { *EWDirection = 0; } else { *EWDirection = 1; // EWDirection = 1 direction_int -= 180; // direction_int = 180 } return (uint8_t) intRangeMax(direction_int, 0, UINT8_MAX); // return 180 (wrong output)
I may be missing something, but the current definition does not allow negative vertical speeds, i.e. a UAS cannot report it is descending.
Hello,
I want to make use of this library into native iOS project.
Will you please guide me how can I integrate library into iOS project.
And if this core-c is not compatible with iOS compiler then, does it have other library which is computable with iOS?
I see, there is library for Android written in Java.
Thank you,
Rashesh Bosamiya
Hi,
INVOLI would like to implement the opendroneid standard in its system. We were wondering if it is possible to have access to the apps to validate our implementation of the standard.
Best regards.
Hi all , I own an esp32-s3-mini1 and found the opendroneid firmware a great alternative to use remoteid .
I am in Europe , and from Jan 1 2024 , the drone I own will have to have a remote id module .
So I would like to know if legally I can use the esp32-s3-mini1 as a remote id module , or do I have to buy a certified module .
I think if it was illegal , this repository would not even exist :) , so I think I already know my answer.
I hope someone knowledgeable can enlighten me . thanks
When attempting to include this library into a project written in C++ compiler complains that the library is not compliant with ISO C++ standard.
Passing an array with an unspecified size:
./lib/ODID/libopendroneid/opendroneid.h:583:45: warning: ISO C++ forbids flexible array member 'odid_message_pack' [-Wpedantic]
ODID_MessagePack_encoded odid_message_pack[];
Implicit conversion from float
to double
on multiple occasions - will penalize performance on Cortex-M4/M7 CPUs (they don't have hardware support for double
):
lib/ODID/libopendroneid/opendroneid.c: In function 'int encodeLocationMessage(ODID_Location_encoded*, ODID_Location_data*)':
lib/ODID/libopendroneid/opendroneid.c:290:34: warning: implicit conversion from 'float' to 'double' to match other operand of binary expression [-Wdouble-promotion]
(inData->SpeedHorizontal > MAX_SPEED_H && inData->SpeedHorizontal < INV_SPEED_H))
Incorrect %
format specifier used:
lib/ODID/libopendroneid/opendroneid.c: In function 'void printAuth_data(ODID_Auth_data*)':
lib/ODID/libopendroneid/opendroneid.c:1305:59: warning: format '%d' expects argument of type 'int', but argument 6 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
Auth->PageCount, Auth->Length, Auth->Timestamp);
I've implemented DroneCAN (previously known as UAVCAN) messages for OpenDroneID that mirror the MAVLink messages.
The message definitions are here:
https://github.com/dronecan/DSDL/tree/master/dronecan/remoteid
they deliberately use identical field names and field definitions to the MAVLink XML to make a dual-protocol implementation easy
I've done a dual-protocol implementation for Arduino on a ESP32-S3 here:
https://github.com/ArduPilot/ArduRemoteID
this implements MAVLink over UART and DroneCAN on bxCAN (known as TWAI in ESP32) in parallel, allowing the OpenDroneID squiter to be connected to a flight controller via either protocol. I've tested this implementation with ArduPilot and the OpenDroneID android receiver.
I think mentioning the DroneCAN definitions would be worthwhile in the OpenDroneID docs to avoid someone else having to re-invent them.
void printBasicID_data(ODID_BasicID_data *BasicID)
{
// Ensure the ID is null-terminated
char buf[ODID_ID_SIZE + 1] = { 0 };
memcpy(buf, BasicID->UASID, ODID_ID_SIZE);
const char ODID_BasicID_data_format[] =
"UAType: %d\nIDType: %d\nUASID: %s\n";
printf(ODID_BasicID_data_format, BasicID->IDType, BasicID->UAType, buf);
}
The IDType and UAType are swapped from whats printed.
I was looking at the broadcast requirements (https://www.ecfr.gov/current/title-14/chapter-I/subchapter-F/part-89/subpart-D/section-89.305)
It states:
A time mark identifying the Coordinated Universal Time (UTC) time of applicability of a position source output.
I was trying to find a UTC timestamp in the location type message. It appears they are providing seconds after the last full hour (opendroneid.c static float decodeTimeStamp(uint16_t Seconds_enc)). Not sure why its using seconds after the hour. Couldn't you get a UTC timestamp from the GPS sensor and broadcast it?
Please consider renaming wifi.h odid_wifi.h. I am trying to get this going on an ESP32 and wifi.h causes a conflict.
The function odid_message_build_pack
will call different enconding call like 'encodeBasicIDMessage', 'encodeLocationMessage' and so on.
The problem is, those encode function CAN fail, and if they do, the error is ignored
Current code:
if (UAS_Data->LocationValid) {
if (msg_pack.MsgPackSize >= ODID_PACK_MAX_MESSAGES)
return -EINVAL;
encodeLocationMessage((void *)&msg_pack.Messages[msg_pack.MsgPackSize], &UAS_Data->Location);
msg_pack.MsgPackSize++;
}
The quick and proper fix is very simple, we do to NOT increment msg_pack.MsgPackSize
on failure:
if (UAS_Data->LocationValid) {
if (msg_pack.MsgPackSize >= ODID_PACK_MAX_MESSAGES)
return -EINVAL;
if (encodeLocationMessage((void *)&msg_pack.Messages[msg_pack.MsgPackSize], &UAS_Data->Location) == ODID_SUCCESS)
msg_pack.MsgPackSize++;
}
this will make sure that the invalid message will be override by the next message, or ignored if last one
Hi all. I wrote a simple code in Arduino IDE to test ESP32 and publish sample data from test/odidtest. But the receiver-android app cannot scan and detect that signals.
I use "Serial Bluetooth Terminal" in Android, it received that signals.
This is my code 🙇
#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run make menuconfig
to and enable it
#endif
BluetoothSerial SerialBT;
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
SerialBT.print("00 12 49 4e 54 43 45 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 00 00 00");
delay(1000);
SerialBT.print("10 24 5a 2c 04 44 bf 24 1b 52 d5 b4 b6 98 08 98 08 34 08 5b 44 58 02 05 00");
delay(1000);
SerialBT.print("20 10 01 0c c0 f3 5e 01 30 33 30 61 30 63 64 30 33 33 61 33 00 00 00 00 00");
delay(1000);
SerialBT.print("30 00 52 65 61 6c 20 45 73 74 61 74 65 20 50 68 6f 74 6f 73 00 00 00 00 00");
delay(1000);
SerialBT.print("40 04 3a bf 24 1b 74 d1 b4 b6 23 00 07 31 09 23 08 24 00 00 00 00 00 00 00");
delay(1000);
SerialBT.print("50 00 39 38 37 36 35 34 33 32 31 30 30 31 32 33 34 35 36 37 38 39 00 00 00");
delay(1000);
}
Thanks very much!
Hello, I am parsing bytes coming through UART and I am having issues with detecting consecutive ODID messages. My code does something like this:
mav2odid_t m2o;
As it receives new bytes over UART -
msg_type = m2o_parseMavlink(&m2o, c);
I seem to have no issue detecting the initial ODID_MESSAGETYPE_BASIC_ID. However, it never detects the ODID_MESSAGETYPE_LOCATION that is received immediately afterwards on the UART port. Do I have to reset anything after detecting the ODID_MESSAGETYPE_BASIC_ID? Any advice on why I am not detecting ODID_MESSAGETYPE_LOCATION?
France has its own WiFi Beacon-based Remote ID format described in https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000039685188/.
Would you be interested in a PR that adds support for this format?
I would suggest adding a function similar to the existing odid_wifi_build_message_pack_beacon_frame
function, maybe called odid_wifi_build_french_beacon_frame
.
Hi, I have a question that's loosely related to opendroneid, but I can't think of a better place to ask.
I'm developing a scanner for remote ID Wi-Fi beacons. Since the ASTM standard technically allows beacons to be broadcast on most channels in the 2.4 and 5.0 GHz bands, I want to be able to scan for beacons on all of these channels, therefore, I want to use Wi-Fi active scanning. (active scanning is where the scanner sends a probe request on a certain channel, and any devices that regularly broadcast on that channel will instantly send a probe response back with the beacon data. This way, the scanner doesn't have to passively wait for beacons to be broadcast, which could take up to the beacon interval amount of time).
I'm wondering if drones or remote ID broadcast modules support active scanning? In other words, will they necessarily respond to a probe request that a scanner sends out?
Implement the following changes:
When compiling with "-Wextra" flag and ODID_AUTH_MAX_PAGES = 16, the compiler warns that we are comparing an uint8_t against MAX_AUTH_LENGTH, in this case with the value 362.
The latest F3411 draft states:
"After the Length limit is reached, additional data may be sent in full 23 byte pages."
My understanding would be that
up to 11 maximum authentication pages (including page zero), we should check that the Length field doesn't exceed MAX_AUTH_LENGTH
for 12 to 16 maximum pages we should only check that Length is different from 255 if LastPageIndex is greater or equal to 11
Currently I'm working on ArduPilot integration ArduPilot/ardupilot#21075 and working on a MAVLink OpenDroneID device. Here, I want to share my experience with the current MAVLink OpenDroneID messages, what is missing. And what I propose to solve it.
I would appreciate feedback. Any thoughts? @friissoren @gabrielcox
In MAVLink messages, a CRC is added to ensure message integrity (https://en.wikipedia.org/wiki/MAVLink#CRC_field). This means that if the definition of an OpenDroneID MAVLink message changes, the CRC checksum will change as well. For instance the OPEN_DRONE_ID_SYSTEM message defintion was recently changed. It means that devices with an older MAVLink library won't be able to receive messages from the current MAVlink library and vice versa.
Proposed solution: keep the current MAVLink message definitions fixed. in case of an updated message definition, define a new message instead.
The current OPEN_DRONE_ID_BASIC_ID messages does not allow to differentiate between multiple Basic ID definitions. Current implementation is okay, just want to raise the subject to raise awareness
Proposed solution: keep the current OPEN_DRONE_ID_BASIC_ID as is. In case of two IDs, multiple OPEN_DRONE_ID_BASIC_ID messages can be send, for each ID one message. The transponder can decode those messages accordingly and decide how to handle it.
The current MAVLink messages don't allow to control the radio transmission. It can be useful to disable radio transmission when the UAV is on the ground. Or to change the radio transmission protocol (WiFi Beacon/NAN, BLE legacy/long range) depending on the region where the device is flying.
Proposed solution: Attached is a proposal for such a MAVLink CMD message.
As Remote ID evolves, it is likely that there will be devices with different MAVLink library versions with not the same OpenDrone ID message definitions. (See the OPEN_DRONE_ID_SYSTEM message example earlier.) Having an ACK message helps to identify:
Proposed solution: Attached is a proposal for such a MAVLink ACK message.
I zipped the attachment, because XML is not accepted
mavlink_opendroneid.xml.zip
(edited to fix some typo's and minor additions for clarification)
.
Hi,
So the ASTM standard requires 6 different types of messages:
int encodeBasicIDMessage(ODID_BasicID_encoded *outEncoded, ODID_BasicID_data *inData);
int encodeLocationMessage(ODID_Location_encoded *outEncoded, ODID_Location_data *inData);
int encodeAuthMessage(ODID_Auth_encoded *outEncoded, ODID_Auth_data *inData);
int encodeSelfIDMessage(ODID_SelfID_encoded *outEncoded, ODID_SelfID_data *inData);
int encodeSystemMessage(ODID_System_encoded *outEncoded, ODID_System_data *inData);
int encodeOperatorIDMessage(ODID_OperatorID_encoded *outEncoded, ODID_OperatorID_data *inData);
int encodeMessagePack(ODID_MessagePack_encoded *outEncoded, ODID_MessagePack_data *inData);
One of encodeMessagePack()'s parameters is the struct *inData. Does *inData have to contain all of the individual messages? Or can it contain some and not others, as long as the periodicity requirements are met for all messages?
And just to clarify, for legacy advertising, you do not need encodeMessagePack() at all? You just broadcast the individual messages one at a time as long as you meet the periodicity requirement?
Thanks in advance, this is a great project 🙏
I was trying to simulate the drone by using raspberry pi 3 b+ to run this application. I was able to successfully run the test application inside the Raspberry Pi OS. (have attached the screenshot for the same)
Now I am trying to figure out how can we connect this stream to get emitted in raspberry pi device Bluetooth. If anyone can help here, is very much appreciated
Trying to build on Ubuntu 20.04 (Focal Fossa) ...
$ cmake .
-- The C compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for module 'libgps'
-- Found libgps, version 3.20
-- Checking for module 'libnl-genl-3.0'
-- Found libnl-genl-3.0, version 3.4.0
-- Configuring done
-- Generating done
... fails with the following error:
[ 46%] Building C object wifi/sender/CMakeFiles/sender.dir/main.c.o
/home/janus/github/opendroneid/opendroneid-core-c/wifi/sender/main.c: In function ‘drone_adopt_gps_data’:
/home/janus/github/opendroneid/opendroneid-core-c/wifi/sender/main.c:232:36: error: invalid operands to binary * (have ‘timespec_t’ {aka ‘struct timespec’} and ‘int’)
232 | time_in_tenth = gpsdata->fix.time * 10;
| ~~~~~~~~~~~~~~~~~ ^
| |
| timespec_t {aka struct timespec}
I assume this is due to the fact that 20.04 has the updated libgps version 3.20. On Ubuntu 18.04, with libgps version 3.17, everything works well.
Hi All,
Firstly, thank you for your great and helpful work.
I am currently tinkering with Authentication part of opendroneid and I am trying to push it to its limits. I have assembled an entire ODID_UAS_Data structure and I am trying to build an ODID message pack. However it obviously fails due to the fact that I am filling ODID_Auth_data to almost its limits.
From the your code, ODID_PACK_MAX_MESSAGES is defined to be 9, therefore if a user wants to build an ODID_MessagePack they can have:
1 x ODID_BasicID_data BasicID
1 x ODID_Location_data Location;
1 x ODID_SelfID_data SelfID;
1 x ODID_System_data System;
1 x ODID_OperatorID_data OperatorID;
which only leaves only 4 pages of the ODID_Auth_data object before the limit of ODID_PACK_MAX_MESSAGES is reached:
4 x ODID_Auth_data Auth;
Deciding to only send pages of the ODID_Auth_data object then a user can only pack 9 pages of that, it allows up to 16 and a user can use 255 bytes for authentication purposes due to the uint8_t "length" field limit.
How would you advice someone wanting to pack and send 16 full pages of ODID_Auth_data or at least take advantage of the allowed 255 bytes of authentication data (12 pages of ODID_Auth_data), hopefully also packing other data such as location and basic Id.
Have you set this limit arbitrarily or is it for some reasons that I have not come across in any documentation? if it is changeable then would it be still ok to transmit this over WiFi/Bluetooth then receive it and decode it without any issue or breaking standards?
I have thought of splitting up the data; send basic id and what not in a transmission then if length permits send ODID_Auth_data in a single pack or in worst case divide it as well into separate transmissions.
Any advice or pointers would be very helpful as I am currently stuck at it for some time, I have seen a few implementations/examples of mock data being sent but no one has gone over 4 pages of ODID_Auth_data. I plan to continue working on this aspect and would gladly contribute any useful outputs to this project.
Sorry for the long explanation but I wanted to be clear.
Thanks for your time and help.
Hi,
This is my first open source contribution. I have a transmitter that emits in BT5 long range according to the RemoteID specification, using a nrf52840 dongle, and I want to share it with the community.
How do I proceed now? I create my repository and then it will be added to the opendroneid repositories?
Thanks for the help.
ODID_BasicID_encoded end with 3 reserved bytes, but are not initialized.
Other struct with reserved bytes, like ODID_OperatorID_encoded used by encodeOperatorIDMessage, get memset to 0.
I guess somewhere a unit test is also not properly checking all bytes generated, or is missing
Hi There !
I am doing code review of opendroneid.
Not an issue but I am just curious about the encoding parts.
Before I review the source code, I thought the meaning of encoding was encryption of message.
But in the source code about encoding was changing each data to ODID data frame such as compression.
I have a question at this point.
Thanks for reading my question,
and hope you can give me any advice !
Description:
I am encountering a "Stack canary watchpoint triggered (BTC_TASK)" error when using the opendroneid-core-c library in my ESP32 project. The error occurs while attempting to decode and print Open Drone ID data from a received Bluetooth advertisement packet.
Steps to Reproduce:
Set up an ESP32 project with the Arduino IDE.
Include the opendroneid-core-c library in the project.
Implement the MyAdvertisedDeviceCallbacks class with the onResult callback function.
In the onResult function, check if the received advertisement packet is a valid drone beacon.
If it is a valid drone beacon, decode the Open Drone ID data using the decodeOpenDroneID function from the library.
Attempt to print the decoded Open Drone ID data using the printBasicID_data and printLocation_data functions.
Expected Behavior:
The code should successfully decode the Open Drone ID data from the received Bluetooth advertisement packet and print the relevant information without triggering any errors or exceptions.
Actual Behavior:
When running the code, a "Stack canary watchpoint triggered (BTC_TASK)" error occurs, causing a panic in the BTC_TASK. The error seems to happen while printing the Open Drone ID data, specifically after printing the UAType.
Error Message
Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception).
Debug exception reason: Stack canary watchpoint triggered (BTC_TASK)
Core 0 register dump:
PC : 0x4038245f PS : 0x00060236 A0 : 0x80381b27 A1 : 0x3fca83f0
A2 : 0x3fc98790 A3 : 0xb33fffff A4 : 0x0000abab A5 : 0x00060223
A6 : 0x00060223 A7 : 0x0000cdcd A8 : 0xb33fffff A9 : 0xffffffff
A10 : 0x00000000 A11 : 0x3fcf0862 A12 : 0x0000000a A13 : 0x3fc96fe0
A14 : 0x02c98790 A15 : 0x00ffffff SAR : 0x00000011 EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x40056fc5 LEND : 0x40056fe7 LCOUNT : 0x00000000
Environment:
ESP32-S3-Dev
Arduino 2.3.2
opendroneid-core-c library
Code used to produce this error
#if not defined(ARDUINO_ARCH_ESP32)
#error "This program requires an ESP32"
#endif
#pragma GCC diagnostic warning "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <BLEBeacon.h>
#include <WiFi.h>
#include "opendroneid.h"
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf("Bluetooth Device: %s\n", advertisedDevice.toString().c_str());
// Print raw advertisement packet
uint8_t* payloadPtr = advertisedDevice.getPayload();
size_t payloadLength = advertisedDevice.getPayloadLength();
Serial.print("Raw Advertisement Packet: ");
for (size_t i = 0; i < payloadLength; i++) {
Serial.printf("%02X ", payloadPtr[i]);
}
Serial.println();
// Check if the advertisement is a valid drone beacon
if (payloadLength >= 2 && payloadPtr[0] == 0xFA && payloadPtr[1] == 0x0B) {
// Decode Open Drone ID data
ODID_UAS_Data uasData;
memset(&uasData, 0, sizeof(uasData));
ODID_messagetype_t messageType = decodeOpenDroneID(&uasData, payloadPtr);
if (messageType != ODID_MESSAGETYPE_INVALID) {
Serial.println("Open Drone ID data:");
if (uasData.BasicIDValid[0]) {
printBasicID_data(&uasData.BasicID[0]);
}
if (uasData.LocationValid) {
printLocation_data(&uasData.Location);
}
// Print other decoded data as needed
}
} else {
Serial.println("Not a valid drone beacon");
}
Serial.println();
}
};
BLEScan* pBLEScan;
void setup() {
Serial.begin(115200);
Serial.println("Open Drone ID Scanner");
// Initialize Bluetooth
Serial.println("Initializing Bluetooth...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->setInterval(100);
pBLEScan->setWindow(99);
// Initialize Wi-Fi
Serial.println("Initializing Wi-Fi...");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
}
void loop() {
// Perform Bluetooth scan
Serial.println("Scanning for Bluetooth devices...");
BLEScanResults foundBLEDevices = pBLEScan->start(5, false);
Serial.print("Bluetooth devices found: ");
Serial.println(foundBLEDevices.getCount());
pBLEScan->clearResults();
// Perform Wi-Fi scan
Serial.println("Scanning for Wi-Fi networks...");
int numNetworks = WiFi.scanNetworks();
Serial.print("Wi-Fi networks found: ");
Serial.println(numNetworks);
for (int i = 0; i < numNetworks; i++) {
Serial.printf("SSID: %s, RSSI: %d\n", WiFi.SSID(i).c_str(), WiFi.RSSI(i));
// Print raw advertisement data for each Wi-Fi network
Serial.print("Raw Advertisement Data: ");
uint8_t* bssid = WiFi.BSSID(i);
for (int j = 0; j < 6; j++) {
Serial.printf("%02X ", bssid[j]);
}
Serial.println();
Serial.println();
}
WiFi.scanDelete();
Serial.println("Scan done!");
delay(30000);
}
I'm building on Ubuntu 20.04 with gcc 8.4:
$ cmake . -DCMAKE_C_COMPILER=gcc-8
-- The C compiler identification is GNU 8.4.0
-- Check for working C compiler: /usr/bin/gcc-8
-- Check for working C compiler: /usr/bin/gcc-8 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for module 'libgps'
-- Found libgps, version 3.20
-- Checking for module 'libnl-genl-3.0'
-- Found libnl-genl-3.0, version 3.4.0
-- Configuring done
-- Generating done
The build runs through fine, but there are several compiler warnings, all of the same type:
[ 53%] Building C object test/CMakeFiles/odidtest.dir/opendroneid_sim.c.o
/home/janus/github/opendroneid/opendroneid-core-c/test/opendroneid_sim.c: In function ‘ODID_getSimData’:
/home/janus/github/opendroneid/opendroneid-core-c/test/opendroneid_sim.c:98:51: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(basicID_data.UASID, id, sizeof(id));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/opendroneid_sim.c:134:53: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(auth_data.AuthData, data, sizeof(data));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/opendroneid_sim.c:143:58: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(selfID_data.Desc, description, sizeof(description));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/opendroneid_sim.c:166:67: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(operatorID_data.OperatorId, operatorId, sizeof(operatorId));
^
[ 61%] Building C object test/CMakeFiles/odidtest.dir/test_inout.c.o
/home/janus/github/opendroneid/opendroneid-core-c/test/test_inout.c: In function ‘test_InOut’:
/home/janus/github/opendroneid/opendroneid-core-c/test/test_inout.c:54:38: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(BasicID.UASID, id, sizeof(id));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/test_inout.c:85:47: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(Auth0.AuthData, auth0_data, sizeof(auth0_data));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/test_inout.c:93:47: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(Auth1.AuthData, auth1_data, sizeof(auth1_data));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/test_inout.c:100:45: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(SelfID.Desc, description, sizeof(description));
^
/home/janus/github/opendroneid/opendroneid-core-c/test/test_inout.c:121:54: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
strncpy(operatorID.OperatorId, operatorId, sizeof(operatorId));
^
They do not occur with gcc 7.5 or earlier. It should be checked if they are justified (or just false alarm). If not, one could just disable the warning flag.
Changes between 0.7 and 0.8 that still needs to be done:
• New UA Type. Check all enumerations
• ID Type names might have changed to follow the data dictionary name. Check this
• Authentication message has changed significantly
• System message is now optional (should not affect to code)
• GroupArea, radius, ceiling and floor have been renamed to not have group in the name. Default AreaCount is now 1.
• New Operator ID message
• SelfId has updated types
• Messages must be combined into one large pack when sending EA/long range. Add the pack type and a packing function
• Non-values now defined for many fields. (Should be added also to the Mavlink descriptions)
• Basic ID enum names have changed
• Change opendroneid-core-c horizontal, speed and time enums: HORACC => HOR_ACC, METERS_SECOND => METER_PER_SECOND and SECONDS => SECOND
wifi.c implements odid_message_process_pack from opendroneid.h.
It does not return 0 on success. It is returning size.
from opendroneid.h:
int odid_message_process_pack(ODID_UAS_Data *UAS_Data, uint8_t *pack, size_t buflen);
/* odid_wifi_receive_message_pack_nan_action_frame - processes a received message pack
Implementation in wifi.c:
int odid_message_process_pack(ODID_UAS_Data *UAS_Data, uint8_t *pack, size_t buflen)
{
ODID_MessagePack_encoded *msg_pack_enc = (ODID_MessagePack_encoded *) pack;
size_t size = sizeof(*msg_pack_enc) - ODID_MESSAGE_SIZE * (ODID_PACK_MAX_MESSAGES - msg_pack_enc->MsgPackSize);
if (size > buflen)
return -ENOMEM;
odid_initUasData(UAS_Data);
if (decodeMessagePack(UAS_Data, msg_pack_enc) != ODID_SUCCESS)
return -1;
return (int) size;
}
Firstly, excellent work on this module!
I've been working with this code a bit and found myself wishing the functions below were exposed in the mav2odid.h
interface:
static int m2o_basicId(mav2odid_t* m2o, mavlink_open_drone_id_basic_id_t* mavBasicId);
static int m2o_location(mav2odid_t* m2o, mavlink_open_drone_id_location_t* mavLocation);
static int m2o_authentication(mav2odid_t* m2o, mavlink_open_drone_id_authentication_t* mavAuthentication);
static int m2o_selfId(mav2odid_t* m2o, mavlink_open_drone_id_self_id_t* mavSelfId);
static int m2o_system(mav2odid_t* m2o, mavlink_open_drone_id_system_t* mavSystem);
static int m2o_operatorId(mav2odid_t* m2o, mavlink_open_drone_id_operator_id_t* mavOperatorId);
The primary reason for this is that the mavlink_open_drone_id_message_pack_t message requires ODID-encoded messages, and the functions above are extremely convenient for this.
Thanks for reading and for the great work done here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.