xref: /btstack/src/ble/gatt-service/cycling_power_service_server.h (revision 9fe70df8e90dd49c2bda5d4537055c27312e7ef8)
1*9fe70df8SMilanka Ringwald /*
2*9fe70df8SMilanka Ringwald  * Copyright (C) 2018 BlueKitchen GmbH
3*9fe70df8SMilanka Ringwald  *
4*9fe70df8SMilanka Ringwald  * Redistribution and use in source and binary forms, with or without
5*9fe70df8SMilanka Ringwald  * modification, are permitted provided that the following conditions
6*9fe70df8SMilanka Ringwald  * are met:
7*9fe70df8SMilanka Ringwald  *
8*9fe70df8SMilanka Ringwald  * 1. Redistributions of source code must retain the above copyright
9*9fe70df8SMilanka Ringwald  *    notice, this list of conditions and the following disclaimer.
10*9fe70df8SMilanka Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*9fe70df8SMilanka Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*9fe70df8SMilanka Ringwald  *    documentation and/or other materials provided with the distribution.
13*9fe70df8SMilanka Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*9fe70df8SMilanka Ringwald  *    contributors may be used to endorse or promote products derived
15*9fe70df8SMilanka Ringwald  *    from this software without specific prior written permission.
16*9fe70df8SMilanka Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*9fe70df8SMilanka Ringwald  *    personal benefit and not for any commercial purpose or for
18*9fe70df8SMilanka Ringwald  *    monetary gain.
19*9fe70df8SMilanka Ringwald  *
20*9fe70df8SMilanka Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*9fe70df8SMilanka Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*9fe70df8SMilanka Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*9fe70df8SMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*9fe70df8SMilanka Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*9fe70df8SMilanka Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*9fe70df8SMilanka Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*9fe70df8SMilanka Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*9fe70df8SMilanka Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*9fe70df8SMilanka Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*9fe70df8SMilanka Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*9fe70df8SMilanka Ringwald  * SUCH DAMAGE.
32*9fe70df8SMilanka Ringwald  *
33*9fe70df8SMilanka Ringwald  * Please inquire about commercial licensing options at
34*9fe70df8SMilanka Ringwald  * [email protected]
35*9fe70df8SMilanka Ringwald  *
36*9fe70df8SMilanka Ringwald  */
37*9fe70df8SMilanka Ringwald #ifndef __CYCLING_POWER_SERVICE_SERVER_H
38*9fe70df8SMilanka Ringwald #define __CYCLING_POWER_SERVICE_SERVER_H
39*9fe70df8SMilanka Ringwald 
40*9fe70df8SMilanka Ringwald #include <stdint.h>
41*9fe70df8SMilanka Ringwald 
42*9fe70df8SMilanka Ringwald #if defined __cplusplus
43*9fe70df8SMilanka Ringwald extern "C" {
44*9fe70df8SMilanka Ringwald #endif
45*9fe70df8SMilanka Ringwald 
46*9fe70df8SMilanka Ringwald /**
47*9fe70df8SMilanka Ringwald  * Implementation of the GATT Cycling Power Service Server
48*9fe70df8SMilanka Ringwald  */
49*9fe70df8SMilanka Ringwald 
50*9fe70df8SMilanka Ringwald // *****************************************************************************
51*9fe70df8SMilanka Ringwald /* GATT_SERVICE_SERVER_START(cycling_power_service_server){Cycling PowerService}
52*9fe70df8SMilanka Ringwald  *
53*9fe70df8SMilanka Ringwald  */
54*9fe70df8SMilanka Ringwald // *****************************************************************************
55*9fe70df8SMilanka Ringwald /* GATT_SERVICE_SERVER_END */
56*9fe70df8SMilanka Ringwald 
57*9fe70df8SMilanka Ringwald /* API_START */
58*9fe70df8SMilanka Ringwald #define CYCLING_POWER_MANUFACTURER_SPECIFIC_DATA_MAX_SIZE   16
59*9fe70df8SMilanka Ringwald 
60*9fe70df8SMilanka Ringwald typedef enum {
61*9fe70df8SMilanka Ringwald     CP_PEDAL_POWER_BALANCE_REFERENCE_UNKNOWN = 0,
62*9fe70df8SMilanka Ringwald     CP_PEDAL_POWER_BALANCE_REFERENCE_LEFT,
63*9fe70df8SMilanka Ringwald     CP_PEDAL_POWER_BALANCE_REFERENCE_NOT_SUPPORTED
64*9fe70df8SMilanka Ringwald } cycling_power_pedal_power_balance_reference_t;
65*9fe70df8SMilanka Ringwald 
66*9fe70df8SMilanka Ringwald typedef enum {
67*9fe70df8SMilanka Ringwald     CP_TORQUE_SOURCE_WHEEL = 0,
68*9fe70df8SMilanka Ringwald     CP_TORQUE_SOURCE_CRANK,
69*9fe70df8SMilanka Ringwald     CP_TORQUE_SOURCE_NOT_SUPPORTED
70*9fe70df8SMilanka Ringwald } cycling_power_torque_source_t;
71*9fe70df8SMilanka Ringwald 
72*9fe70df8SMilanka Ringwald typedef enum {
73*9fe70df8SMilanka Ringwald     CP_SENSOR_MEASUREMENT_CONTEXT_FORCE = 0,
74*9fe70df8SMilanka Ringwald     CP_SENSOR_MEASUREMENT_CONTEXT_TORQUE
75*9fe70df8SMilanka Ringwald } cycling_power_sensor_measurement_context_t;
76*9fe70df8SMilanka Ringwald 
77*9fe70df8SMilanka Ringwald typedef enum {
78*9fe70df8SMilanka Ringwald     CP_DISTRIBUTED_SYSTEM_UNSPECIFIED = 0,
79*9fe70df8SMilanka Ringwald     CP_DISTRIBUTED_SYSTEM_NOT_SUPPORTED,
80*9fe70df8SMilanka Ringwald     CP_DISTRIBUTED_SYSTEM_SUPPORTED
81*9fe70df8SMilanka Ringwald } cycling_power_distributed_system_t;
82*9fe70df8SMilanka Ringwald 
83*9fe70df8SMilanka Ringwald typedef enum {
84*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_PEDAL_POWER_BALANCE_PRESENT = 0,
85*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_PEDAL_POWER_BALANCE_REFERENCE, // 0 - unknown, 1 - left
86*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_ACCUMULATED_TORQUE_PRESENT,
87*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_ACCUMULATED_TORQUE_SOURCE, // 0 - wheel based, 1 - crank based
88*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_WHEEL_REVOLUTION_DATA_PRESENT,
89*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_CRANK_REVOLUTION_DATA_PRESENT,
90*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_EXTREME_FORCE_MAGNITUDES_PRESENT,
91*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_EXTREME_TORQUE_MAGNITUDES_PRESENT,
92*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_EXTREME_ANGLES_PRESENT,
93*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_TOP_DEAD_SPOT_ANGLE_PRESENT,
94*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_BOTTOM_DEAD_SPOT_ANGLE_PRESENT,
95*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_ACCUMULATED_ENERGY_PRESENT,
96*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_OFFSET_COMPENSATION_INDICATOR,
97*9fe70df8SMilanka Ringwald     CP_MEASUREMENT_FLAG_RESERVED
98*9fe70df8SMilanka Ringwald } cycling_power_measurement_flag_t;
99*9fe70df8SMilanka Ringwald 
100*9fe70df8SMilanka Ringwald typedef enum {
101*9fe70df8SMilanka Ringwald     CP_INSTANTANEOUS_MEASUREMENT_DIRECTION_UNKNOWN = 0,
102*9fe70df8SMilanka Ringwald     CP_INSTANTANEOUS_MEASUREMENT_DIRECTION_TANGENTIAL_COMPONENT,
103*9fe70df8SMilanka Ringwald     CP_INSTANTANEOUS_MEASUREMENT_DIRECTION_RADIAL_COMPONENT,
104*9fe70df8SMilanka Ringwald     CP_INSTANTANEOUS_MEASUREMENT_DIRECTION_LATERAL_COMPONENT
105*9fe70df8SMilanka Ringwald } cycling_power_instantaneous_measurement_direction_t;
106*9fe70df8SMilanka Ringwald 
107*9fe70df8SMilanka Ringwald typedef enum {
108*9fe70df8SMilanka Ringwald     CP_VECTOR_FLAG_CRANK_REVOLUTION_DATA_PRESENT = 0,
109*9fe70df8SMilanka Ringwald     CP_VECTOR_FLAG_FIRST_CRANK_MEASUREMENT_ANGLE_PRESENT,
110*9fe70df8SMilanka Ringwald     CP_VECTOR_FLAG_INSTANTANEOUS_FORCE_MAGNITUDE_ARRAY_PRESENT,
111*9fe70df8SMilanka Ringwald     CP_VECTOR_FLAG_INSTANTANEOUS_TORQUE_MAGNITUDE_ARRAY_PRESENT,
112*9fe70df8SMilanka Ringwald     CP_VECTOR_FLAG_INSTANTANEOUS_MEASUREMENT_DIRECTION = 4, // 2 bit
113*9fe70df8SMilanka Ringwald     CP_VECTOR_FLAG_RESERVED = 6
114*9fe70df8SMilanka Ringwald } cycling_power_vector_flag_t;
115*9fe70df8SMilanka Ringwald 
116*9fe70df8SMilanka Ringwald typedef enum {
117*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_OTHER,
118*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_TOP_OF_SHOE,
119*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_IN_SHOE,
120*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_HIP,
121*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_FRONT_WHEEL,
122*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_LEFT_CRANK,
123*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_RIGHT_CRANK,
124*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_LEFT_PEDAL,
125*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_RIGHT_PEDAL,
126*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_FRONT_HUB,
127*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_REAR_DROPOUT,
128*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_CHAINSTAY,
129*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_REAR_WHEEL,
130*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_REAR_HUB,
131*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_CHEST,
132*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_SPIDER,
133*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_CHAIN_RING,
134*9fe70df8SMilanka Ringwald     CP_SENSOR_LOCATION_RESERVED
135*9fe70df8SMilanka Ringwald } cycling_power_sensor_location_t;
136*9fe70df8SMilanka Ringwald 
137*9fe70df8SMilanka Ringwald typedef enum {
138*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_PEDAL_POWER_BALANCE_SUPPORTED = 0,
139*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_ACCUMULATED_TORQUE_SUPPORTED,
140*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_WHEEL_REVOLUTION_DATA_SUPPORTED,
141*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_CRANK_REVOLUTION_DATA_SUPPORTED,
142*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_EXTREME_MAGNITUDES_SUPPORTED,
143*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_EXTREME_ANGLES_SUPPORTED,
144*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_TOP_AND_BOTTOM_DEAD_SPOT_ANGLE_SUPPORTED,
145*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_ACCUMULATED_ENERGY_SUPPORTED,
146*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_OFFSET_COMPENSATION_INDICATOR_SUPPORTED,
147*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_OFFSET_COMPENSATION_SUPPORTED,
148*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_CYCLING_POWER_MEASUREMENT_CHARACTERISTIC_CONTENT_MASKING_SUPPORTED,
149*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_MULTIPLE_SENSOR_LOCATIONS_SUPPORTED,
150*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_CRANK_LENGTH_ADJUSTMENT_SUPPORTED,
151*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_CHAIN_LENGTH_ADJUSTMENT_SUPPORTED,
152*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_CHAIN_WEIGHT_ADJUSTMENT_SUPPORTED,
153*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_SPAN_LENGTH_ADJUSTMENT_SUPPORTED,
154*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_SENSOR_MEASUREMENT_CONTEXT, // 0-force based, 1-torque based
155*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_INSTANTANEOUS_MEASUREMENT_DIRECTION_SUPPORTED,
156*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_FACTORY_CALIBRATION_DATE_SUPPORTED,
157*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_ENHANCED_OFFSET_COMPENSATION_SUPPORTED,
158*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_DISTRIBUTED_SYSTEM_SUPPORT = 20,  // 0-unspecified, 1-not for use in distr. system, 2-used in distr. system, 3-reserved
159*9fe70df8SMilanka Ringwald     CP_FEATURE_FLAG_RESERVED = 22
160*9fe70df8SMilanka Ringwald } cycling_power_feature_flag_t;
161*9fe70df8SMilanka Ringwald 
162*9fe70df8SMilanka Ringwald typedef enum {
163*9fe70df8SMilanka Ringwald     CP_CALIBRATION_STATUS_INCORRECT_CALIBRATION_POSITION = 0x01,
164*9fe70df8SMilanka Ringwald     CP_CALIBRATION_STATUS_MANUFACTURER_SPECIFIC_ERROR_FOLLOWS = 0xFF
165*9fe70df8SMilanka Ringwald } cycling_power_calibration_status_t;
166*9fe70df8SMilanka Ringwald 
167*9fe70df8SMilanka Ringwald 
168*9fe70df8SMilanka Ringwald /**
169*9fe70df8SMilanka Ringwald  * @brief Init Server with ATT DB
170*9fe70df8SMilanka Ringwald  */
171*9fe70df8SMilanka Ringwald void cycling_power_service_server_init(uint32_t feature_flags,
172*9fe70df8SMilanka Ringwald     cycling_power_pedal_power_balance_reference_t reference, cycling_power_torque_source_t torque_source,
173*9fe70df8SMilanka Ringwald     cycling_power_sensor_location_t * supported_sensor_locations, uint16_t num_supported_sensor_locations,
174*9fe70df8SMilanka Ringwald     cycling_power_sensor_location_t current_sensor_location);
175*9fe70df8SMilanka Ringwald /**
176*9fe70df8SMilanka Ringwald  * @brief Push update
177*9fe70df8SMilanka Ringwald  * @note triggers notifications if subscribed
178*9fe70df8SMilanka Ringwald  */
179*9fe70df8SMilanka Ringwald void cycling_power_service_server_update_values(void);
180*9fe70df8SMilanka Ringwald 
181*9fe70df8SMilanka Ringwald void cycling_power_server_enhanced_calibration_done(cycling_power_sensor_measurement_context_t measurement_type,
182*9fe70df8SMilanka Ringwald                 uint16_t calibrated_value, uint16_t manufacturer_company_id,
183*9fe70df8SMilanka Ringwald                 uint8_t num_manufacturer_specific_data, uint8_t * manufacturer_specific_data);
184*9fe70df8SMilanka Ringwald 
185*9fe70df8SMilanka Ringwald int cycling_power_get_measurement_adv(uint16_t adv_interval, uint8_t * value, uint16_t max_value_size);
186*9fe70df8SMilanka Ringwald /**
187*9fe70df8SMilanka Ringwald  * @brief Register callback for the calibration.
188*9fe70df8SMilanka Ringwald  * @param callback
189*9fe70df8SMilanka Ringwald  */
190*9fe70df8SMilanka Ringwald void cycling_power_service_server_packet_handler(btstack_packet_handler_t callback);
191*9fe70df8SMilanka Ringwald 
192*9fe70df8SMilanka Ringwald void  cycling_power_server_calibration_done(cycling_power_sensor_measurement_context_t measurement_type, uint16_t calibrated_value);
193*9fe70df8SMilanka Ringwald 
194*9fe70df8SMilanka Ringwald int  cycling_power_service_server_set_factory_calibration_date(gatt_date_time_t date);
195*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_sampling_rate(uint8_t sampling_rate_hz);
196*9fe70df8SMilanka Ringwald 
197*9fe70df8SMilanka Ringwald void cycling_power_service_server_add_torque(int16_t torque_m);
198*9fe70df8SMilanka Ringwald void cycling_power_service_server_add_wheel_revolution(int32_t wheel_revolution, uint16_t wheel_event_time_s);
199*9fe70df8SMilanka Ringwald void cycling_power_service_server_add_crank_revolution(uint16_t crank_revolution, uint16_t crank_event_time_s);
200*9fe70df8SMilanka Ringwald void cycling_power_service_add_energy(uint16_t energy_kJ);
201*9fe70df8SMilanka Ringwald 
202*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_instantaneous_power(int16_t instantaneous_power_watt);
203*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_pedal_power_balance(uint8_t pedal_power_balance_percentage);
204*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_force_magnitude(int16_t min_force_magnitude_newton, int16_t max_force_magnitude_newton);
205*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_torque_magnitude(int16_t min_torque_magnitude_newton, int16_t max_torque_magnitude_newton);
206*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_angle(uint16_t min_angle_deg, uint16_t max_angle_deg);
207*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_top_dead_spot_angle(uint16_t top_dead_spot_angle_deg);
208*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_bottom_dead_spot_angle(uint16_t bottom_dead_spot_angle_deg);
209*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_force_magnitude_values(int force_magnitude_count, int16_t * force_magnitude_newton_array);
210*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_torque_magnitude_values(int torque_magnitude_count, int16_t * torque_magnitude_newton_array);
211*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_instantaneous_measurement_direction(cycling_power_instantaneous_measurement_direction_t direction);
212*9fe70df8SMilanka Ringwald // send only in first packet, ignore during continuation
213*9fe70df8SMilanka Ringwald void cycling_power_service_server_set_first_crank_measurement_angle(uint16_t first_crank_measurement_angle_deg);
214*9fe70df8SMilanka Ringwald 
215*9fe70df8SMilanka Ringwald uint16_t cycling_power_service_measurement_flags(void);
216*9fe70df8SMilanka Ringwald uint8_t  cycling_power_service_vector_flags(void);
217*9fe70df8SMilanka Ringwald /* API_END */
218*9fe70df8SMilanka Ringwald 
219*9fe70df8SMilanka Ringwald #if defined __cplusplus
220*9fe70df8SMilanka Ringwald }
221*9fe70df8SMilanka Ringwald #endif
222*9fe70df8SMilanka Ringwald 
223*9fe70df8SMilanka Ringwald #endif
224*9fe70df8SMilanka Ringwald 
225