Skip to content

Commit

Permalink
runtime custom advertising data and scan response data
Browse files Browse the repository at this point in the history
  • Loading branch information
TorstenRobitzki committed Aug 31, 2023
1 parent 7476126 commit 2d9a807
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 11 deletions.
84 changes: 84 additions & 0 deletions bluetoe/custom_advertising.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,53 @@ namespace bluetoe {
/** @endcond */
};

struct auto_advertising_data
{
/** @cond HIDDEN_SYMBOLS */
struct meta_type :
details::advertising_data_meta_type,
details::valid_server_option_meta_type {};
/** @endcond */
};

/**
* @brief provides data to be advertised at runtime
*
* Add the set_runtime_custom_advertising_data() function to the server.
* By default, the advertings data is of length 0.
*/
struct runtime_custom_advertising_data
{
void set_runtime_custom_advertising_data( const std::uint8_t* begin, std::size_t buffer_size )
{
advertising_data_size_ = std::min( std::size_t{ advertising_data_max_size }, buffer_size );
std::copy( &begin[ 0 ], &begin[ advertising_data_size_ ], &advertising_data_[ 0 ] );
}

/** @cond HIDDEN_SYMBOLS */
runtime_custom_advertising_data() : advertising_data_size_( 0 )
{
}

std::size_t advertising_data( std::uint8_t* begin, std::size_t buffer_size ) const
{
const std::size_t copy_size = std::min( advertising_data_size_, buffer_size );
std::copy( &advertising_data_[ 0 ], &advertising_data_[ copy_size ], begin );

return copy_size;
}

struct meta_type :
details::advertising_data_meta_type,
details::valid_server_option_meta_type {};

private:
static constexpr std::size_t advertising_data_max_size = 31;
std::uint8_t advertising_data_[ advertising_data_max_size ];
std::size_t advertising_data_size_;
/** @endcond */
};

/**
* @brief provides data to be use in response to a scan request
*/
Expand All @@ -50,6 +97,43 @@ namespace bluetoe {
details::valid_server_option_meta_type {};
/** @endcond */
};

struct auto_scan_response_data
{
/** @cond HIDDEN_SYMBOLS */
struct meta_type :
details::scan_response_data_meta_type,
details::valid_server_option_meta_type {};
/** @endcond */
};

struct runtime_custom_scan_response_data
{
void set_runtime_custom_scan_response_data( const std::uint8_t* begin, std::size_t buffer_size )
{
scan_response_data_size_ = std::min( std::size_t{ scan_response_data_max_size }, buffer_size );
std::copy( &begin[ 0 ], &begin[ scan_response_data_size_ ], &scan_response_data_[ 0 ] );
}

/** @cond HIDDEN_SYMBOLS */
std::size_t scan_response_data( std::uint8_t* begin, std::size_t buffer_size ) const
{
const std::size_t copy_size = std::min( scan_response_data_size_, buffer_size );
std::copy( &scan_response_data_[ 0 ], &scan_response_data_[ copy_size ], begin );

return copy_size;
}

struct meta_type :
details::scan_response_data_meta_type,
details::valid_server_option_meta_type {};

private:
static constexpr std::size_t scan_response_data_max_size = 31;
std::uint8_t scan_response_data_[ scan_response_data_max_size ];
std::size_t scan_response_data_size_;
/** @endcond */
};
}
#endif

44 changes: 34 additions & 10 deletions bluetoe/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <bluetoe/attribute_handle.hpp>
#include <bluetoe/l2cap_channels.hpp>
#include <bluetoe/notification_queue.hpp>
#include <bluetoe/custom_advertising.hpp>

#include <cstdint>
#include <cstddef>
Expand All @@ -29,6 +30,25 @@
#include <cassert>

namespace bluetoe {
namespace details {

template < typename ... Options >
using selected_advertising_data_source =
typename details::find_by_meta_type<
details::advertising_data_meta_type,
Options...,
auto_advertising_data
>::type;

template < typename ... Options >
using selected_scan_response_data_source =
typename details::find_by_meta_type<
details::scan_response_data_meta_type,
Options...,
auto_scan_response_data
>::type;
}

/**
* @brief Root of the declaration of a GATT server.
*
Expand Down Expand Up @@ -60,6 +80,8 @@ namespace bluetoe {
class server
: private details::write_queue< typename details::find_by_meta_type< details::write_queue_meta_type, Options... >::type >
, public details::derive_from< typename details::collect_mixins< Options... >::type >
, public details::selected_advertising_data_source< Options ... >
, public details::selected_scan_response_data_source< Options ... >
{
public:
/** @cond HIDDEN_SYMBOLS */
Expand Down Expand Up @@ -393,12 +415,12 @@ namespace bluetoe {
// mapping of a last handle to a valid attribute index
std::size_t last_handle_index( std::uint16_t ending_handle );

std::size_t advertising_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const details::no_such_type& ) const;
std::size_t advertising_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const auto_advertising_data& ) const;

template < class T >
std::size_t advertising_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const T& ) const;

std::size_t scan_response_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const details::no_such_type& ) const;
std::size_t scan_response_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const auto_scan_response_data& ) const;

template < class T >
std::size_t scan_response_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const T& ) const;
Expand Down Expand Up @@ -612,19 +634,20 @@ namespace bluetoe {
return advertising_data_impl( begin, buffer_size,
typename details::find_by_meta_type<
details::advertising_data_meta_type,
Options...
Options...,
auto_advertising_data
>::type() );
}

template < typename ... Options >
template < class Advertiser >
std::size_t server< Options... >::advertising_data_impl( std::uint8_t* begin, std::size_t buffer_size, const Advertiser& advertiser ) const
std::size_t server< Options... >::advertising_data_impl( std::uint8_t* begin, std::size_t buffer_size, const Advertiser& ) const
{
return advertiser.advertising_data( begin, buffer_size );
return static_cast< const Advertiser& >( *this ).advertising_data( begin, buffer_size );
}

template < typename ... Options >
std::size_t server< Options... >::advertising_data_impl( std::uint8_t* begin, std::size_t buffer_size, const details::no_such_type& ) const
std::size_t server< Options... >::advertising_data_impl( std::uint8_t* begin, std::size_t buffer_size, const auto_advertising_data& ) const
{
std::uint8_t* const end = begin + buffer_size;

Expand Down Expand Up @@ -697,12 +720,13 @@ namespace bluetoe {
return scan_response_data_impl( buffer, buffer_size,
typename details::find_by_meta_type<
details::scan_response_data_meta_type,
Options...
Options...,
auto_scan_response_data
>::type() );
}

template < typename ... Options >
std::size_t server< Options... >::scan_response_data_impl( std::uint8_t* buffer, std::size_t /* buffer_size */, const details::no_such_type& ) const
std::size_t server< Options... >::scan_response_data_impl( std::uint8_t* buffer, std::size_t /* buffer_size */, const auto_scan_response_data& ) const
{
// add aditional empty AD to be visible to Nordic sniffer.
// Some stacks do not recognize the response without this empty AD.
Expand All @@ -714,9 +738,9 @@ namespace bluetoe {

template < typename ... Options >
template < class T >
std::size_t server< Options... >::scan_response_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const T& responder ) const
std::size_t server< Options... >::scan_response_data_impl( std::uint8_t* buffer, std::size_t buffer_size, const T& ) const
{
return responder.scan_response_data( buffer, buffer_size );
return static_cast< const T& >( *this ).scan_response_data( buffer, buffer_size );
}

template < typename ... Options >
Expand Down
57 changes: 56 additions & 1 deletion tests/advertising_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ BOOST_FIXTURE_TEST_CASE( specific_range_encoding, specifed_range )

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE( peripheral_connection_interval_range )
BOOST_AUTO_TEST_SUITE( custom_advertisings )

static const std::uint8_t custom_advertising_data[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
Expand Down Expand Up @@ -363,6 +363,61 @@ BOOST_FIXTURE_TEST_CASE( custom_scan_response_test, custom_advertising )
}, *this );
}

using runtime_custom_advertising = bluetoe::extend_server<
test::small_temperature_service,
bluetoe::runtime_custom_advertising_data,
bluetoe::runtime_custom_scan_response_data
>;

BOOST_FIXTURE_TEST_CASE( runtime_custom_advertising_test_default, runtime_custom_advertising )
{
expected_advertising( {
}, *this );
}

BOOST_FIXTURE_TEST_CASE( runtime_custom_advertising_test, runtime_custom_advertising )
{
static constexpr std::uint8_t data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
};

set_runtime_custom_advertising_data( &data[ 0 ], 0x1f );

expected_advertising( {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
}, *this );
}

BOOST_FIXTURE_TEST_CASE( runtime_custom_scan_response_test_default, runtime_custom_advertising )
{
expected_scan_response( {}, *this );
}

BOOST_FIXTURE_TEST_CASE( runtime_custom_scan_response_test, runtime_custom_advertising )
{
static constexpr std::uint8_t data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
};

set_runtime_custom_advertising_data( &data[ 0 ], 0x1f );

expected_advertising( {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
}, *this );
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE( appearance_advertised )
Expand Down

0 comments on commit 2d9a807

Please sign in to comment.