BlueToe
an alternative GATT/BLE implementation
Loading...
Searching...
No Matches
adv_service_list.hpp
1#ifndef BLUETOE_ADV_SERVICE_LIST_HPP
2#define BLUETOE_ADV_SERVICE_LIST_HPP
3
4#include <bluetoe/codes.hpp>
5#include <bluetoe/bits.hpp>
7#include <bluetoe/service_uuid.hpp>
8#include <bluetoe/meta_types.hpp>
9
10#include <algorithm>
11
12namespace bluetoe {
13
14 namespace details {
15 struct list_of_16_bit_service_uuids_tag {};
16 struct list_of_128_bit_service_uuids_tag {};
17 }
18
27 template < typename ... UUID16 >
30 struct meta_type
31 : details::list_of_16_bit_service_uuids_tag
32 , details::valid_server_option_meta_type
33 {};
34
35 static std::uint8_t* advertising_data( std::uint8_t* begin, std::uint8_t* end )
36 {
37 const std::size_t buffer_size = end - begin;
38
39 if ( buffer_size < 4 )
40 return begin;
41
42 const std::size_t max_uuids = std::min( (buffer_size - 2) / 2, sizeof ...(UUID16));
43
44 *begin = 1 + 2 * max_uuids;
45 ++begin;
46
47 *begin = max_uuids == sizeof ...(UUID16)
48 ? bits( details::gap_types::complete_service_uuids_16 )
49 : bits( details::gap_types::incomplete_service_uuids_16 );
50 ++begin;
51
52 for ( std::size_t uuid = 0; uuid != max_uuids; ++uuid )
53 {
54 begin = details::write_16bit( begin, values_[ uuid ] );
55 }
56
57 return begin;
58 }
59
60 static constexpr std::uint16_t values_[ sizeof ...(UUID16) ] = { UUID16::as_16bit()...};
62 };
63
65 template < typename ... UUID16 >
66 constexpr std::uint16_t list_of_16_bit_service_uuids< UUID16... >::values_[ sizeof ...(UUID16) ];
70 template <>
72 struct meta_type
73 : details::list_of_16_bit_service_uuids_tag
74 , details::valid_server_option_meta_type
75 {};
76
77 static std::uint8_t* advertising_data( std::uint8_t* begin, std::uint8_t* )
78 {
79 return begin;
80 }
81 };
82
83 template < typename ... UUID16 >
84 struct list_of_16_bit_service_uuids< std::tuple< UUID16... > > : list_of_16_bit_service_uuids< UUID16... > {};
89 struct meta_type
90 : details::list_of_16_bit_service_uuids_tag
91 , details::list_of_128_bit_service_uuids_tag
92 , details::valid_server_option_meta_type
93 {};
94
95 static constexpr std::uint8_t* advertising_data( std::uint8_t* begin, std::uint8_t* )
96 {
97 return begin;
98 }
100 };
101
102 namespace details {
103
104 struct uuid_128_writer
105 {
106 constexpr uuid_128_writer( std::uint8_t*& b, std::uint8_t* e )
107 : begin( b )
108 , end( e )
109 {
110 }
111
112 template< typename UUID >
113 void each()
114 {
115 if ( begin + sizeof( UUID::bytes ) <= end )
116 {
117 std::copy( std::begin( UUID::bytes ), std::end( UUID::bytes ), begin );
118 begin += sizeof( UUID::bytes );
119 }
120 }
121
122 std::uint8_t*& begin;
123 std::uint8_t* const end;
124 };
125 }
126
127 template < typename ... UUID128 >
130 struct meta_type :
131 details::list_of_128_bit_service_uuids_tag,
132 details::valid_server_option_meta_type {};
133
134 static std::uint8_t* advertising_data( std::uint8_t* begin, std::uint8_t* end )
135 {
136 static constexpr std::size_t uuid_size = 16;
137 const std::size_t buffer_size = end - begin;
138
139 if ( buffer_size < 2 + uuid_size )
140 return begin;
141
142 const std::size_t max_uuids = std::min( (buffer_size - 2) / uuid_size, sizeof ...(UUID128));
143
144 *begin = 1 + uuid_size * max_uuids;
145 ++begin;
146
147 *begin = max_uuids == sizeof ...(UUID128)
148 ? bits( details::gap_types::complete_service_uuids_128 )
149 : bits( details::gap_types::incomplete_service_uuids_128 );
150 ++begin;
151
152 details::for_< UUID128... >::each( details::uuid_128_writer( begin, end ) );
153
154 return begin;
155 }
157 };
158
160 template < typename ... UUID16 >
161 struct list_of_128_bit_service_uuids< std::tuple< UUID16... > > : list_of_128_bit_service_uuids< UUID16... > {};
162
163 template <>
164 struct list_of_128_bit_service_uuids<> {
165 struct meta_type :
166 details::list_of_128_bit_service_uuids_tag,
167 details::valid_server_option_meta_type {};
168
169 static constexpr std::uint8_t* advertising_data( std::uint8_t* begin, std::uint8_t* ) {
170 return begin;
171 }
172 };
175 namespace details {
176 template < typename T >
177 struct extract_uuid {
178 using type = typename T::uuid;
179 };
180
181 template < typename Filter, typename ... Services >
182 struct create_list_of_service_uuids
183 {
184 typedef typename bluetoe::details::transform_list<
185 std::tuple< Services... >,
186 extract_uuid >::type uuids;
187
188 typedef typename find_all_by_meta_type< Filter, uuids >::type type;
189 };
190
191 template < typename ServiceList >
192 struct default_list_of_16_bit_service_uuids;
193
194 template < typename ... Services >
195 struct default_list_of_16_bit_service_uuids< std::tuple< Services... > > : list_of_16_bit_service_uuids<
196 typename create_list_of_service_uuids< bluetoe::details::service_uuid_16_meta_type, Services... >::type > {};
197
198 template < typename ServiceList >
199 struct default_list_of_128_bit_service_uuids;
200
201 template < typename ... Services >
202 struct default_list_of_128_bit_service_uuids< std::tuple< Services... > > : list_of_128_bit_service_uuids<
203 typename create_list_of_service_uuids< bluetoe::details::service_uuid_128_meta_type, Services... >::type > {};
204 }
205}
206
207#endif
Definition: adv_service_list.hpp:128
complete / incomplete list of 16 bit service UUIDs to be added to the advertising data
Definition: adv_service_list.hpp:28
Definition: adv_service_list.hpp:87