torstenrobitzki / bluetoe Goto Github PK
View Code? Open in Web Editor NEWC++ Framework to build Bluetooth LE Server (GATT)
License: MIT License
C++ Framework to build Bluetooth LE Server (GATT)
License: MIT License
Bluetoe implements currently all 4.2 ATT PDUs. If the optional PDUs could be disabled, the overall program size should become smaller.
If Bluetoe receives an error respond. The current behaviors is to respond that with an error response (Request not supported).
Currently, it is not possible to have a GATT server, that requires_encryption
and to run that on a binding, that does not support any pairing. There might be use cases, where a long term key might already exists and can be used without any required pairing.
Currently, a GATT server does not respond to a scan request.
The security manager gets a buffer to reply to a public key exchange that is generally allocated with a size equal to the negotiated ATT MTU size. If no negotiation happened, the default is 23 and thus, pairing will fail.
If built with something different from -O0 device crashes with the below stack trace.
(gdb) bt
#0 0x00004568 in _exit ()
#1 0x000034a2 in abort ()
#2 0x000034c8 in __assert_func ()
#3 0x00002b70 in bluetoe::nrf51_details::scheduled_radio_base::schedule_advertisment (this=this@entry=0x2000012c <gatt_srv+156>, channel=channel@entry=38, advertising_data=..., response_data=...,
when=..., receive=...) at /Users/nlopezcasad/work/bluetoe/bluetoe/bindings/nrf51.cpp:307
#4 0x00000b5e in bluetoe::link_layer::details::advertiser<bluetoe::link_layer::link_layer<bluetoe::server<bluetoe::server_name<((char const*)(& blink_name))>, bluetoe::service<bluetoe::service_uuid<3
239143905ul, 25170u, 17488u, 37660u, 29977313048635ull>, bluetoe::characteristic<bluetoe::free_write_handler<bool, io_pin_write_handler> > > >, bluetoe::nrf51_details::scheduled_radio>, std::tuple<>,
std::tuplebluetoe::link_layer::connectable_undirected_advertising >::handle_adv_timeout(void) (this=0x20000154 <gatt_srv+196>)
at /Users/nlopezcasad/work/bluetoe/examples/nrf52/../../bluetoe/link_layer/advertising.hpp:979
#5 0x0000314a in bluetoe::nrf51_details::scheduled_radio_base::run (this=this@entry=0x2000012c <gatt_srv+156>) at /Users/nlopezcasad/work/bluetoe/bluetoe/bindings/nrf51.cpp:662
#6 0x0000160a in bluetoe::link_layer::link_layer<bluetoe::server<bluetoe::server_name<(char const*)(&blink_name)>, bluetoe::service<bluetoe::service_uuid<3239143905ul, 25170u, 17488u, 37660u, 2997731
3048635ull>, bluetoe::characteristic<bluetoe::free_write_handler<bool, io_pin_write_handler> > > >, bluetoe::nrf51_details::scheduled_radio>::run (this=0x20000090 <gatt_srv>, server=...)
at /Users/nlopezcasad/work/bluetoe/examples/nrf52/../../bluetoe/link_layer/link_layer.hpp:390
#7 main () at /Users/nlopezcasad/work/bluetoe/examples/nrf52/blinky.cpp:42
(gdb)
Bluetoe lakes a Security Manager.
I just built bluetoe code on my Ubuntu 18.04 box. The build went fine.
Next, I copied simple_server.cpp to mysvr.cpp in a new directory.
Here is my simple command to build it:
g++
-I$ThirdParty/bluetoe
-I$ThirdParty/bluetoe/bluetoe/utility/include
mysvr.cpp -o mysvr
I still need to link with libraries but that will come once I overcome my problem.
When I try to compile, I am getting the following assertion from server.hpp:
static_assert( number_of_client_configs != 0, "there is no characteristic that is configured for notification or indication" );
Is it something that I am doing wrong?
Thanks
Peter
Looks like may_require_encryption is not working as intended. If a server used the may_require_encryption option, every access to a characteristic value is responded with "Insufficient Authentication".
Similar to #17: when using notification priorities, the reordering of the client characteristic index leads to the wrong characteristic beeing configured when ATT read / writes are used to access the CCCD.
As bonds are stored persistent, Bluetoe can not store them but has to provide an API to store and retrieve bonding information. Following information must be stored / retrieved:
The API might require a template, where the Bluetoe could provide certain, compile time known values, like the number of CCCDs, etc.
Details are following...
Hi There,
This project is still using an old implementation of LGTM's automated code review, which has now been disabled. To continue using automated code review, and receive checks on your Pull Requests, please install the GitHub App on this repository.
Thanks,
The LGTM Team
Hi there,
I'm trying to use your library through an HCI host, basically I'm instantiating a bluetoe::server
class and pass the advertising and L2CAP data back and forth with my own link layer through l2cap_input
. I've got advertising working, and I can connect and discover all the services, however I have not been able to get characteristics discovery working. When an client sends Read By Type Request with 0x2803 for characteristics declarations, the server instance invariably returns an error response with code 0x0a (Attribute Not Found).
I have tried all the server examples and none of them seems to work.
Tony
Compiling and running all unit tests with clangs address sanitizer enabled flags some test as being bogus (-fsanitize=address). All tests should run with address sanitizer enabled, without any errors.
The is_connection_request_in_filter
is actually never called and there is not test that reveals this.
Currently, there is no support for the service changed indication described in GAP (Vol 3; Part G; 7.1).
With the new SM update, hardware required overheads in the memory usage are introduced. The current default for buffer sizes just takes the protocol requirements into account.
This will lead to the need to manually define the buffer sizes, if the choosen hardware binding introduces an overhead.
In any case, there should be a default, that defines just the minimum buffer sizes for the choosen configuration.
using arm-none-eabi-gcc version 8.3.1 20190703, with C++ version 17 or 2a, the following snipped:
#include <bluetoe/server.hpp>
#include <bluetoe/service.hpp>
#include <bluetoe/characteristic.hpp>
using s = typename bluetoe::details::remove_if_equal<
std::tuple<
std::tuple<
bluetoe::details::characteristic_declaration_parameter,
bluetoe::characteristic_uuid<745866312, 46925, 19597, 45443, 208696923798549>,
bluetoe::details::empty_meta_type<bluetoe::details::characteristic_declaration_parameter>
>,
std::tuple<
bluetoe::details::characteristic_value_declaration_parameter,
bluetoe::characteristic_uuid<745866312, 46925, 19597, 45443, 208696923798549>,
bluetoe::fixed_uint8_value<8>
>,
std::tuple<bluetoe::details::characteristic_user_description_parameter>,
std::tuple<bluetoe::details::client_characteristic_configuration_parameter>,
std::tuple<bluetoe::details::descriptor_parameter>
>,
std::tuple<bluetoe::details::wildcard>
>::type;
results in the following error message:
/Users/todi/bootloader_poc/bluetoe/bluetoe/utility/include/bluetoe/meta_tools.hpp: In instantiation of 'struct bluetoe::details::remove_if_equal<std::tuple<std::tuple<bluetoe::details::characteristic_user_description_parameter>, std::tuple<bluetoe::details::client_characteristic_configuration_parameter>, std::tuple<bluetoe::details::descriptor_parameter> >, std::tuple<bluetoe::details::wildcard> >':
/Users/todi/bootloader_poc/bluetoe/bluetoe/utility/include/bluetoe/meta_tools.hpp:170:17: recursively required from 'struct bluetoe::details::remove_if_equal<std::tuple<std::tuple<bluetoe::details::characteristic_value_declaration_parameter, bluetoe::characteristic_uuid<745866312, 46925, 19597, 45443, 208696923798549>, bluetoe::fixed_value<unsigned char, 8> >, std::tuple<bluetoe::details::characteristic_user_description_parameter>, std::tuple<bluetoe::details::client_characteristic_configuration_parameter>, std::tuple<bluetoe::details::descriptor_parameter> >, std::tuple<bluetoe::details::wildcard> >'
/Users/todi/bootloader_poc/bluetoe/bluetoe/utility/include/bluetoe/meta_tools.hpp:170:17: required from 'struct bluetoe::details::remove_if_equal<std::tuple<std::tuple<bluetoe::details::characteristic_declaration_parameter, bluetoe::characteristic_uuid<745866312, 46925, 19597, 45443, 208696923798549>, bluetoe::details::empty_meta_type<bluetoe::details::characteristic_declaration_parameter> >, std::tuple<bluetoe::details::characteristic_value_declaration_parameter, bluetoe::characteristic_uuid<745866312, 46925, 19597, 45443, 208696923798549>, bluetoe::fixed_value<unsigned char, 8> >, std::tuple<bluetoe::details::characteristic_user_description_parameter>, std::tuple<bluetoe::details::client_characteristic_configuration_parameter>, std::tuple<bluetoe::details::descriptor_parameter> >, std::tuple<bluetoe::details::wildcard> >'
/Users/todi/bootloader_poc/source/bootloader.cpp:23:2: required from here
/Users/todi/bootloader_poc/bluetoe/bluetoe/utility/include/bluetoe/meta_tools.hpp:170:17: error: ambiguous template instantiation for 'struct bluetoe::details::remove_if_equal<std::tuple<std::tuple<bluetoe::details::characteristic_user_description_parameter> >, std::tuple<bluetoe::details::wildcard> >'
>::type type;
^~~~
compilation terminated due to -Wfatal-errors.
With the same compiler, using C++ version 11 or 14 does not trigger this error.
Applying the following options to a characteristic:
bluetoe::characteristic<
control_point_uuid,
bluetoe::mixin_write_notification_control_point_handler<
ble_handler,
&ble_handler::control_point_write,
control_point_uuid
>,
bluetoe::mixin_read_handler<
ble_handler,
&ble_handler::control_point_read
>,
bluetoe::notify,
bluetoe::write_without_response,
bluetoe::no_read_access
>
results in a warning:
/Users/todi/ble_spi/bluetoe/bluetoe/characteristic.hpp:484:104: error: enum constant in boolean context [-Werror=int-in-bool-context]
count_by_meta_type< client_characteristic_configuration_parameter, Options... >::count ? 1 : 0 };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
This should not happen! Warning occurred, when adding the write_without_response
option to the characteristic. client_characteristic_configuration_parameter
has a meta type of client_characteristic_configuration_parameter
, which seems to be not correct to me.
Right now server::notification_output()
/server::indication_output()
seems to check for CCCD bits regardless of whether it's actually used by the client, and from my understanding of the spec (3.3.3.3) it is entirely optional for either the client or the server to implement the descriptor (since a client can just drop the notification/indication if it doesn't want to handle it).
Nice to have for simple servers (also I had spent a few hours trying to figure out why I kept getting empty notifications and indications but that's neither here nor there).
The approach to keep LL control PDUs in the LL buffer leads to long delays in the LL communications as some LL masters use very large Instance value (os/x for example).
Passing an argument that is meant to be a parameter for a template should be caught as error when passing to an other template. For example when passing an appearance::mouse server option to a service, this should yield an error.
The "GAP SERVICE AND CHARACTERISTICS FOR GATT SERVER" Version 4.2 [Vol 3, Part C] is not implemented, but is mandatory for a LE peripheral.
server<>::notify<>()
and server<>::indicate<>()
are indicating the wrong (without respecting priorites) characteristics, when priorities are used.
while testing a bootloader example, there was a situation, where the ATT_write_request and ATT_write_reponse suddenly started to take place in a single connection event. The error code at the end of last ATT_write_request was 0x83 which is buffer_overrun_attempt
on the application layer and indicates that the bootloader received more data the what was send from the bootloader client.
Idea: Maybe it could save some power to copy some of the functions that are involved in handling empty connection events to RAM to run fast (due to not having wait states) and thus to keep the CPU more in sleep.
Especially with GCC, compile times are rising fast, when having real-world projects and using notification priorities.
http://metaben.ch seems to be a good list to pick one library from.
Connecting HCI over a generalized transport (USB, SPI, UART...) to a bluetoe::server<>
instance.
We can start this on a separated branch. Separating the transport will help in making the part of the library testable. I would suggest to add new folders named hci to the ./bluetoe and ./tests folder.
I don't think that reusing bluetoe::link_layer::link_layer
would make sense, when we are implementing L2CAP over HCI.
Currently, in nrf51.cpp the initialization of the radio waits busy for the readiness of the high frequency clock. This should be avoided to save power.
Implementation of the Device Timer Service 1.0.
The new attribute_handle<> feature costs ~600 bytes in flash if applied on a small size example, even when the feature is not used. Maybe it is possible to create some short cuts that can be used when the feature is not used.
applying server_name<>
as a service argument does not yield a compilation error. Instead, the option in not applied and silently ignored.
If this option is given as an option to a service, this has to result in a compilation error.
Due to changed paths, the example won't build with the include directories given in ./examples/nrfXX_toolchain_support.
Make sure, a user can get the information, which peripherals are used by Bluetoe.
Using a service_uuid instead of a characteristic_uuid does not yield an error. Instead bluetoe uses generated UUIDs for the characteristics.
link_layer::disconnect does not wait just until the send out PDU gets acknowledged, but until the connection timeout is reached.
If the attempt to read the characteristic value for an value indication, fails, there should be no PDU being send out.
This should not compile due to the missing characteristic UUID:
bluetoe::server<
bluetoe::service<
bluetoe::service_uuid16< 0x0816 >,
bluetoe::characteristic<
bluetoe::fixed_uint8_value< 0x42 >
>
>
>;
When a project adds Bluetoe by including Bluetoe's top level CMakeLists.txt (add_subdirectory), all unit test binary targets of Bluetoe become targets of the including project.
In order for the GATT Discover All Primary Services procedure to work correctly, Read by Group Type Request should not return lists that contains gaps. Group Type Request is used to discover services, and can return only services of the same UUID length. If the server contains mixed 16-bit and 128-bit UUIDs, the server shall not assemble lists where two services are contain, where a service of the other kind would be in the middle.
For example, a server containing a 16-bit UUID service, followed by a 128-bit UUID service, followed by a 16-bit UUID service again, the server should not put both 16-bit UUID services into one Read by Group Type Response.
I notify()
is called on a characteristic that gets it's UUID automatic the static_assert( !std::is_same< uuid, no_such_type >::value, "If instanciating a characteristic<> for testing, please provide a UUID." );
in characteristic.hpp fires.
If the connection is encrypted, currently, if a the CRC of a received PDU is correct, but the MIC is incorrect, the last PDU is resent.
This might happen, if the master did not received the acknowledgment for a PDU and thus resends a PDU. In this case, the receive packet counter would have been incremented and would result in a MIC error computed by the radios CCM hardware. This case could be detected by looking at the PDUs sequence number. If that indicates that the PDU was resend, the MIC error is ok. Otherwise, the connection should be closed (if CRC is correct).
This applies to the current nrf51 binding.
implement Reconnection Configuration Service
Currently, the default transmit and receive buffer size is 59, which is 2 * minimum PDU size + 1 to allow effective usage of pdu_ring_buffer<>. If the minimum PDU size is larger due to overhead between header and body (as for the nrf51/52), fragmentation can cause an exhausting of the buffer (when both pointers point in the middle of the buffer).
according to "Generic Access Profile" 9.3.9:
"While a device is in the Peripheral role the device may support the connection parameter update procedure."
Travis CI seems to have a fixed maximum runtime of 10 minutes. Running make with -j results in build failures during the compilation of the tests (out of memory).
A new CI should:
If we host a CI server on our own, we could add additional hardware to do integration tests with different hardware bindings (but maybe this shouldn't be scope of this issue).
The link layer shows support for Connection Parameters Request Procedure. According to Core Spec 4.2: Vol. 6, Part B, 4.6.2:
A Controller that supports Connection Parameters Request Procedure shall support the following sections within this document:
• LL_REJECT_IND_EXT
...
The Bluetoe link layer indicates support for Connection Parameters Request Procedure, so it would also have to indicate support for Extended Reject Indication.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.