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