Skip to content

Commit

Permalink
fix: more cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
stoprocent committed Sep 22, 2024
1 parent 9e95925 commit c16a652
Show file tree
Hide file tree
Showing 6 changed files with 3,449 additions and 5,007 deletions.
4 changes: 2 additions & 2 deletions examples/le-advertisement-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,6 @@ console.log('isDevUp = ' + bluetoothHciSocket.isDevUp());

setAdvertiseEnable(false);
setAdvertisingParameter();
setScanResponseData(Buffer.alloc('0909657374696d6f74650e160a182eb8855fb5ddb601000200', 'hex'));
setAdvertisingData(Buffer.alloc('0201061aff4c000215b9407f30f5f8466eaff925556b57fe6d00010002b6', 'hex'));
setScanResponseData(Buffer.from('0909657374696d6f74650e160a182eb8855fb5ddb601000200', 'hex'));
setAdvertisingData(Buffer.from('0201061aff4c000215b9407f30f5f8466eaff925556b57fe6d00010002b6', 'hex'));
setAdvertiseEnable(true);
4 changes: 2 additions & 2 deletions examples/le-connection-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ bluetoothHciSocket.on('data', function (data) {
console.log('\t' + latency);
console.log('\t' + supervisionTimeout * 10);

writeHandle(handle, Buffer.alloc('020001', 'hex'));
writeHandle(handle, Buffer.from('020001', 'hex'));
}
}
} else if (data.readUInt8(0) === HCI_ACLDATA_PKT) {
Expand Down Expand Up @@ -143,7 +143,7 @@ function createConnection (address, addressType) {
cmd.writeUInt8(0x00, 8); // initiator filter

cmd.writeUInt8(addressType === 'random' ? 0x01 : 0x00, 9); // peer address type
(Buffer.alloc(address.split(':').reverse().join(''), 'hex')).copy(cmd, 10); // peer address
(Buffer.from(address.split(':').reverse().join(''), 'hex')).copy(cmd, 10); // peer address

cmd.writeUInt8(0x00, 16); // own address type

Expand Down
167 changes: 144 additions & 23 deletions include/BluetoothHciSocket.h
Original file line number Diff line number Diff line change
@@ -1,55 +1,176 @@
#ifndef ___BLUETOOTH_HCI_SOCKET_H___
#define ___BLUETOOTH_HCI_SOCKET_H___
#ifndef BLUETOOTH_HCI_SOCKET_H
#define BLUETOOTH_HCI_SOCKET_H

#include <napi.h>
#include <atomic>
#include <thread>
// Include necessary headers
#include <napi.h> // N-API for Node.js addons

#include "BluetoothHciL2Socket.h"
#include <atomic> // For std::atomic
#include <thread> // For std::thread
#include <map> // For std::map
#include <memory> // For smart pointers
#include "BluetoothHciL2Socket.h" // Header for BluetoothHciL2Socket class

/**
* @brief Class representing a Bluetooth HCI (Host Controller Interface) socket.
*
* This class interfaces with the Bluetooth hardware using HCI sockets
* and integrates with Node.js using N-API for addon development.
*/
class BluetoothHciSocket : public Napi::ObjectWrap<BluetoothHciSocket> {
friend class BluetoothHciL2Socket;
friend class BluetoothHciL2Socket; ///< Grant access to BluetoothHciL2Socket class

public:
/**
* @brief Initializes the BluetoothHciSocket class and sets up exports to Node.js.
* @param env The N-API environment.
* @param exports The exports object to which the class is added.
* @return The modified exports object.
*/
static Napi::Object Init(Napi::Env env, Napi::Object exports);

/**
* @brief Constructor for BluetoothHciSocket.
* @param info Callback information from N-API.
*/
BluetoothHciSocket(const Napi::CallbackInfo& info);

/// Destructor
~BluetoothHciSocket();

// Binding methods to interface with HCI socket
/**
* @brief Binds the socket in raw mode.
* @param info Callback information from N-API.
* @return Napi::Value indicating success or failure.
*/
Napi::Value BindRaw(const Napi::CallbackInfo& info);

/**
* @brief Binds the socket in user mode.
* @param info Callback information from N-API.
* @return Napi::Value indicating success or failure.
*/
Napi::Value BindUser(const Napi::CallbackInfo& info);

/**
* @brief Binds the socket in control mode.
* @param info Callback information from N-API.
*/
void BindControl(const Napi::CallbackInfo& info);

// Device methods
/**
* @brief Checks if the Bluetooth device is up.
* @param info Callback information from N-API.
* @return Napi::Value indicating the device status.
*/
Napi::Value IsDevUp(const Napi::CallbackInfo& info);

/**
* @brief Retrieves the list of Bluetooth devices.
* @param info Callback information from N-API.
* @return Napi::Value containing the device list.
*/
Napi::Value GetDeviceList(const Napi::CallbackInfo& info);

// Configuration methods
/**
* @brief Sets the HCI filter for the socket.
* @param info Callback information from N-API.
*/
void SetFilter(const Napi::CallbackInfo& info);

// Control methods
/**
* @brief Starts the socket for communication.
* @param info Callback information from N-API.
*/
void Start(const Napi::CallbackInfo& info);

/**
* @brief Stops the socket communication.
* @param info Callback information from N-API.
*/
void Stop(const Napi::CallbackInfo& info);

/**
* @brief Writes data to the socket.
* @param info Callback information from N-API.
*/
void Write(const Napi::CallbackInfo& info);

/**
* @brief Cleans up resources used by the socket.
* @param info Callback information from N-API.
*/
void Cleanup(const Napi::CallbackInfo& info);

private:
/**
* @brief Polls the socket for events in a separate thread.
*/
void PollSocket();

void emitErrnoError(const char* syscall);
/**
* @brief Emits an error event based on errno.
* @param info Callback information from N-API.
* @param syscall Name of the system call that failed.
*/
void EmitError(const Napi::CallbackInfo& info, const char* syscall);

/**
* @brief Retrieves the device ID for a given device.
* @param devId Pointer to the device ID.
* @param isUp Whether to check if the device is up.
* @return Device ID or -1 on failure.
*/
int devIdFor(const int* devId, bool isUp);

/**
* @brief Workaround for kernel disconnect issues.
* @param length Length of the data.
* @param data Pointer to the data buffer.
* @return Result code.
*/
int kernelDisconnectWorkArounds(int length, char* data);

/**
* @brief Workaround for kernel connect issues.
* @param data Pointer to the data buffer.
* @param length Length of the data.
* @return True if handled, false otherwise.
*/
bool kernelConnectWorkArounds(char* data, int length);
void setConnectionParameters(unsigned short connMinInterval, unsigned short connMaxInterval, unsigned short connLatency, unsigned short supervisionTimeout);

/**
* @brief Sets connection parameters for Bluetooth LE connections.
* @param connMinInterval Minimum connection interval.
* @param connMaxInterval Maximum connection interval.
* @param connLatency Connection latency.
* @param supervisionTimeout Supervision timeout.
*/
void setConnectionParameters(uint16_t connMinInterval, uint16_t connMaxInterval, uint16_t connLatency, uint16_t supervisionTimeout);

private:
Napi::ThreadSafeFunction tsfn;
std::atomic<bool> stopFlag;
std::thread pollingThread;
Napi::ObjectReference thisObj;
int _mode;
int _socket;
int _devId;
uint8_t _address[6];
uint8_t _addressType;
std::map<bdaddr_t, std::weak_ptr<BluetoothHciL2Socket>> _l2sockets_connected;
std::map<bdaddr_t, std::shared_ptr<BluetoothHciL2Socket>> _l2sockets_connecting;
std::map<unsigned short, std::shared_ptr<BluetoothHciL2Socket>> _l2sockets_handles;
// N-API thread-safe function and object reference
Napi::ThreadSafeFunction tsfn; ///< Thread-safe function for callbacks
Napi::ObjectReference thisObj; ///< Reference to the JavaScript object

// Threading and synchronization
std::atomic<bool> stopFlag; ///< Atomic flag to signal the polling thread to stop
std::thread pollingThread; ///< Thread for polling the socket

// Internal state
int _mode; ///< Operating mode of the socket
int _socket; ///< File descriptor for the socket
int _devId; ///< Device ID

uint8_t _address[6]; ///< Local Bluetooth device address
uint8_t _addressType; ///< Address type (public or random)

// Maps to manage connected and connecting L2CAP sockets
std::map<bdaddr_t, std::weak_ptr<BluetoothHciL2Socket>> _l2sockets_connected; ///< Connected L2CAP sockets
std::map<bdaddr_t, std::shared_ptr<BluetoothHciL2Socket>> _l2sockets_connecting; ///< Connecting L2CAP sockets
std::map<uint16_t, std::shared_ptr<BluetoothHciL2Socket>> _l2sockets_handles; ///< L2CAP sockets by handle
};

#endif
#endif // BLUETOOTH_HCI_SOCKET_H
Loading

0 comments on commit c16a652

Please sign in to comment.