I won't maintain it anymore, so this will remain at this stage
- File transfer (Sender) using bluetooth protocol
- Turn on/off BLE advertising
- Implement individual characteristics
- Implement services
- Scan for all available BLE peripheral devices
- List all services and characteristics
- Read/Write Characteristics
Used this android app to try connecting with the server: https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp
Follow on screen instructions and start scanning
Mai bas tests se idhar copy kr rha hu, sayad only sdbus wale programs ho skte is library ko use bhi na krte ho
Dont pay too much attention on why BLE vs bluetooth written in two parts :')
-
BLE
-
Bluetooth
-
Miscellaneous
This is a long one... The steps are:
- Declare application, services, characteristics classes, inheriting respective base classes
class MyApplication : public Application {
public:
MyApplication(sdbus::IConnection &connection,
const std::string &application_object_path)
: Application(connection, application_object_path) {}
void onInterfacesAdded(
const sdbus::ObjectPath &object_path,
const std::map<std::string, std::map<std::string, sdbus::Variant>>
&interfaces_and_properties) override {
cout << "Kuchh karo idhar" << endl;
}
void
onInterfacesRemoved(const sdbus::ObjectPath &object_path,
const std::vector<std::string> &interfaces) override {
cout << "Isko kaun handle karega :' )" << endl;
}
};
class MyService : public Service {
public:
MyService(sdbus::IConnection &connection,
std::string application_path, unsigned int index,
std::string UUID)
: Service(connection, application_path, 0, UUID) {}
struct MyCharacteristic1 : public Characteristic {
MyCharacteristic1(sdbus::IConnection &connection,
std::string service_path, unsigned int index,
std::string UUID)
: Characteristic(connection, service_path, index, UUID) {}
std::vector<uint8_t> ReadValue(
std::map<std::string, sdbus::Variant> options) const override {
return {};
}
void
WriteValue(std::vector<uint8_t> value,
std::map<std::string, sdbus::Variant> options) override {
cout << "Kuchh write karo idhar\n";
}
};
struct MyCharacteristic2 : public Characteristic {
MyCharacteristic2(sdbus::IConnection &connection,
std::string service_path, unsigned int index,
std::string UUID)
: Characteristic(connection, service_path, index, UUID) {}
std::vector<uint8_t> ReadValue(
std::map<std::string, sdbus::Variant> options) const override {
return {};
}
void
WriteValue(std::vector<uint8_t> value,
std::map<std::string, sdbus::Variant> options) override {
cout << "Kuchh write karo idhar\n";
}
};
};
- Create instance of your application class
auto myapp = new MyApplication(conn, "/com/example");
auto &service = myapp->addService<MyService>(
0, "0000180d-0000-1000-8000-00805f9b34fb");
service.addCharacteristic<MyService::MyCharacteristic1>(
0, "00002a37-0000-1000-8000-00805f9b34fb");
service.addCharacteristic<MyService::MyCharacteristic2>(
1, "00002a38-0000-1000-8000-00805f9b34fb");
- Register application (automatically registers services and their characteristics)
myapp->registerWithGattManager();
For this, the library provides an advertisement object, just create it and call turnOnAdvertising.
TODO: Provide user to set advertised name etc.
#include "ble/advertisement.h"
auto conn = sdbus::createSystemBusConnection();
auto advertisement = Advertisement(conn);
advertisement.turnOnAdvertising();
Two ways: Using the address, or using name
#include "bluetooth/functions.h"
connect_to_device_using_address("XX:XX:XX:XX:XX:XX");
connect_to_device_using_name("Rockerz 450");
#include "bluetooth/file_transfer.h"
sendFile("XX:XX:XX:XX:XX:XX", "/etc/fstab");
For eg. just creating a root object
auto root_obj = sdbus::createObject(conn, "/");
root_obj->registerProperty("name")
.onInterface("me.adig.DBus.Properties")
.withGetter([]() { return "gupta"; });
root_obj->finishRegistration();
Just get the "Powered" property on the adapter object
bool is_powered_on = sdbus::createProxy("org.bluez", "/org/bluez/hci0")
->getProperty("Powered")
.onInterface("org.bluez.Adapter1")
.get<bool>();
For an adapter (eg. "/org/bluez/hci0") to support advertising, it must implement "org.bluez.LEAdvertisingManager1" interface
auto results = std::map<
sdbus::ObjectPath,
std::map<std::string, std::map<std::string, sdbus::Variant>>>();
sdbus::createProxy("org.bluez", "/")
->callMethod("GetManagedObjects")
.onInterface("org.freedesktop.DBus.ObjectManager")
.storeResultsTo(results);
for (const auto &obj : results) {
auto it = obj.second.find("org.bluez.LEAdvertisingManager1");
if (it != obj.second.cend()) {
return obj.first;
}
}
throw std::logic_error(
"No adapter implementing org.bluez.LEAdvertisingManager1 found !");
If you know the device name, you can find the address programmatically using:
auto actual_name = string();
auto address = string();
auto result =
std::map<sdbus::ObjectPath,
std::map<string, std::map<string, sdbus::Variant>>>();
sdbus::createProxy("org.bluez", "/")
->callMethod("GetManagedObjects")
.onInterface("org.freedesktop.DBus.ObjectManager")
.storeResultsTo(result);
for (auto &p : result) {
if (p.first.find("/org/bluez/hci0/dev_") == 0 &&
p.first.length() ==
sizeof("/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX") - 1) {
auto name = p.second["org.bluez.Device1"]["Alias"].get<string>();
const auto &addr =
p.second["org.bluez.Device1"]["Address"].get<string>();
if (name.find(device_name) != string::npos) {
// `device_name` matched a substring in name
return addr;
}
}
}
Or simply,
#include "bluetooth/device.h"
auto addr = get_device_address_by_name("Rockerz 450");
First of all:
Reading documentation for 2 hour, will prevent you from 12 hours of frustration due to "why it's not working".
I read it somewhere once, and i just keep passing this :)
To read the code, or modify it:
- Read about bluez DBus API. I suggest https://www.bluetooth.com/bluetooth-resources/bluetooth-for-linux/, read Chapter 2-4 atleast
- Read about sdbus-c++, a short wiki is at https://github.com/Kistler-Group/sdbus-cpp/blob/master/docs/using-sdbus-c++.md
Then, check if the tests are working:
cmake -B build && cmake --build build
./build/ble/test_ble
./build/bluetooth/test_bluetooth