Skip to content

Commit

Permalink
interface to allow asynchronouse handling of the connection parameter…
Browse files Browse the repository at this point in the history
… requests
  • Loading branch information
TorstenRobitzki committed Oct 2, 2023
1 parent 1825df8 commit b231237
Show file tree
Hide file tree
Showing 3 changed files with 322 additions and 10 deletions.
23 changes: 16 additions & 7 deletions bluetoe/link_layer/include/bluetoe/link_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,11 @@ namespace link_layer {
details::ll_pdu_receive_data_callback_meta_type,
Options...,
no_l2cap_callback
>::type,
public bluetoe::details::find_by_meta_type<
details::desired_connection_parameters_meta_type,
Options...,
no_desired_connection_parameters
>::type
{
public:
Expand Down Expand Up @@ -934,6 +939,7 @@ namespace link_layer {
this->set_access_address_and_crc_init( read_32bit( &body[ 12 ] ), read_24bit( &body[ 16 ] ) );

this->reset_pdu_buffer();
this->reset_connection_parameter_request();
setup_next_connection_event();

this->connection_request( connection_addresses( address_, remote_address ) );
Expand Down Expand Up @@ -1226,7 +1232,10 @@ namespace link_layer {
{
static constexpr std::uint8_t connection_param_req_size = 24u;

if ( !connection_parameters_request_pending_ && !phy_update_request_pending_ && !remote_versions_request_pending_ )
if ( !connection_parameters_request_pending_
&& !phy_update_request_pending_
&& !remote_versions_request_pending_
&& !this->connection_parameters_response_pending() )
return;

// first check if we have memory to transmit the message, or otherwise notifications would get lost
Expand Down Expand Up @@ -1286,6 +1295,11 @@ namespace link_layer {

this->commit_ll_transmit_buffer( out_buffer );
}
else if ( this->connection_parameters_response_pending() )
{
this->template connection_parameters_response_fill< layout_t >( out_buffer );
this->commit_ll_transmit_buffer( out_buffer );
}
}

template < class Server, template < std::size_t, std::size_t, class > class ScheduledRadio, typename ... Options >
Expand Down Expand Up @@ -1627,12 +1641,7 @@ namespace link_layer {
}
else if ( opcode == LL_CONNECTION_PARAM_REQ && size == 24 )
{
using connection_param_responder = typename bluetoe::details::find_by_meta_type<
bluetoe::link_layer::details::desired_connection_parameters_meta_type,
Options...,
no_desired_connection_parameters >::type;

connection_param_responder::template fill_response< layout_t >( pdu, write );
commit = this->template handle_connection_parameters_request< layout_t >( pdu, write );
}
else if ( this->handle_encryption_pdus( opcode, size, pdu, write, commit ) )
{
Expand Down
146 changes: 144 additions & 2 deletions bluetoe/link_layer/include/bluetoe/ll_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ namespace link_layer
static constexpr std::uint8_t LL_CONNECTION_PARAM_RSP = 0x10;
static constexpr std::uint8_t LL_REJECT_EXT_IND = 0x11;
static constexpr std::uint8_t invalid_ll_paramerters = 0x1E;
static constexpr std::uint8_t unacceptable_connection_parameters = 0x3B;

template < class Layout >
static bool parse_and_check_params( const write_buffer& request, read_buffer response, requested_connection_parameters& params )
Expand Down Expand Up @@ -206,6 +207,8 @@ namespace link_layer
* Finally, Bluetoe should implement some mean / algorithm / heuristic to
* establish the desired connection parameters. (for example, by requesting
* them from the Central).
*
* @sa asynchronous_connection_parameter_request
*/
template <
std::uint16_t Interval_min,
Expand All @@ -222,7 +225,7 @@ namespace link_layer
details::valid_link_layer_option_meta_type {};

template < class Layout >
static void fill_response(
bool handle_connection_parameters_request(
const write_buffer& request, read_buffer response )
{
const std::uint8_t* const body = Layout::body( request ).first;
Expand Down Expand Up @@ -266,7 +269,131 @@ namespace link_layer
std::copy( &body[ 9 ], &body[ size ], &write_body[ 9 ] );
}

return true;
}

template < class Layout >
void connection_parameters_response_fill( read_buffer )
{}

bool connection_parameters_response_pending() const
{
return false;
}

void reset_connection_parameter_request()
{}
/** @endcond */
};

/**
* @brief configures the link_layer to implement the connection parameter update request / response
* by upcalling a callback and then awaiting an response from the application.
*
* @sa desired_connection_parameters
*/
template < class Callback, Callback& Obj >
struct asynchronous_connection_parameter_request : private details::desired_connection_parameters_base
{
public:
void connection_parameters_request_reply(
std::uint16_t interval_min,
std::uint16_t interval_max,
std::uint16_t latency,
std::uint16_t timeout )
{
pending_ = true;
negative_ = false;
interval_min_ = interval_min;
interval_max_ = interval_max;
latency_ = latency;
timeout_ = timeout;
}

void connection_parameters_request_negative_reply()
{
pending_ = true;
negative_ = true;
}

/** @cond HIDDEN_SYMBOLS */
struct meta_type :
details::desired_connection_parameters_meta_type,
details::valid_link_layer_option_meta_type {};

protected:
template < class Layout >
bool handle_connection_parameters_request(
const write_buffer& request, read_buffer response )
{
details::requested_connection_parameters params;
if ( !parse_and_check_params< Layout >( request, response, params ) )
return true;

Obj.ll_remote_connection_parameter_request(
params.min_interval, params.max_interval,
params.latency, params.timeout );

return false;
}

template < class Layout >
void connection_parameters_response_fill( read_buffer response )
{
if ( negative_ )
{
fill< Layout >( response, {
ll_control_pdu_code, 3,
LL_REJECT_EXT_IND,
LL_CONNECTION_PARAM_REQ,
unacceptable_connection_parameters
} );
}
else
{
fill< Layout >( response, {
ll_control_pdu_code, size,
LL_CONNECTION_PARAM_RSP,
static_cast< std::uint8_t >( interval_min_ ),
static_cast< std::uint8_t >( interval_min_ >> 8 ),
static_cast< std::uint8_t >( interval_max_ ),
static_cast< std::uint8_t >( interval_max_ >> 8 ),
static_cast< std::uint8_t >( latency_ ),
static_cast< std::uint8_t >( latency_ >> 8 ),
static_cast< std::uint8_t >( timeout_ ),
static_cast< std::uint8_t >( timeout_ >> 8 ),
0,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
} );
}


pending_ = false;
}

bool connection_parameters_response_pending() const
{
return pending_;
}

void reset_connection_parameter_request()
{
pending_ = false;
}

private:
bool pending_;
bool negative_;
std::uint16_t interval_min_;
std::uint16_t interval_max_;
std::uint16_t latency_;
std::uint16_t timeout_;
/** @endcond */
};

Expand All @@ -278,7 +405,7 @@ namespace link_layer
details::valid_link_layer_option_meta_type {};

template < class Layout >
static void fill_response(
bool handle_connection_parameters_request(
const write_buffer& request, read_buffer response )
{
details::requested_connection_parameters params;
Expand All @@ -291,7 +418,22 @@ namespace link_layer

std::copy( &body[ 1 ], &body[ 1 + size - 1 ], &write_body[ 1 ] );
}

return true;
}

template < class Layout >
void connection_parameters_response_fill( read_buffer )
{}

bool connection_parameters_response_pending() const
{
return false;
}

void reset_connection_parameter_request()
{}

};
/** @endcond */

Expand Down
Loading

0 comments on commit b231237

Please sign in to comment.