26#ifndef DB_GATT_SERVER_HPP_
27#define DB_GATT_SERVER_HPP_
35#include <initializer_list>
55#ifdef JAU_TRACE_DBGATT
56 #define JAU_TRACE_DBGATT_PRINT(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); }
58 #define JAU_TRACE_DBGATT_PRINT(...)
101 std::shared_ptr<const jau::uuid_t> type;
105 bool variable_length;
117 std::shared_ptr<const jau::uuid_t>&
getType() noexcept {
return type; }
120 std::shared_ptr<const jau::uuid_t>
getType() const noexcept {
return type; }
169 jau::POctets && value_,
bool variable_length_=
false) noexcept
170 : handle(0), type(
std::move(type_)), value(
std::move( value_ ) ), variable_length(variable_length_)
173 variable_length =
false;
184 handle(o.handle), type(o.type),
185 value(o.value, o.value.capacity()),
186 variable_length(o.variable_length)
196 : handle(o.handle), type(std::move(o.type)),
197 value(std::move(o.value)),
198 variable_length(o.variable_length)
229 const std::string len = variable_length ?
"var" :
"fixed";
238 {
return lhs.getHandle() == rhs.getHandle(); }
241 {
return !(lhs == rhs); }
268 bool enabledNotifyState =
false;
269 bool enabledIndicateState =
false;
275 uint16_t value_handle;
277 std::shared_ptr<const jau::uuid_t> value_type;
285 bool variable_length;
287 int clientCharConfigIndex;
289 int userDescriptionIndex;
317 std::shared_ptr<const jau::uuid_t>&
getValueType() noexcept {
return value_type; }
320 std::shared_ptr<const jau::uuid_t>
getValueType() const noexcept {
return value_type; }
385 jau::POctets && value_,
bool variable_length_=
false) noexcept
386 : handle(0), end_handle(0), value_handle(0),
387 value_type(
std::move(value_type_)),
388 properties(properties_),
389 descriptors(
std::move( descriptors_ ) ),
390 value(
std::move( value_ ) ), variable_length(variable_length_),
391 clientCharConfigIndex(-1),
392 userDescriptionIndex(-1)
397 if( 0 > clientCharConfigIndex && d->isClientCharConfig() ) {
398 clientCharConfigIndex=i;
399 }
else if( 0 > userDescriptionIndex && d->isUserDescription() ) {
400 userDescriptionIndex=i;
413 handle(o.handle), end_handle(o.end_handle),
414 value_handle(o.value_handle), value_type(o.value_type),
415 properties(o.properties),
416 descriptors(o.descriptors),
417 value(o.value, o.value.capacity()),
418 variable_length(o.variable_length),
419 clientCharConfigIndex(o.clientCharConfigIndex),
420 userDescriptionIndex(o.userDescriptionIndex)
430 : handle(o.handle), end_handle(o.end_handle),
431 value_handle(o.value_handle), value_type(std::move(o.value_type)),
432 properties(o.properties),
433 descriptors(std::move(o.descriptors)),
434 value(std::move(o.value)),
435 variable_length(o.variable_length),
436 clientCharConfigIndex(o.clientCharConfigIndex),
437 userDescriptionIndex(o.userDescriptionIndex)
450 if( 0 > clientCharConfigIndex ) {
453 return descriptors.
at(
static_cast<size_t>(clientCharConfigIndex));
457 if( 0 > userDescriptionIndex ) {
460 return descriptors.
at(
static_cast<size_t>(userDescriptionIndex));
463 if( 0 > clientCharConfigIndex ) {
466 return descriptors.
at(
static_cast<size_t>(clientCharConfigIndex));
470 if( 0 > userDescriptionIndex ) {
473 return descriptors.
at(
static_cast<size_t>(userDescriptionIndex));
477 std::string char_name, notify_str;
480 if(
nullptr != ud ) {
481 char_name =
", '" +
jau::dfa_utf8_decode( ud->getValue().get_ptr(), ud->getValue().size() ) +
"'";
487 const std::string len = variable_length ?
"var" :
"fixed";
490 char_name+
", value[type 0x"+value_type->toString()+
", handle "+
jau::to_hexstring(value_handle)+
", len "+len+
498 {
return lhs.getHandle() == rhs.getHandle() && lhs.getEndHandle() == rhs.getEndHandle(); }
501 {
return !(lhs == rhs); }
515 p.
put_bytes_nc(0,
reinterpret_cast<const uint8_t*
>(name), name_len);
544 std::memcpy(p.
get_wptr(), sourcelist.begin(), max_size);
573 std::shared_ptr<const jau::uuid_t> type;
600 std::shared_ptr<const jau::uuid_t>&
getType() noexcept {
return type; }
603 std::shared_ptr<const jau::uuid_t>
getType() const noexcept {
return type; }
621 std::shared_ptr<const jau::uuid_t> type_,
623 : primary(primary_), handle(0), end_handle(0),
624 type(
std::move(type_)),
625 characteristics(
std::move( characteristics_ ) )
633 if( char_uuid.equivalent( *c->value_type ) ) {
641 if( char_value_handle == c->value_handle ) {
656 if( 0 == start_handle ) {
661 uint16_t h = start_handle;
665 c->value_handle = h++;
672 return ( end_handle - handle ) + 1;
682 {
return lhs.getHandle() == rhs.getHandle() && lhs.getEndHandle() == rhs.getEndHandle(); }
685 {
return !(lhs == rhs); }
848 const bool notificationEnabled,
const bool indicationEnabled) = 0;
857 {
return this == &rhs; }
860 {
return !(*
this == rhs); }
871 uint16_t max_att_mtu;
889 void setMaxAttMTU(
const uint16_t v)
noexcept { max_att_mtu = std::min<uint16_t>(512+1, v); }
907 #ifdef JAU_TRACE_DBGATT
917 : max_att_mtu(512+1),
919 fwdServer( nullptr ),
929 : max_att_mtu(
std::
min<uint16_t>(512+1, max_att_mtu_)),
930 services(
std::move( services_ ) ),
931 fwdServer( nullptr ),
932 mode( services.size() > 0 ?
Mode::DB :
Mode::NOP )
942 : max_att_mtu(512+1),
943 services(
std::move( services_ ) ),
944 fwdServer( nullptr ),
945 mode( services.size() > 0 ?
Mode::DB :
Mode::NOP )
954 : max_att_mtu(512+1),
956 fwdServer(
std::move( fwdServer_ )),
962 if( type.equivalent( *s->getType() ) ) {
970 if(
nullptr == service ) {
973 return service->findGattChar(char_uuid);
980 return c->getClientCharConfig();
993 DBGattCharRef r = s->findGattCharByValueHandle(char_value_handle);
1017 int l = s->setHandles(h);
1031 res.append(
" ").append(s->toString()).append(
"\n");
1033 res.append(
" ").append(c->toString()).append(
"\n");
1035 res.append(
" ").append(d->toString()).append(
"\n");
1042 std::string
toString() const noexcept override;
#define JAVA_MAIN_PACKAGE
#define JAU_TRACE_DBGATT_PRINT(...)
PropertyBitVal
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.1.1 Characteristic Properties.
static const std::shared_ptr< jau::uuid_t > TYPE_CCC_DESC
static const std::shared_ptr< jau::uuid_t > TYPE_USER_DESC
static const std::shared_ptr< jau::uuid_t > TYPE_EXT_PROP
Representing a Gatt Characteristic object from the GATTRole::Server perspective.
static std::string java_class() noexcept
const DBGattDescRef getClientCharConfig() const noexcept
std::shared_ptr< const jau::uuid_t > & getValueType() noexcept
int getUserDescriptionIndex() const noexcept
std::string toString() const noexcept override
bool hasProperties(const BTGattChar::PropertyBitVal v) const noexcept
uint16_t getHandle() const noexcept
Characteristic Handle of this instance.
bool hasVariableLength() const noexcept
True if value is of variable length, otherwise fixed length.
bool setValue(const uint8_t *source, const jau::nsize_t source_len, const jau::nsize_t dest_pos) noexcept
Set this characteristics's value.
~DBGattChar() noexcept override
DBGattChar(std::shared_ptr< const jau::uuid_t > value_type_, const BTGattChar::PropertyBitVal properties_, jau::darray< DBGattDescRef > &&descriptors_, jau::POctets &&value_, bool variable_length_=false) noexcept
DBGattDescRef getClientCharConfig() noexcept
jau::POctets & getValue() noexcept
Get reference of this characteristics's value.
DBGattChar(DBGattChar &&o) noexcept
Move constructor.
int getClientCharConfigIndex() const noexcept
DBGattDescRef getUserDescription() noexcept
jau::darray< DBGattDescRef > & getDescriptors() noexcept
List of Characteristic Descriptions.
DBGattChar(const DBGattChar &o)
Copy constructor preserving the capacity of the value.
const DBGattDescRef getUserDescription() const noexcept
BTGattChar::PropertyBitVal getProperties() const noexcept
uint16_t getEndHandle() const noexcept
Characteristic end handle, inclusive.
std::string get_java_class() const noexcept override
uint16_t getValueHandle() const noexcept
Characteristics Value Handle.
std::shared_ptr< const jau::uuid_t > getValueType() const noexcept
void bzero() noexcept
Fill value with zero bytes.
Representing a Gatt Characteristic Descriptor object from the GATTRole::Server perspective.
std::shared_ptr< const jau::uuid_t > getType() const noexcept
Type of descriptor.
std::shared_ptr< const jau::uuid_t > & getType() noexcept
Type of descriptor.
std::string get_java_class() const noexcept override
DBGattDesc(DBGattDesc &&o) noexcept
Move constructor.
std::string toString() const noexcept override
bool hasVariableLength() const noexcept
True if value is of variable length, otherwise fixed length.
bool setValue(const uint8_t *source, const jau::nsize_t source_len, const jau::nsize_t dest_pos) noexcept
Set this characteristic descriptor's value.
bool isUserDescription() const noexcept
bool isExtendedProperties() const noexcept
Value is uint16_t bitfield.
DBGattDesc(std::shared_ptr< const jau::uuid_t > type_, jau::POctets &&value_, bool variable_length_=false) noexcept
jau::POctets & getValue() noexcept
Get reference of this characteristic descriptor's value.
uint16_t getHandle() const noexcept
Characteristic Descriptor Handle.
bool isClientCharConfig() const noexcept
void bzero() noexcept
Fill value with zero bytes.
static std::string java_class() noexcept
static std::shared_ptr< DBGattDesc > createClientCharConfig()
Return a newly constructed Client Characteristic Configuration with a zero uint16_t value of fixed le...
DBGattDesc(const DBGattDesc &o)
Copy constructor preserving the capacity of the value.
~DBGattDesc() noexcept override
Listener to remote master device's operations on the local GATT-Server.
virtual bool operator==(const Listener &rhs) const
Default comparison operator, merely testing for same memory reference.
virtual bool writeCharValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const jau::TROOctets &value, const uint16_t value_offset)=0
Signals attempt to write a single or bulk (prepare) value.
virtual ~Listener()=default
virtual bool readCharValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c)=0
Signals attempt to read a value.
virtual bool readDescValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d)=0
Signals attempt to read a value.
virtual bool writeDescValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d, const jau::TROOctets &value, const uint16_t value_offset)=0
Signals attempt to write a single or bulk (prepare) value.
virtual void clientCharConfigChanged(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d, const bool notificationEnabled, const bool indicationEnabled)=0
Notifies a change of the Client Characteristic Configuration Descriptor (CCCD) value.
virtual void connected(const BTDeviceRef &device, const uint16_t initialMTU)=0
Notification that device got connected.
bool operator!=(const Listener &rhs) const
virtual void mtuChanged(const BTDeviceRef &device, const uint16_t mtu)=0
Notification that the MTU has changed.
virtual void disconnected(const BTDeviceRef &device)=0
Notification that device got disconnected.
virtual void writeDescValueDone(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d)=0
Notifies completion of single or bulk writeCharValue() after having accepted and performed all write ...
virtual void writeCharValueDone(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c)=0
Notifies completion of single or bulk writeCharValue() after having accepted and performed all write ...
Representing a complete list of Gatt Service objects from the GATTRole::Server perspective,...
BTDeviceRef getFwdServer() noexcept
DBGattServer(jau::darray< DBGattServiceRef > &&services_)
DBGattServer in Mode::DB mode if given services_ are not empty, otherwise in Mode::NOP mode.
jau::darray< DBGattServiceRef, size_type > GattServiceList_t
DBGattServiceRef findGattService(const jau::uuid_t &type) noexcept
std::shared_ptr< Listener > ListenerRef
DBGattServer(BTDeviceRef fwdServer_)
DBGattServer in Mode::FWD to the given forward BTDevice.
bool resetGattClientCharConfig(const jau::uuid_t &service_uuid, const jau::uuid_t &char_uuid) noexcept
size_type setServicesHandles()
Sets all handles of all service instances and all its owned childs, i.e.
Mode
Operating mode of a DBGattServer instance.
DBGattServer()
DBGattServer in Mode::NOP mode.
bool addListener(const ListenerRef &l)
static std::string toModeString(const Mode m) noexcept
DBGattCharRef findGattChar(const jau::uuid_t &service_uuid, const jau::uuid_t &char_uuid) noexcept
jau::darray< DBGattServiceRef > & getServices() noexcept
List of Services.
DBGattServer(uint16_t max_att_mtu_, jau::darray< DBGattServiceRef > &&services_)
DBGattServer in Mode::DB mode if given services_ are not empty, otherwise in Mode::NOP mode.
bool removeListener(const ListenerRef &l)
uint16_t getMaxAttMTU() const noexcept
Used maximum server Rx ATT_MTU, defaults to 512+1.
jau::cow_darray< ListenerRef, size_type > ListenerList_t
void setMaxAttMTU(const uint16_t v) noexcept
Set maximum server Rx ATT_MTU, defaults to 512+1 limit.
~DBGattServer() noexcept override
DBGattCharRef findGattCharByValueHandle(const uint16_t char_value_handle) noexcept
std::string get_java_class() const noexcept override
std::string toFullString()
std::string toString() const noexcept override
Mode getMode() const noexcept
static std::string java_class() noexcept
ListenerList_t & listener()
DBGattDescRef findGattClientCharConfig(const jau::uuid_t &service_uuid, const jau::uuid_t &char_uuid) noexcept
Representing a Gatt Service object from the GATTRole::Server perspective.
std::string get_java_class() const noexcept override
std::string toString() const noexcept override
DBGattService(DBGattService &&o) noexcept=default
bool isPrimary() const noexcept
Indicate whether this service is a primary service.
uint16_t getEndHandle() const noexcept
Service end handle, inclusive.
~DBGattService() noexcept override
std::shared_ptr< const jau::uuid_t > & getType() noexcept
Service type UUID.
std::shared_ptr< const jau::uuid_t > getType() const noexcept
Service type UUID.
uint16_t getHandle() const noexcept
Service start handle.
DBGattService(const bool primary_, std::shared_ptr< const jau::uuid_t > type_, jau::darray< DBGattCharRef > &&characteristics_)
DBGattCharRef findGattChar(const jau::uuid_t &char_uuid) noexcept
DBGattService(const DBGattService &o)=default
int setHandles(const uint16_t start_handle)
Sets all handles of this service instance and all its owned childs, i.e.
jau::darray< DBGattCharRef > & getCharacteristics() noexcept
List of Characteristic Declarations.
static std::string java_class() noexcept
DBGattCharRef findGattCharByValueHandle(const uint16_t char_value_handle) noexcept
Persistent endian aware octet data, i.e.
std::string toString() const
void put_bytes_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept
void bzero(const nsize_t i, const nsize_t byte_count)
constexpr void put_uint16_nc(const nsize_t i, const uint16_t v) noexcept
uint8_t * get_wptr() noexcept
Transient read only and endian aware octet data, i.e.
constexpr nsize_t size() const noexcept
Returns the used memory size for read and write operations, may be zero.
constexpr uint8_t const * get_ptr() const noexcept
constexpr size_type size() const noexcept
Like std::vector::size().
const_reference at(size_type i) const
Like std::vector::at(size_type), immutable reference.
Sharing the anonymous Java object (JavaAnon), i.e.
std::string javaObjectToString() const noexcept
JavaUplink() noexcept=default
uint32_t dfa_utf8_decode(uint32_t &state, uint32_t &codep, const uint32_t byte_value)
@ little
Identifier for little endian, equivalent to endian::little.
bool operator==(const BTAdapter &lhs, const BTAdapter &rhs) noexcept
std::shared_ptr< BTDevice > BTDeviceRef
std::string to_string(const DiscoveryPolicy v) noexcept
bool operator!=(const BTAdapter &lhs, const BTAdapter &rhs) noexcept
std::shared_ptr< DBGattDesc > DBGattDescRef
jau::POctets make_gvalue(const char *name)
Convenience jau::POctets ctor function to create DBGattChar or DBGattDesc values.
std::shared_ptr< DBGattService > DBGattServiceRef
std::shared_ptr< DBGattServer > DBGattServerRef
std::string to_string(const DBGattServer::Mode m) noexcept
std::shared_ptr< DBGattChar > DBGattCharRef
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
void print_backtrace(const bool skip_anon_frames, const jau::snsize_t max_frames=-1, const jau::snsize_t skip_frames=2) noexcept
Prints the de-mangled backtrace string separated by newline excluding this function to stderr,...