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/GattInterface.h | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/GattInterface.h (limited to 'src/GattInterface.h') diff --git a/src/GattInterface.h b/src/GattInterface.h new file mode 100644 index 0000000..3c4075e --- /dev/null +++ b/src/GattInterface.h @@ -0,0 +1,231 @@ +// 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 is our abstraction layer for GATT interfaces, used by GattService, GattCharacteristic & GattDescriptor +// +// >> +// >>> DISCUSSION +// >> +// +// See the discussion at the top of GattInterface.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#pragma once + +#include +#include +#include + +#include "TickEvent.h" +#include "DBusInterface.h" +#include "GattProperty.h" +#include "GattUuid.h" +#include "Server.h" +#include "Utils.h" + +// --------------------------------------------------------------------------------------------------------------------------------- +// Forward declarations +// --------------------------------------------------------------------------------------------------------------------------------- + +struct GattInterface; +struct DBusObject; + +// --------------------------------------------------------------------------------------------------------------------------------- +// Pure virtual representation of a Bluetooth GATT Interface, the base class for Services, Characteristics and Descriptors +// --------------------------------------------------------------------------------------------------------------------------------- + +struct GattInterface : DBusInterface +{ + // Standard constructor + GattInterface(DBusObject &owner, const std::string &name); + virtual ~GattInterface(); + + // Returns a string identifying the type of interface + virtual const std::string getInterfaceType() const = 0; + + // + // GATT Characteristic properties + // + + // Returns the list of GATT properties + const std::list &getProperties() const; + + // Add a `GattProperty` to the interface + // + // There are helper methods for adding properties for common types as well as a generalized helper method for adding a + // `GattProperty` of a generic GVariant * type. + template + T &addProperty(const GattProperty &property) + { + properties.push_back(property); + return *static_cast(this); + } + + // Add a named property with a GVariant * + // + // There are helper methods for common types (UUIDs, strings, boolean, etc.) Use this method when no helper method exists for + // the type you want to use. There is also a helper method for adding a named property of a pre-built `GattProperty`. + template + T &addProperty(const std::string &name, GVariant *pValue, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, pValue, getter, setter)); + } + + // Helper method for adding a named property with a `GattUuid` + template + T &addProperty(const std::string &name, const GattUuid &uuid, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromString(uuid.toString128().c_str()), getter, setter)); + } + + // Helper method for adding a named property with a `DBusObjectPath` + template + T &addProperty(const std::string &name, const DBusObjectPath &path, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromObject(path), getter, setter)); + } + + // Helper method for adding a named property with a std::strings + template + T &addProperty(const std::string &name, const std::string &str, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromString(str), getter, setter)); + } + + // Helper method for adding a named property with an array of std::strings + template + T &addProperty(const std::string &name, const std::vector &arr, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromStringArray(arr), getter, setter)); + } + + // Helper method for adding a named property with an array of C strings + template + T &addProperty(const std::string &name, const std::vector &arr, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromStringArray(arr), getter, setter)); + } + + // Helper method for adding a named property with a given C string + template + T &addProperty(const std::string &name, const char *pStr, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromString(pStr), getter, setter)); + } + + // Helper method for adding a named property with a given boolean value + template + T &addProperty(const std::string &name, bool value, GDBusInterfaceGetPropertyFunc getter = nullptr, GDBusInterfaceSetPropertyFunc setter = nullptr) + { + return addProperty(GattProperty(name, Utils::gvariantFromBoolean(value), getter, setter)); + } + + // Return a data value from the server's registered data getter (GGKServerDataGetter) + // + // This method is for use with non-pointer types. For pointer types, use `getDataPointer()` instead. + // + // This method is intended to be used in the server description. An example usage would be: + // + // uint8_t batteryLevel = self.getDataValue("battery/level", 0); + template + T getDataValue(const char *pName, const T defaultValue) const + { + const void *pData = TheServer->getDataGetter()(pName); + return nullptr == pData ? defaultValue : *static_cast(pData); + } + + // Return a data pointer from the server's registered data getter (GGKServerDataGetter) + // + // This method is for use with pointer types. For non-pointer types, use `getDataValue()` instead. + // + // This method is intended to be used in the server description. An example usage would be: + // + // const char *pTextString = self.getDataPointer("text/string", ""); + template + T getDataPointer(const char *pName, const T defaultValue) const + { + const void *pData = TheServer->getDataGetter()(pName); + return nullptr == pData ? defaultValue : static_cast(pData); + } + + // Sends a data value from the server back to the application through the server's registered data setter + // (GGKServerDataSetter) + // + // This method is for use with non-pointer types. For pointer types, use `setDataPointer()` instead. + // + // This method is intended to be used in the server description. An example usage would be: + // + // self.setDataValue("battery/level", batteryLevel); + template + bool setDataValue(const char *pName, const T value) const + { + return TheServer->getDataSetter()(pName, static_cast(&value)) != 0; + } + + // Sends a data pointer from the server back to the application through the server's registered data setter + // (GGKServerDataSetter) + // + // This method is for use with pointer types. For non-pointer types, use `setDataValue()` instead. + // + // This method is intended to be used in the server description. An example usage would be: + // + // self.setDataPointer("text/string", stringFromGVariantByteArray(pAyBuffer).c_str()); + template + bool setDataPointer(const char *pName, const T pointer) const + { + return TheServer->getDataSetter()(pName, static_cast(pointer)) != 0; + } + + // When responding to a ReadValue method, we need to return a GVariant value in the form "(ay)" (a tuple containing an array of + // bytes). This method will simplify this slightly by wrapping a GVariant of the type "ay" and wrapping it in a tuple before + // sending it off as the method response. + // + // This is the generalized form that accepts a GVariant *. There is a templated helper method (`methodReturnValue()`) that accepts + // common types. + void methodReturnVariant(GDBusMethodInvocation *pInvocation, GVariant *pVariant, bool wrapInTuple = false) const; + + // When responding to a ReadValue method, we need to return a GVariant value in the form "(ay)" (a tuple containing an array of + // bytes). This method will simplify this slightly by wrapping a GVariant of the type "ay" and wrapping it in a tuple before + // sending it off as the method response. + // + // This is a templated helper method that only works with common types. For a more generic form which can be used for custom + // types, see `methodReturnVariant()'. + template + void methodReturnValue(GDBusMethodInvocation *pInvocation, T value, bool wrapInTuple = false) const + { + GVariant *pVariant = Utils::gvariantFromByteArray(value); + methodReturnVariant(pInvocation, pVariant, wrapInTuple); + } + + // Locates a `GattProperty` within the interface + // + // This method returns a pointer to the property or nullptr if not found + const GattProperty *findProperty(const std::string &name) const; + + // Internal method used to generate introspection XML used to describe our services on D-Bus + virtual std::string generateIntrospectionXML(int depth) const; + +protected: + + std::list properties; +}; -- cgit v1.2.3