Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IBluetooth] Update with JSON-RPC interface #392

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
318 changes: 314 additions & 4 deletions interfaces/IBluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#pragma once
#include "Module.h"

// @insert <com/IIteratorType.h>

namespace Thunder {

Expand All @@ -38,7 +39,7 @@ namespace Exchange {
struct EXTERNAL ISecurityCallback : virtual public Core::IUnknown {
enum { ID = ID_BLUETOOTH_DEVICE_CLASSIC_SECURITYCALLBACK };

virtual void PINCodeRequest() = 0;
virtual void PINCodeRequest() = 0;
};

virtual void PINCode(const string& pinCode) = 0;
Expand Down Expand Up @@ -75,9 +76,9 @@ namespace Exchange {
};

enum type : uint8_t {
ADDRESS_BREDR /*@text:Classic */,
ADDRESS_LE_PUBLIC /*@text:LowEnergy */,
ADDRESS_LE_RANDOM /*@text:LowEnergyRandom */
ADDRESS_BREDR,
ADDRESS_LE_PUBLIC,
ADDRESS_LE_RANDOM
};

enum pairingcapabilities : uint8_t {
Expand Down Expand Up @@ -186,6 +187,315 @@ namespace Exchange {
virtual uint32_t ForgetDevice(const string& address, const IDevice::type type) = 0;
};


namespace JSONRPC {

// @json 1.0.0 @text:legacy_lowercase
struct EXTERNAL IBluetoothControl {

virtual ~IBluetoothControl() = default;

enum class adaptertype : uint8_t {
CLASSIC,
LOW_ENERGY,
DUAL
};

enum class devicetype : uint8_t {
CLASSIC = IBluetooth::IDevice::type::ADDRESS_BREDR,
LOW_ENERGY = IBluetooth::IDevice::type::ADDRESS_LE_PUBLIC,
LOW_ENERGY_RANDOM = IBluetooth::IDevice::type::ADDRESS_LE_RANDOM
};

enum class scantype : uint8_t {
CLASSIC,
LOW_ENERGY
};

enum class scanmode : uint8_t {
GENERAL,
LIMITED
};

enum class devicestate : uint8_t {
PAIRING,
PAIRED,
UNPAIRED,
CONNECTED,
DISCONNECTED
};

enum class disconnectreason : uint8_t {
CONNECTION_TIMEOUT,
AUTHENTICATION_FAILURE,
REMOTE_LOW_ON_RESOURCES,
REMOTE_POWERED_OFF,
TERMINATED_BY_REMOTE,
TERMINATED_BY_HOST
};


using pairingcapabilities = IBluetooth::IDevice::pairingcapabilities;

struct device {
string address /* @brief Bluetooth address */;
devicetype type /* @brief Bluetooth device type */;
};

struct adapterinfo {
uint8_t id /* @brief Adapter ID number */;
string interface /* @brief Interface name (e.g. "hci0") */;
string address /* @brief Bluetooth address */;
adaptertype type /* @brief Adapter type */;
uint8_t version /* @brief Version */;
Core::OptionalType<uint16_t> manufacturer /* @brief Company Identification Code (CIC) (e.g. 305) */;
Core::OptionalType<uint32_t> cod /* @text:class */ /* @brief Class of Device (CoD) value (e.g. 2360324) */ /* @restrict:0xFFFFFF */;
Core::OptionalType<string> name /* @brief Name */;
Core::OptionalType<string> shortName /* @brief Shortened name */;
};

using IUUIDIterator = RPC::IIteratorType<string, 0>;
using IDeviceIterator = RPC::IIteratorType<device, 0>;
using IAdapterIterator = RPC::IIteratorType<uint8_t, 0>;
using IAddressIterator = RPC::IIteratorType<string, 0>;

// @event
struct EXTERNAL INotification {

virtual ~INotification() = default;

// @statuslistener
// @brief Reports entering the discoverable state
// @param mode Advertising or inquiry scanning mode
// @param connectable Specifies if LE advertising reports that the device is connectable (LE-only)
virtual void DiscoverableStarted(const scantype type, const scanmode mode,
const Core::OptionalType<bool>& connectable) = 0;

// @brief Reports leaving the discoverable state
virtual void DiscoverableComplete(const scantype type) = 0;

// @statuslistener
// @brief Reports start of scanning
// @param mode Discovery or inquiry mode
virtual void ScanStarted(const scantype type, const scanmode mode) = 0;

// @brief Reports end of scanning
virtual void ScanComplete(const scantype type) = 0;

// @statuslistener
// @brief Reports device state changes
// @brief disconnectReason If disconnected specifies the cause of disconnection
virtual void DeviceStateChanged(const string& address, const devicetype type,
const devicestate state, const Core::OptionalType<disconnectreason>& disconnectReason) = 0;
};

// @event
struct EXTERNAL ISecurityNotification {

virtual ~ISecurityNotification() = default;

// @brief Notifies of a PIN code request during authenticated BR/EDR legacy pairing process
// @details Upon receiving this event the client is required to respond with "providePinCode" call
// in order to complete the pairing procedure. The PIN code value is typically collected by
// prompting the end-user on the local device. If the client fails to respond before the pairing
// timeout elapses the pairing procedure will be aborted.
virtual void PINCodeRequest(const string& address, const devicetype type) = 0;

// @brief Notifies of a user confirmation request during authenticated BR/EDR SSP pairing process
// @details Upon receiving this event the client is required to respond with "confirmPasskey" call
// in order to complete the pairing procedure. The passkey confirmation is typically collected
// by prompting the end-user on the local device. If the client fails to respond before the pairing
// timeout elapses the pairing procedure will be aborted.
// @param secret A six-digit decimal number sent by the remote device to be presented to the end-user
// for confirmation on the local device (e.g 123456). The passkey may be omitted for simple yes/no paring.
virtual void PasskeyConfirmRequest(const string& address, const devicetype type,
const Core::OptionalType<uint32_t>& secret /* @restrict:999999 */) = 0;

// @brief Notifies of a passkey supply request during authenticated LE pairing process
// @details Upon receiving this event the client is required to respond with "providePasskey" call
// in order to complete the pairing procedure. The passkey value is typically collected by
// prompting the end-user on the local device. If the client fails to respond before the pairing
// timeout elapses the pairing procedure will be aborted.
virtual void PasskeyRequest(const string& address, const devicetype type) = 0;

// @brief Notifies of a passkey presentation request during authenticated LE pairing process
// @details Upon receiving this event the client is required to display the passkey on the local
// device. The end-user on the remote device will need to enter this passkey to complete the
// pairing procedure. If end-user fails to respond before the pairing timeout elapses the pairing
// procedure will be aborted.
// @param secret A six-digit decimal number to be displayed on the local device (e.g 123456)
virtual void PasskeyDisplayRequest(const string& address, const devicetype type, const uint32_t secret /* @restrict:999999 */) = 0;
};


// @brief Starts LE advertising or BR/EDR inquiry scanning, making the local interface visible for
// nearby Bluetooth devices
// @param mode Advertising or inquiry scanning mode
// @param connectable Specifies if LE advertising should report the device is connectable (LE-only)
// @param duration Time span of the discoverable state in seconds
// @retval ERROR_UNAVAILABLE The adapter does not support selected discovery type
// @retval ERROR_INPROGRESS Discoverable state of selected type is already in progress
virtual Core::hresult SetDiscoverable(const scantype type,
const Core::OptionalType<scanmode>& mode /* @default:GENERAL */,
const Core::OptionalType<bool>& connectable /* @default:true */,
const Core::OptionalType<uint16_t>& duration /* @default:30 */) = 0;

// @brief Stops LE advertising or BR/EDR inquiry scanning operation
// @retval ERROR_UNAVAILABLE The adapter does not support selected discovery type
// @retval ERROR_ILLEGAL_STATE The adapter is in not discoverable state of selected type
virtual Core::hresult StopDiscoverable(const scantype type) = 0;

// @brief Starts LE active discovery or BR/EDR inquiry of nearby Bluetooth devices
// @param mode Discovery or inquiry mode (scan picks up only devices discoverable in paricular mode)
// @param duration Time span of the discovery in seconds
// @retval ERROR_UNAVAILABLE The adapter does not support selected scan type
// @retval ERROR_INPROGRESS Scan of selected type is already in progress
virtual Core::hresult Scan(const scantype type,
const Core::OptionalType<scanmode>& mode /* @default:GENERAL */,
const Core::OptionalType<uint16_t>& duration /* @default:12 */) = 0;

// @brief Stops LE discovery or BR/EDR inquiry operation
// @retval ERROR_UNAVAILABLE The adapter does not support selected scan type
// @retval ERROR_ILLEGAL_STATE Scan of selected type is not in progress
virtual Core::hresult StopScanning(const scantype type) = 0;

// @brief Connects to a Bluetooth device
// @details This call also enables automatic reconnection of the device. If the device is currently
// not available it will be automatically connected as soon it becomes available. This call is asynchronous.
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_INPROGRESS The host adapter is currently busy
// @retval ERROR_ILLEGAL_STATE The device is not paired
// @retval ERROR_ALREADY_CONNECTED The device is already connected
// @retval ERROR_REQUEST_SUBMITTED The device has not been connected, but will be automatically
// connected when it becomes available
virtual Core::hresult Connect(const string& address, const devicetype type) = 0;

// @brief Disconnects from a connected Bluetooth device
// @details This call also disables automatic reconnection. If the device is currently not connected it
// will not be reconnected when it again becomes available.
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_INPROGRESS The host adapter is currently busy
// @retval ERROR_ALREADY_RELEASED The device is not connected
// @retval ERROR_REQUEST_SUBMITTED The device is currently not connected, but it's automatic reconnection
// mode has been disabled
virtual Core::hresult Disconnect(const string& address, const devicetype type) = 0;

// @brief Pairs a Bluetooth device
// @details PIN-code or passkey requests may appear during the pairing process. The process can be
// cancelled any time by calling *abortPairing*. This call is asynchronous.
// @param capabilities Host device pairing capabilities
// @param timeout Time allowed for the pairing process to complete
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_INPROGRESS The host adapter is currently busy
// @retval ERROR_ALREADY_CONNECTED The device is already paired
// @retval ERROR_GENERAL Failed to pair
virtual Core::hresult Pair(const string& address, const devicetype type,
const Core::OptionalType<pairingcapabilities>& capabilities /* @default:NO_INPUT_NO_OUTPUT */,
const Core::OptionalType<uint16_t>& timeout /* @default:10 */) = 0;

// @brief Unpairs a paired Bluetooth device
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_INPROGRESS The host adapter is currently busy
// @retval ERROR_ALREADY_RELEASED The device is not paired
virtual Core::hresult Unpair(const string& address, const devicetype type) = 0;

// @brief Aborts pairing operation
// @details This call is asynchronous.
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_ILLEGAL_STATE The device not currently pairing
virtual Core::hresult AbortPairing(const string& address, const devicetype type) = 0;

// @brief Provides a PIN-code for authentication during a legacy pairing process
// @details This method should be called upon receiving a "pinCodeRequest" event during a legacy pairing
// process. If the specified PIN-code is incorrect the pairing process will be aborted.
// @param secret A PIN code, typically 4 ASCII digits (e.g. "1234")
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_ILLEGAL_STATE The device not currently pairing or a PIN code has not been requested
virtual Core::hresult ProvidePINCode(const string& address, const devicetype type, const string& secret /* @restrict:16 */) = 0;

// @brief Confirms a passkey for authentication during a BR/EDR SSP pairing processs
// @details This method should be called upon receiving a passkeyConfirmationRequest event during a pairing
// process. If the confirmation is negative the pairing process will be aborted.
// @param accept Confirm pairing (normally if the presented passkey is correct)
// @retval ERROR_UNKNOWN_KEY Unknown device
// @retval ERROR_ILLEGAL_STATE The device is currently not pairing or passkey confirmation has not been requested
virtual Core::hresult ConfirmPasskey(const string& address, const devicetype type, const bool accept) = 0;

// @brief Provides a passkey for authentication during a pairing process
// @details This method should be called upon receiving a "passkeyRequest" event during pairing process.
// If the specified passkey is incorrect or empty the pairing process will be aborted.
// @param secret A decimal six-digit passkey value (e.g. 123456)
// @retval ERROR_UNKNOWN_KEY Unknown device
// @retval ERROR_ILLEGAL_STATE The device not currently pairing or a passkey has not been requested
virtual Core::hresult ProvidePasskey(const string& address, const devicetype type, const uint32_t secret /* @restrict:999999 */) = 0;

// @brief Forgets a previously seen Bluetooth device
// @details The device will no longer be listed and its status tracked. If paired the device must be unpaired first.
// @retval ERROR_UNKNOWN_KEY The device is not known
// @retval ERROR_ILLEGAL_STATE The device is paired
virtual Core::hresult Forget(const string& address, const devicetype type) = 0;

// @brief Retrieves a list of known remote Bluetooth devices
virtual Core::hresult GetDeviceList(IDeviceIterator*& devices /* @out */) const = 0;

// @brief Retrieves detailed information about a known Bluetooth device
// @param name Device local name
// @param version Device version
// @param manufacturer Company Identification Code (CIC) (e.g. 305)
// @param cod Class of Device (CoD) value (e.g. 2360324)
// @param appearance Appearance value (LE-only) (e.g. 2113)
// @param services A list of supported service UUIDs
// @param paired Specifies if the device is currently paired
// @param connected Specifies if the device is currently connected
// @retval ERROR_UNKNOWN_KEY The device is not known
virtual Core::hresult GetDeviceInfo(string& address /* @inout */, devicetype& type /* @inout */,
Core::OptionalType<string>& name /* @out */,
Core::OptionalType<uint8_t>& version /* @out */,
Core::OptionalType<uint16_t>& manufacturer /* @out */,
Core::OptionalType<uint32_t>& cod /* @out @text:class @restrict:0xFFFFFF */,
Core::OptionalType<uint16_t>& appearance /* @out */,
Core::OptionalType<IUUIDIterator*>& services /* @out */,
bool& paired /* @out */,
bool& connected /* @out */) const = 0;

// @property
// @brief List of local Bluetooth adapters
virtual Core::hresult Adapters(IAdapterIterator*& adapters /* @out */) const = 0;

// @property
// @brief Local Bluetooth adapter information
// @param adapter Adapter index
// @retval ERROR_UNKNOWN_KEY The adapter ID is invalid
virtual Core::hresult Adapter(const uint8_t adapter /* @index */, adapterinfo& info /* @out */) const = 0;


// The legacy API below works with LowEnergy devices only and thus is deprecated

struct deviceinfo {
string address /* @brief Bluetooth address */;
IBluetoothControl::devicetype type /* @brief Device type */;
Core::OptionalType<string> name /* @brief Device name */;
Core::OptionalType<uint32_t> cod /* @text:class */ /* @brief Class of Device (CoD) value (e.g. 2360324) */ /* @restrict:0xFFFFFF */;
Core::OptionalType<uint16_t> appearance /* @brief Appearance value (LE only) (e.g. 2113) */;
Core::OptionalType<string> services /* @opaque */ /* @brief Array of supported service UUIDs */;
bool paired /* @brief Specifies if the device is currently paired */;
bool connected /* @brief Specifies if the device is currently connected */;
};

// @property
// @deprecated
// @brief List of known remote Bluetooth LE devices
virtual Core::hresult Devices(IAddressIterator*& devices /* @out */) const = 0;

// @property
// @deprecated
// @brief Remote Bluetooth LE device information
// @retval ERROR_UNKNOWN_KEY The device is not known
virtual Core::hresult Device(const string& deviceAddress /* @index */, deviceinfo& info /* @out */) const = 0;
};

} // namespace JSONRPC

} // namespace Exchange

}
Loading
Loading