1#ifndef BLUETOE_BINDINGS_NRF51_HPP
2#define BLUETOE_BINDINGS_NRF51_HPP
4#include <bluetoe/link_layer.hpp>
5#include <bluetoe/ll_data_pdu_buffer.hpp>
6#include <bluetoe/nrf.hpp>
9extern "C" void RADIO_IRQHandler(
void);
10extern "C" void TIMER0_IRQHandler(
void);
14 namespace nrf51_details
25 void copy_to( std::uint8_t* target )
const;
32 virtual void adv_received(
const link_layer::read_buffer& receive ) = 0;
33 virtual void adv_timeout() = 0;
34 virtual void timeout() = 0;
35 virtual void end_event() = 0;
37 virtual link_layer::write_buffer received_data(
const link_layer::read_buffer& ) = 0;
38 virtual link_layer::write_buffer next_transmit() = 0;
39 virtual link_layer::read_buffer allocate_receive_buffer() = 0;
40 virtual void load_transmit_counter() = 0;
42 virtual bool is_scan_request_in_filter_callback(
const link_layer::device_address& )
const = 0;
45 class scheduled_radio_base
54 lock_guard(
const lock_guard& ) =
delete;
55 lock_guard& operator=(
const lock_guard& ) =
delete;
57 const std::uint32_t context_;
60 scheduled_radio_base( adv_callbacks&, std::uint32_t encrypted_area );
61 explicit scheduled_radio_base( adv_callbacks& );
63 void schedule_advertisment(
65 const link_layer::write_buffer& advertising_data,
66 const link_layer::write_buffer& response_data,
67 link_layer::delta_time when,
68 const link_layer::read_buffer& receive );
70 void set_access_address_and_crc_init( std::uint32_t access_address, std::uint32_t crc_init );
76 std::uint32_t static_random_address_seed()
const;
79 static constexpr std::size_t radio_maximum_white_list_entries = 0;
81 static constexpr bool hardware_supports_encryption =
false;
83 void increment_receive_packet_counter()
87 void increment_transmit_packet_counter()
96 void nrf_flash_memory_access_begin();
97 void nrf_flash_memory_access_end();
105 const link_layer::read_buffer& receive_buffer );
107 void configure_encryption(
bool receive,
bool transmit );
110 friend void ::RADIO_IRQHandler(
void);
111 friend void ::TIMER0_IRQHandler(
void);
113 bool is_valid_scan_request()
const;
116 void adv_radio_interrupt();
117 void adv_timer_interrupt();
118 void evt_radio_interrupt();
119 void evt_timer_interrupt();
120 void radio_interrupt();
121 void timer_interrupt();
123 unsigned frequency_from_channel(
unsigned channel )
const;
125 adv_callbacks& callbacks_;
126 volatile bool timeout_;
127 volatile bool received_;
128 volatile bool evt_timeout_;
129 volatile bool end_evt_;
130 volatile int wake_up_;
132 static constexpr unsigned connection_event_type_base = 100;
139 adv_transmitting_response,
141 evt_wait_connect = connection_event_type_base,
142 evt_transmiting_closing,
145 volatile state state_;
149 link_layer::read_buffer receive_buffer_;
150 link_layer::write_buffer response_data_;
151 std::uint8_t empty_receive_[ 3 ];
152 bool receive_encrypted_;
153 bool transmit_encrypted_;
154 std::uint32_t encrypted_area_;
157 class scheduled_radio_base_with_encryption_base :
public scheduled_radio_base
160 scheduled_radio_base_with_encryption_base( adv_callbacks& cbs, std::uint32_t scratch_area, std::uint32_t encrypted_area );
162 void load_transmit_packet_counter();
168 const link_layer::read_buffer& receive_buffer )
170 load_receive_packet_counter();
171 return start_connection_event_impl( channel, start_receive, end_receive, receive_buffer );
175 static constexpr bool hardware_supports_lesc_pairing =
true;
176 static constexpr bool hardware_supports_legacy_pairing =
true;
177 static constexpr bool hardware_supports_encryption = hardware_supports_lesc_pairing || hardware_supports_legacy_pairing;
182 bluetoe::details::uint128_t create_srand();
184 bluetoe::details::longterm_key_t create_long_term_key();
186 bluetoe::details::uint128_t c1(
187 const bluetoe::details::uint128_t& temp_key,
188 const bluetoe::details::uint128_t& rand,
189 const bluetoe::details::uint128_t& p1,
190 const bluetoe::details::uint128_t& p2 )
const;
192 bluetoe::details::uint128_t s1(
193 const bluetoe::details::uint128_t& temp_key,
194 const bluetoe::details::uint128_t& srand,
195 const bluetoe::details::uint128_t& mrand );
200 bool is_valid_public_key(
const std::uint8_t* public_key )
const;
202 std::pair< bluetoe::details::ecdh_public_key_t, bluetoe::details::ecdh_private_key_t > generate_keys();
204 bluetoe::details::uint128_t select_random_nonce();
206 bluetoe::details::ecdh_shared_secret_t p256(
const std::uint8_t* private_key,
const std::uint8_t* public_key );
208 bluetoe::details::uint128_t f4(
const std::uint8_t* u,
const std::uint8_t* v,
const std::array< std::uint8_t, 16 >& k, std::uint8_t z );
210 std::pair< bluetoe::details::uint128_t, bluetoe::details::uint128_t > f5(
211 const bluetoe::details::ecdh_shared_secret_t dh_key,
212 const bluetoe::details::uint128_t& nonce_central,
213 const bluetoe::details::uint128_t& nonce_periperal,
217 bluetoe::details::uint128_t f6(
218 const bluetoe::details::uint128_t& key,
219 const bluetoe::details::uint128_t& n1,
220 const bluetoe::details::uint128_t& n2,
221 const bluetoe::details::uint128_t& r,
222 const bluetoe::details::io_capabilities_t& io_caps,
227 const std::uint8_t* u,
228 const std::uint8_t* v,
229 const bluetoe::details::uint128_t& x,
230 const bluetoe::details::uint128_t& y );
235 bluetoe::details::uint128_t create_passkey();
240 std::pair< std::uint64_t, std::uint32_t > setup_encryption( bluetoe::details::uint128_t key, std::uint64_t skdm, std::uint32_t ivm );
242 void start_receive_encrypted();
243 void start_transmit_encrypted();
244 void stop_receive_encrypted();
245 void stop_transmit_encrypted();
247 void increment_receive_packet_counter()
249 rx_counter_.increment();
252 void increment_transmit_packet_counter()
254 tx_counter_.increment();
263 void set_identity_resolving_key(
const details::identity_resolving_key_t& irk );
266 void load_receive_packet_counter();
276 template <
typename ... Options >
277 class scheduled_radio_base_with_encryption :
public scheduled_radio_base_with_encryption_base
280 scheduled_radio_base_with_encryption( adv_callbacks& cbs )
281 : scheduled_radio_base_with_encryption_base( cbs,
282 reinterpret_cast< std::uintptr_t >( &scratch_area_.data[ 0 ] ),
283 reinterpret_cast< std::uintptr_t >( &encrypted_message_.data[ 0 ] ) )
290 static constexpr std::size_t scratch_size = 267;
292 struct alignas( 4 ) scratch_area_t {
293 std::uint8_t data[ scratch_size ];
299 struct alignas( 4 ) encrypted_message_t {
300 std::uint8_t data[ 260 ];
301 } encrypted_message_;
304 class scheduled_radio_without_encryption_base :
public scheduled_radio_base
311 const link_layer::read_buffer& receive_buffer )
313 return start_connection_event_impl( channel, start_receive, end_receive, receive_buffer );
316 scheduled_radio_without_encryption_base( adv_callbacks& cbs ) : scheduled_radio_base( cbs, 0 )
320 void load_transmit_packet_counter()
325 template < std::
size_t TransmitSize, std::
size_t ReceiveSize,
typename CallBack,
typename Base >
326 class scheduled_radio :
328 private adv_callbacks,
332 scheduled_radio() : Base( static_cast< adv_callbacks& >( *this ) )
342 link_layer::read_buffer read;
344 class Base::lock_guard lock;
348 return this->start_connection_event( channel, start_receive, end_receive, read );
353 void adv_received(
const link_layer::read_buffer& receive )
override
355 static_cast< CallBack*
>( this )->adv_received( receive );
358 void adv_timeout()
override
360 static_cast< CallBack*
>( this )->adv_timeout();
363 void timeout()
override
365 static_cast< CallBack*
>( this )->timeout();
368 void end_event()
override
370 static_cast< CallBack*
>( this )->end_event();
373 link_layer::write_buffer received_data(
const link_layer::read_buffer& b )
override
390 void load_transmit_counter()
override
392 this->load_transmit_packet_counter();
395 bool is_scan_request_in_filter_callback(
const link_layer::device_address& addr )
const override
397 return static_cast< const CallBack*
>( this )->is_scan_request_in_filter( addr );
401 template <
typename Base >
402 struct scheduled_radio_factory
404 template < std::
size_t TransmitSize, std::
size_t ReceiveSize,
typename CallBack >
405 using scheduled_radio = nrf51_details::scheduled_radio< TransmitSize, ReceiveSize, CallBack, Base >;
412 template <
class Server,
typename ... Options >
413 using nrf51_without_encryption = link_layer::link_layer<
415 nrf51_details::template scheduled_radio_factory<
416 nrf51_details::scheduled_radio_without_encryption_base
423 template <
class Server,
typename ... Options >
424 using nrf51 = link_layer::link_layer<
426 nrf51_details::template scheduled_radio_factory<
427 nrf51_details::scheduled_radio_base_with_encryption< Options... >
428 >::template scheduled_radio,
431 namespace link_layer {
438 template < std::size_t TransmitSize, std::size_t ReceiveSize,
typename CallBack,
typename ... Options >
439 struct pdu_layout_by_radio<
440 nrf51_details::scheduled_radio< TransmitSize, ReceiveSize, CallBack, nrf51_details::scheduled_radio_base_with_encryption< Options... > > >
446 using pdu_layout = bluetoe::nrf_details::encrypted_pdu_layout;
positiv time quantum used to express distance in time.
Definition: delta_time.hpp:14
data type containing a device address and the address type (public or random).
Definition: address.hpp:107
ring buffers for ingoing and outgoing LL Data PDUs
Definition: ll_data_pdu_buffer.hpp:38
read_buffer allocate_receive_buffer() const
allocates a buffer for the next PDU to be received.
Definition: ll_data_pdu_buffer.hpp:551
write_buffer next_transmit()
returns the next PDU to be transmitted
Definition: ll_data_pdu_buffer.hpp:465
write_buffer received(read_buffer)
This function will be called by the scheduled radio when a PDU was received without error.
Definition: ll_data_pdu_buffer.hpp:557
default_pdu_layout pdu_layout
the layout to be applied when Radio is used
Definition: default_pdu_layout.hpp:108