BlueToe
an alternative GATT/BLE implementation
Loading...
Searching...
No Matches
outgoing_priority.hpp
1#ifndef BLUETOE_OUTGOING_PRIORITY_HPP
2#define BLUETOE_OUTGOING_PRIORITY_HPP
3
5
6namespace bluetoe {
7
8 namespace details {
9 struct outgoing_priority_meta_type {};
10
11 template < typename Services, typename ServiceUUID >
12 struct number_of_additional_priorities
13 {
14 template < typename Service >
15 using has_uuid = std::is_same< typename Service::uuid, ServiceUUID >;
16
17 // find the Service from the ServiceUUID in the List of Services
18 using service = typename find_if< Services, has_uuid >::type;
19 static constexpr int size = service::notification_priority::size;
20
21 // if the number of named characteristics is equal to the number of characteristics in the service,
22 // no characteristic will have default priority
23 static constexpr int size_with_default = size == service::number_of_client_configs
24 ? size
25 : size + 1;
26
27 // For a Service that doesn't contain a priority per characteristic, there is at least one
28 // addition priority, because all characteristics in the service form have a new unique priority
29 using type = std::integral_constant< int, size_with_default == 0 ? 1 : size_with_default >;
30 };
31
32 template < typename ... Us >
33 struct check_server_parameter
34 {
35 static_assert( details::count_by_meta_type< details::service_uuid_meta_type, Us... >::count == sizeof...( Us ),
36 "Only service UUIDs are acceptable parameters to higher_outgoing_priority<> as server parameter." );
37
38 static constexpr bool check = true;
39 };
40
41 template < typename ... Us >
42 struct check_service_parameter
43 {
44 static_assert( details::count_by_meta_type< details::characteristic_uuid_meta_type, Us... >::count == sizeof...( Us ),
45 "Only characteristic UUIDs are acceptable parameters to higher_outgoing_priority<> as service parameter." );
46
47 static constexpr bool check = true;
48 };
49
50 template < typename T, int Prio >
51 struct add_prio;
52
53 template <>
54 struct add_prio< std::tuple<>, 0 >
55 {
56 using type = std::tuple< std::integral_constant< int, 1 > >;
57 };
58
59 template < int N, typename ...Ts >
60 struct add_prio< std::tuple< std::integral_constant< int, N >, Ts... >, 0 >
61 {
62 using type = std::tuple< std::integral_constant< int, N + 1 >, Ts... >;
63 };
64
65 template < int Prio >
66 struct add_prio< std::tuple<>, Prio >
67 {
68 using type = typename add_type<
69 std::integral_constant< int, 0 >,
70 typename add_prio< std::tuple<>, Prio -1 >::type >::type;
71 };
72
73 template < int N, typename ...Ts, int Prio >
74 struct add_prio< std::tuple< std::integral_constant< int, N >, Ts... >, Prio >
75 {
76 using type = typename add_type<
77 std::integral_constant< int, N >,
78 typename add_prio< std::tuple< Ts... >, Prio -1 >::type >::type;
79 };
80
81 }
82
159 template < typename ... UUIDs >
162 struct meta_type :
163 details::outgoing_priority_meta_type,
164 details::valid_service_option_meta_type,
165 details::valid_server_option_meta_type {};
166
167 template < typename Services, typename Service >
168 struct service_base_priority
169 {
170 template < typename Sum, typename ServiceUUID >
171 struct optional_sum_prio
172 {
173 using found = std::integral_constant< bool, Sum::first_type::value || std::is_same< ServiceUUID, typename Service::uuid >::value >;
174 using prio = typename Sum::second_type;
175
176 // Only sum up the priorities that are before ServiceUUID in UUIDs...
177 using sum = typename details::select_type< found::value,
178 prio,
179 typename details::number_of_additional_priorities< Services, ServiceUUID >::type >::type;
180
181 using type = details::pair< found, sum >;
182 };
183
184 // while Service::uuid is not in UUIDs... sum up the priorities of the services
185 using type = typename details::fold_left<
186 std::tuple< UUIDs... >,
187 optional_sum_prio,
188 details::pair< std::false_type, std::integral_constant< int, 0 > > >::type;
189
190 static constexpr int value = type::second_type::value;
191 };
192
193 template < typename Sum, typename Service >
194 struct expand_shared_priorities
195 {
196 static constexpr int sum = Sum::value;
197
198 // is this one of the services that share the priorities?
199 static constexpr bool shared = details::index_of< typename Service::uuid, UUIDs... >::value == sizeof...( UUIDs );
200
201 static constexpr int prios = Service::notification_priority::size;
202
203 static constexpr int shared_value = prios > sum ? prios : sum;
204 static constexpr int value = shared ? shared_value : sum;
205
206 using type = std::integral_constant< int, value >;
207 };
208
209 // this function is called on the server instantiation
210 template < typename Services, typename Service, typename Characteristic >
211 struct characteristic_priority
212 {
213 static constexpr auto checked = details::check_server_parameter< UUIDs... >::check;
214
215 static constexpr int service_prio = service_base_priority< Services, Service >::value;
216
217 // there is a big difference whether a Service is within UUIDs or not. In case, a Service is not within UUIDs
218 // (Service B and C in the example above), characteristics from different services can share the same priority.
219 static constexpr bool priorized_service = details::index_of< typename Service::uuid, UUIDs... >::value != sizeof...( UUIDs );
220
221 // the maximum of introduced priorities of all services that are not within UUIDs (and thus share a range of priorities).
222 static constexpr int shared_priorities = details::fold< Services, expand_shared_priorities, std::integral_constant< int, 0 > >::type::value;
223
224 static constexpr int char_prio = Service::notification_priority::template characteristic_position< Characteristic, priorized_service, shared_priorities >::value;
225
226 static constexpr int value = service_prio + char_prio;
227 };
228
229 template < typename Services, typename Service >
230 struct numbers_from_char
231 {
232 template < typename Numbers, typename Characteristic >
233 struct impl
234 {
235 static constexpr int prio = characteristic_priority< Services, Service, Characteristic >::value;
236 using type = typename details::add_prio< Numbers, prio >::type;
237 };
238 };
239
240 // Returns a list of numbers of priorities, starting with the number of characteristics with prio 0 (highest)
241 template < typename Services >
242 struct numbers
243 {
244 template < typename List, typename Characteristic >
245 using characteristics_with_cccd = details::select_type<
246 Characteristic::number_of_client_configs,
247 typename details::add_type< List, Characteristic >::type,
248 List >;
249
250 template < typename Numbers, typename Service >
251 using numbers_from_services = details::fold<
252 typename details::fold<
253 typename Service::characteristics,
254 characteristics_with_cccd >::type,
255 numbers_from_char< Services, Service >::template impl,
256 Numbers >;
257
258 using type = typename details::fold< Services, numbers_from_services, std::tuple<> >::type;
259 };
260
261 static constexpr std::size_t size = sizeof...( UUIDs );
262
263 // this function is called on the service instantiation
264 template < typename Characteristic, bool WithinPriorizedService, int SharedPriorities >
265 struct characteristic_position
266 {
267 static constexpr auto checked = details::check_service_parameter< UUIDs... >::check;
268
269 static constexpr int pos = details::index_of< typename Characteristic::configured_uuid, UUIDs... >::value;
270 static constexpr int value = WithinPriorizedService
271 ? pos
272 : pos + SharedPriorities - size;
273 };
274
276 };
277
283 template < class ... UUIDs >
286 struct meta_type :
287 details::outgoing_priority_meta_type,
288 details::valid_service_option_meta_type,
289 details::valid_server_option_meta_type {};
291 };
292
298}
299
300
301#endif
wrap< typename select_type_impl< Select >::template f< A, B > > select_type
Select A or B by Select. If Select == true, the result is A; B otherwise.
Definition: meta_tools.hpp:38
Defines priorities of notified or indicated characteristics.
Definition: outgoing_priority.hpp:160
Defines priorities of notified or indicated characteristics.
Definition: outgoing_priority.hpp:284