Skip to content
Closed
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ poetry.lock
/*.pem
/*.log
/peers_keys.txt
/temp
30 changes: 26 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
cmake_minimum_required(VERSION 3.20)
project(bitchat)

# policies
cmake_policy(SET CMP0054 NEW) # only interpret if() arguments as variables or keywords when unquoted
cmake_policy(SET CMP0076 NEW) # target_sources() command converts relative paths to absolute
set(CMAKE_POLICY_DEFAULT_CMP0091 NEW) # msvc runtime library flags are selected by an abstraction
set(CMAKE_POLICY_DEFAULT_CMP0135 NEW) # set the timestamps of all extracted contents to the time of the extraction

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand Down Expand Up @@ -36,6 +42,8 @@ elseif(UNIX AND NOT APPLE)
set(PLATFORM_LINUX TRUE)
find_package(PkgConfig REQUIRED)
pkg_check_modules(BLUEZ REQUIRED bluez)
pkg_check_modules(BLUEZ_DBUS_CPP REQUIRED bluez-dbus-cpp)
pkg_check_modules(SDBUS_CPP REQUIRED sdbus-c++)
endif()

# Add dependencies via CPM
Expand Down Expand Up @@ -64,6 +72,12 @@ endif()
# Find OpenSSL
find_package(OpenSSL REQUIRED)

# Find Threads
if(PLATFORM_LINUX)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()

# Include directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
Expand Down Expand Up @@ -112,11 +126,19 @@ if(PLATFORM_APPLE)
${FRAMEWORK_IOKIT}
${FRAMEWORK_COREFOUNDATION}
)
# Only compile .mm files as Objective-C++, not the entire target
# target_compile_options(bitchat PRIVATE -x objective-c++)
elseif(PLATFORM_LINUX)
target_link_libraries(bitchat ${BLUEZ_LIBRARIES})
target_include_directories(bitchat PRIVATE ${BLUEZ_INCLUDE_DIRS})
target_link_libraries(bitchat
Threads::Threads
${BLUEZ_DBUS_CPP_LIBRARIES}
${SDBUS_CPP_LIBRARIES}
${BLUEZ_LIBRARIES}
)
target_include_directories(bitchat PRIVATE
${BLUEZ_INCLUDE_DIRS}
${BLUEZ_DBUS_CPP_INCLUDE_DIRS}
${SDBUS_CPP_INCLUDE_DIRS}
)
target_compile_options(bitchat PRIVATE ${BLUEZ_DBUS_CPP_CFLAGS_OTHER} ${SDBUS_CPP_CFLAGS_OTHER})
endif()

# Compiler-specific flags
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ clean:
build:
rm -rf build
cmake -B build . -G Ninja
cmake --build build
cmake --build build

run:
./build/bin/bitchat
Expand Down
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,19 @@ make
### Linux

```bash
# Install dependencies
sudo apt-get install cmake libssl-dev libbluetooth-dev
# Install system dependencies
sudo apt-get install cmake libssl-dev libbluetooth-dev libsigc++-3.0-dev libpopt-dev libdbus-1-dev libsystemd-dev libsdbus-c++-dev pkg-config git ninja-build build-essential

# Install bluez-dbus-cpp library
git clone https://github.com/weareaudiofile/bluez-dbus-cpp.git
cd bluez-dbus-cpp
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
sudo make install

# Update library cache
sudo ldconfig

# Build
mkdir build && cd build
Expand All @@ -138,6 +149,25 @@ make
./bin/bitchat
```

**Dependencies for Linux:**
- `cmake` - Build system
- `libssl-dev` - OpenSSL development libraries
- `libbluetooth-dev` - BlueZ Bluetooth development libraries
- `libsigc++-3.0-dev` - libsigc++ library (required by dbus-cxx)
- `libpopt-dev` - POPT library (required by dbus-cxx)
- `libdbus-1-dev` - D-Bus development libraries
- `libsystemd-dev` - systemd development libraries (for sd-bus)
- `pkg-config` - Package configuration tool

**Note on SDBUSCPP_SDBUS_LIB:**
The `SDBUSCPP_SDBUS_LIB` option defines which sd-bus implementation to use:
- `default` (recommended): Auto-detects systemd → elogind → basu
- `systemd`: Uses libsystemd (most common on modern Linux distributions)
- `elogind`: Uses libelogind (for systems without systemd)
- `basu`: Uses basu (minimal implementation for embedded systems)

For Ubuntu and most modern Linux distributions, install `libsystemd-dev` and use the default setting.

### Windows

```bash
Expand Down
10 changes: 5 additions & 5 deletions include/bitchat/platform/bluetooth_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ namespace bitchat
struct BitchatPacket;
struct BitchatMessage;

// Callback types for Bluetooth transport events - PURE TRANSPORT ONLY
// Callback types for Bluetooth transport events
using PeerDisconnectedCallback = std::function<void(const std::string &peerId)>;
using PacketReceivedCallback = std::function<void(const BitchatPacket &packet)>;

// Abstract Bluetooth interface that platforms must implement - PURE TRANSPORT ONLY
// Abstract Bluetooth interface that platforms must implement
// This interface handles only BLE transport, all business logic is in BitchatManager
class BluetoothInterface
{
Expand All @@ -32,10 +32,10 @@ class BluetoothInterface
// Stop all Bluetooth operations
virtual void stop() = 0;

// Send packet to all connected peers - PURE TRANSPORT
// Send packet to all connected peers
virtual bool sendPacket(const BitchatPacket &packet) = 0;

// Send packet to specific peer - PURE TRANSPORT
// Send packet to specific peer
virtual bool sendPacketToPeer(const BitchatPacket &packet, const std::string &peerId) = 0;

// Check if Bluetooth is ready
Expand All @@ -44,7 +44,7 @@ class BluetoothInterface
// Get local peer ID
virtual std::string getLocalPeerId() const = 0;

// Set callbacks - PURE TRANSPORT ONLY
// Set callbacks
virtual void setPeerDisconnectedCallback(PeerDisconnectedCallback callback) = 0;
virtual void setPacketReceivedCallback(PacketReceivedCallback callback) = 0;

Expand Down
59 changes: 30 additions & 29 deletions include/platforms/linux/bluetooth.h
Original file line number Diff line number Diff line change
@@ -1,53 +1,54 @@
#pragma once

#include "bitchat/platform/bluetooth_interface.h"
#include <atomic>
#include <functional>
#include <map>
#include <mutex>
#include <memory>
#include <string>
#include <thread>
#include <vector>

namespace bitchat
{
// Forward declarations
class ChatClient;

class LinuxBluetooth : public BluetoothInterface
class LinuxBluetooth : public bitchat::BluetoothInterface
{
public:
LinuxBluetooth();
~LinuxBluetooth() override;
~LinuxBluetooth();

bool initialize() override;
bool start() override;
void stop() override;
bool sendPacket(const BitchatPacket &packet) override;
bool sendPacketToPeer(const BitchatPacket &packet, const std::string &peerId) override;

bool sendPacket(const bitchat::BitchatPacket &packet) override;
bool sendPacketToPeer(const bitchat::BitchatPacket &packet, const std::string &peerId) override;

bool isReady() const override;
std::string getLocalPeerId() const override;
void setPeerDisconnectedCallback(PeerDisconnectedCallback callback) override;
void setPacketReceivedCallback(PacketReceivedCallback callback) override;
size_t getConnectedPeersCount() const override;

private:
void scanThreadFunc();
void readerThreadFunc(const std::string &deviceId, int socket);
void acceptThreadFunc();
// Advertisement status methods
bool isAdvertising() const;
std::string getAdvertisementStatus() const;

int deviceId;
int hciSocket;
int rfcommSocket;
std::string localPeerId;
void setPeerDisconnectedCallback(bitchat::PeerDisconnectedCallback callback) override;
void setPacketReceivedCallback(bitchat::PacketReceivedCallback callback) override;

std::thread scanThread;
std::thread acceptThread;
std::atomic<bool> stopThreads;
// Method to handle data received from other devices
void onDataReceived(const std::vector<uint8_t> &data);

PacketReceivedCallback packetReceivedCallback;
PeerDisconnectedCallback peerDisconnectedCallback;
// Methods for managing subscribed clients (used by ChatCharacteristic)
void addSubscribedClient(std::shared_ptr<ChatClient> client);
void removeSubscribedClient(std::shared_ptr<ChatClient> client);

std::map<std::string, int> connectedSockets;
mutable std::mutex socketsMutex;
private:
void startScanning();
void registerAdvertisement();
void setupDeviceMonitoring();
void setupDevicePropertiesMonitoring(const std::string &devicePath);
void onDeviceRemoved(const std::string &devicePath);
void onDeviceConnected(const std::string &devicePath);
void onDeviceDisconnected(const std::string &devicePath);
void onDeviceServicesResolved(const std::string &devicePath);
struct Impl;
std::unique_ptr<Impl> impl;
};

} // namespace bitchat
Loading
Loading