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