Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we use raspberry pi 3 b+ and simulate the drone through bluetooth #42

Closed
punithbm opened this issue Mar 11, 2021 · 6 comments
Closed

Comments

@punithbm
Copy link

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)
IMG_7288 (1)

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

@friissoren
Copy link
Contributor

I unfortunately personally don't have time at the moment to help with this kind of task. However, if you do manage to figure out how to do this, I would be very interested in hearing the results of it.

If you are willing to provide this kind of code, that could even be something we add to this or another repository here. It would be very useful to have example transmit code for BT4 and/or WiFi NaN/Beacon transmission on Raspberry PI HW.

Just FYI: For BT, if you run into problems with the fixed header values and the filter in the Android receiver app, the discussion here might be of use.

@gabrielcox
Copy link
Contributor

gabrielcox commented Mar 15, 2021

Since you're using a RPi I think the best approach would be to try to leverage Bluetooth libraries for Linux. Have you looked at BlueZ (bluez link) ? I think if bluez works on the RPi and you follow the sample code here: example-advertisement link , you may able to get it (signs of life) to work. I would start with substituting the following:

class TestAdvertisement(Advertisement):

        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_uuid('FFFA')  // notice substitution
        self.add_service_data('FFFA', [<counter>, <msg type/version>, <data byte>, <data byte>,...])  // replace your data here
        self.add_local_name('OpenDroneID')
        self.include_tx_power = True

I found this interesting as well:
https://stackoverflow.com/questions/47427913/advertise-custom-service-uuid-with-bluez-5-4x
The opendroneid service id is 0xFFFA

I haven't tried any of this above, but this would be my starting place if attempting to make this work under linux.

Let us know how it goes. As Soren said, we would be happy to embrace this dev effort and add an additional repository under opendroneid called "transmitter-linux".

Also, I would certainly recommend debugging with some some Bluetooth scanner like NRF Connect,

@friissoren
Copy link
Contributor

Possibly the discussion here might be of some use also?

If you manage to get bluez to output something, it should be possible to pick it up in the Android nRF Connect application and you can then start comparing against the example binary strings given in the issue, to ensure you send out the data in the correct format?

@friissoren
Copy link
Contributor

One very delayed addition to this discussion. I managed to get at least legacy advertising to transmit something from an Ubuntu desktop machine to the Android receiver application. This only worked for me on Ubuntu 20.04.2 with kernel 5.8.0-63-generic. I tried also on 18.04.5 with kernel 5.4.0-77-generic but that would always fail with an advertising timeout (probably some kernel/driver/something mismatch). This was on a CometLake Z490 desktop with built in WiFi/BT.

I did get it running also on a RaspberryPi4 running Debian/GNU 10 with RaspberryPi kernel 5.10.17-v8+.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.60.tar.xz
tar xvf bluez-5.60.tar.xz
gedit bluez-5.60/test/example-advertisement

Find the TestAdvertisement class and change the init function to contain only the following:

    def __init__(self, bus, index):
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_data('FFFA', [0x0D, 0x00, 0x10, 0x20, 0x38, 0x00, 0x00, 0x58, 0xD6, 0xDF, 0x1D, 0x90, 0x55,
                                       0xA3, 0x08, 0x82, 0x0D, 0xC1, 0x0A, 0xCF, 0x07, 0x28, 0x03, 0xD2, 0x0F, 0x01, 0x00])

Then execute with “python3 example-advertisement”. I found it useful to have “sudo btmon” running in a separate shell to get a bit more debug output.

The above just sends out a hard-coded location message and nothing else but is at least enough to prove that data is flowing. I pulled the example data from this discussion (which gives some instructions on how to configure the Android app nRF Connect to simulate the same).

Despite btmon talking about Extended Advertising, it clearly cannot be using that (or then there is some other limitation somewhere) since whenever I tried to add more data than what fit in legacy advertising, it would throw an error at me. I don’t know if it is possible to get this example code to use the Long Range and Extended Advertising features.

@friissoren
Copy link
Contributor

For WiFi Beacon, I found out the following. When using hostapd on Linux, it is possible to update the Information Element content of the beacon data by using the hostapd_cli interface. I got the following working on a RaspberryPi 4 (would probably work on Ubuntu also). The Pi cannot be connected to any WiFi networks: that seems to prevent it from going properly into the Access Point mode. The version of hostapd that by default gets installed by apt on Raspbian GNU/Linux 10 (buster) is too old (2.8-devel). I had to fetch the source code and compile it to get a version that supported the update beacon command.

sudo apt install libssl-dev libnl-3-dev
git clone git://w1.fi/hostap.git
cd hostap/hostapd
cp defconfig .config
make -j4

(If some dependency is still missing, the full set seems to be: sudo apt install build-essential git libpcap-dev libsqlite3-dev binutils-dev bc pkg-config libssl-dev libiberty-dev libdbus-1-dev libnl-3-dev libnl-genl-3-dev libnl-route-3-dev )

Create a configuration file with this content:

country_code=GB
interface=wlan0
ssid=DroneIDTest
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=thisisaverylongpassword
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
ctrl_interface=/var/run/hostapd

#This is an empty information element. dd indicates hex. 01 is the length of the data and 00 the actual data:
vendor_elements=dd0100

#This information element has one fixed Location message:
#vendor_elements=dd1EFA0BBC0D00102038000058D6DF1D9055A308820DC10ACF072803D20F0100

For testing purposes, it is enough to start the access point using the configuration file:
sudo ./hostapd beacon.conf

In a separate shell, then start:
sudo ./hostapd_cli
And type in the two following commands:
set vendor_elements dd1EFA0BBC0D00102038000058D6DF1D9055A308820DC10ACF072803D20F0100
update beacon

That made the beacon visible in the Android receiver application.

Clearly this is a very clumsy way of doing things and only servers to prove that it is possible to create a functional beacon and update the data that it is sending. An actual program of some kind would have to be written. There are C APIs for the set and update commands and when looking at the test code for hostapd, there is apparently also a Python interface:
https://w1.fi/cgit/hostap/tree/tests/hwsim/test_ap_params.py#n81

I probably won’t have the bandwidth any time soon to look further into that, but it would certainly be an interesting exercise at some point.

@friissoren
Copy link
Contributor

There is now a simple application example available for Linux for transmitting Wi-Fi Beacon and Bluetooth 4 and Bluetooth 5 drone ID signals:
https://github.com/opendroneid/transmitter-linux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants