Skip to content

Commit 6f8a859

Browse files
project updated
1 parent f872f7c commit 6f8a859

19 files changed

Lines changed: 347 additions & 20 deletions

include/bitchat/core/constants.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ namespace constants
1313
const std::string BLE_SERVICE_UUID = "F47B5E2D-4A9E-4C5A-9B3F-8E1D2C3A4B5C";
1414
const std::string BLE_CHARACTERISTIC_UUID = "A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D";
1515

16+
// Client Version
17+
const std::string CLIENT_VERSION = "1.0";
18+
19+
// Platform
20+
const std::string PLATFORM = "cpp";
21+
1622
// BLE Configuration Constants
1723
const double BLE_SCAN_INTERVAL_SECONDS = 0.1;
1824
const double BLE_CONNECTION_TIMEOUT_SECONDS = 10.0;

include/bitchat/platform/bluetooth_interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class BitchatMessage;
1616
using PeerConnectedCallback = std::function<void(const std::string &peripheralID)>;
1717
using PeerDisconnectedCallback = std::function<void(const std::string &peripheralID)>;
1818
using PacketReceivedCallback = std::function<void(const BitchatPacket &packet, const std::string &peripheralID)>;
19+
using PeripheralDiscoveredCallback = std::function<void(const std::string &peripheralID)>;
1920

2021
// Abstract Bluetooth network interface that platforms must implement
2122
// This interface handles only BLE transport, all business logic is in BitchatManager
@@ -46,6 +47,7 @@ class IBluetoothNetwork
4647
virtual void setPeerConnectedCallback(PeerConnectedCallback callback) = 0;
4748
virtual void setPeerDisconnectedCallback(PeerDisconnectedCallback callback) = 0;
4849
virtual void setPacketReceivedCallback(PacketReceivedCallback callback) = 0;
50+
virtual void setPeripheralDiscoveredCallback(PeripheralDiscoveredCallback callback) = 0;
4951

5052
// Get connected peers count
5153
virtual size_t getConnectedPeersCount() const = 0;

include/bitchat/protocol/packet_serializer.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ class PacketSerializer
3737
// Parse channel announce payload
3838
void parseChannelAnnouncePayload(const std::vector<uint8_t> &payload, std::string &channel, bool &joining);
3939

40+
// Create version hello payload
41+
std::vector<uint8_t> makeVersionHelloPayload(const std::vector<uint8_t> &supportedVersions, uint8_t preferredVersion, const std::string &clientVersion, const std::string &platform, const std::vector<std::string> &capabilities = {});
42+
43+
// Parse version hello payload
44+
void parseVersionHelloPayload(const std::vector<uint8_t> &payload, std::vector<uint8_t> &supportedVersions, uint8_t &preferredVersion, std::string &clientVersion, std::string &platform, std::vector<std::string> &capabilities);
45+
4046
// Create packet with proper fields
41-
BitchatPacket makePacket(uint8_t type, const std::vector<uint8_t> &payload,
42-
bool hasRecipient = false, bool hasSignature = false,
43-
const std::string &senderID = "");
47+
BitchatPacket makePacket(uint8_t type, const std::vector<uint8_t> &payload, bool hasRecipient, bool hasSignature, const std::string &senderID);
4448

4549
private:
4650
// Helper functions for serialization

include/bitchat/services/message_service.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ class MessageService
5959
// Centralized packet processing - main entry point for all packets
6060
void processPacket(const BitchatPacket &packet, const std::string &peripheralID);
6161

62+
// Utility methods
63+
BitchatPacket createMessagePacket(const BitchatMessage &message);
64+
BitchatPacket createAnnouncePacket();
65+
BitchatPacket createChannelAnnouncePacket(const std::string &channel, bool joining);
66+
BitchatPacket createVersionHelloPacket();
67+
6268
// Set callbacks for message events
6369
using MessageReceivedCallback = std::function<void(const BitchatMessage &)>;
6470
using ChannelJoinedCallback = std::function<void(const std::string &)>;
@@ -106,9 +112,6 @@ class MessageService
106112
void processNoiseIdentityAnnouncePacket(const BitchatPacket &packet);
107113

108114
// Utility methods
109-
BitchatPacket createMessagePacket(const BitchatMessage &message);
110-
BitchatPacket createAnnouncePacket();
111-
BitchatPacket createChannelAnnouncePacket(const std::string &channel, bool joining);
112115
std::string generateMessageID() const;
113116

114117
// Helper methods

include/bitchat/services/network_service.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace bitchat
1919
class BluetoothAnnounceRunner;
2020
class CleanupRunner;
2121
class IBluetoothNetwork;
22+
class MessageService;
2223

2324
// NetworkService: Manages network operations, peer discovery, and message routing
2425
class NetworkService
@@ -28,7 +29,7 @@ class NetworkService
2829
~NetworkService();
2930

3031
// Initialize the network service
31-
bool initialize(std::shared_ptr<IBluetoothNetwork> bluetoothNetworkInterface, std::shared_ptr<BluetoothAnnounceRunner> announceRunner, std::shared_ptr<CleanupRunner> cleanupRunner);
32+
bool initialize(std::shared_ptr<IBluetoothNetwork> bluetoothNetworkInterface, std::shared_ptr<MessageService> messageService, std::shared_ptr<BluetoothAnnounceRunner> announceRunner, std::shared_ptr<CleanupRunner> cleanupRunner);
3233

3334
// Start network operations
3435
bool start();
@@ -42,9 +43,6 @@ class NetworkService
4243
// Send a packet to a specific peer
4344
bool sendPacketToPeer(const BitchatPacket &packet, const std::string &peerID);
4445

45-
// Set the Bluetooth network interface
46-
void setBluetoothNetworkInterface(std::shared_ptr<IBluetoothNetwork> bluetoothNetworkInterface);
47-
4846
// Set callbacks
4947
using PacketReceivedCallback = std::function<void(const BitchatPacket &, const std::string &)>;
5048
using PeerConnectedCallback = std::function<void(const std::string &)>;
@@ -58,6 +56,9 @@ class NetworkService
5856
// Bluetooth interface
5957
std::shared_ptr<IBluetoothNetwork> bluetoothNetworkInterface;
6058

59+
// Message service for packet creation
60+
std::shared_ptr<MessageService> messageService;
61+
6162
// Runners
6263
std::shared_ptr<BluetoothAnnounceRunner> announceRunner;
6364
std::shared_ptr<CleanupRunner> cleanupRunner;
@@ -71,6 +72,7 @@ class NetworkService
7172
void onPeerConnected(const std::string &peripheralID);
7273
void onPeerDisconnected(const std::string &peripheralID);
7374
void onPacketReceived(const BitchatPacket &packet, const std::string &peripheralID);
75+
void onPeripheralDiscovered(const std::string &peripheralID);
7476
void relayPacket(const BitchatPacket &packet);
7577
};
7678

include/platforms/apple/bluetooth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
@property(nonatomic, copy) void (^peerConnectedCallback)(NSString *);
2525
@property(nonatomic, copy) void (^peerDisconnectedCallback)(NSString *);
2626
@property(nonatomic, copy) void (^packetReceivedCallback)(NSData *, NSString *);
27+
@property(nonatomic, copy) void (^peripheralDiscoveredCallback)(NSString *);
2728

2829
// Initialization
2930
- (instancetype)init;
@@ -43,6 +44,7 @@
4344
// Callback setters
4445
- (void)setPeerDisconnectedCallback:(void (^)(NSString *peerID))callback;
4546
- (void)setPacketReceivedCallback:(void (^)(NSData *packetData, NSString *peripheralID))callback;
47+
- (void)setPeripheralDiscoveredCallback:(void (^)(NSString *peripheralID))callback;
4648

4749
// Constants
4850
+ (NSString *)serviceUUID;

include/platforms/apple/bluetooth_bridge.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class AppleBluetoothNetworkBridge : public bitchat::IBluetoothNetwork
3434
std::shared_ptr<bitchat::PacketSerializer> serializer; // Handles packet serialization/deserialization
3535

3636
// Callback function pointers for C++ interface
37-
PeerConnectedCallback peerConnectedCallback; // Called when a peer connects
38-
PeerDisconnectedCallback peerDisconnectedCallback; // Called when a peer disconnects
39-
PacketReceivedCallback packetReceivedCallback; // Called when a packet is received
37+
PeerConnectedCallback peerConnectedCallback; // Called when a peer connects
38+
PeerDisconnectedCallback peerDisconnectedCallback; // Called when a peer disconnects
39+
PacketReceivedCallback packetReceivedCallback; // Called when a packet is received
40+
PeripheralDiscoveredCallback peripheralDiscoveredCallback; // Called when peripheral is discovered
4041

4142
public:
4243
/**
@@ -105,6 +106,12 @@ class AppleBluetoothNetworkBridge : public bitchat::IBluetoothNetwork
105106
*/
106107
void setPacketReceivedCallback(PacketReceivedCallback callback) override;
107108

109+
/**
110+
* @brief Set callback for peripheral discovery events
111+
* @param callback Function to call when peripheral is discovered
112+
*/
113+
void setPeripheralDiscoveredCallback(PeripheralDiscoveredCallback callback) override;
114+
108115
/**
109116
* @brief Get the number of currently connected peers
110117
* @return Number of connected peers

include/platforms/linux/bluetooth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class LinuxBluetoothNetwork : public IBluetoothNetwork
2828
void setPeerConnectedCallback(PeerConnectedCallback callback) override;
2929
void setPeerDisconnectedCallback(PeerDisconnectedCallback callback) override;
3030
void setPacketReceivedCallback(PacketReceivedCallback callback) override;
31+
void setPeripheralDiscoveredCallback(PeripheralDiscoveredCallback callback) override;
3132
size_t getConnectedPeersCount() const override;
3233

3334
private:
@@ -46,6 +47,7 @@ class LinuxBluetoothNetwork : public IBluetoothNetwork
4647
PacketReceivedCallback packetReceivedCallback;
4748
PeerConnectedCallback peerConnectedCallback;
4849
PeerDisconnectedCallback peerDisconnectedCallback;
50+
PeripheralDiscoveredCallback peripheralDiscoveredCallback;
4951

5052
std::map<std::string, int> connectedSockets;
5153
std::mutex socketsMutex;

src/bitchat/core/bitchat_manager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ bool BitchatManager::initialize(
5656
BitchatData::shared()->setPeerID(localPeerID);
5757

5858
// Initialize services
59-
if (!networkService->initialize(bluetoothNetworkInterface, announceRunner, cleanupRunner))
59+
if (!networkService->initialize(bluetoothNetworkInterface, messageService, announceRunner, cleanupRunner))
6060
{
6161
spdlog::error("Failed to initialize NetworkService");
6262
return false;

src/bitchat/protocol/packet_serializer.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,4 +603,159 @@ void PacketSerializer::parseChannelAnnouncePayload(const std::vector<uint8_t> &p
603603
}
604604
}
605605

606+
std::vector<uint8_t> PacketSerializer::makeVersionHelloPayload(const std::vector<uint8_t> &supportedVersions, uint8_t preferredVersion, const std::string &clientVersion, const std::string &platform, const std::vector<std::string> &capabilities)
607+
{
608+
std::vector<uint8_t> data;
609+
610+
// Flags byte: bit 0 = hasCapabilities
611+
uint8_t flags = 0;
612+
if (!capabilities.empty())
613+
{
614+
flags |= 0x01;
615+
}
616+
writeUint8(data, flags);
617+
618+
// Supported versions array
619+
writeUint8(data, static_cast<uint8_t>(supportedVersions.size()));
620+
for (uint8_t version : supportedVersions)
621+
{
622+
writeUint8(data, version);
623+
}
624+
625+
// Preferred version
626+
writeUint8(data, preferredVersion);
627+
628+
// Client version (string with length prefix)
629+
writeUint8(data, static_cast<uint8_t>(std::min(static_cast<size_t>(255), clientVersion.length())));
630+
data.insert(data.end(), clientVersion.begin(), clientVersion.begin() + std::min(static_cast<size_t>(255), clientVersion.length()));
631+
632+
// Platform (string with length prefix)
633+
writeUint8(data, static_cast<uint8_t>(std::min(static_cast<size_t>(255), platform.length())));
634+
data.insert(data.end(), platform.begin(), platform.begin() + std::min(static_cast<size_t>(255), platform.length()));
635+
636+
// Capabilities (if present)
637+
if (!capabilities.empty())
638+
{
639+
writeUint8(data, static_cast<uint8_t>(capabilities.size()));
640+
for (const std::string &capability : capabilities)
641+
{
642+
writeUint8(data, static_cast<uint8_t>(std::min(static_cast<size_t>(255), capability.length())));
643+
data.insert(data.end(), capability.begin(), capability.begin() + std::min(static_cast<size_t>(255), capability.length()));
644+
}
645+
}
646+
647+
return data;
648+
}
649+
650+
void PacketSerializer::parseVersionHelloPayload(const std::vector<uint8_t> &payload, std::vector<uint8_t> &supportedVersions, uint8_t &preferredVersion, std::string &clientVersion, std::string &platform, std::vector<std::string> &capabilities)
651+
{
652+
// Minimum size check: flags(1) + versionCount(1) + at least one version(1) + preferredVersion(1) + min strings
653+
if (payload.size() < 4)
654+
{
655+
spdlog::error("Version hello payload too short");
656+
return;
657+
}
658+
659+
size_t offset = 0;
660+
661+
// Flags byte
662+
uint8_t flags = readUint8(payload, offset);
663+
bool hasCapabilities = (flags & 0x01) != 0;
664+
665+
// Supported versions count
666+
uint8_t versionCount = readUint8(payload, offset);
667+
supportedVersions.clear();
668+
669+
for (uint8_t i = 0; i < versionCount; i++)
670+
{
671+
if (offset >= payload.size())
672+
{
673+
spdlog::error("Version hello payload buffer overflow reading supported versions");
674+
return;
675+
}
676+
677+
supportedVersions.push_back(readUint8(payload, offset));
678+
}
679+
680+
// Preferred version
681+
if (offset >= payload.size())
682+
{
683+
spdlog::error("Version hello payload buffer overflow reading preferred version");
684+
return;
685+
}
686+
687+
preferredVersion = readUint8(payload, offset);
688+
689+
// Client version (string with length prefix)
690+
if (offset >= payload.size())
691+
{
692+
spdlog::error("Version hello payload buffer overflow reading client version length");
693+
return;
694+
}
695+
696+
uint8_t clientVersionLen = readUint8(payload, offset);
697+
698+
if (offset + clientVersionLen > payload.size())
699+
{
700+
spdlog::error("Version hello payload buffer overflow reading client version");
701+
return;
702+
}
703+
704+
clientVersion = std::string(payload.begin() + offset, payload.begin() + offset + clientVersionLen);
705+
offset += clientVersionLen;
706+
707+
// Platform (string with length prefix)
708+
if (offset >= payload.size())
709+
{
710+
spdlog::error("Version hello payload buffer overflow reading platform length");
711+
return;
712+
}
713+
714+
uint8_t platformLen = readUint8(payload, offset);
715+
716+
if (offset + platformLen > payload.size())
717+
{
718+
spdlog::error("Version hello payload buffer overflow reading platform");
719+
return;
720+
}
721+
722+
platform = std::string(payload.begin() + offset, payload.begin() + offset + platformLen);
723+
offset += platformLen;
724+
725+
// Capabilities (if present)
726+
capabilities.clear();
727+
728+
if (hasCapabilities)
729+
{
730+
if (offset >= payload.size())
731+
{
732+
spdlog::error("Version hello payload buffer overflow reading capabilities count");
733+
return;
734+
}
735+
736+
uint8_t capCount = readUint8(payload, offset);
737+
738+
for (uint8_t i = 0; i < capCount; i++)
739+
{
740+
if (offset >= payload.size())
741+
{
742+
spdlog::error("Version hello payload buffer overflow reading capability length");
743+
return;
744+
}
745+
746+
uint8_t capLen = readUint8(payload, offset);
747+
748+
if (offset + capLen > payload.size())
749+
{
750+
spdlog::error("Version hello payload buffer overflow reading capability");
751+
return;
752+
}
753+
754+
capabilities.push_back(std::string(payload.begin() + offset, payload.begin() + offset + capLen));
755+
756+
offset += capLen;
757+
}
758+
}
759+
}
760+
606761
} // namespace bitchat

0 commit comments

Comments
 (0)