From 06f646aec4dbce64d28bae1be6111bd833f8e79e Mon Sep 17 00:00:00 2001 From: Paul Nettle Date: Fri, 25 Aug 2017 09:30:39 -0500 Subject: Initial version 1.0 --- src/Mgmt.h | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/Mgmt.h (limited to 'src/Mgmt.h') diff --git a/src/Mgmt.h b/src/Mgmt.h new file mode 100644 index 0000000..c58c9bc --- /dev/null +++ b/src/Mgmt.h @@ -0,0 +1,213 @@ +// Copyright 2017 Paul Nettle. +// +// This file is part of Gobbledegook. +// +// Gobbledegook is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Gobbledegook is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Gobbledegook. If not, see . + +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// >> +// >>> INSIDE THIS FILE +// >> +// +// This file contains various functions for interacting with Bluetooth Management interface, which provides adapter configuration. +// +// >> +// >>> DISCUSSION +// >> +// +// We only cover the basics here. If there are configuration features you need that aren't supported (such as configuring BR/EDR), +// then this would be a good place for them. +// +// Note that this class relies on the `HciAdapter`, which is a very primitive implementation. Use with caution. +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#pragma once + +#include +#include + +#include "HciAdapter.h" +#include "Utils.h" + +struct Mgmt +{ + // + // Constants + // + + // The length of the controller's name (not including null terminator) + static const int kMaxNameLength = 248; + + // The length of the controller's short name (not including null terminator) + static const int kMaxShortNameLength = 10; + + // + // Types + // + + // HCI Controller Settings + enum EHciControllerSettings + { + EHciPowered = (1<<0), + EHciConnectable = (1<<1), + EHciFastConnectable = (1<<2), + EHciDiscoverable = (1<<3), + EHciBondable = (1<<4), + EHciLinkLevelSecurity = (1<<5), + EHciSecureSimplePairing = (1<<6), + EHciBasicRate_EnhancedDataRate = (1<<7), + EHciHighSpeed = (1<<8), + EHciLowEnergy = (1<<9), + EHciAdvertising = (1<<10), + EHciSecureConnections = (1<<11), + EHciDebugKeys = (1<<12), + EHciPrivacy = (1<<13), + EHciControllerConfiguration = (1<<14), + EHciStaticAddress = (1<<15) + }; + + // The comments documenting these fields are very high level. There is a lot of detailed information not present, for example + // some values are not available at all times. This is fully documented in: + // + // https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/mgmt-api.txt + struct ControllerInformation + { + uint8_t address[6]; // The Bluetooth address + uint8_t bluetoothVersion; // Bluetooth version + uint16_t manufacturer; // The manufacturer + uint32_t supportedSettings; // Bits for various supported settings (see EHciControllerSettings) + uint32_t currentSettings; // Bits for various currently configured settings (see EHciControllerSettings) + uint8_t classOfDevice[3]; // Um, yeah. That. + char name[249]; // Null terminated name + char shortName[11]; // Null terminated short name + + void toHost() + { + manufacturer = Utils::endianToHost(manufacturer); + supportedSettings = Utils::endianToHost(supportedSettings); + currentSettings = Utils::endianToHost(currentSettings); + } + } __attribute__((packed)); + + // Construct the Mgmt device + // + // Set `controllerIndex` to the zero-based index of the device as recognized by the OS. If this parameter is omitted, the index + // of the first device (0) will be used. + Mgmt(uint16_t controllerIndex = kDefaultControllerIndex); + + // Returns the version information: + // + // bits 0-15 = revision + // bits 16-23 = version + // + // ... or -1 on error + int getVersion(); + + // Returns information about the controller (address, name, current settings, etc.) + // + // See the definition for MgmtControllerInformation for details. + // + // ... or nullptr on error + ControllerInformation *getControllerInformation(); + + // Set the adapter name and short name + // + // The inputs `name` and `shortName` may be truncated prior to setting them on the adapter. To ensure that `name` and + // `shortName` conform to length specifications prior to calling this method, see the constants `kMaxNameLength` and + // `kMaxShortNameLength`. In addition, the static methods `truncateName()` and `truncateShortName()` may be helpful. + // + // Returns true on success, otherwise false + bool setName(std::string name, std::string shortName); + + // Set a setting state to 'newState' + // + // Many settings are set the same way, this is just a convenience routine to handle them all + // + // Returns true on success, otherwise false + bool setState(const char *pSettingName, uint16_t commandCode, uint16_t controllerId, uint8_t newState); + + // Set the powered state to `newState` (true = powered on, false = powered off) + // + // Returns true on success, otherwise false + bool setPowered(bool newState); + + // Set the BR/EDR state to `newState` (true = enabled, false = disabled) + // + // Returns true on success, otherwise false + bool setBredr(bool newState); + + // Set the Secure Connection state (0 = disabled, 1 = enabled, 2 = secure connections only mode) + // + // Returns true on success, otherwise false + bool setSecureConnections(uint8_t newState); + + // Set the bondable state to `newState` (true = enabled, false = disabled) + // + // Returns true on success, otherwise false + bool setBondable(bool newState); + + // Set the connectable state to `newState` (true = enabled, false = disabled) + // + // Returns true on success, otherwise false + bool setConnectable(bool newState); + + // Set the LE state to `newState` (true = enabled, false = disabled) + // + // Returns true on success, otherwise false + bool setLE(bool newState); + + // Set the advertising state to `newState` (0 = disabled, 1 = enabled (with consideration towards the connectable setting), + // 2 = enabled in connectable mode). + // + // Returns true on success, otherwise false + bool setAdvertising(uint8_t newState); + + // + // Utilitarian + // + + // Transforms a "Current_Settings" value (4 octets as defined by the Bluetooth Management API specification) into a human- + // readable string of flags and settings. + static std::string controllerSettingsString(uint32_t bits); + + // Truncates the string `name` to the maximum allowed length for an adapter name. If `name` needs no truncation, a copy of + // `name` is returned. + static std::string truncateName(const std::string &name); + + // Truncates the string `name` to the maximum allowed length for an adapter short-name. If `name` needs no truncation, a copy + // of `name` is returned. + static std::string truncateShortName(const std::string &name); + +private: + + // + // Data members + // + + // Our adapter - we use this to connect to the HCI socket to talk to the adapter + HciAdapter hciAdapter; + + // Our controller information, updated each time the controller information is received + ControllerInformation controllerInfo; + + // The default controller index (the first device) + uint16_t controllerIndex; + + // Default controller index + static const uint16_t kDefaultControllerIndex = 0; + + // A constant referring to a 'non-controller' (for commands that do not require a controller index) + static const uint16_t kNonController = 0xffff; +}; -- cgit v1.2.3