Skip to content

Commit

Permalink
Working on non-blocking reading
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Sep 11, 2018
1 parent 8bce039 commit 3376d17
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
36 changes: 30 additions & 6 deletions Sources/BluetoothLinux/L2CAP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import Foundation
import Bluetooth
import CSwiftBluetoothLinux

/// L2CAP Bluetooth socket
public final class L2CAPSocket: L2CAPSocketProtocol {
Expand Down Expand Up @@ -133,7 +134,9 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
addressType: AddressType?) throws -> (CInt, sockaddr_l2) {

// open socket
let internalSocket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BluetoothProtocol.l2cap.rawValue)
let internalSocket = socket(AF_BLUETOOTH,
SOCK_SEQPACKET,
BluetoothProtocol.l2cap.rawValue)

// error creating socket
guard internalSocket >= 0
Expand Down Expand Up @@ -252,8 +255,13 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
}

/// Reads from the socket.
public func recieve(_ bufferSize: Int = 1024) throws -> Data {

public func recieve(_ bufferSize: Int = 1024) throws -> Data? {

// check if reading buffer has data.
guard try canRead()
else { return nil }

// read socket
var buffer = [UInt8](repeating: 0, count: bufferSize)

let actualByteCount = read(internalSocket, &buffer, bufferSize)
Expand All @@ -264,6 +272,22 @@ public final class L2CAPSocket: L2CAPSocketProtocol {

return Data(bytes: actualBytes)
}

private func canRead() throws -> Bool {

var readSockets = FileDescriptorSet()
readSockets.zero()
readSockets.add(internalSocket)

var time = timeval()

let fdCount = select(internalSocket + 1, &readSockets, nil, nil, &time)

guard fdCount != -1
else { throw POSIXError.fromErrno! }

return readSockets.contains(internalSocket)
}

/// Write to the socket.
public func send(_ data: Data) throws {
Expand Down Expand Up @@ -389,8 +413,8 @@ struct bt_security {

#if os(Linux)

public let SOCK_SEQPACKET: CInt = 5
let SOCK_SEQPACKET: CInt = CInt(Glibc.SOCK_SEQPACKET.rawValue)

#endif

// MARK: - OS X support
Expand All @@ -400,5 +424,5 @@ struct bt_security {
let SO_PROTOCOL: CInt = 38

let SO_DOMAIN: CInt = 39

#endif
51 changes: 51 additions & 0 deletions Sources/CSwiftBluetoothLinux/include/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
*/

#include <stdint.h>
#include <stdbool.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/select.h>

/**
@brief Manipulates the underlying device parameters of special files.
Expand All @@ -32,3 +35,51 @@ __attribute__((swift_name("HCISetBit(_:_:)")))
{
*((uint32_t *) destination + (bit >> 5)) |= (1 << (bit & 31));
}

/**
A set of file descriptors.
*/
typedef fd_set FileDescriptorSet __attribute__((swift_name("FileDescriptorSet")));

/**
Initializes a file descriptor set on the stack.
*/
static inline FileDescriptorSet* swift_bluetooth_fd_set_zero(FileDescriptorSet* set)
__attribute__((swift_name("FileDescriptorSet.zero(self:)")))
{
FD_ZERO(set);
return set;
}

/**
Add a given file descriptor to a set.
@param fd The file descriptor to add to the set.
@param set The file descriptor set.
*/
static inline void swift_bluetooth_fd_set_add(FileDescriptorSet* set, int fileDescriptor)
__attribute__((swift_name("FileDescriptorSet.add(self:_:)")))
{
FD_SET(fileDescriptor, set);
}

/**
Removed a given file descriptor from a set.
@param fd The file descriptor to add to the set.
@param set The file descriptor set.
*/
static inline void swift_bluetooth_fd_set_remove(FileDescriptorSet* set, int fileDescriptor)
__attribute__((swift_name("FileDescriptorSet.remove(self:_:)")))
{
FD_CLR(fileDescriptor, set);
}

/**
Checks if a file descriptor is part of the set.
@param fd The file descriptor to to check for membership.
@param set The targeted value.
*/
static inline bool swift_bluetooth_fd_set_contains(FileDescriptorSet* set, int fileDescriptor)
__attribute__((swift_name("FileDescriptorSet.contains(self:_:)")))
{
return FD_ISSET(fileDescriptor, set);
}

0 comments on commit 3376d17

Please sign in to comment.